From 5119f7da18eb7f10457d3e4b2c1d60f8d94a4cbf Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 23 May 2023 20:04:51 +0200 Subject: directory size limit :< --- src/tools/tidy/src/ui_tests.rs | 2 +- tests/ui/higher-lifetime-bounds.rs | 69 ----------- tests/ui/higher-lifetime-bounds.stderr | 68 ----------- tests/ui/higher-rank-trait-bounds/complex.rs | 28 ----- .../due-to-where-clause.rs | 13 -- .../due-to-where-clause.stderr | 11 -- .../higher-rank-trait-bounds/fn-ptr.classic.stderr | 19 --- tests/ui/higher-rank-trait-bounds/fn-ptr.rs | 14 --- .../hang-on-deeply-nested-dyn.rs | 16 --- .../hang-on-deeply-nested-dyn.stderr | 22 ---- .../hrtb-binder-levels-in-object-types.rs | 29 ----- .../hrtb-cache-issue-54302.rs | 24 ---- .../hrtb-cache-issue-54302.stderr | 11 -- .../hrtb-conflate-regions.rs | 31 ----- .../hrtb-conflate-regions.stderr | 20 --- .../hrtb-debruijn-in-receiver.rs | 18 --- .../hrtb-debruijn-in-receiver.stderr | 14 --- .../hrtb-debruijn-object-types-in-closures.rs | 16 --- .../hrtb-exists-forall-fn.rs | 18 --- .../hrtb-exists-forall-fn.stderr | 12 -- .../hrtb-exists-forall-trait-contravariant.rs | 36 ------ .../hrtb-exists-forall-trait-contravariant.stderr | 11 -- .../hrtb-exists-forall-trait-covariant.rs | 37 ------ .../hrtb-exists-forall-trait-invariant.rs | 29 ----- .../hrtb-exists-forall-trait-invariant.stderr | 11 -- .../hrtb-fn-like-trait-object.rs | 27 ---- .../higher-rank-trait-bounds/hrtb-fn-like-trait.rs | 27 ---- .../hrtb-higher-ranker-supertraits-transitive.rs | 50 -------- ...rtb-higher-ranker-supertraits-transitive.stderr | 23 ---- .../hrtb-higher-ranker-supertraits.rs | 48 -------- .../hrtb-higher-ranker-supertraits.stderr | 43 ------- .../hrtb-identity-fn-borrows.rs | 26 ---- .../hrtb-identity-fn-borrows.stderr | 14 --- .../hrtb-just-for-static.rs | 35 ------ .../hrtb-just-for-static.stderr | 34 ------ .../hrtb-malformed-lifetime-generics.rs | 20 --- .../hrtb-malformed-lifetime-generics.stderr | 62 ---------- .../higher-rank-trait-bounds/hrtb-opt-in-copy.rs | 28 ----- tests/ui/higher-rank-trait-bounds/hrtb-parse.rs | 36 ------ .../hrtb-perfect-forwarding.polonius.stderr | 71 ----------- .../hrtb-perfect-forwarding.rs | 56 --------- .../hrtb-perfect-forwarding.stderr | 79 ------------ .../hrtb-precedence-of-plus-where-clause.rs | 25 ---- .../hrtb-precedence-of-plus.rs | 13 -- .../hrtb-resolve-lifetime.rs | 14 --- .../hrtb-trait-object-paren-notation.rs | 26 ---- .../hrtb-trait-object-passed-to-closure.rs | 25 ---- .../higher-rank-trait-bounds/hrtb-type-outlives.rs | 46 ------- .../hrtb-unboxed-closure-trait.rs | 11 -- .../ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs | 7 -- .../hrtb-wrong-kind.stderr | 21 ---- tests/ui/higher-rank-trait-bounds/issue-100689.rs | 29 ----- tests/ui/higher-rank-trait-bounds/issue-102899.rs | 32 ----- tests/ui/higher-rank-trait-bounds/issue-30786.rs | 136 --------------------- .../ui/higher-rank-trait-bounds/issue-30786.stderr | 46 ------- .../issue-36139-normalize-closure-sig.rs | 19 --- tests/ui/higher-rank-trait-bounds/issue-39292.rs | 17 --- tests/ui/higher-rank-trait-bounds/issue-42114.rs | 20 --- tests/ui/higher-rank-trait-bounds/issue-43623.rs | 21 ---- tests/ui/higher-rank-trait-bounds/issue-46989.rs | 40 ------ .../ui/higher-rank-trait-bounds/issue-46989.stderr | 11 -- tests/ui/higher-rank-trait-bounds/issue-57639.rs | 29 ----- tests/ui/higher-rank-trait-bounds/issue-58451.rs | 13 -- .../ui/higher-rank-trait-bounds/issue-58451.stderr | 19 --- tests/ui/higher-rank-trait-bounds/issue-59311.rs | 22 ---- .../ui/higher-rank-trait-bounds/issue-59311.stderr | 18 --- tests/ui/higher-rank-trait-bounds/issue-60283.rs | 20 --- .../issue-62203-hrtb-ice.rs | 54 -------- .../issue-62203-hrtb-ice.stderr | 66 ---------- tests/ui/higher-rank-trait-bounds/issue-88446.rs | 35 ------ .../issue-88586-hr-self-outlives-in-trait-def.rs | 13 -- tests/ui/higher-rank-trait-bounds/issue-90177.rs | 32 ----- tests/ui/higher-rank-trait-bounds/issue-95034.rs | 80 ------------ .../issue-95230.next.stderr | 19 --- tests/ui/higher-rank-trait-bounds/issue-95230.rs | 11 -- .../normalize-under-binder/issue-44005.rs | 31 ----- .../normalize-under-binder/issue-56556.rs | 30 ----- .../normalize-under-binder/issue-62529-1.rs | 88 ------------- .../normalize-under-binder/issue-62529-2.rs | 33 ----- .../normalize-under-binder/issue-62529-3.rs | 32 ----- .../normalize-under-binder/issue-62529-3.stderr | 19 --- .../normalize-under-binder/issue-62529-4.rs | 39 ------ .../normalize-under-binder/issue-62529-5.rs | 27 ---- .../normalize-under-binder/issue-62529-6.rs | 77 ------------ .../normalize-under-binder/issue-70120.rs | 31 ----- .../issue-71955.migrate.stderr | 79 ------------ .../normalize-under-binder/issue-71955.rs | 51 -------- .../normalize-under-binder/issue-71955.stderr | 79 ------------ .../normalize-under-binder/issue-74261.rs | 30 ----- .../normalize-under-binder/issue-76956.rs | 15 --- .../normalize-under-binder/issue-80706.rs | 71 ----------- .../normalize-under-binder/issue-80956.rs | 21 ---- .../normalize-under-binder/issue-81809.rs | 21 ---- .../normalize-under-binder/issue-85455.rs | 19 --- .../normalize-under-binder/issue-85455.stderr | 25 ---- .../normalize-under-binder/issue-89118.rs | 32 ----- .../normalize-under-binder/issue-89118.stderr | 69 ----------- .../normalize-under-binder/issue-89436.rs | 44 ------- .../normalize-under-binder/issue-90612.rs | 41 ------- .../normalize-under-binder/issue-90638.rs | 35 ------ .../normalize-under-binder/issue-90875.rs | 31 ----- .../normalize-under-binder/issue-90950.rs | 53 -------- .../normalize-under-binder/issue-90950.stderr | 21 ---- .../norm-before-method-resolution.rs | 23 ---- .../norm-before-method-resolution.stderr | 18 --- tests/ui/higher-ranked/higher-lifetime-bounds.rs | 69 +++++++++++ .../ui/higher-ranked/higher-lifetime-bounds.stderr | 68 +++++++++++ ...subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr | 17 +++ .../subtype/hr-subtype.bound_a_vs_free_x.stderr | 17 +++ .../hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr | 31 +++++ .../hr-subtype.free_inv_x_vs_free_inv_y.stderr | 42 +++++++ .../subtype/hr-subtype.free_x_vs_free_y.stderr | 19 +++ tests/ui/higher-ranked/subtype/hr-subtype.rs | 111 +++++++++++++++++ .../subtype/placeholder-pattern-fail.rs | 25 ++++ .../subtype/placeholder-pattern-fail.stderr | 12 ++ .../higher-ranked/subtype/placeholder-pattern.rs | 18 +++ tests/ui/higher-ranked/subtype/return-static.rs | 13 ++ tests/ui/higher-ranked/trait-bounds/complex.rs | 28 +++++ .../trait-bounds/due-to-where-clause.rs | 13 ++ .../trait-bounds/due-to-where-clause.stderr | 11 ++ .../trait-bounds/fn-ptr.classic.stderr | 19 +++ tests/ui/higher-ranked/trait-bounds/fn-ptr.rs | 14 +++ .../trait-bounds/hang-on-deeply-nested-dyn.rs | 16 +++ .../trait-bounds/hang-on-deeply-nested-dyn.stderr | 22 ++++ .../hrtb-binder-levels-in-object-types.rs | 29 +++++ .../trait-bounds/hrtb-cache-issue-54302.rs | 24 ++++ .../trait-bounds/hrtb-cache-issue-54302.stderr | 11 ++ .../trait-bounds/hrtb-conflate-regions.rs | 31 +++++ .../trait-bounds/hrtb-conflate-regions.stderr | 20 +++ .../trait-bounds/hrtb-debruijn-in-receiver.rs | 18 +++ .../trait-bounds/hrtb-debruijn-in-receiver.stderr | 14 +++ .../hrtb-debruijn-object-types-in-closures.rs | 16 +++ .../trait-bounds/hrtb-exists-forall-fn.rs | 18 +++ .../trait-bounds/hrtb-exists-forall-fn.stderr | 12 ++ .../hrtb-exists-forall-trait-contravariant.rs | 36 ++++++ .../hrtb-exists-forall-trait-contravariant.stderr | 11 ++ .../hrtb-exists-forall-trait-covariant.rs | 37 ++++++ .../hrtb-exists-forall-trait-invariant.rs | 29 +++++ .../hrtb-exists-forall-trait-invariant.stderr | 11 ++ .../trait-bounds/hrtb-fn-like-trait-object.rs | 27 ++++ .../trait-bounds/hrtb-fn-like-trait.rs | 27 ++++ .../hrtb-higher-ranker-supertraits-transitive.rs | 50 ++++++++ ...rtb-higher-ranker-supertraits-transitive.stderr | 23 ++++ .../trait-bounds/hrtb-higher-ranker-supertraits.rs | 48 ++++++++ .../hrtb-higher-ranker-supertraits.stderr | 43 +++++++ .../trait-bounds/hrtb-identity-fn-borrows.rs | 26 ++++ .../trait-bounds/hrtb-identity-fn-borrows.stderr | 14 +++ .../trait-bounds/hrtb-just-for-static.rs | 35 ++++++ .../trait-bounds/hrtb-just-for-static.stderr | 34 ++++++ .../hrtb-malformed-lifetime-generics.rs | 20 +++ .../hrtb-malformed-lifetime-generics.stderr | 62 ++++++++++ .../higher-ranked/trait-bounds/hrtb-opt-in-copy.rs | 28 +++++ tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs | 36 ++++++ .../hrtb-perfect-forwarding.polonius.stderr | 71 +++++++++++ .../trait-bounds/hrtb-perfect-forwarding.rs | 56 +++++++++ .../trait-bounds/hrtb-perfect-forwarding.stderr | 79 ++++++++++++ .../hrtb-precedence-of-plus-where-clause.rs | 25 ++++ .../trait-bounds/hrtb-precedence-of-plus.rs | 13 ++ .../trait-bounds/hrtb-resolve-lifetime.rs | 14 +++ .../hrtb-trait-object-paren-notation.rs | 26 ++++ .../hrtb-trait-object-passed-to-closure.rs | 25 ++++ .../trait-bounds/hrtb-type-outlives.rs | 46 +++++++ .../trait-bounds/hrtb-unboxed-closure-trait.rs | 11 ++ .../higher-ranked/trait-bounds/hrtb-wrong-kind.rs | 7 ++ .../trait-bounds/hrtb-wrong-kind.stderr | 21 ++++ .../ui/higher-ranked/trait-bounds/issue-100689.rs | 29 +++++ .../ui/higher-ranked/trait-bounds/issue-102899.rs | 32 +++++ tests/ui/higher-ranked/trait-bounds/issue-30786.rs | 136 +++++++++++++++++++++ .../higher-ranked/trait-bounds/issue-30786.stderr | 46 +++++++ .../issue-36139-normalize-closure-sig.rs | 19 +++ tests/ui/higher-ranked/trait-bounds/issue-39292.rs | 17 +++ tests/ui/higher-ranked/trait-bounds/issue-42114.rs | 20 +++ tests/ui/higher-ranked/trait-bounds/issue-43623.rs | 21 ++++ tests/ui/higher-ranked/trait-bounds/issue-46989.rs | 40 ++++++ .../higher-ranked/trait-bounds/issue-46989.stderr | 11 ++ tests/ui/higher-ranked/trait-bounds/issue-57639.rs | 29 +++++ tests/ui/higher-ranked/trait-bounds/issue-58451.rs | 13 ++ .../higher-ranked/trait-bounds/issue-58451.stderr | 19 +++ tests/ui/higher-ranked/trait-bounds/issue-59311.rs | 22 ++++ .../higher-ranked/trait-bounds/issue-59311.stderr | 18 +++ tests/ui/higher-ranked/trait-bounds/issue-60283.rs | 20 +++ .../trait-bounds/issue-62203-hrtb-ice.rs | 54 ++++++++ .../trait-bounds/issue-62203-hrtb-ice.stderr | 66 ++++++++++ tests/ui/higher-ranked/trait-bounds/issue-88446.rs | 35 ++++++ .../issue-88586-hr-self-outlives-in-trait-def.rs | 13 ++ tests/ui/higher-ranked/trait-bounds/issue-90177.rs | 32 +++++ tests/ui/higher-ranked/trait-bounds/issue-95034.rs | 80 ++++++++++++ .../trait-bounds/issue-95230.next.stderr | 19 +++ tests/ui/higher-ranked/trait-bounds/issue-95230.rs | 11 ++ .../normalize-under-binder/issue-44005.rs | 31 +++++ .../normalize-under-binder/issue-56556.rs | 30 +++++ .../normalize-under-binder/issue-62529-1.rs | 88 +++++++++++++ .../normalize-under-binder/issue-62529-2.rs | 33 +++++ .../normalize-under-binder/issue-62529-3.rs | 32 +++++ .../normalize-under-binder/issue-62529-3.stderr | 19 +++ .../normalize-under-binder/issue-62529-4.rs | 39 ++++++ .../normalize-under-binder/issue-62529-5.rs | 27 ++++ .../normalize-under-binder/issue-62529-6.rs | 77 ++++++++++++ .../normalize-under-binder/issue-70120.rs | 31 +++++ .../issue-71955.migrate.stderr | 79 ++++++++++++ .../normalize-under-binder/issue-71955.rs | 51 ++++++++ .../normalize-under-binder/issue-71955.stderr | 79 ++++++++++++ .../normalize-under-binder/issue-74261.rs | 30 +++++ .../normalize-under-binder/issue-76956.rs | 15 +++ .../normalize-under-binder/issue-80706.rs | 71 +++++++++++ .../normalize-under-binder/issue-80956.rs | 21 ++++ .../normalize-under-binder/issue-81809.rs | 21 ++++ .../normalize-under-binder/issue-85455.rs | 19 +++ .../normalize-under-binder/issue-85455.stderr | 25 ++++ .../normalize-under-binder/issue-89118.rs | 32 +++++ .../normalize-under-binder/issue-89118.stderr | 69 +++++++++++ .../normalize-under-binder/issue-89436.rs | 44 +++++++ .../normalize-under-binder/issue-90612.rs | 41 +++++++ .../normalize-under-binder/issue-90638.rs | 35 ++++++ .../normalize-under-binder/issue-90875.rs | 31 +++++ .../normalize-under-binder/issue-90950.rs | 53 ++++++++ .../normalize-under-binder/issue-90950.stderr | 21 ++++ .../norm-before-method-resolution.rs | 23 ++++ .../norm-before-method-resolution.stderr | 18 +++ ...subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr | 17 --- .../hr-subtype/hr-subtype.bound_a_vs_free_x.stderr | 17 --- .../hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr | 31 ----- .../hr-subtype.free_inv_x_vs_free_inv_y.stderr | 42 ------- .../hr-subtype/hr-subtype.free_x_vs_free_y.stderr | 19 --- tests/ui/hr-subtype/hr-subtype.rs | 111 ----------------- tests/ui/hr-subtype/placeholder-pattern-fail.rs | 25 ---- .../ui/hr-subtype/placeholder-pattern-fail.stderr | 12 -- tests/ui/hr-subtype/placeholder-pattern.rs | 18 --- tests/ui/hr-subtype/return-static.rs | 13 -- 229 files changed, 3737 insertions(+), 3737 deletions(-) delete mode 100644 tests/ui/higher-lifetime-bounds.rs delete mode 100644 tests/ui/higher-lifetime-bounds.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/complex.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/due-to-where-clause.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/due-to-where-clause.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/fn-ptr.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-parse.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-100689.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-102899.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-30786.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-30786.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-39292.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-42114.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-43623.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-46989.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-46989.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-57639.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-58451.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-58451.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-59311.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-59311.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-60283.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-88446.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-90177.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-95034.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-95230.next.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/issue-95230.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-56556.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-2.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-4.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-5.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-6.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-76956.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80706.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80956.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-81809.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90875.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs delete mode 100644 tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr create mode 100644 tests/ui/higher-ranked/higher-lifetime-bounds.rs create mode 100644 tests/ui/higher-ranked/higher-lifetime-bounds.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr create mode 100644 tests/ui/higher-ranked/subtype/hr-subtype.rs create mode 100644 tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs create mode 100644 tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr create mode 100644 tests/ui/higher-ranked/subtype/placeholder-pattern.rs create mode 100644 tests/ui/higher-ranked/subtype/return-static.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/complex.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/due-to-where-clause.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/due-to-where-clause.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/fn-ptr.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-covariant.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait-object.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-opt-in-copy.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-paren-notation.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-type-outlives.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-unboxed-closure-trait.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-100689.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-102899.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-30786.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-30786.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-36139-normalize-closure-sig.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-39292.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-42114.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-43623.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-46989.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-46989.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-57639.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-58451.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-58451.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-59311.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-59311.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-60283.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-88446.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-90177.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-95034.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/issue-95230.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-44005.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-56556.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-2.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-4.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-5.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-70120.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-74261.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-76956.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80706.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80956.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-81809.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90612.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90875.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr delete mode 100644 tests/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr delete mode 100644 tests/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr delete mode 100644 tests/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr delete mode 100644 tests/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr delete mode 100644 tests/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr delete mode 100644 tests/ui/hr-subtype/hr-subtype.rs delete mode 100644 tests/ui/hr-subtype/placeholder-pattern-fail.rs delete mode 100644 tests/ui/hr-subtype/placeholder-pattern-fail.stderr delete mode 100644 tests/ui/hr-subtype/placeholder-pattern.rs delete mode 100644 tests/ui/hr-subtype/return-static.rs diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 3e9bf18a287..01ef4abd3dc 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1898; -const ROOT_ENTRY_LIMIT: usize = 894; +const ROOT_ENTRY_LIMIT: usize = 891; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/ui/higher-lifetime-bounds.rs b/tests/ui/higher-lifetime-bounds.rs deleted file mode 100644 index f3393347d90..00000000000 --- a/tests/ui/higher-lifetime-bounds.rs +++ /dev/null @@ -1,69 +0,0 @@ -#![allow(dead_code, non_camel_case_types)] - -// Test that bounds on higher-kinded lifetime binders are rejected. - -fn bar1<'a, 'b>( - x: &'a i32, - y: &'b i32, - f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) - //~^ ERROR lifetime bounds cannot be used in this context -{ - // If the bound in f's type would matter, the call below would (have to) - // be rejected. - f(x, y); -} - -fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>( - //~^ ERROR lifetime bounds cannot be used in this context - x: &'a i32, - y: &'b i32, - f: F) -{ - // If the bound in f's type would matter, the call below would (have to) - // be rejected. - f(x, y); -} - -fn bar3<'a, 'b, F>( - x: &'a i32, - y: &'b i32, - f: F) - where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 - //~^ ERROR lifetime bounds cannot be used in this context -{ - // If the bound in f's type would matter, the call below would (have to) - // be rejected. - f(x, y); -} - -fn bar4<'a, 'b, F>( - x: &'a i32, - y: &'b i32, - f: F) - where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 - //~^ ERROR lifetime bounds cannot be used in this context -{ - // If the bound in f's type would matter, the call below would (have to) - // be rejected. - f(x, y); -} - -struct S1 Fn(&'xa i32, &'xb i32) -> &'xa i32>(F); -//~^ ERROR lifetime bounds cannot be used in this context -struct S2(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32; -//~^ ERROR lifetime bounds cannot be used in this context -struct S3(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32; -//~^ ERROR lifetime bounds cannot be used in this context - -struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32); -//~^ ERROR lifetime bounds cannot be used in this context - -type T1 = Box Fn(&'xa i32, &'xb i32) -> &'xa i32>; -//~^ ERROR lifetime bounds cannot be used in this context - -fn main() { - let _ : Option fn(&'xa i32, &'xb i32) -> &'xa i32> = None; - //~^ ERROR lifetime bounds cannot be used in this context - let _ : Option Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None; - //~^ ERROR lifetime bounds cannot be used in this context -} diff --git a/tests/ui/higher-lifetime-bounds.stderr b/tests/ui/higher-lifetime-bounds.stderr deleted file mode 100644 index bc6d2288cdf..00000000000 --- a/tests/ui/higher-lifetime-bounds.stderr +++ /dev/null @@ -1,68 +0,0 @@ -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:8:22 - | -LL | f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) - | ^^^ ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:16:34 - | -LL | fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>( - | ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:31:28 - | -LL | where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 - | ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:43:25 - | -LL | where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 - | ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:51:28 - | -LL | struct S1 Fn(&'xa i32, &'xb i32) -> &'xa i32>(F); - | ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:53:40 - | -LL | struct S2(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32; - | ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:55:37 - | -LL | struct S3(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32; - | ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:58:29 - | -LL | struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32); - | ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:61:33 - | -LL | type T1 = Box Fn(&'xa i32, &'xb i32) -> &'xa i32>; - | ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:65:34 - | -LL | let _ : Option fn(&'xa i32, &'xb i32) -> &'xa i32> = None; - | ^^^ - -error: lifetime bounds cannot be used in this context - --> $DIR/higher-lifetime-bounds.rs:67:42 - | -LL | let _ : Option Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None; - | ^^^ - -error: aborting due to 11 previous errors - diff --git a/tests/ui/higher-rank-trait-bounds/complex.rs b/tests/ui/higher-rank-trait-bounds/complex.rs deleted file mode 100644 index 8cdfe247e02..00000000000 --- a/tests/ui/higher-rank-trait-bounds/complex.rs +++ /dev/null @@ -1,28 +0,0 @@ -// check-pass - -trait A<'a> {} -trait B<'b> {} -fn foo() where for<'a> T: A<'a> + 'a {} -trait C<'c>: for<'a> A<'a> + for<'b> B<'b> { - type As; -} -struct D where T: for<'c> C<'c, As=&'c ()> { - t: std::marker::PhantomData, -} -trait E<'e, 'g> { - type As; -} -trait F<'f>: for<'a> A<'a> + for<'e> E<'e, 'f> {} -struct G where T: for<'f> F<'f, As=&'f ()> { - t: std::marker::PhantomData, -} -trait H<'a, 'b> { - type As; -} -trait I<'a>: for<'b> H<'a, 'b> {} - -struct J where T: for<'i> I<'i, As=&'i ()> { - t: std::marker::PhantomData, -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/due-to-where-clause.rs b/tests/ui/higher-rank-trait-bounds/due-to-where-clause.rs deleted file mode 100644 index 1afd15613b5..00000000000 --- a/tests/ui/higher-rank-trait-bounds/due-to-where-clause.rs +++ /dev/null @@ -1,13 +0,0 @@ -fn main() { - test::(&mut 42); //~ ERROR implementation of `Foo` is not general enough -} - -trait Foo<'a> {} - -struct FooS<'a> { - data: &'a mut u32, -} - -impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {} - -fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {} diff --git a/tests/ui/higher-rank-trait-bounds/due-to-where-clause.stderr b/tests/ui/higher-rank-trait-bounds/due-to-where-clause.stderr deleted file mode 100644 index 520938a6335..00000000000 --- a/tests/ui/higher-rank-trait-bounds/due-to-where-clause.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: implementation of `Foo` is not general enough - --> $DIR/due-to-where-clause.rs:2:5 - | -LL | test::(&mut 42); - | ^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`... - = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1` - -error: aborting due to previous error - diff --git a/tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr b/tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr deleted file mode 100644 index 9af6bc45c7a..00000000000 --- a/tests/ui/higher-rank-trait-bounds/fn-ptr.classic.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: expected a `Fn<(&'w (),)>` closure, found `fn(&'w ())` - --> $DIR/fn-ptr.rs:12:5 - | -LL | ice(); - | ^^^ expected an `Fn<(&'w (),)>` closure, found `fn(&'w ())` - | - = help: the trait `for<'w> Fn<(&'w (),)>` is not implemented for `fn(&'w ())` -note: required by a bound in `ice` - --> $DIR/fn-ptr.rs:7:25 - | -LL | fn ice() - | --- required by a bound in this function -LL | where -LL | for<'w> fn(&'w ()): Fn(&'w ()), - | ^^^^^^^^^^ required by this bound in `ice` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-rank-trait-bounds/fn-ptr.rs b/tests/ui/higher-rank-trait-bounds/fn-ptr.rs deleted file mode 100644 index 853160f9612..00000000000 --- a/tests/ui/higher-rank-trait-bounds/fn-ptr.rs +++ /dev/null @@ -1,14 +0,0 @@ -// revisions: classic next -//[next] compile-flags: -Ztrait-solver=next -//[next] check-pass - -fn ice() -where - for<'w> fn(&'w ()): Fn(&'w ()), -{ -} - -fn main() { - ice(); - //[classic]~^ ERROR expected a `Fn<(&'w (),)>` closure, found `fn(&'w ())` -} diff --git a/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.rs b/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.rs deleted file mode 100644 index d34b7a29623..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.rs +++ /dev/null @@ -1,16 +0,0 @@ -// normalize-stderr-test: "long-type-\d+" -> "long-type-hash" - -fn id( - f: &dyn Fn(u32), -) -> &dyn Fn( - &dyn Fn( - &dyn Fn( - &dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(u32))))))))), - ), - ), -) { - f - //~^ ERROR mismatched types -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.stderr deleted file mode 100644 index 3662cbfb9ba..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hang-on-deeply-nested-dyn.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/hang-on-deeply-nested-dyn.rs:12:5 - | -LL | ) -> &dyn Fn( - | ______- -LL | | &dyn Fn( -LL | | &dyn Fn( -LL | | &dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(u32))))))))), -LL | | ), -LL | | ), -LL | | ) { - | |_- expected `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` because of return type -LL | f - | ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&...)))`, found `&dyn Fn(u32)` - | - = note: expected reference `&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&...)))))))))))` - the full type name has been written to '$TEST_BUILD_DIR/higher-rank-trait-bounds/hang-on-deeply-nested-dyn/hang-on-deeply-nested-dyn.long-type-hash.txt' - found reference `&dyn Fn(u32)` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs b/tests/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs deleted file mode 100644 index cc766c0605c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs +++ /dev/null @@ -1,29 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -// Test that we handle binder levels in object types correctly. -// Initially, the reference to `'tcx` in the object type -// `&Typer<'tcx>` was getting an incorrect binder level, yielding -// weird compilation ICEs and so forth. - -// pretty-expanded FIXME #23616 - -trait Typer<'tcx> { - fn method(&self, data: &'tcx isize) -> &'tcx isize { data } -} - -struct Tcx<'tcx> { - fields: &'tcx isize -} - -impl<'tcx> Typer<'tcx> for Tcx<'tcx> { -} - -fn g<'tcx>(typer: &dyn Typer<'tcx>) { -} - -fn check_static_type<'x>(tcx: &Tcx<'x>) { - g(tcx) -} - -fn main() { } diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs b/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs deleted file mode 100644 index a20d03c7747..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Regression test for #54302. -// -// We were incorrectly using the "evaluation cache" (which ignored -// region results) to conclude that `&'static str: Deserialize`, even -// though it would require that `for<'de> 'de: 'static`, which is -// clearly false. - -trait Deserialize<'de> {} - -trait DeserializeOwned: for<'de> Deserialize<'de> {} -impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} - -// Based on this impl, `&'static str` only implements Deserialize<'static>. -// It does not implement for<'de> Deserialize<'de>. -impl<'de: 'a, 'a> Deserialize<'de> for &'a str {} - -fn main() { - fn assert_deserialize_owned() {} - assert_deserialize_owned::<&'static str>(); //~ ERROR - - // It correctly does not implement for<'de> Deserialize<'de>. - // fn assert_hrtb Deserialize<'de>>() {} - // assert_hrtb::<&'static str>(); -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr deleted file mode 100644 index f014eab8601..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-cache-issue-54302.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: implementation of `Deserialize` is not general enough - --> $DIR/hrtb-cache-issue-54302.rs:19:5 - | -LL | assert_deserialize_owned::<&'static str>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough - | - = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`... - = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1` - -error: aborting due to previous error - diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs b/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs deleted file mode 100644 index e83686404a3..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Test that an impl with only one bound region `'a` cannot be used to -// satisfy a constraint where there are two bound regions. - -trait Foo { - fn foo(&self, x: X) { } -} - -fn want_foo2() - where T : for<'a,'b> Foo<(&'a isize, &'b isize)> -{ -} - -fn want_foo1() - where T : for<'z> Foo<(&'z isize, &'z isize)> -{ -} - -// Expressed as a where clause - -struct SomeStruct; - -impl<'a> Foo<(&'a isize, &'a isize)> for SomeStruct -{ -} - -fn a() { want_foo1::(); } // OK -- foo wants just one region -fn b() { want_foo2::(); } -//~^ ERROR implementation of -//~| ERROR implementation of - -fn main() { } diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr deleted file mode 100644 index 46f5308dd87..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-conflate-regions.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: implementation of `Foo` is not general enough - --> $DIR/hrtb-conflate-regions.rs:27:10 - | -LL | fn b() { want_foo2::(); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`... - = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` - -error: implementation of `Foo` is not general enough - --> $DIR/hrtb-conflate-regions.rs:27:10 - | -LL | fn b() { want_foo2::(); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`... - = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs b/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs deleted file mode 100644 index 05d3e1a434e..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Test the case where the `Self` type has a bound lifetime that must -// be adjusted in the fn signature. Issue #19537. - -use std::collections::HashMap; - -struct Foo<'a> { - map: HashMap -} - -impl<'a> Foo<'a> { - fn new() -> Foo<'a> { panic!() } - fn insert(&'a mut self) { } -} -fn main() { - let mut foo = Foo::new(); - foo.insert(); - foo.insert(); //~ ERROR cannot borrow -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr deleted file mode 100644 index fa391ecba8a..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-in-receiver.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0499]: cannot borrow `foo` as mutable more than once at a time - --> $DIR/hrtb-debruijn-in-receiver.rs:17:5 - | -LL | foo.insert(); - | ------------ first mutable borrow occurs here -LL | foo.insert(); - | ^^^^^^^^^^^^ - | | - | second mutable borrow occurs here - | first borrow later used here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs b/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs deleted file mode 100644 index 8431226a3ec..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -trait Typer<'tcx> { - fn method(&self, data: &'tcx isize) -> &'tcx isize { data } - fn dummy(&self) { } -} - -fn g(_: F) where F: FnOnce(&dyn Typer) {} - -fn h() { - g(|typer| typer.dummy()) -} - -fn main() { } diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs b/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs deleted file mode 100644 index 56780237618..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! -// -// In particular, we test this pattern in trait solving, where it is not connected -// to any part of the source code. - -fn foo<'a>() -> fn(&'a u32) { - panic!() -} - -fn main() { - // Here, proving that `fn(&'a u32) <: for<'b> fn(&'b u32)`: - // - // - instantiates `'b` with a placeholder `!b`, - // - requires that `&!b u32 <: &'a u32` and hence that `!b: 'a`, - // - but we can never know this. - - let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr deleted file mode 100644 index 9914783d976..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-fn.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/hrtb-exists-forall-fn.rs:17:34 - | -LL | let _: for<'b> fn(&'b u32) = foo(); - | ^^^^^ one type is more general than the other - | - = note: expected fn pointer `for<'b> fn(&'b u32)` - found fn pointer `fn(&u32)` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs b/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs deleted file mode 100644 index 921061916fc..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Test a case where variance and higher-ranked types interact in surprising ways. -// -// In particular, we test this pattern in trait solving, where it is not connected -// to any part of the source code. - -trait Trait {} - -fn foo() -where - T: Trait fn(&'b u32)>, -{ -} - -impl<'a> Trait for () {} - -fn main() { - // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: - // - // - The impl provides the clause `forall<'a> { (): Trait }` - // - We instantiate `'a` existentially to get `(): Trait` - // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` -- this does a - // "bidirectional" subtyping check, so we wind up with: - // - `fn(&?a u32) <: for<'b> fn(&'b u32)` :- - // - `&'!b u32 <: &?a u32` - // - `!'b: ?a` -- solveable if `?a` is inferred to `'empty` - // - `for<'b> fn(&'b u32) <: fn(&?a u32)` :- - // - `&?a u32 u32 <: &?b u32` - // - `?a: ?b` -- solveable if `?b` is also inferred to `'empty` - // - So the subtyping check succeeds, somewhat surprisingly. - // This is because we can use `'empty`. - // - // NB. *However*, the reinstated leak-check gives an error here. - - foo::<()>(); - //~^ ERROR implementation of `Trait` is not general enough -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr deleted file mode 100644 index 364b613fc77..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-contravariant.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: implementation of `Trait` is not general enough - --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5 - | -LL | foo::<()>(); - | ^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `()` must implement `Trait fn(&'b u32)>` - = note: ...but it actually implements `Trait`, for some specific lifetime `'0` - -error: aborting due to previous error - diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs b/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs deleted file mode 100644 index f95496a6c3c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-covariant.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Test a case where variance and higher-ranked types interact in surprising ways. -// -// In particular, we test this pattern in trait solving, where it is not connected -// to any part of the source code. -// -// check-pass - -trait Trait {} - -fn foo() -where - T: Trait fn(fn(&'b u32))>, -{ -} - -impl<'a> Trait for () {} - -fn main() { - // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: - // - // - The impl provides the clause `forall<'a> { (): Trait }` - // - We instantiate `'a` existentially to get `(): Trait` - // - We unify `fn(fn(&?a u32))` with `for<'b> fn(fn(&'b u32))` -- this does a - // "bidirectional" subtyping check, so we wind up with: - // - `fn(fn(&?a u32)) <: for<'b> fn(fn(&'b u32))` :- - // - `fn(&!b u32) <: fn(&?a u32)` - // - `&?a u32 <: &!b u32` - // - `?a: !'b` -- solveable if `?a` is inferred to `'static` - // - `for<'b> fn(fn(&'b u32)) <: fn(fn(&?a u32))` :- - // - `fn(&?a u32) <: fn(&?b u32)` - // - `&?b u32 <: &?a u32` - // - `?b: ?a` -- solveable if `?b` is inferred to `'static` - // - So the subtyping check succeeds, somewhat surprisingly. - // This is because we can use `'static`. - - foo::<()>(); -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs b/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs deleted file mode 100644 index 9b9e4496a87..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! -// -// In particular, we test this pattern in trait solving, where it is not connected -// to any part of the source code. - -use std::cell::Cell; - -trait Trait {} - -fn foo() -where - T: Trait fn(Cell<&'b u32>)>, -{ -} - -impl<'a> Trait)> for () {} - -fn main() { - // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: - // - // - The impl provides the clause `forall<'a> { (): Trait }` - // - We instantiate `'a` existentially to get `(): Trait` - // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` - // - This requires (among other things) instantiating `'b` universally, - // yielding `fn(&!b u32)`, in a fresh universe U1 - // - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`. - - foo::<()>(); //~ ERROR implementation of `Trait` is not general enough -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr deleted file mode 100644 index cb2ce8a4116..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-exists-forall-trait-invariant.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: implementation of `Trait` is not general enough - --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5 - | -LL | foo::<()>(); - | ^^^^^^^^^^^ implementation of `Trait` is not general enough - | - = note: `()` must implement `Trait fn(Cell<&'b u32>)>` - = note: ...but it actually implements `Trait)>`, for some specific lifetime `'0` - -error: aborting due to previous error - diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs b/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs deleted file mode 100644 index ff84ad9d298..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass -// A basic test of using a higher-ranked trait bound. - - -trait FnLike { - fn call(&self, arg: A) -> R; -} - -type FnObject<'b> = dyn for<'a> FnLike<&'a isize, &'a isize> + 'b; - -struct Identity; - -impl<'a, T> FnLike<&'a T, &'a T> for Identity { - fn call(&self, arg: &'a T) -> &'a T { - arg - } -} - -fn call_repeatedly(f: &FnObject) { - let x = 3; - let y = f.call(&x); - assert_eq!(3, *y); -} - -fn main() { - call_repeatedly(&Identity); -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs b/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs deleted file mode 100644 index afab9986ce2..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass -// A basic test of using a higher-ranked trait bound. - - -trait FnLike { - fn call(&self, arg: A) -> R; -} - -struct Identity; - -impl<'a, T> FnLike<&'a T, &'a T> for Identity { - fn call(&self, arg: &'a T) -> &'a T { - arg - } -} - -fn call_repeatedly(f: F) - where F : for<'a> FnLike<&'a isize, &'a isize> -{ - let x = 3; - let y = f.call(&x); - assert_eq!(3, *y); -} - -fn main() { - call_repeatedly(Identity); -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs deleted file mode 100644 index f9ae1429ee4..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Test HRTB supertraits with several levels of expansion required. - -trait Foo<'tcx> -{ - fn foo(&'tcx self) -> &'tcx isize; -} - -trait Bar<'ccx> - : for<'tcx> Foo<'tcx> -{ - fn bar(&'ccx self) -> &'ccx isize; -} - -trait Baz - : for<'ccx> Bar<'ccx> -{ - fn dummy(&self); -} - -trait Qux - : Bar<'static> -{ - fn dummy(&self); -} - -fn want_foo_for_any_tcx(f: &F) - where F : for<'tcx> Foo<'tcx> -{ -} - -fn want_bar_for_any_ccx(b: &B) - where B : for<'ccx> Bar<'ccx> -{ -} - -fn want_baz(b: &B) - where B : Baz -{ - want_foo_for_any_tcx(b); - want_bar_for_any_ccx(b); -} - -fn want_qux(b: &B) - where B : Qux -{ - want_foo_for_any_tcx(b); - want_bar_for_any_ccx(b); //~ ERROR -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr deleted file mode 100644 index b1b8ffa8c54..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied - --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26 - | -LL | want_bar_for_any_ccx(b); - | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` - | | - | required by a bound introduced by this call - | -note: required by a bound in `want_bar_for_any_ccx` - --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15 - | -LL | fn want_bar_for_any_ccx(b: &B) - | -------------------- required by a bound in this function -LL | where B : for<'ccx> Bar<'ccx> - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` -help: consider further restricting this bound - | -LL | where B : Qux + for<'ccx> Bar<'ccx> - | +++++++++++++++++++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs deleted file mode 100644 index 48ebe5017aa..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Test a trait (`Bar`) with a higher-ranked supertrait. - -trait Foo<'tcx> -{ - fn foo(&'tcx self) -> &'tcx isize; -} - -trait Bar<'ccx> - : for<'tcx> Foo<'tcx> -{ - fn bar(&'ccx self) -> &'ccx isize; -} - -fn want_foo_for_some_tcx<'x,F>(f: &'x F) - where F : Foo<'x> -{ - want_foo_for_some_tcx(f); - want_foo_for_any_tcx(f); //~ ERROR not satisfied -} - -fn want_foo_for_any_tcx(f: &F) - where F : for<'tcx> Foo<'tcx> -{ - want_foo_for_some_tcx(f); - want_foo_for_any_tcx(f); -} - -fn want_bar_for_some_ccx<'x,B>(b: &B) - where B : Bar<'x> -{ - want_foo_for_some_tcx(b); - want_foo_for_any_tcx(b); - - want_bar_for_some_ccx(b); - want_bar_for_any_ccx(b); //~ ERROR not satisfied -} - -fn want_bar_for_any_ccx(b: &B) - where B : for<'ccx> Bar<'ccx> -{ - want_foo_for_some_tcx(b); - want_foo_for_any_tcx(b); - - want_bar_for_some_ccx(b); - want_bar_for_any_ccx(b); -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr deleted file mode 100644 index 7f96909b6e7..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied - --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26 - | -LL | want_foo_for_any_tcx(f); - | -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F` - | | - | required by a bound introduced by this call - | -note: required by a bound in `want_foo_for_any_tcx` - --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15 - | -LL | fn want_foo_for_any_tcx(f: &F) - | -------------------- required by a bound in this function -LL | where F : for<'tcx> Foo<'tcx> - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx` -help: consider further restricting this bound - | -LL | where F : Foo<'x> + for<'tcx> Foo<'tcx> - | +++++++++++++++++++++ - -error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied - --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26 - | -LL | want_bar_for_any_ccx(b); - | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` - | | - | required by a bound introduced by this call - | -note: required by a bound in `want_bar_for_any_ccx` - --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15 - | -LL | fn want_bar_for_any_ccx(b: &B) - | -------------------- required by a bound in this function -LL | where B : for<'ccx> Bar<'ccx> - | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` -help: consider further restricting this bound - | -LL | where B : Bar<'x> + for<'ccx> Bar<'ccx> - | +++++++++++++++++++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs b/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs deleted file mode 100644 index 89fc4705a78..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Test that the `'a` in the where clause correctly links the region -// of the output to the region of the input. - -trait FnLike { - fn call(&self, arg: A) -> R; -} - -fn call_repeatedly(f: F) - where F : for<'a> FnLike<&'a isize, &'a isize> -{ - // Result is stored: cannot re-assign `x` - let mut x = 3; - let y = f.call(&x); - x = 5; //~ ERROR cannot assign to `x` because it is borrowed - - // Result is not stored: can re-assign `x` - let mut x = 3; - f.call(&x); - f.call(&x); - f.call(&x); - x = 5; - drop(y); -} - -fn main() { -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr deleted file mode 100644 index 25af011e3fc..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-identity-fn-borrows.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0506]: cannot assign to `x` because it is borrowed - --> $DIR/hrtb-identity-fn-borrows.rs:14:5 - | -LL | let y = f.call(&x); - | -- `x` is borrowed here -LL | x = 5; - | ^^^^^ `x` is assigned to here but it was already borrowed -... -LL | drop(y); - | - borrow later used here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0506`. diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs b/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs deleted file mode 100644 index 8fb4218f8a4..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Test a case where you have an impl of `Foo` for all `X` that -// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. - -trait Foo { - fn foo(&self, x: X) { } -} - -fn want_hrtb() - where T : for<'a> Foo<&'a isize> -{ -} - -// AnyInt implements Foo<&'a isize> for any 'a, so it is a match. -struct AnyInt; -impl<'a> Foo<&'a isize> for AnyInt { } -fn give_any() { - want_hrtb::() -} - -// StaticInt only implements Foo<&'static isize>, so it is an error. -struct StaticInt; -impl Foo<&'static isize> for StaticInt { } -fn give_static() { - want_hrtb::() //~ ERROR -} - -// &'a u32 only implements Foo<&'a isize> for specific 'a, so it is an error. -impl<'a> Foo<&'a isize> for &'a u32 { } -fn give_some<'a>() { - want_hrtb::<&'a u32>() - //~^ ERROR lifetime may not live long enough - //~| ERROR implementation of `Foo` is not general enough -} - -fn main() { } diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr deleted file mode 100644 index 31e11e12835..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-just-for-static.stderr +++ /dev/null @@ -1,34 +0,0 @@ -error: implementation of `Foo` is not general enough - --> $DIR/hrtb-just-for-static.rs:24:5 - | -LL | want_hrtb::() - | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`... - = note: ...but it actually implements `Foo<&'static isize>` - -error: lifetime may not live long enough - --> $DIR/hrtb-just-for-static.rs:30:5 - | -LL | fn give_some<'a>() { - | -- lifetime `'a` defined here -LL | want_hrtb::<&'a u32>() - | ^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` - | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/hrtb-just-for-static.rs:9:15 - | -LL | where T : for<'a> Foo<&'a isize> - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: implementation of `Foo` is not general enough - --> $DIR/hrtb-just-for-static.rs:30:5 - | -LL | want_hrtb::<&'a u32>() - | ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `Foo<&'0 isize>` would have to be implemented for the type `&u32`, for any lifetime `'0`... - = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` - -error: aborting due to 3 previous errors - diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.rs b/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.rs deleted file mode 100644 index 4b096be591a..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Test that Fn-family traits with lifetime parameters shouldn't compile and -// we suggest the usage of higher-rank trait bounds instead. - -fn fa(_: impl Fn<'a>(&'a str) -> bool) {} -//~^ ERROR `Fn` traits cannot take lifetime parameters - -fn fb(_: impl FnMut<'a, 'b>(&'a str, &'b str) -> bool) {} -//~^ ERROR `Fn` traits cannot take lifetime parameters - -fn fc(_: impl std::fmt::Display + FnOnce<'a>(&'a str) -> bool + std::fmt::Debug) {} -//~^ ERROR `Fn` traits cannot take lifetime parameters - -use std::ops::Fn as AliasedFn; -fn fd(_: impl AliasedFn<'a>(&'a str) -> bool) {} -//~^ ERROR `Fn` traits cannot take lifetime parameters - -fn fe(_: F) where F: Fn<'a>(&'a str) -> bool {} -//~^ ERROR `Fn` traits cannot take lifetime parameters - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.stderr deleted file mode 100644 index e8f6d63b5ab..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-malformed-lifetime-generics.stderr +++ /dev/null @@ -1,62 +0,0 @@ -error: `Fn` traits cannot take lifetime parameters - --> $DIR/hrtb-malformed-lifetime-generics.rs:4:17 - | -LL | fn fa(_: impl Fn<'a>(&'a str) -> bool) {} - | ^^^^ - | -help: consider using a higher-ranked trait bound instead - | -LL - fn fa(_: impl Fn<'a>(&'a str) -> bool) {} -LL + fn fa(_: impl for<'a> Fn(&'a str) -> bool) {} - | - -error: `Fn` traits cannot take lifetime parameters - --> $DIR/hrtb-malformed-lifetime-generics.rs:7:20 - | -LL | fn fb(_: impl FnMut<'a, 'b>(&'a str, &'b str) -> bool) {} - | ^^^^^^^^ - | -help: consider using a higher-ranked trait bound instead - | -LL - fn fb(_: impl FnMut<'a, 'b>(&'a str, &'b str) -> bool) {} -LL + fn fb(_: impl for<'a, 'b> FnMut(&'a str, &'b str) -> bool) {} - | - -error: `Fn` traits cannot take lifetime parameters - --> $DIR/hrtb-malformed-lifetime-generics.rs:10:41 - | -LL | fn fc(_: impl std::fmt::Display + FnOnce<'a>(&'a str) -> bool + std::fmt::Debug) {} - | ^^^^ - | -help: consider using a higher-ranked trait bound instead - | -LL - fn fc(_: impl std::fmt::Display + FnOnce<'a>(&'a str) -> bool + std::fmt::Debug) {} -LL + fn fc(_: impl std::fmt::Display + for<'a> FnOnce(&'a str) -> bool + std::fmt::Debug) {} - | - -error: `Fn` traits cannot take lifetime parameters - --> $DIR/hrtb-malformed-lifetime-generics.rs:14:24 - | -LL | fn fd(_: impl AliasedFn<'a>(&'a str) -> bool) {} - | ^^^^ - | -help: consider using a higher-ranked trait bound instead - | -LL - fn fd(_: impl AliasedFn<'a>(&'a str) -> bool) {} -LL + fn fd(_: impl for<'a> AliasedFn(&'a str) -> bool) {} - | - -error: `Fn` traits cannot take lifetime parameters - --> $DIR/hrtb-malformed-lifetime-generics.rs:17:27 - | -LL | fn fe(_: F) where F: Fn<'a>(&'a str) -> bool {} - | ^^^^ - | -help: consider using a higher-ranked trait bound instead - | -LL - fn fe(_: F) where F: Fn<'a>(&'a str) -> bool {} -LL + fn fe(_: F) where F: for<'a> Fn(&'a str) -> bool {} - | - -error: aborting due to 5 previous errors - diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs b/tests/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs deleted file mode 100644 index 04519f11600..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass -// Test that we handle binder levels correctly when checking whether a -// type can implement `Copy`. In particular, we had a bug where we failed to -// liberate the late-bound regions from the impl, and thus wound up -// searching for an impl of `for<'tcx> Foo<&'tcx T>`. The impl that -// exists however is `impl Copy for Foo` and the current rules -// did not consider that a match (something I would like to revise in -// a later PR). - -#![allow(dead_code)] - -use std::marker::PhantomData; - -#[derive(Copy, Clone)] -struct Foo { x: T } - -type Ty<'tcx> = &'tcx TyS<'tcx>; - -enum TyS<'tcx> { - Boop(PhantomData<*mut &'tcx ()>) -} - -#[derive(Copy, Clone)] -enum Bar<'tcx> { - Baz(Foo>) -} - -fn main() { } diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-parse.rs b/tests/ui/higher-rank-trait-bounds/hrtb-parse.rs deleted file mode 100644 index 1fab9758c5c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-parse.rs +++ /dev/null @@ -1,36 +0,0 @@ -// run-pass -// Test that we can parse all the various places that a `for` keyword -// can appear representing universal quantification. - -// pretty-expanded FIXME #23616 - -#![allow(unused_variables)] -#![allow(dead_code)] - -trait Get { - fn get(&self, arg: A) -> R; -} - -// Parse HRTB with explicit `for` in a where-clause: - -fn foo00(t: T) - where T : for<'a> Get<&'a i32, &'a i32> -{ -} - -fn foo01 Get<&'a i32, &'a i32>>(t: T) -{ -} - -// Parse HRTB with explicit `for` in various sorts of types: - -fn foo10(t: Box Get>) { } -fn foo11(t: Box Fn(i32) -> i32>) { } - -fn foo20(t: for<'a> fn(i32) -> i32) { } -fn foo21(t: for<'a> unsafe fn(i32) -> i32) { } -fn foo22(t: for<'a> extern "C" fn(i32) -> i32) { } -fn foo23(t: for<'a> unsafe extern "C" fn(i32) -> i32) { } - -fn main() { -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr deleted file mode 100644 index a94c80eb30b..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.polonius.stderr +++ /dev/null @@ -1,71 +0,0 @@ -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:16:1 - | -LL | / fn no_hrtb<'b, T>(mut t: T) -LL | | where -LL | | T: Bar<&'b isize>, -LL | | { -... | -LL | | no_hrtb(&mut t); - | | --------------- recursive call site -LL | | } - | |_^ cannot return without recursing - | - = note: `#[warn(unconditional_recursion)]` on by default - = help: a `loop` may express intention better if this is on purpose - -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:25:1 - | -LL | / fn bar_hrtb(mut t: T) -LL | | where -LL | | T: for<'b> Bar<&'b isize>, -LL | | { -... | -LL | | bar_hrtb(&mut t); - | | ---------------- recursive call site -LL | | } - | |_^ cannot return without recursing - | - = help: a `loop` may express intention better if this is on purpose - -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:35:1 - | -LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T) -LL | | where -LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>, -LL | | { -... | -LL | | foo_hrtb_bar_not(&mut t); - | | ------------------------ recursive call site -LL | | -LL | | -LL | | } - | |_^ cannot return without recursing - | - = help: a `loop` may express intention better if this is on purpose - -error: higher-ranked subtype error - --> $DIR/hrtb-perfect-forwarding.rs:43:5 - | -LL | foo_hrtb_bar_not(&mut t); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:48:1 - | -LL | / fn foo_hrtb_bar_hrtb(mut t: T) -LL | | where -LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>, -LL | | { -LL | | // OK -- now we have `T : for<'b> Bar<&'b isize>`. -LL | | foo_hrtb_bar_hrtb(&mut t); - | | ------------------------- recursive call site -LL | | } - | |_^ cannot return without recursing - | - = help: a `loop` may express intention better if this is on purpose - -error: aborting due to previous error; 4 warnings emitted - diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs b/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs deleted file mode 100644 index d45fa183c0c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Test a case where you have an impl of `Foo` for all `X` that -// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. - -trait Foo { - fn foo(&mut self, x: X) {} -} - -trait Bar { - fn bar(&mut self, x: X) {} -} - -impl<'a, X, F> Foo for &'a mut F where F: Foo + Bar {} - -impl<'a, X, F> Bar for &'a mut F where F: Bar {} - -fn no_hrtb<'b, T>(mut t: T) //~ WARN function cannot return -where - T: Bar<&'b isize>, -{ - // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that - // `&mut T : Bar<&'b isize>`. - no_hrtb(&mut t); -} - -fn bar_hrtb(mut t: T) //~ WARN function cannot return -where - T: for<'b> Bar<&'b isize>, -{ - // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above - // ensures that `&mut T : for<'b> Bar<&'b isize>`. This is an - // example of a "perfect forwarding" impl. - bar_hrtb(&mut t); -} - -fn foo_hrtb_bar_not<'b, T>(mut t: T) //~ WARN function cannot return -where - T: for<'a> Foo<&'a isize> + Bar<&'b isize>, -{ - // Not OK -- The forwarding impl for `Foo` requires that `Bar` also - // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a - // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where - // clause only specifies `T : Bar<&'b isize>`. - foo_hrtb_bar_not(&mut t); - //~^ ERROR implementation of `Bar` is not general enough - //~^^ ERROR lifetime may not live long enough -} - -fn foo_hrtb_bar_hrtb(mut t: T) //~ WARN function cannot return -where - T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>, -{ - // OK -- now we have `T : for<'b> Bar<&'b isize>`. - foo_hrtb_bar_hrtb(&mut t); -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr deleted file mode 100644 index 727b9e6bec8..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr +++ /dev/null @@ -1,79 +0,0 @@ -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:16:1 - | -LL | / fn no_hrtb<'b, T>(mut t: T) -LL | | where -LL | | T: Bar<&'b isize>, - | |______________________^ cannot return without recursing -... -LL | no_hrtb(&mut t); - | --------------- recursive call site - | - = help: a `loop` may express intention better if this is on purpose - = note: `#[warn(unconditional_recursion)]` on by default - -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:25:1 - | -LL | / fn bar_hrtb(mut t: T) -LL | | where -LL | | T: for<'b> Bar<&'b isize>, - | |______________________________^ cannot return without recursing -... -LL | bar_hrtb(&mut t); - | ---------------- recursive call site - | - = help: a `loop` may express intention better if this is on purpose - -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:35:1 - | -LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T) -LL | | where -LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>, - | |_______________________________________________^ cannot return without recursing -... -LL | foo_hrtb_bar_not(&mut t); - | ------------------------ recursive call site - | - = help: a `loop` may express intention better if this is on purpose - -error: lifetime may not live long enough - --> $DIR/hrtb-perfect-forwarding.rs:43:5 - | -LL | fn foo_hrtb_bar_not<'b, T>(mut t: T) - | -- lifetime `'b` defined here -... -LL | foo_hrtb_bar_not(&mut t); - | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static` - | -note: due to current limitations in the borrow checker, this implies a `'static` lifetime - --> $DIR/hrtb-perfect-forwarding.rs:37:8 - | -LL | T: for<'a> Foo<&'a isize> + Bar<&'b isize>, - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: implementation of `Bar` is not general enough - --> $DIR/hrtb-perfect-forwarding.rs:43:5 - | -LL | foo_hrtb_bar_not(&mut t); - | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough - | - = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`... - = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1` - -warning: function cannot return without recursing - --> $DIR/hrtb-perfect-forwarding.rs:48:1 - | -LL | / fn foo_hrtb_bar_hrtb(mut t: T) -LL | | where -LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>, - | |_______________________________________________________^ cannot return without recursing -... -LL | foo_hrtb_bar_hrtb(&mut t); - | ------------------------- recursive call site - | - = help: a `loop` may express intention better if this is on purpose - -error: aborting due to 2 previous errors; 4 warnings emitted - diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs b/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs deleted file mode 100644 index 42247798f66..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -// pretty-expanded FIXME #23616 - -// Test that `F : Fn(isize) -> isize + Send` is interpreted as two -// distinct bounds on `F`. - -fn foo1(f: F) - where F : FnOnce(isize) -> isize + Send -{ - bar(f); -} - -fn foo2(f: F) - where F : FnOnce(isize) -> isize + Send -{ - baz(f); -} - -fn bar(f: F) { } - -fn baz isize>(f: F) { } - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs b/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs deleted file mode 100644 index 6834c392d4e..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs +++ /dev/null @@ -1,13 +0,0 @@ -// run-pass -#![allow(dead_code)] -// pretty-expanded FIXME #23616 - -// Test that `Fn(isize) -> isize + 'static` parses as `(Fn(isize) -> isize) + -// 'static` and not `Fn(isize) -> (isize + 'static)`. The latter would -// cause a compilation error. Issue #18772. - -fn adder(y: isize) -> Box isize + 'static> { - Box::new(move |x| y + x) -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs b/tests/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs deleted file mode 100644 index b97fdf4df50..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -#![allow(dead_code)] -// A basic test of using a higher-ranked trait bound. - -// pretty-expanded FIXME #23616 - -trait FnLike { - fn call(&self, arg: A) -> R; -} - -type FnObject<'b> = dyn for<'a> FnLike<&'a isize, &'a isize> + 'b; - -fn main() { -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs b/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs deleted file mode 100644 index d8c726cdd71..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -// A basic test of using a higher-ranked trait bound. - -trait FnLike { - fn call(&self, arg: A) -> R; -} - -type FnObject<'b> = dyn for<'a> FnLike<(&'a i32,), &'a i32> + 'b; - -struct Identity; - -impl<'a, T> FnLike<(&'a T,), &'a T> for Identity { - fn call(&self, (arg,): (&'a T,)) -> &'a T { - arg - } -} - -fn call_repeatedly(f: &FnObject) { - let x = 3; - let y = f.call((&x,)); - assert_eq!(3, *y); -} - -fn main() { - call_repeatedly(&Identity); -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs b/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs deleted file mode 100644 index 41ebb3f5a14..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -#![allow(dead_code)] -// Test that `&PrinterSupport`, which is really short for `&'a -// PrinterSupport<'b>`, gets properly expanded when it appears in a -// closure type. This used to result in messed up De Bruijn indices. - -// pretty-expanded FIXME #23616 - -trait PrinterSupport<'ast> { - fn ast_map(&self) -> Option<&'ast usize> { None } -} - -struct NoAnn<'ast> { - f: Option<&'ast usize> -} - -impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> { -} - -fn foo<'ast, G>(f: Option<&'ast usize>, g: G) where G: FnOnce(&dyn PrinterSupport) { - let annotation = NoAnn { f: f }; - g(&annotation) -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs b/tests/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs deleted file mode 100644 index 88d396101db..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs +++ /dev/null @@ -1,46 +0,0 @@ -// run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -// Test what happens when a HR obligation is applied to an impl with -// "outlives" bounds. Currently we're pretty conservative here; this -// will probably improve in time. - -trait Foo { - fn foo(&self, x: X) { } -} - -fn want_foo() - where T : for<'a> Foo<&'a isize> -{ -} - -// Expressed as a where clause - -struct SomeStruct { - x: X -} - -impl<'a,X> Foo<&'a isize> for SomeStruct - where X : 'a -{ -} - -fn one() { - want_foo::>(); -} - -// Expressed as shorthand - -struct AnotherStruct { - x: X -} - -impl<'a,X:'a> Foo<&'a isize> for AnotherStruct -{ -} - -fn two() { - want_foo::>(); -} - -fn main() { } diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs b/tests/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs deleted file mode 100644 index a4a8a5ac6cc..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass -// Test HRTB used with the `Fn` trait. - -fn foo(f: F) { - let x = 22; - f(&x); -} - -fn main() { - foo(|x: &isize| println!("{}", *x)); -} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs b/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs deleted file mode 100644 index 1a9bb252340..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn a() where for T: Copy {} -//~^ ERROR only lifetime parameters can be used in this context - -fn b() where for [(); C]: Copy {} -//~^ ERROR only lifetime parameters can be used in this context - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr deleted file mode 100644 index 765ea9f7854..00000000000 --- a/tests/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0658]: only lifetime parameters can be used in this context - --> $DIR/hrtb-wrong-kind.rs:1:18 - | -LL | fn a() where for T: Copy {} - | ^ - | - = note: see issue #108185 for more information - = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable - -error[E0658]: only lifetime parameters can be used in this context - --> $DIR/hrtb-wrong-kind.rs:4:24 - | -LL | fn b() where for [(); C]: Copy {} - | ^ - | - = note: see issue #108185 for more information - = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/higher-rank-trait-bounds/issue-100689.rs b/tests/ui/higher-rank-trait-bounds/issue-100689.rs deleted file mode 100644 index 2db7f8a354c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-100689.rs +++ /dev/null @@ -1,29 +0,0 @@ -// check-pass - -struct Foo<'a> { - foo: &'a mut usize, -} - -trait Bar<'a> { - type FooRef<'b> - where - 'a: 'b; - fn uwu(foo: Foo<'a>, f: impl for<'b> FnMut(Self::FooRef<'b>)); -} -impl<'a> Bar<'a> for () { - type FooRef<'b> - = - &'b Foo<'a> - where - 'a : 'b, - ; - - fn uwu( - foo: Foo<'a>, - mut f: impl for<'b> FnMut(&'b Foo<'a>), //relevant part - ) { - f(&foo); - } -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/issue-102899.rs b/tests/ui/higher-rank-trait-bounds/issue-102899.rs deleted file mode 100644 index 952b81584f3..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-102899.rs +++ /dev/null @@ -1,32 +0,0 @@ -// check-pass - -pub trait BufferTrait<'buffer> { - type Subset<'channel> - where - 'buffer: 'channel; - - fn for_each_subset(&self, f: F) - where - F: for<'channel> Fn(Self::Subset<'channel>); -} - -pub struct SomeBuffer<'buffer> { - samples: &'buffer [()], -} - -impl<'buffer> BufferTrait<'buffer> for SomeBuffer<'buffer> { - type Subset<'subset> = Subset<'subset> where 'buffer: 'subset; - - fn for_each_subset(&self, _f: F) - where - F: for<'subset> Fn(Subset<'subset>), - { - todo!() - } -} - -pub struct Subset<'subset> { - buffer: &'subset [()], -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/issue-30786.rs b/tests/ui/higher-rank-trait-bounds/issue-30786.rs deleted file mode 100644 index 4a6399c8f62..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-30786.rs +++ /dev/null @@ -1,136 +0,0 @@ -// normalize-stderr-test: "long-type-\d+" -> "long-type-hash" - -// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream Option; -} - -// Example stream -pub struct Repeat(u64); - -impl<'a> Stream for &'a mut Repeat { - type Item = &'a u64; - fn next(self) -> Option { - Some(&self.0) - } -} - -pub struct Map { - stream: S, - func: F, -} - -impl<'a, A, F, T> Stream for &'a mut Map -where - &'a mut A: Stream, - F: FnMut(<&'a mut A as Stream>::Item) -> T, -{ - type Item = T; - fn next(self) -> Option { - match self.stream.next() { - Some(item) => Some((self.func)(item)), - None => None, - } - } -} - -pub struct Filter { - stream: S, - func: F, -} - -impl<'a, A, F, T> Stream for &'a mut Filter -where - for<'b> &'b mut A: Stream, // <---- BAD - F: FnMut(&T) -> bool, -{ - type Item = <&'a mut A as Stream>::Item; - fn next(self) -> Option { - while let Some(item) = self.stream.next() { - if (self.func)(&item) { - return Some(item); - } - } - None - } -} - -pub trait StreamExt -where - for<'b> &'b mut Self: Stream, -{ - fn mapx(self, func: F) -> Map - where - Self: Sized, - for<'a> &'a mut Map: Stream, - { - Map { func: func, stream: self } - } - - fn filterx(self, func: F) -> Filter - where - Self: Sized, - for<'a> &'a mut Filter: Stream, - { - Filter { func: func, stream: self } - } - - fn countx(mut self) -> usize - where - Self: Sized, - { - let mut count = 0; - while let Some(_) = self.next() { - count += 1; - } - count - } -} - -impl StreamExt for T where for<'a> &'a mut T: Stream {} - -fn identity(x: &T) -> &T { - x -} - -fn variant1() { - let source = Repeat(10); - - // Here, the call to `mapx` returns a type `T` to which `StreamExt` - // is not applicable, because `for<'b> &'b mut T: Stream`) doesn't hold. - // - // More concretely, the type `T` is `Map`, and - // the where clause doesn't hold because the signature of the - // closure gets inferred to a signature like `|&'_ Stream| -> &'_` - // for some specific `'_`, rather than a more generic - // signature. - // - // Why *exactly* we opt for this signature is a bit unclear to me, - // we deduce it somehow from a reuqirement that `Map: Stream` I - // guess. - let map = source.mapx(|x: &_| x); - let filter = map.filterx(|x: &_| true); - //~^ ERROR the method -} - -fn variant2() { - let source = Repeat(10); - - // Here, we use a function, which is not subject to the vagaries - // of closure signature inference. In this case, we get the error - // on `countx` as, I think, the test originally expected. - let map = source.mapx(identity); - let filter = map.filterx(|x: &_| true); - let count = filter.countx(); - //~^ ERROR the method -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/issue-30786.stderr b/tests/ui/higher-rank-trait-bounds/issue-30786.stderr deleted file mode 100644 index 6ec34d11a7e..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-30786.stderr +++ /dev/null @@ -1,46 +0,0 @@ -error[E0599]: the method `filterx` exists for struct `Map`, but its trait bounds were not satisfied - --> $DIR/issue-30786.rs:120:22 - | -LL | pub struct Map { - | -------------------- - | | - | method `filterx` not found for this struct - | doesn't satisfy `_: StreamExt` -... -LL | let filter = map.filterx(|x: &_| true); - | ^^^^^^^ method cannot be called on `Map` due to unsatisfied trait bounds - | -note: the following trait bounds were not satisfied: - `&'a mut &Map: Stream` - `&'a mut &mut Map: Stream` - `&'a mut Map: Stream` - --> $DIR/issue-30786.rs:98:50 - | -LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} - | --------- - ^^^^^^ unsatisfied trait bound introduced here - -error[E0599]: the method `countx` exists for struct `Filter &u64 {identity::}>, [closure@issue-30786.rs:131:30]>`, but its trait bounds were not satisfied - --> $DIR/issue-30786.rs:132:24 - | -LL | pub struct Filter { - | ----------------------- - | | - | method `countx` not found for this struct - | doesn't satisfy `_: StreamExt` -... -LL | let count = filter.countx(); - | ^^^^^^ method cannot be called due to unsatisfied trait bounds - | - = note: the full type name has been written to '$TEST_BUILD_DIR/higher-rank-trait-bounds/issue-30786/issue-30786.long-type-hash.txt' -note: the following trait bounds were not satisfied: - `&'a mut &Filter fn(&'a u64) -> &'a u64 {identity::}>, [closure@$DIR/issue-30786.rs:131:30: 131:37]>: Stream` - `&'a mut &mut Filter fn(&'a u64) -> &'a u64 {identity::}>, [closure@$DIR/issue-30786.rs:131:30: 131:37]>: Stream` - `&'a mut Filter fn(&'a u64) -> &'a u64 {identity::}>, [closure@$DIR/issue-30786.rs:131:30: 131:37]>: Stream` - --> $DIR/issue-30786.rs:98:50 - | -LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} - | --------- - ^^^^^^ unsatisfied trait bound introduced here - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs b/tests/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs deleted file mode 100644 index 2d49151ffcc..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-36139-normalize-closure-sig.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -// Previously the closure's argument would be inferred to -// >::Item, causing an error in MIR type -// checking - -trait ITrait<'a> {type Item;} - -struct S {} - -impl<'a> ITrait<'a> for S { type Item = &'a mut usize; } - -fn m(_: F) - where I: for<'a> ITrait<'a>, - F: for<'a> FnMut(>::Item) { } - - -fn main() { - m::(|x| { *x += 1; }); -} diff --git a/tests/ui/higher-rank-trait-bounds/issue-39292.rs b/tests/ui/higher-rank-trait-bounds/issue-39292.rs deleted file mode 100644 index 968cf08916f..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-39292.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// Regression test for issue #39292. The object vtable was being -// incorrectly left with a null pointer. - -trait Foo { - fn print<'a>(&'a self) where T: 'a { println!("foo"); } -} - -impl<'a> Foo<&'a ()> for () { } - -trait Bar: for<'a> Foo<&'a ()> { } - -impl Bar for () {} - -fn main() { - (&() as &dyn Bar).print(); // Segfault -} diff --git a/tests/ui/higher-rank-trait-bounds/issue-42114.rs b/tests/ui/higher-rank-trait-bounds/issue-42114.rs deleted file mode 100644 index 01515fdc9d2..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-42114.rs +++ /dev/null @@ -1,20 +0,0 @@ -// check-pass - -fn lifetime<'a>() -where - &'a (): 'a, -{ - /* do nothing */ -} - -fn doesnt_work() -where - for<'a> &'a (): 'a, -{ - /* do nothing */ -} - -fn main() { - lifetime(); - doesnt_work(); -} diff --git a/tests/ui/higher-rank-trait-bounds/issue-43623.rs b/tests/ui/higher-rank-trait-bounds/issue-43623.rs deleted file mode 100644 index cedcf7c361c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-43623.rs +++ /dev/null @@ -1,21 +0,0 @@ -// check-pass - -pub trait Trait<'a> { - type Assoc; -} - -pub struct Type; - -impl<'a> Trait<'a> for Type { - type Assoc = (); -} - -pub fn break_me(f: F) -where - T: for<'b> Trait<'b>, - F: for<'b> FnMut(>::Assoc), -{ - break_me::; -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/issue-46989.rs b/tests/ui/higher-rank-trait-bounds/issue-46989.rs deleted file mode 100644 index 4a09f4be156..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-46989.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Regression test for #46989: -// -// In the move to universes, this test started passing. -// It is not necessarily WRONG to do so, but it was a bit -// surprising. The reason that it passed is that when we were -// asked to prove that -// -// for<'a> fn(&'a i32): Foo -// -// we were able to use the impl below to prove -// -// fn(&'empty i32): Foo -// -// and then we were able to prove that -// -// fn(&'empty i32) = for<'a> fn(&'a i32) -// -// This last fact is somewhat surprising, but essentially "falls out" -// from handling variance correctly. In particular, consider the subtyping -// relations. First: -// -// fn(&'empty i32) <: for<'a> fn(&'a i32) -// -// This holds because -- intuitively -- a fn that takes a reference but doesn't use -// it can be given a reference with any lifetime. Similarly, the opposite direction: -// -// for<'a> fn(&'a i32) <: fn(&'empty i32) -// -// holds because 'a can be instantiated to 'empty. - -trait Foo {} - -impl Foo for fn(A) {} - -fn assert_foo() {} - -fn main() { - assert_foo::(); - //~^ ERROR implementation of `Foo` is not general enough -} diff --git a/tests/ui/higher-rank-trait-bounds/issue-46989.stderr b/tests/ui/higher-rank-trait-bounds/issue-46989.stderr deleted file mode 100644 index 3f874220a27..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-46989.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: implementation of `Foo` is not general enough - --> $DIR/issue-46989.rs:38:5 - | -LL | assert_foo::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `Foo` would have to be implemented for the type `for<'a> fn(&'a i32)` - = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0` - -error: aborting due to previous error - diff --git a/tests/ui/higher-rank-trait-bounds/issue-57639.rs b/tests/ui/higher-rank-trait-bounds/issue-57639.rs deleted file mode 100644 index 392e7233b56..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-57639.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Regression test for #57639: -// -// In the move to universes, this test stopped working. The problem -// was that when the trait solver was asked to prove `for<'a> T::Item: -// Foo<'a>` as part of WF checking, it wound up "eagerly committing" -// to the where clause, which says that `T::Item: Foo<'a>`, but it -// should instead have been using the bound found in the trait -// declaration. Pre-universe, this used to work out ok because we got -// "eager errors" due to the leak check. -// -// See [this comment on GitHub][c] for more details. -// -// check-pass -// -// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861 - -trait Foo<'a> {} - -trait Bar { - type Item: for<'a> Foo<'a>; -} - -fn foo<'a, T>(_: T) -where - T: Bar, - T::Item: Foo<'a>, -{} - -fn main() { } diff --git a/tests/ui/higher-rank-trait-bounds/issue-58451.rs b/tests/ui/higher-rank-trait-bounds/issue-58451.rs deleted file mode 100644 index 6006a108c5c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-58451.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Regression test for #58451: -// -// Error reporting here encountered an ICE in the shift to universes. - -fn f(i: I) -where - I: IntoIterator, - I::Item: for<'a> Into<&'a ()>, -{} - -fn main() { - f(&[f()]); //~ ERROR function takes 1 argument -} diff --git a/tests/ui/higher-rank-trait-bounds/issue-58451.stderr b/tests/ui/higher-rank-trait-bounds/issue-58451.stderr deleted file mode 100644 index 0f051be2128..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-58451.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0061]: this function takes 1 argument but 0 arguments were supplied - --> $DIR/issue-58451.rs:12:9 - | -LL | f(&[f()]); - | ^-- an argument is missing - | -note: function defined here - --> $DIR/issue-58451.rs:5:4 - | -LL | fn f(i: I) - | ^ ---- -help: provide the argument - | -LL | f(&[f(/* i */)]); - | ~~~~~~~~~ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/higher-rank-trait-bounds/issue-59311.rs b/tests/ui/higher-rank-trait-bounds/issue-59311.rs deleted file mode 100644 index 3ad548450e5..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-59311.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Regression test for #59311. The test is taken from -// rust-lang/rust/issues/71546#issuecomment-620638437 -// as they seem to have the same cause. - -// FIXME: It's not clear that this code ought to report -// an error, but the regression test is here to ensure -// that it does not ICE. See discussion on #74889 for details. - -pub trait T { - fn t(&self, _: F) {} -} - -pub fn crash(v: &V) -where - for<'a> &'a V: T + 'static, -{ - v.t(|| {}); - //~^ ERROR: higher-ranked lifetime error - //~| ERROR: higher-ranked lifetime error -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/issue-59311.stderr b/tests/ui/higher-rank-trait-bounds/issue-59311.stderr deleted file mode 100644 index c01ab8e347c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-59311.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: higher-ranked lifetime error - --> $DIR/issue-59311.rs:17:5 - | -LL | v.t(|| {}); - | ^^^^^^^^^^ - | - = note: could not prove `[closure@$DIR/issue-59311.rs:17:9: 17:11] well-formed` - -error: higher-ranked lifetime error - --> $DIR/issue-59311.rs:17:9 - | -LL | v.t(|| {}); - | ^^^^^ - | - = note: could not prove `for<'a> &'a V: 'static` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/higher-rank-trait-bounds/issue-60283.rs b/tests/ui/higher-rank-trait-bounds/issue-60283.rs deleted file mode 100644 index 05315b3f9f5..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-60283.rs +++ /dev/null @@ -1,20 +0,0 @@ -// check-pass - -pub trait Trait<'a> { - type Item; -} - -impl<'a> Trait<'a> for () { - type Item = (); -} - -pub fn foo(_: T, _: F) -where - T: for<'a> Trait<'a>, - F: for<'a> FnMut(>::Item), -{ -} - -fn main() { - foo((), drop) -} diff --git a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs b/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs deleted file mode 100644 index e70f6fc3430..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.rs +++ /dev/null @@ -1,54 +0,0 @@ -trait T0<'a, A> { - type O; -} - -struct L { - f: T, -} - -// explicitly named variants of what one would normally denote by the -// unit type `()`. Why do this? So that we can differentiate them in -// the diagnostic output. -struct Unit1; -struct Unit2; -struct Unit3; -struct Unit4; - -impl<'a, A, T> T0<'a, A> for L -where - T: FnMut(A) -> Unit3, -{ - type O = T::Output; -} - -trait T1: for<'r> Ty<'r> { - fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 - where - F: for<'r> T0<'r, (>::V,), O = >::V>, - { - unimplemented!(); - } -} - -trait Ty<'a> { - type V; -} - -fn main() { - let v = Unit2.m( - L { - //~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4` - //~| ERROR type mismatch - f: |x| { - drop(x); - Unit4 - }, - }, - ); -} - -impl<'a> Ty<'a> for Unit2 { - type V = &'a u8; -} - -impl T1 for Unit2 {} diff --git a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr b/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr deleted file mode 100644 index 4d470ae7022..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr +++ /dev/null @@ -1,66 +0,0 @@ -error[E0271]: type mismatch resolving ` as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` - --> $DIR/issue-62203-hrtb-ice.rs:39:9 - | -LL | let v = Unit2.m( - | - required by a bound introduced by this call -LL | / L { -LL | | -LL | | -LL | | f: |x| { -... | -LL | | }, -LL | | }, - | |_________^ type mismatch resolving ` as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` - | -note: expected this to be `<_ as Ty<'_>>::V` - --> $DIR/issue-62203-hrtb-ice.rs:21:14 - | -LL | type O = T::Output; - | ^^^^^^^^^ - = note: expected associated type `<_ as Ty<'_>>::V` - found struct `Unit4` - = help: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` or calling a method that returns `<_ as Ty<'_>>::V` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html -note: required by a bound in `T1::m` - --> $DIR/issue-62203-hrtb-ice.rs:27:51 - | -LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 - | - required by a bound in this associated function -LL | where -LL | F: for<'r> T0<'r, (>::V,), O = >::V>, - | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` - -error[E0271]: expected `[closure@issue-62203-hrtb-ice.rs:42:16]` to be a closure that returns `Unit3`, but it returns `Unit4` - --> $DIR/issue-62203-hrtb-ice.rs:39:9 - | -LL | let v = Unit2.m( - | - required by a bound introduced by this call -LL | / L { -LL | | -LL | | -LL | | f: |x| { -... | -LL | | }, -LL | | }, - | |_________^ expected `Unit3`, found `Unit4` - | -note: required for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>` to implement `for<'r> T0<'r, (&'r u8,)>` - --> $DIR/issue-62203-hrtb-ice.rs:17:16 - | -LL | impl<'a, A, T> T0<'a, A> for L - | ^^^^^^^^^ ^^^^ -LL | where -LL | T: FnMut(A) -> Unit3, - | ----- unsatisfied trait bound introduced here -note: required by a bound in `T1::m` - --> $DIR/issue-62203-hrtb-ice.rs:27:12 - | -LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 - | - required by a bound in this associated function -LL | where -LL | F: for<'r> T0<'r, (>::V,), O = >::V>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/higher-rank-trait-bounds/issue-88446.rs b/tests/ui/higher-rank-trait-bounds/issue-88446.rs deleted file mode 100644 index 571b8531757..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-88446.rs +++ /dev/null @@ -1,35 +0,0 @@ -// check-pass - -trait Yokeable<'a> { - type Output: 'a; -} -impl<'a> Yokeable<'a> for () { - type Output = (); -} - -trait DataMarker<'data> { - type Yokeable: for<'a> Yokeable<'a>; -} -impl<'data> DataMarker<'data> for () { - type Yokeable = (); -} - -struct DataPayload<'data, M>(&'data M); - -impl DataPayload<'static, ()> { - pub fn map_project_with_capture( - _: for<'a> fn( - capture: T, - std::marker::PhantomData<&'a ()>, - ) -> >::Output, - ) -> DataPayload<'static, M2> - where - M2: DataMarker<'static>, - { - todo!() - } -} - -fn main() { - let _: DataPayload<()> = DataPayload::<()>::map_project_with_capture::<_, &()>(|_, _| todo!()); -} diff --git a/tests/ui/higher-rank-trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs b/tests/ui/higher-rank-trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs deleted file mode 100644 index 92b7c5deb81..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Regression test for #88586: a higher-ranked outlives bound on Self in a trait -// definition caused an ICE when debug_assertions were enabled. -// -// Made to pass as part of fixing #98095. -// -// check-pass - -trait A where - for<'a> Self: 'a, -{ -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/issue-90177.rs b/tests/ui/higher-rank-trait-bounds/issue-90177.rs deleted file mode 100644 index b151a9d3ab6..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-90177.rs +++ /dev/null @@ -1,32 +0,0 @@ -// check-pass - -trait Base<'f> { - type Assoc; - - fn do_something(&self); -} - -trait ForAnyLifetime: for<'f> Base<'f> {} - -impl ForAnyLifetime for T where T: for<'f> Base<'f> {} - -trait CanBeDynamic: ForAnyLifetime + for<'f> Base<'f, Assoc = ()> {} - -fn foo(a: &dyn CanBeDynamic) { - a.do_something(); -} - -struct S; - -impl<'a> Base<'a> for S { - type Assoc = (); - - fn do_something(&self) {} -} - -impl CanBeDynamic for S {} - -fn main() { - let s = S; - foo(&s); -} diff --git a/tests/ui/higher-rank-trait-bounds/issue-95034.rs b/tests/ui/higher-rank-trait-bounds/issue-95034.rs deleted file mode 100644 index af4946a187f..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-95034.rs +++ /dev/null @@ -1,80 +0,0 @@ -// check-pass -// compile-flags: --edition=2021 --crate-type=lib - -use std::{ - future::Future, - marker::PhantomData, - pin::Pin, - task::{Context, Poll}, -}; - -mod object { - use super::*; - - pub trait Object<'a> { - type Error; - type Future: Future; - fn create() -> Self::Future; - } - - impl<'a> Object<'a> for u8 { - type Error = (); - type Future = Pin>>; - fn create() -> Self::Future { - unimplemented!() - } - } - - impl<'a, E, A: Object<'a, Error = E>> Object<'a> for (A,) { - type Error = (); - type Future = CustomFut<'a, E, A>; - fn create() -> Self::Future { - unimplemented!() - } - } - - pub struct CustomFut<'f, E, A: Object<'f, Error = E>> { - ph: PhantomData<(A::Future,)>, - } - - impl<'f, E, A: Object<'f, Error = E>> Future for CustomFut<'f, E, A> { - type Output = (A,); - fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { - unimplemented!() - } - } -} - -mod async_fn { - use super::*; - - pub trait AsyncFn { - type Future: Future; - fn call(&self) -> Self::Future; - } - - impl AsyncFn for F - where - F: Fn() -> Fut, - Fut: Future, - { - type Future = Fut; - fn call(&self) -> Self::Future { - (self)() - } - } -} - -pub async fn test() { - use self::{async_fn::AsyncFn, object::Object}; - - async fn create>() { - T::create().await; - } - - async fn call_async_fn(inner: impl AsyncFn) { - inner.call().await; - } - - call_async_fn(create::<(u8,)>).await; -} diff --git a/tests/ui/higher-rank-trait-bounds/issue-95230.next.stderr b/tests/ui/higher-rank-trait-bounds/issue-95230.next.stderr deleted file mode 100644 index d4bc5b67220..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-95230.next.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0275]: overflow evaluating the requirement `for<'a> &'a mut Bar well-formed` - --> $DIR/issue-95230.rs:9:13 - | -LL | for<'a> &'a mut Self:; - | ^^^^^^^^^^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_95230`) -note: required by a bound in `Bar` - --> $DIR/issue-95230.rs:9:13 - | -LL | pub struct Bar - | --- required by a bound in this struct -LL | where -LL | for<'a> &'a mut Self:; - | ^^^^^^^^^^^^ required by this bound in `Bar` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/higher-rank-trait-bounds/issue-95230.rs b/tests/ui/higher-rank-trait-bounds/issue-95230.rs deleted file mode 100644 index 49a1584d54e..00000000000 --- a/tests/ui/higher-rank-trait-bounds/issue-95230.rs +++ /dev/null @@ -1,11 +0,0 @@ -// revisions: old next -//[next] compile-flags: -Ztrait-solver=next -//[old] check-pass -//[next] known-bug: #109764 - - -pub struct Bar -where - for<'a> &'a mut Self:; - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs deleted file mode 100644 index f255eac0c4b..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs +++ /dev/null @@ -1,31 +0,0 @@ -// check-pass - -pub trait Foo<'a> { - type Bar; - fn foo(&'a self) -> Self::Bar; -} - -impl<'a, 'b, T: 'a> Foo<'a> for &'b T { - type Bar = &'a T; - fn foo(&'a self) -> &'a T { - self - } -} - -pub fn uncallable(x: T, f: F) -where - T: for<'a> Foo<'a>, - F: for<'a> Fn(>::Bar), -{ - f(x.foo()); -} - -pub fn catalyst(x: &i32) { - broken(x, |_| {}) -} - -pub fn broken(x: &i32, f: F) { - uncallable(x, |y| f(y)); -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-56556.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-56556.rs deleted file mode 100644 index 4d38cb19e9b..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-56556.rs +++ /dev/null @@ -1,30 +0,0 @@ -// check-pass - -fn foo(t: T) -> usize -where - for<'a> &'a T: IntoIterator, - for<'a> <&'a T as IntoIterator>::IntoIter: ExactSizeIterator, -{ - t.into_iter().len() -} - -fn main() { - foo::>(vec![]); -} - -mod another { - use std::ops::Deref; - - fn test() - where - T: Deref, - TDeref: ?Sized, - for<'a> &'a TDeref: IntoIterator, - for<'a> <&'a TDeref as IntoIterator>::IntoIter: Clone, - { - } - - fn main() { - test::, _>(); - } -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs deleted file mode 100644 index c6f29fa5908..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs +++ /dev/null @@ -1,88 +0,0 @@ -// check-pass - -// FamilyType (GAT workaround) -pub trait FamilyLt<'a> { - type Out; -} - -struct RefMutFamily(std::marker::PhantomData, ()); -impl<'a, T: 'a> FamilyLt<'a> for RefMutFamily { - type Out = &'a mut T; -} - -pub trait Execute { - type E: Inject; - fn execute(self, value: <::I as FamilyLt>::Out); -} - -pub trait Inject -where - Self: Sized, -{ - type I: for<'a> FamilyLt<'a>; - fn inject(_: &()) -> ::Out; -} - -impl Inject for RefMutFamily { - type I = Self; - fn inject(_: &()) -> ::Out { - unimplemented!() - } -} - -// This struct is only used to give a hint to the compiler about the type `Q` -struct Annotate(std::marker::PhantomData); -impl Annotate { - fn new() -> Self { - Self(std::marker::PhantomData) - } -} - -// This function annotate a closure so it can have Higher-Rank Lifetime Bounds -// -// See 'annotate' workaround: https://github.com/rust-lang/rust/issues/58052 -fn annotate(_q: Annotate, func: F) -> impl Execute + 'static -where - F: for<'r> FnOnce(<::I as FamilyLt<'r>>::Out) + 'static, - Q: Inject + 'static, -{ - let wrapper: Wrapper = Wrapper(std::marker::PhantomData, func); - wrapper -} - -struct Wrapper(std::marker::PhantomData, F); -impl Execute for Wrapper - where - Q: Inject, - F: for<'r> FnOnce(<::I as FamilyLt<'r>>::Out), -{ - type E = Q; - - fn execute(self, value: <::I as FamilyLt>::Out) { - (self.1)(value) - } -} - -struct Task { - _processor: Box, -} - -// This function consume the closure -fn task

>::Output, -) -> MiniYoke

-where - Y: for<'a> MiniYokeable<'a>, - P: for<'a> MiniYokeable<'a> -{ - unimplemented!() -} - -struct Bar<'a> { - string_1: &'a str, - string_2: &'a str, -} - -impl<'a> MiniYokeable<'a> for Bar<'static> { - type Output = Bar<'a>; -} - -impl<'a> MiniYokeable<'a> for &'static str { - type Output = &'a str; -} - -fn demo_broken(bar: MiniYoke>) -> MiniYoke<&'static str> { - map_project_broken(bar, |bar, _| bar.string_1) -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs deleted file mode 100644 index effc329456d..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs +++ /dev/null @@ -1,41 +0,0 @@ -// check-pass - -use std::marker::PhantomData; - -trait Family: Sized { - type Item<'a>; - - fn apply_all(&self, f: F) - where - F: FamilyItemFn { } -} - -struct Array(PhantomData); - -impl Family for Array { - type Item<'a> = &'a T; -} - -trait FamilyItemFn { - fn apply(&self, item: T::Item<'_>); -} - -impl FamilyItemFn for F -where - T: Family, - for<'a> F: Fn(T::Item<'a>) -{ - fn apply(&self, item: T::Item<'_>) { - (*self)(item); - } -} - -fn process(array: Array) { - // Works - array.apply_all(|x: &T| { }); - - // ICE: NoSolution - array.apply_all(|x: as Family>::Item<'_>| { }); -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs deleted file mode 100644 index 628b5cba104..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs +++ /dev/null @@ -1,35 +0,0 @@ -//check-pass - -trait Yokeable<'a>: 'static { - type Output: 'a; -} - -trait IsCovariant<'a> {} - -struct Yoke Yokeable<'a>> { - data: Y, -} - -impl Yokeable<'a>> Yoke { - fn project Yokeable<'a>>(&self, _f: for<'a> fn(>::Output, &'a ()) - -> >::Output) -> Yoke { - - unimplemented!() - } -} - -fn _upcast(x: Yoke) -> Yoke + 'static>> where - Y: for<'a> Yokeable<'a>, - for<'a> >::Output: IsCovariant<'a> - { - x.project(|data, _| { - Box::new(data) - }) -} - - -impl<'a> Yokeable<'a> for Box + 'static> { - type Output = Box + 'a>; -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90875.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90875.rs deleted file mode 100644 index ffd6857d84a..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90875.rs +++ /dev/null @@ -1,31 +0,0 @@ -// check-pass - -trait Variable<'a> { - type Type; -} - -impl Variable<'_> for () { - type Type = (); -} - -fn check(_: F) -where - F: Fn(T), // <- if removed, all fn_* then require type annotations - F: for<'a> Fn(>::Type), - T: for<'a> Variable<'a>, -{ -} - -fn test(arg: impl Fn(())) { - fn fn_1(_: ()) {} - let fn_2 = |_: ()| (); - let fn_3 = |a| fn_1(a); - let fn_4 = arg; - - check(fn_1); // Error - check(fn_2); // Ok - check(fn_3); // Ok - check(fn_4); // Error -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs deleted file mode 100644 index ab9d9a7ce6f..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.rs +++ /dev/null @@ -1,53 +0,0 @@ -// check-fail -// known-bug: #90950 - -trait Yokeable<'a>: 'static { - type Output: 'a; -} - - -trait IsCovariant<'a> {} - -struct Yoke Yokeable<'a>> { - data: Y, -} - - -// impl Yokeable<'a>> Yoke { -// fn project Yokeable<'a>>( -// &self, -// f: for<'a> fn(>::Output, &'a (), -// ) -> >::Output) -> Yoke { -// unimplemented!() -// } -// } - -fn upcast(x: Yoke) -> Yoke + 'static>> where - Y: for<'a> Yokeable<'a>, - for<'a> >::Output: IsCovariant<'a> - { - // x.project(|data, _| { - // Box::new(data) - // }) - unimplemented!() -} - - -impl<'a> Yokeable<'a> for Box + 'static> { - type Output = Box + 'a>; -} - -// this impl is mostly an example and unnecessary for the pure repro -use std::borrow::*; -impl<'a, T: ToOwned + ?Sized> Yokeable<'a> for Cow<'static, T> { - type Output = Cow<'a, T>; -} -impl<'a, T: ToOwned + ?Sized> IsCovariant<'a> for Cow<'a, T> {} - - - -fn upcast_yoke(y: Yoke>) -> Yoke + 'static>> { - upcast(y) -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr deleted file mode 100644 index 5be33bccdc3..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0277]: the trait bound `for<'a> <_ as Yokeable<'a>>::Output: IsCovariant<'a>` is not satisfied - --> $DIR/issue-90950.rs:50:12 - | -LL | upcast(y) - | ------ ^ the trait `for<'a> IsCovariant<'a>` is not implemented for `<_ as Yokeable<'a>>::Output` - | | - | required by a bound introduced by this call - | - = help: the trait `IsCovariant<'a>` is implemented for `std::borrow::Cow<'a, T>` -note: required by a bound in `upcast` - --> $DIR/issue-90950.rs:27:42 - | -LL | fn upcast(x: Yoke) -> Yoke + 'static>> where - | ------ required by a bound in this function -LL | Y: for<'a> Yokeable<'a>, -LL | for<'a> >::Output: IsCovariant<'a> - | ^^^^^^^^^^^^^^^ required by this bound in `upcast` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs deleted file mode 100644 index 7693b118247..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.rs +++ /dev/null @@ -1,23 +0,0 @@ -// check-fail -// known-bug: #89196 - -// Should pass, but we normalize and check bounds before we resolve the generics -// of the function (which we know because of the return type). - -trait Trait<'a> { - type Out; -} - -impl<'a, T> Trait<'a> for T { - type Out = T; -} - -fn weird_bound() -> X - where - for<'a> X: Trait<'a>, - for<'a> >::Out: Copy -{ todo!() } - -fn main() { - let _: () = weird_bound(); -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr deleted file mode 100644 index 73388a72574..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: the trait bound `for<'a> <_ as Trait<'a>>::Out: Copy` is not satisfied - --> $DIR/norm-before-method-resolution.rs:22:17 - | -LL | let _: () = weird_bound(); - | ^^^^^^^^^^^ the trait `for<'a> Copy` is not implemented for `<_ as Trait<'a>>::Out` - | -note: required by a bound in `weird_bound` - --> $DIR/norm-before-method-resolution.rs:18:40 - | -LL | fn weird_bound() -> X - | ----------- required by a bound in this function -... -LL | for<'a> >::Out: Copy - | ^^^^ required by this bound in `weird_bound` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/higher-lifetime-bounds.rs b/tests/ui/higher-ranked/higher-lifetime-bounds.rs new file mode 100644 index 00000000000..f3393347d90 --- /dev/null +++ b/tests/ui/higher-ranked/higher-lifetime-bounds.rs @@ -0,0 +1,69 @@ +#![allow(dead_code, non_camel_case_types)] + +// Test that bounds on higher-kinded lifetime binders are rejected. + +fn bar1<'a, 'b>( + x: &'a i32, + y: &'b i32, + f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) + //~^ ERROR lifetime bounds cannot be used in this context +{ + // If the bound in f's type would matter, the call below would (have to) + // be rejected. + f(x, y); +} + +fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>( + //~^ ERROR lifetime bounds cannot be used in this context + x: &'a i32, + y: &'b i32, + f: F) +{ + // If the bound in f's type would matter, the call below would (have to) + // be rejected. + f(x, y); +} + +fn bar3<'a, 'b, F>( + x: &'a i32, + y: &'b i32, + f: F) + where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 + //~^ ERROR lifetime bounds cannot be used in this context +{ + // If the bound in f's type would matter, the call below would (have to) + // be rejected. + f(x, y); +} + +fn bar4<'a, 'b, F>( + x: &'a i32, + y: &'b i32, + f: F) + where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 + //~^ ERROR lifetime bounds cannot be used in this context +{ + // If the bound in f's type would matter, the call below would (have to) + // be rejected. + f(x, y); +} + +struct S1 Fn(&'xa i32, &'xb i32) -> &'xa i32>(F); +//~^ ERROR lifetime bounds cannot be used in this context +struct S2(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32; +//~^ ERROR lifetime bounds cannot be used in this context +struct S3(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32; +//~^ ERROR lifetime bounds cannot be used in this context + +struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32); +//~^ ERROR lifetime bounds cannot be used in this context + +type T1 = Box Fn(&'xa i32, &'xb i32) -> &'xa i32>; +//~^ ERROR lifetime bounds cannot be used in this context + +fn main() { + let _ : Option fn(&'xa i32, &'xb i32) -> &'xa i32> = None; + //~^ ERROR lifetime bounds cannot be used in this context + let _ : Option Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None; + //~^ ERROR lifetime bounds cannot be used in this context +} diff --git a/tests/ui/higher-ranked/higher-lifetime-bounds.stderr b/tests/ui/higher-ranked/higher-lifetime-bounds.stderr new file mode 100644 index 00000000000..bc6d2288cdf --- /dev/null +++ b/tests/ui/higher-ranked/higher-lifetime-bounds.stderr @@ -0,0 +1,68 @@ +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:8:22 + | +LL | f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) + | ^^^ ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:16:34 + | +LL | fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>( + | ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:31:28 + | +LL | where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 + | ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:43:25 + | +LL | where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 + | ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:51:28 + | +LL | struct S1 Fn(&'xa i32, &'xb i32) -> &'xa i32>(F); + | ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:53:40 + | +LL | struct S2(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32; + | ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:55:37 + | +LL | struct S3(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32; + | ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:58:29 + | +LL | struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32); + | ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:61:33 + | +LL | type T1 = Box Fn(&'xa i32, &'xb i32) -> &'xa i32>; + | ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:65:34 + | +LL | let _ : Option fn(&'xa i32, &'xb i32) -> &'xa i32> = None; + | ^^^ + +error: lifetime bounds cannot be used in this context + --> $DIR/higher-lifetime-bounds.rs:67:42 + | +LL | let _ : Option Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None; + | ^^^ + +error: aborting due to 11 previous errors + diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr new file mode 100644 index 00000000000..b7264c7e933 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:54:13 + | +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +... +LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, +LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) } + | |_____________________________________________- in this macro invocation + | + = note: expected enum `Option fn(&'a u32, &'b u32) -> &'a u32>` + found enum `Option fn(&'a u32, &'a u32) -> &'a u32>` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr new file mode 100644 index 00000000000..2355979b0f9 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_a_vs_free_x.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:54:13 + | +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +... +LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), +LL | | fn(&'x u32)) } + | |______________- in this macro invocation + | + = note: expected enum `Option fn(&'a u32)>` + found enum `Option` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr new file mode 100644 index 00000000000..a73c03feb87 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:54:13 + | +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +... +LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), +LL | | for<'a> fn(Inv<'a>, Inv<'a>)) } + | |__________________________________- in this macro invocation + | + = note: expected enum `Option fn(Inv<'a>, Inv<'b>)>` + found enum `Option fn(Inv<'a>, Inv<'a>)>` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/hr-subtype.rs:54:13 + | +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other +... +LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), +LL | | for<'a> fn(Inv<'a>, Inv<'a>)) } + | |__________________________________- in this macro invocation + | + = note: expected enum `Option fn(Inv<'a>, Inv<'b>)>` + found enum `Option fn(Inv<'a>, Inv<'a>)>` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr new file mode 100644 index 00000000000..31d36d7168b --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr @@ -0,0 +1,42 @@ +error: lifetime may not live long enough + --> $DIR/hr-subtype.rs:48:13 + | +LL | fn subtype<'x, 'y: 'x, 'z: 'y>() { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | gimme::<$t2>(None::<$t1>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` +... +LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), +LL | | fn(Inv<'y>)) } + | |______________- in this macro invocation + | + = help: consider adding the following bound: `'x: 'y` + = note: requirement occurs because of the type `Inv<'_>`, which makes the generic argument `'_` invariant + = note: the struct `Inv<'a>` is invariant over the parameter `'a` + = help: see for more information about variance + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: lifetime may not live long enough + --> $DIR/hr-subtype.rs:54:13 + | +LL | fn supertype<'x, 'y: 'x, 'z: 'y>() { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` +... +LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), +LL | | fn(Inv<'y>)) } + | |______________- in this macro invocation + | + = help: consider adding the following bound: `'x: 'y` + = note: requirement occurs because of the type `Inv<'_>`, which makes the generic argument `'_` invariant + = note: the struct `Inv<'a>` is invariant over the parameter `'a` + = help: see for more information about variance + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr b/tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr new file mode 100644 index 00000000000..269cde54c7e --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.free_x_vs_free_y.stderr @@ -0,0 +1,19 @@ +error: lifetime may not live long enough + --> $DIR/hr-subtype.rs:54:13 + | +LL | fn supertype<'x, 'y: 'x, 'z: 'y>() { + | -- -- lifetime `'y` defined here + | | + | lifetime `'x` defined here +LL | gimme::<$t1>(None::<$t2>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` +... +LL | / check! { free_x_vs_free_y: (fn(&'x u32), +LL | | fn(&'y u32)) } + | |______________- in this macro invocation + | + = help: consider adding the following bound: `'x: 'y` + = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/tests/ui/higher-ranked/subtype/hr-subtype.rs b/tests/ui/higher-ranked/subtype/hr-subtype.rs new file mode 100644 index 00000000000..c770e0de85c --- /dev/null +++ b/tests/ui/higher-ranked/subtype/hr-subtype.rs @@ -0,0 +1,111 @@ +// Targeted tests for the higher-ranked subtyping code. + +#![allow(dead_code)] + +// revisions: bound_a_vs_bound_a +// revisions: bound_a_vs_bound_b +// revisions: bound_inv_a_vs_bound_inv_b +// revisions: bound_co_a_vs_bound_co_b +// revisions: bound_a_vs_free_x +// revisions: free_x_vs_free_x +// revisions: free_x_vs_free_y +// revisions: free_inv_x_vs_free_inv_y +// revisions: bound_a_b_vs_bound_a +// revisions: bound_co_a_b_vs_bound_co_a +// revisions: bound_contra_a_contra_b_ret_co_a +// revisions: bound_co_a_co_b_ret_contra_a +// revisions: bound_inv_a_b_vs_bound_inv_a +// revisions: bound_a_b_ret_a_vs_bound_a_ret_a + +//[bound_a_vs_bound_a] check-pass +//[bound_a_vs_bound_b] check-pass +//[bound_inv_a_vs_bound_inv_b] check-pass +//[bound_co_a_vs_bound_co_b] check-pass +//[free_x_vs_free_x] check-pass +//[bound_co_a_b_vs_bound_co_a] check-pass +//[bound_co_a_co_b_ret_contra_a] check-pass +//[bound_a_b_vs_bound_a] check-pass +//[bound_contra_a_contra_b_ret_co_a] check-pass + +fn gimme(_: Option) {} + +struct Inv<'a> { + x: *mut &'a u32, +} + +struct Co<'a> { + x: fn(&'a u32), +} + +struct Contra<'a> { + x: &'a u32, +} + +macro_rules! check { + ($rev:ident: ($t1:ty, $t2:ty)) => { + #[cfg($rev)] + fn subtype<'x, 'y: 'x, 'z: 'y>() { + gimme::<$t2>(None::<$t1>); + //[free_inv_x_vs_free_inv_y]~^ ERROR + } + + #[cfg($rev)] + fn supertype<'x, 'y: 'x, 'z: 'y>() { + gimme::<$t1>(None::<$t2>); + //[bound_a_vs_free_x]~^ ERROR + //[free_x_vs_free_y]~^^ ERROR + //[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR + //[bound_inv_a_b_vs_bound_inv_a]~| ERROR + //[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^^ ERROR + //[free_inv_x_vs_free_inv_y]~^^^^^^ ERROR + } + }; +} + +// If both have bound regions, they are equivalent, regardless of +// variant. +check! { bound_a_vs_bound_a: (for<'a> fn(&'a u32), +for<'a> fn(&'a u32)) } +check! { bound_a_vs_bound_b: (for<'a> fn(&'a u32), +for<'b> fn(&'b u32)) } +check! { bound_inv_a_vs_bound_inv_b: (for<'a> fn(Inv<'a>), +for<'b> fn(Inv<'b>)) } +check! { bound_co_a_vs_bound_co_b: (for<'a> fn(Co<'a>), +for<'b> fn(Co<'b>)) } + +// Bound is a subtype of free. +check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), +fn(&'x u32)) } + +// Two free regions are relatable if subtyping holds. +check! { free_x_vs_free_x: (fn(&'x u32), +fn(&'x u32)) } +check! { free_x_vs_free_y: (fn(&'x u32), +fn(&'y u32)) } +check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), +fn(Inv<'y>)) } + +// Somewhat surprisingly, a fn taking two distinct bound lifetimes and +// a fn taking one bound lifetime can be interchangeable, but only if +// we are co- or contra-variant with respect to both lifetimes. +// +// The reason is: +// - if we are covariant, then 'a and 'b can be set to the call-site +// intersection; +// - if we are contravariant, then 'a can be inferred to 'static. +check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32), +for<'a> fn(&'a u32, &'a u32)) } +check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>), +for<'a> fn(Co<'a>, Co<'a>)) } +check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>, +for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) } +check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>, +for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) } + +// If we make those lifetimes invariant, then the two types are not interchangeable. +check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), +for<'a> fn(Inv<'a>, Inv<'a>)) } +check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, +for<'a> fn(&'a u32, &'a u32) -> &'a u32) } + +fn main() {} diff --git a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs new file mode 100644 index 00000000000..bd4533e0433 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs @@ -0,0 +1,25 @@ +// Check that incorrect higher ranked subtyping +// causes an error. +struct Inv<'a>(fn(&'a ()) -> &'a ()); +fn hr_subtype<'c>(f: for<'a, 'b> fn(Inv<'a>, Inv<'a>)) { + // ok + let _: for<'a> fn(Inv<'a>, Inv<'a>) = f; + let sub: for<'a> fn(Inv<'a>, Inv<'a>) = f; + // no + let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; + //~^ ERROR mismatched types +} + +fn simple1<'c>(x: (&'c i32,)) { + let _x: (&'static i32,) = x; +} + +fn simple2<'c>(x: (&'c i32,)) { + let _: (&'static i32,) = x; +} + +fn main() { + hr_subtype(|_, _| {}); + simple1((&3,)); + simple2((&3,)); +} diff --git a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr new file mode 100644 index 00000000000..73b0a317364 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/placeholder-pattern-fail.rs:9:47 + | +LL | let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; + | ^^^ one type is more general than the other + | + = note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)` + found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/subtype/placeholder-pattern.rs b/tests/ui/higher-ranked/subtype/placeholder-pattern.rs new file mode 100644 index 00000000000..061e66e54d2 --- /dev/null +++ b/tests/ui/higher-ranked/subtype/placeholder-pattern.rs @@ -0,0 +1,18 @@ +// check-pass +// Check that higher ranked subtyping correctly works when using +// placeholder patterns. +fn hr_subtype<'c>(f: for<'a, 'b> fn(&'a (), &'b ())) { + let _: for<'a> fn(&'a (), &'a ()) = f; + let _: for<'a, 'b> fn(&'a (), &'b ()) = f; + let _: for<'a> fn(&'a (), &'c ()) = f; + let _: fn(&'c (), &'c ()) = f; +} + +fn simple<'c>(x: (&'static i32,)) { + let _: (&'c i32,) = x; +} + +fn main() { + hr_subtype(|_, _| {}); + simple((&3,)); +} diff --git a/tests/ui/higher-ranked/subtype/return-static.rs b/tests/ui/higher-ranked/subtype/return-static.rs new file mode 100644 index 00000000000..6455854f34d --- /dev/null +++ b/tests/ui/higher-ranked/subtype/return-static.rs @@ -0,0 +1,13 @@ +// check-pass + +fn make() -> T { + panic!() +} + +fn take(x: T) {} + +fn main() { + let x: for<'a> fn(&'a u32) -> _ = make(); + let y: &'static u32 = x(&22); + take:: fn(&'b u32) -> &'b u32>(x); +} diff --git a/tests/ui/higher-ranked/trait-bounds/complex.rs b/tests/ui/higher-ranked/trait-bounds/complex.rs new file mode 100644 index 00000000000..8cdfe247e02 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/complex.rs @@ -0,0 +1,28 @@ +// check-pass + +trait A<'a> {} +trait B<'b> {} +fn foo() where for<'a> T: A<'a> + 'a {} +trait C<'c>: for<'a> A<'a> + for<'b> B<'b> { + type As; +} +struct D where T: for<'c> C<'c, As=&'c ()> { + t: std::marker::PhantomData, +} +trait E<'e, 'g> { + type As; +} +trait F<'f>: for<'a> A<'a> + for<'e> E<'e, 'f> {} +struct G where T: for<'f> F<'f, As=&'f ()> { + t: std::marker::PhantomData, +} +trait H<'a, 'b> { + type As; +} +trait I<'a>: for<'b> H<'a, 'b> {} + +struct J where T: for<'i> I<'i, As=&'i ()> { + t: std::marker::PhantomData, +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.rs b/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.rs new file mode 100644 index 00000000000..1afd15613b5 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.rs @@ -0,0 +1,13 @@ +fn main() { + test::(&mut 42); //~ ERROR implementation of `Foo` is not general enough +} + +trait Foo<'a> {} + +struct FooS<'a> { + data: &'a mut u32, +} + +impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {} + +fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {} diff --git a/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.stderr b/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.stderr new file mode 100644 index 00000000000..520938a6335 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/due-to-where-clause.stderr @@ -0,0 +1,11 @@ +error: implementation of `Foo` is not general enough + --> $DIR/due-to-where-clause.rs:2:5 + | +LL | test::(&mut 42); + | ^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`... + = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1` + +error: aborting due to previous error + diff --git a/tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr b/tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr new file mode 100644 index 00000000000..9af6bc45c7a --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr @@ -0,0 +1,19 @@ +error[E0277]: expected a `Fn<(&'w (),)>` closure, found `fn(&'w ())` + --> $DIR/fn-ptr.rs:12:5 + | +LL | ice(); + | ^^^ expected an `Fn<(&'w (),)>` closure, found `fn(&'w ())` + | + = help: the trait `for<'w> Fn<(&'w (),)>` is not implemented for `fn(&'w ())` +note: required by a bound in `ice` + --> $DIR/fn-ptr.rs:7:25 + | +LL | fn ice() + | --- required by a bound in this function +LL | where +LL | for<'w> fn(&'w ()): Fn(&'w ()), + | ^^^^^^^^^^ required by this bound in `ice` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs b/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs new file mode 100644 index 00000000000..853160f9612 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/fn-ptr.rs @@ -0,0 +1,14 @@ +// revisions: classic next +//[next] compile-flags: -Ztrait-solver=next +//[next] check-pass + +fn ice() +where + for<'w> fn(&'w ()): Fn(&'w ()), +{ +} + +fn main() { + ice(); + //[classic]~^ ERROR expected a `Fn<(&'w (),)>` closure, found `fn(&'w ())` +} diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs new file mode 100644 index 00000000000..d34b7a29623 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs @@ -0,0 +1,16 @@ +// normalize-stderr-test: "long-type-\d+" -> "long-type-hash" + +fn id( + f: &dyn Fn(u32), +) -> &dyn Fn( + &dyn Fn( + &dyn Fn( + &dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(u32))))))))), + ), + ), +) { + f + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr new file mode 100644 index 00000000000..a9d649b8285 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/hang-on-deeply-nested-dyn.rs:12:5 + | +LL | ) -> &dyn Fn( + | ______- +LL | | &dyn Fn( +LL | | &dyn Fn( +LL | | &dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(u32))))))))), +LL | | ), +LL | | ), +LL | | ) { + | |_- expected `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` because of return type +LL | f + | ^ expected `&dyn Fn(&dyn Fn(&dyn Fn(&...)))`, found `&dyn Fn(u32)` + | + = note: expected reference `&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&...)))))))))))` + the full type name has been written to '$TEST_BUILD_DIR/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn/hang-on-deeply-nested-dyn.long-type-hash.txt' + found reference `&dyn Fn(u32)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs new file mode 100644 index 00000000000..cc766c0605c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-binder-levels-in-object-types.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that we handle binder levels in object types correctly. +// Initially, the reference to `'tcx` in the object type +// `&Typer<'tcx>` was getting an incorrect binder level, yielding +// weird compilation ICEs and so forth. + +// pretty-expanded FIXME #23616 + +trait Typer<'tcx> { + fn method(&self, data: &'tcx isize) -> &'tcx isize { data } +} + +struct Tcx<'tcx> { + fields: &'tcx isize +} + +impl<'tcx> Typer<'tcx> for Tcx<'tcx> { +} + +fn g<'tcx>(typer: &dyn Typer<'tcx>) { +} + +fn check_static_type<'x>(tcx: &Tcx<'x>) { + g(tcx) +} + +fn main() { } diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.rs new file mode 100644 index 00000000000..a20d03c7747 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.rs @@ -0,0 +1,24 @@ +// Regression test for #54302. +// +// We were incorrectly using the "evaluation cache" (which ignored +// region results) to conclude that `&'static str: Deserialize`, even +// though it would require that `for<'de> 'de: 'static`, which is +// clearly false. + +trait Deserialize<'de> {} + +trait DeserializeOwned: for<'de> Deserialize<'de> {} +impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} + +// Based on this impl, `&'static str` only implements Deserialize<'static>. +// It does not implement for<'de> Deserialize<'de>. +impl<'de: 'a, 'a> Deserialize<'de> for &'a str {} + +fn main() { + fn assert_deserialize_owned() {} + assert_deserialize_owned::<&'static str>(); //~ ERROR + + // It correctly does not implement for<'de> Deserialize<'de>. + // fn assert_hrtb Deserialize<'de>>() {} + // assert_hrtb::<&'static str>(); +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr new file mode 100644 index 00000000000..f014eab8601 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-cache-issue-54302.stderr @@ -0,0 +1,11 @@ +error: implementation of `Deserialize` is not general enough + --> $DIR/hrtb-cache-issue-54302.rs:19:5 + | +LL | assert_deserialize_owned::<&'static str>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough + | + = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`... + = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1` + +error: aborting due to previous error + diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.rs new file mode 100644 index 00000000000..e83686404a3 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.rs @@ -0,0 +1,31 @@ +// Test that an impl with only one bound region `'a` cannot be used to +// satisfy a constraint where there are two bound regions. + +trait Foo { + fn foo(&self, x: X) { } +} + +fn want_foo2() + where T : for<'a,'b> Foo<(&'a isize, &'b isize)> +{ +} + +fn want_foo1() + where T : for<'z> Foo<(&'z isize, &'z isize)> +{ +} + +// Expressed as a where clause + +struct SomeStruct; + +impl<'a> Foo<(&'a isize, &'a isize)> for SomeStruct +{ +} + +fn a() { want_foo1::(); } // OK -- foo wants just one region +fn b() { want_foo2::(); } +//~^ ERROR implementation of +//~| ERROR implementation of + +fn main() { } diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr new file mode 100644 index 00000000000..46f5308dd87 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-conflate-regions.stderr @@ -0,0 +1,20 @@ +error: implementation of `Foo` is not general enough + --> $DIR/hrtb-conflate-regions.rs:27:10 + | +LL | fn b() { want_foo2::(); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` + +error: implementation of `Foo` is not general enough + --> $DIR/hrtb-conflate-regions.rs:27:10 + | +LL | fn b() { want_foo2::(); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`... + = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.rs new file mode 100644 index 00000000000..05d3e1a434e --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.rs @@ -0,0 +1,18 @@ +// Test the case where the `Self` type has a bound lifetime that must +// be adjusted in the fn signature. Issue #19537. + +use std::collections::HashMap; + +struct Foo<'a> { + map: HashMap +} + +impl<'a> Foo<'a> { + fn new() -> Foo<'a> { panic!() } + fn insert(&'a mut self) { } +} +fn main() { + let mut foo = Foo::new(); + foo.insert(); + foo.insert(); //~ ERROR cannot borrow +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.stderr new file mode 100644 index 00000000000..fa391ecba8a --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-in-receiver.stderr @@ -0,0 +1,14 @@ +error[E0499]: cannot borrow `foo` as mutable more than once at a time + --> $DIR/hrtb-debruijn-in-receiver.rs:17:5 + | +LL | foo.insert(); + | ------------ first mutable borrow occurs here +LL | foo.insert(); + | ^^^^^^^^^^^^ + | | + | second mutable borrow occurs here + | first borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs new file mode 100644 index 00000000000..8431226a3ec --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-debruijn-object-types-in-closures.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait Typer<'tcx> { + fn method(&self, data: &'tcx isize) -> &'tcx isize { data } + fn dummy(&self) { } +} + +fn g(_: F) where F: FnOnce(&dyn Typer) {} + +fn h() { + g(|typer| typer.dummy()) +} + +fn main() { } diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.rs new file mode 100644 index 00000000000..56780237618 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.rs @@ -0,0 +1,18 @@ +// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! +// +// In particular, we test this pattern in trait solving, where it is not connected +// to any part of the source code. + +fn foo<'a>() -> fn(&'a u32) { + panic!() +} + +fn main() { + // Here, proving that `fn(&'a u32) <: for<'b> fn(&'b u32)`: + // + // - instantiates `'b` with a placeholder `!b`, + // - requires that `&!b u32 <: &'a u32` and hence that `!b: 'a`, + // - but we can never know this. + + let _: for<'b> fn(&'b u32) = foo(); //~ ERROR mismatched types +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr new file mode 100644 index 00000000000..9914783d976 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-fn.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/hrtb-exists-forall-fn.rs:17:34 + | +LL | let _: for<'b> fn(&'b u32) = foo(); + | ^^^^^ one type is more general than the other + | + = note: expected fn pointer `for<'b> fn(&'b u32)` + found fn pointer `fn(&u32)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.rs new file mode 100644 index 00000000000..921061916fc --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.rs @@ -0,0 +1,36 @@ +// Test a case where variance and higher-ranked types interact in surprising ways. +// +// In particular, we test this pattern in trait solving, where it is not connected +// to any part of the source code. + +trait Trait {} + +fn foo() +where + T: Trait fn(&'b u32)>, +{ +} + +impl<'a> Trait for () {} + +fn main() { + // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: + // + // - The impl provides the clause `forall<'a> { (): Trait }` + // - We instantiate `'a` existentially to get `(): Trait` + // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` -- this does a + // "bidirectional" subtyping check, so we wind up with: + // - `fn(&?a u32) <: for<'b> fn(&'b u32)` :- + // - `&'!b u32 <: &?a u32` + // - `!'b: ?a` -- solveable if `?a` is inferred to `'empty` + // - `for<'b> fn(&'b u32) <: fn(&?a u32)` :- + // - `&?a u32 u32 <: &?b u32` + // - `?a: ?b` -- solveable if `?b` is also inferred to `'empty` + // - So the subtyping check succeeds, somewhat surprisingly. + // This is because we can use `'empty`. + // + // NB. *However*, the reinstated leak-check gives an error here. + + foo::<()>(); + //~^ ERROR implementation of `Trait` is not general enough +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.stderr new file mode 100644 index 00000000000..364b613fc77 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-contravariant.stderr @@ -0,0 +1,11 @@ +error: implementation of `Trait` is not general enough + --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5 + | +LL | foo::<()>(); + | ^^^^^^^^^^^ implementation of `Trait` is not general enough + | + = note: `()` must implement `Trait fn(&'b u32)>` + = note: ...but it actually implements `Trait`, for some specific lifetime `'0` + +error: aborting due to previous error + diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-covariant.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-covariant.rs new file mode 100644 index 00000000000..f95496a6c3c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-covariant.rs @@ -0,0 +1,37 @@ +// Test a case where variance and higher-ranked types interact in surprising ways. +// +// In particular, we test this pattern in trait solving, where it is not connected +// to any part of the source code. +// +// check-pass + +trait Trait {} + +fn foo() +where + T: Trait fn(fn(&'b u32))>, +{ +} + +impl<'a> Trait for () {} + +fn main() { + // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: + // + // - The impl provides the clause `forall<'a> { (): Trait }` + // - We instantiate `'a` existentially to get `(): Trait` + // - We unify `fn(fn(&?a u32))` with `for<'b> fn(fn(&'b u32))` -- this does a + // "bidirectional" subtyping check, so we wind up with: + // - `fn(fn(&?a u32)) <: for<'b> fn(fn(&'b u32))` :- + // - `fn(&!b u32) <: fn(&?a u32)` + // - `&?a u32 <: &!b u32` + // - `?a: !'b` -- solveable if `?a` is inferred to `'static` + // - `for<'b> fn(fn(&'b u32)) <: fn(fn(&?a u32))` :- + // - `fn(&?a u32) <: fn(&?b u32)` + // - `&?b u32 <: &?a u32` + // - `?b: ?a` -- solveable if `?b` is inferred to `'static` + // - So the subtyping check succeeds, somewhat surprisingly. + // This is because we can use `'static`. + + foo::<()>(); +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.rs new file mode 100644 index 00000000000..9b9e4496a87 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.rs @@ -0,0 +1,29 @@ +// Test an `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! +// +// In particular, we test this pattern in trait solving, where it is not connected +// to any part of the source code. + +use std::cell::Cell; + +trait Trait {} + +fn foo() +where + T: Trait fn(Cell<&'b u32>)>, +{ +} + +impl<'a> Trait)> for () {} + +fn main() { + // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: + // + // - The impl provides the clause `forall<'a> { (): Trait }` + // - We instantiate `'a` existentially to get `(): Trait` + // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` + // - This requires (among other things) instantiating `'b` universally, + // yielding `fn(&!b u32)`, in a fresh universe U1 + // - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`. + + foo::<()>(); //~ ERROR implementation of `Trait` is not general enough +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.stderr new file mode 100644 index 00000000000..cb2ce8a4116 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-exists-forall-trait-invariant.stderr @@ -0,0 +1,11 @@ +error: implementation of `Trait` is not general enough + --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5 + | +LL | foo::<()>(); + | ^^^^^^^^^^^ implementation of `Trait` is not general enough + | + = note: `()` must implement `Trait fn(Cell<&'b u32>)>` + = note: ...but it actually implements `Trait)>`, for some specific lifetime `'0` + +error: aborting due to previous error + diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait-object.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait-object.rs new file mode 100644 index 00000000000..ff84ad9d298 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait-object.rs @@ -0,0 +1,27 @@ +// run-pass +// A basic test of using a higher-ranked trait bound. + + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +type FnObject<'b> = dyn for<'a> FnLike<&'a isize, &'a isize> + 'b; + +struct Identity; + +impl<'a, T> FnLike<&'a T, &'a T> for Identity { + fn call(&self, arg: &'a T) -> &'a T { + arg + } +} + +fn call_repeatedly(f: &FnObject) { + let x = 3; + let y = f.call(&x); + assert_eq!(3, *y); +} + +fn main() { + call_repeatedly(&Identity); +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait.rs new file mode 100644 index 00000000000..afab9986ce2 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-fn-like-trait.rs @@ -0,0 +1,27 @@ +// run-pass +// A basic test of using a higher-ranked trait bound. + + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +struct Identity; + +impl<'a, T> FnLike<&'a T, &'a T> for Identity { + fn call(&self, arg: &'a T) -> &'a T { + arg + } +} + +fn call_repeatedly(f: F) + where F : for<'a> FnLike<&'a isize, &'a isize> +{ + let x = 3; + let y = f.call(&x); + assert_eq!(3, *y); +} + +fn main() { + call_repeatedly(Identity); +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs new file mode 100644 index 00000000000..f9ae1429ee4 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.rs @@ -0,0 +1,50 @@ +// Test HRTB supertraits with several levels of expansion required. + +trait Foo<'tcx> +{ + fn foo(&'tcx self) -> &'tcx isize; +} + +trait Bar<'ccx> + : for<'tcx> Foo<'tcx> +{ + fn bar(&'ccx self) -> &'ccx isize; +} + +trait Baz + : for<'ccx> Bar<'ccx> +{ + fn dummy(&self); +} + +trait Qux + : Bar<'static> +{ + fn dummy(&self); +} + +fn want_foo_for_any_tcx(f: &F) + where F : for<'tcx> Foo<'tcx> +{ +} + +fn want_bar_for_any_ccx(b: &B) + where B : for<'ccx> Bar<'ccx> +{ +} + +fn want_baz(b: &B) + where B : Baz +{ + want_foo_for_any_tcx(b); + want_bar_for_any_ccx(b); +} + +fn want_qux(b: &B) + where B : Qux +{ + want_foo_for_any_tcx(b); + want_bar_for_any_ccx(b); //~ ERROR +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr new file mode 100644 index 00000000000..b1b8ffa8c54 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied + --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26 + | +LL | want_bar_for_any_ccx(b); + | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` + | | + | required by a bound introduced by this call + | +note: required by a bound in `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15 + | +LL | fn want_bar_for_any_ccx(b: &B) + | -------------------- required by a bound in this function +LL | where B : for<'ccx> Bar<'ccx> + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` +help: consider further restricting this bound + | +LL | where B : Qux + for<'ccx> Bar<'ccx> + | +++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs new file mode 100644 index 00000000000..48ebe5017aa --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs @@ -0,0 +1,48 @@ +// Test a trait (`Bar`) with a higher-ranked supertrait. + +trait Foo<'tcx> +{ + fn foo(&'tcx self) -> &'tcx isize; +} + +trait Bar<'ccx> + : for<'tcx> Foo<'tcx> +{ + fn bar(&'ccx self) -> &'ccx isize; +} + +fn want_foo_for_some_tcx<'x,F>(f: &'x F) + where F : Foo<'x> +{ + want_foo_for_some_tcx(f); + want_foo_for_any_tcx(f); //~ ERROR not satisfied +} + +fn want_foo_for_any_tcx(f: &F) + where F : for<'tcx> Foo<'tcx> +{ + want_foo_for_some_tcx(f); + want_foo_for_any_tcx(f); +} + +fn want_bar_for_some_ccx<'x,B>(b: &B) + where B : Bar<'x> +{ + want_foo_for_some_tcx(b); + want_foo_for_any_tcx(b); + + want_bar_for_some_ccx(b); + want_bar_for_any_ccx(b); //~ ERROR not satisfied +} + +fn want_bar_for_any_ccx(b: &B) + where B : for<'ccx> Bar<'ccx> +{ + want_foo_for_some_tcx(b); + want_foo_for_any_tcx(b); + + want_bar_for_some_ccx(b); + want_bar_for_any_ccx(b); +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr new file mode 100644 index 00000000000..7f96909b6e7 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr @@ -0,0 +1,43 @@ +error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied + --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26 + | +LL | want_foo_for_any_tcx(f); + | -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F` + | | + | required by a bound introduced by this call + | +note: required by a bound in `want_foo_for_any_tcx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15 + | +LL | fn want_foo_for_any_tcx(f: &F) + | -------------------- required by a bound in this function +LL | where F : for<'tcx> Foo<'tcx> + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx` +help: consider further restricting this bound + | +LL | where F : Foo<'x> + for<'tcx> Foo<'tcx> + | +++++++++++++++++++++ + +error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied + --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26 + | +LL | want_bar_for_any_ccx(b); + | -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B` + | | + | required by a bound introduced by this call + | +note: required by a bound in `want_bar_for_any_ccx` + --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15 + | +LL | fn want_bar_for_any_ccx(b: &B) + | -------------------- required by a bound in this function +LL | where B : for<'ccx> Bar<'ccx> + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` +help: consider further restricting this bound + | +LL | where B : Bar<'x> + for<'ccx> Bar<'ccx> + | +++++++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.rs new file mode 100644 index 00000000000..89fc4705a78 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.rs @@ -0,0 +1,26 @@ +// Test that the `'a` in the where clause correctly links the region +// of the output to the region of the input. + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +fn call_repeatedly(f: F) + where F : for<'a> FnLike<&'a isize, &'a isize> +{ + // Result is stored: cannot re-assign `x` + let mut x = 3; + let y = f.call(&x); + x = 5; //~ ERROR cannot assign to `x` because it is borrowed + + // Result is not stored: can re-assign `x` + let mut x = 3; + f.call(&x); + f.call(&x); + f.call(&x); + x = 5; + drop(y); +} + +fn main() { +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.stderr new file mode 100644 index 00000000000..25af011e3fc --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-identity-fn-borrows.stderr @@ -0,0 +1,14 @@ +error[E0506]: cannot assign to `x` because it is borrowed + --> $DIR/hrtb-identity-fn-borrows.rs:14:5 + | +LL | let y = f.call(&x); + | -- `x` is borrowed here +LL | x = 5; + | ^^^^^ `x` is assigned to here but it was already borrowed +... +LL | drop(y); + | - borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0506`. diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.rs new file mode 100644 index 00000000000..8fb4218f8a4 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.rs @@ -0,0 +1,35 @@ +// Test a case where you have an impl of `Foo` for all `X` that +// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. + +trait Foo { + fn foo(&self, x: X) { } +} + +fn want_hrtb() + where T : for<'a> Foo<&'a isize> +{ +} + +// AnyInt implements Foo<&'a isize> for any 'a, so it is a match. +struct AnyInt; +impl<'a> Foo<&'a isize> for AnyInt { } +fn give_any() { + want_hrtb::() +} + +// StaticInt only implements Foo<&'static isize>, so it is an error. +struct StaticInt; +impl Foo<&'static isize> for StaticInt { } +fn give_static() { + want_hrtb::() //~ ERROR +} + +// &'a u32 only implements Foo<&'a isize> for specific 'a, so it is an error. +impl<'a> Foo<&'a isize> for &'a u32 { } +fn give_some<'a>() { + want_hrtb::<&'a u32>() + //~^ ERROR lifetime may not live long enough + //~| ERROR implementation of `Foo` is not general enough +} + +fn main() { } diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr new file mode 100644 index 00000000000..31e11e12835 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr @@ -0,0 +1,34 @@ +error: implementation of `Foo` is not general enough + --> $DIR/hrtb-just-for-static.rs:24:5 + | +LL | want_hrtb::() + | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`... + = note: ...but it actually implements `Foo<&'static isize>` + +error: lifetime may not live long enough + --> $DIR/hrtb-just-for-static.rs:30:5 + | +LL | fn give_some<'a>() { + | -- lifetime `'a` defined here +LL | want_hrtb::<&'a u32>() + | ^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + | +note: due to current limitations in the borrow checker, this implies a `'static` lifetime + --> $DIR/hrtb-just-for-static.rs:9:15 + | +LL | where T : for<'a> Foo<&'a isize> + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: implementation of `Foo` is not general enough + --> $DIR/hrtb-just-for-static.rs:30:5 + | +LL | want_hrtb::<&'a u32>() + | ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<&'0 isize>` would have to be implemented for the type `&u32`, for any lifetime `'0`... + = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.rs new file mode 100644 index 00000000000..4b096be591a --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.rs @@ -0,0 +1,20 @@ +// Test that Fn-family traits with lifetime parameters shouldn't compile and +// we suggest the usage of higher-rank trait bounds instead. + +fn fa(_: impl Fn<'a>(&'a str) -> bool) {} +//~^ ERROR `Fn` traits cannot take lifetime parameters + +fn fb(_: impl FnMut<'a, 'b>(&'a str, &'b str) -> bool) {} +//~^ ERROR `Fn` traits cannot take lifetime parameters + +fn fc(_: impl std::fmt::Display + FnOnce<'a>(&'a str) -> bool + std::fmt::Debug) {} +//~^ ERROR `Fn` traits cannot take lifetime parameters + +use std::ops::Fn as AliasedFn; +fn fd(_: impl AliasedFn<'a>(&'a str) -> bool) {} +//~^ ERROR `Fn` traits cannot take lifetime parameters + +fn fe(_: F) where F: Fn<'a>(&'a str) -> bool {} +//~^ ERROR `Fn` traits cannot take lifetime parameters + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.stderr new file mode 100644 index 00000000000..e8f6d63b5ab --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-malformed-lifetime-generics.stderr @@ -0,0 +1,62 @@ +error: `Fn` traits cannot take lifetime parameters + --> $DIR/hrtb-malformed-lifetime-generics.rs:4:17 + | +LL | fn fa(_: impl Fn<'a>(&'a str) -> bool) {} + | ^^^^ + | +help: consider using a higher-ranked trait bound instead + | +LL - fn fa(_: impl Fn<'a>(&'a str) -> bool) {} +LL + fn fa(_: impl for<'a> Fn(&'a str) -> bool) {} + | + +error: `Fn` traits cannot take lifetime parameters + --> $DIR/hrtb-malformed-lifetime-generics.rs:7:20 + | +LL | fn fb(_: impl FnMut<'a, 'b>(&'a str, &'b str) -> bool) {} + | ^^^^^^^^ + | +help: consider using a higher-ranked trait bound instead + | +LL - fn fb(_: impl FnMut<'a, 'b>(&'a str, &'b str) -> bool) {} +LL + fn fb(_: impl for<'a, 'b> FnMut(&'a str, &'b str) -> bool) {} + | + +error: `Fn` traits cannot take lifetime parameters + --> $DIR/hrtb-malformed-lifetime-generics.rs:10:41 + | +LL | fn fc(_: impl std::fmt::Display + FnOnce<'a>(&'a str) -> bool + std::fmt::Debug) {} + | ^^^^ + | +help: consider using a higher-ranked trait bound instead + | +LL - fn fc(_: impl std::fmt::Display + FnOnce<'a>(&'a str) -> bool + std::fmt::Debug) {} +LL + fn fc(_: impl std::fmt::Display + for<'a> FnOnce(&'a str) -> bool + std::fmt::Debug) {} + | + +error: `Fn` traits cannot take lifetime parameters + --> $DIR/hrtb-malformed-lifetime-generics.rs:14:24 + | +LL | fn fd(_: impl AliasedFn<'a>(&'a str) -> bool) {} + | ^^^^ + | +help: consider using a higher-ranked trait bound instead + | +LL - fn fd(_: impl AliasedFn<'a>(&'a str) -> bool) {} +LL + fn fd(_: impl for<'a> AliasedFn(&'a str) -> bool) {} + | + +error: `Fn` traits cannot take lifetime parameters + --> $DIR/hrtb-malformed-lifetime-generics.rs:17:27 + | +LL | fn fe(_: F) where F: Fn<'a>(&'a str) -> bool {} + | ^^^^ + | +help: consider using a higher-ranked trait bound instead + | +LL - fn fe(_: F) where F: Fn<'a>(&'a str) -> bool {} +LL + fn fe(_: F) where F: for<'a> Fn(&'a str) -> bool {} + | + +error: aborting due to 5 previous errors + diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-opt-in-copy.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-opt-in-copy.rs new file mode 100644 index 00000000000..04519f11600 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-opt-in-copy.rs @@ -0,0 +1,28 @@ +// run-pass +// Test that we handle binder levels correctly when checking whether a +// type can implement `Copy`. In particular, we had a bug where we failed to +// liberate the late-bound regions from the impl, and thus wound up +// searching for an impl of `for<'tcx> Foo<&'tcx T>`. The impl that +// exists however is `impl Copy for Foo` and the current rules +// did not consider that a match (something I would like to revise in +// a later PR). + +#![allow(dead_code)] + +use std::marker::PhantomData; + +#[derive(Copy, Clone)] +struct Foo { x: T } + +type Ty<'tcx> = &'tcx TyS<'tcx>; + +enum TyS<'tcx> { + Boop(PhantomData<*mut &'tcx ()>) +} + +#[derive(Copy, Clone)] +enum Bar<'tcx> { + Baz(Foo>) +} + +fn main() { } diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs new file mode 100644 index 00000000000..1fab9758c5c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-parse.rs @@ -0,0 +1,36 @@ +// run-pass +// Test that we can parse all the various places that a `for` keyword +// can appear representing universal quantification. + +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] +#![allow(dead_code)] + +trait Get { + fn get(&self, arg: A) -> R; +} + +// Parse HRTB with explicit `for` in a where-clause: + +fn foo00(t: T) + where T : for<'a> Get<&'a i32, &'a i32> +{ +} + +fn foo01 Get<&'a i32, &'a i32>>(t: T) +{ +} + +// Parse HRTB with explicit `for` in various sorts of types: + +fn foo10(t: Box Get>) { } +fn foo11(t: Box Fn(i32) -> i32>) { } + +fn foo20(t: for<'a> fn(i32) -> i32) { } +fn foo21(t: for<'a> unsafe fn(i32) -> i32) { } +fn foo22(t: for<'a> extern "C" fn(i32) -> i32) { } +fn foo23(t: for<'a> unsafe extern "C" fn(i32) -> i32) { } + +fn main() { +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr new file mode 100644 index 00000000000..a94c80eb30b --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.polonius.stderr @@ -0,0 +1,71 @@ +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:16:1 + | +LL | / fn no_hrtb<'b, T>(mut t: T) +LL | | where +LL | | T: Bar<&'b isize>, +LL | | { +... | +LL | | no_hrtb(&mut t); + | | --------------- recursive call site +LL | | } + | |_^ cannot return without recursing + | + = note: `#[warn(unconditional_recursion)]` on by default + = help: a `loop` may express intention better if this is on purpose + +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:25:1 + | +LL | / fn bar_hrtb(mut t: T) +LL | | where +LL | | T: for<'b> Bar<&'b isize>, +LL | | { +... | +LL | | bar_hrtb(&mut t); + | | ---------------- recursive call site +LL | | } + | |_^ cannot return without recursing + | + = help: a `loop` may express intention better if this is on purpose + +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:35:1 + | +LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T) +LL | | where +LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>, +LL | | { +... | +LL | | foo_hrtb_bar_not(&mut t); + | | ------------------------ recursive call site +LL | | +LL | | +LL | | } + | |_^ cannot return without recursing + | + = help: a `loop` may express intention better if this is on purpose + +error: higher-ranked subtype error + --> $DIR/hrtb-perfect-forwarding.rs:43:5 + | +LL | foo_hrtb_bar_not(&mut t); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:48:1 + | +LL | / fn foo_hrtb_bar_hrtb(mut t: T) +LL | | where +LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>, +LL | | { +LL | | // OK -- now we have `T : for<'b> Bar<&'b isize>`. +LL | | foo_hrtb_bar_hrtb(&mut t); + | | ------------------------- recursive call site +LL | | } + | |_^ cannot return without recursing + | + = help: a `loop` may express intention better if this is on purpose + +error: aborting due to previous error; 4 warnings emitted + diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.rs new file mode 100644 index 00000000000..d45fa183c0c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.rs @@ -0,0 +1,56 @@ +// Test a case where you have an impl of `Foo` for all `X` that +// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. + +trait Foo { + fn foo(&mut self, x: X) {} +} + +trait Bar { + fn bar(&mut self, x: X) {} +} + +impl<'a, X, F> Foo for &'a mut F where F: Foo + Bar {} + +impl<'a, X, F> Bar for &'a mut F where F: Bar {} + +fn no_hrtb<'b, T>(mut t: T) //~ WARN function cannot return +where + T: Bar<&'b isize>, +{ + // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that + // `&mut T : Bar<&'b isize>`. + no_hrtb(&mut t); +} + +fn bar_hrtb(mut t: T) //~ WARN function cannot return +where + T: for<'b> Bar<&'b isize>, +{ + // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above + // ensures that `&mut T : for<'b> Bar<&'b isize>`. This is an + // example of a "perfect forwarding" impl. + bar_hrtb(&mut t); +} + +fn foo_hrtb_bar_not<'b, T>(mut t: T) //~ WARN function cannot return +where + T: for<'a> Foo<&'a isize> + Bar<&'b isize>, +{ + // Not OK -- The forwarding impl for `Foo` requires that `Bar` also + // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a + // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where + // clause only specifies `T : Bar<&'b isize>`. + foo_hrtb_bar_not(&mut t); + //~^ ERROR implementation of `Bar` is not general enough + //~^^ ERROR lifetime may not live long enough +} + +fn foo_hrtb_bar_hrtb(mut t: T) //~ WARN function cannot return +where + T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>, +{ + // OK -- now we have `T : for<'b> Bar<&'b isize>`. + foo_hrtb_bar_hrtb(&mut t); +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.stderr new file mode 100644 index 00000000000..727b9e6bec8 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.stderr @@ -0,0 +1,79 @@ +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:16:1 + | +LL | / fn no_hrtb<'b, T>(mut t: T) +LL | | where +LL | | T: Bar<&'b isize>, + | |______________________^ cannot return without recursing +... +LL | no_hrtb(&mut t); + | --------------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:25:1 + | +LL | / fn bar_hrtb(mut t: T) +LL | | where +LL | | T: for<'b> Bar<&'b isize>, + | |______________________________^ cannot return without recursing +... +LL | bar_hrtb(&mut t); + | ---------------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:35:1 + | +LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T) +LL | | where +LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>, + | |_______________________________________________^ cannot return without recursing +... +LL | foo_hrtb_bar_not(&mut t); + | ------------------------ recursive call site + | + = help: a `loop` may express intention better if this is on purpose + +error: lifetime may not live long enough + --> $DIR/hrtb-perfect-forwarding.rs:43:5 + | +LL | fn foo_hrtb_bar_not<'b, T>(mut t: T) + | -- lifetime `'b` defined here +... +LL | foo_hrtb_bar_not(&mut t); + | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static` + | +note: due to current limitations in the borrow checker, this implies a `'static` lifetime + --> $DIR/hrtb-perfect-forwarding.rs:37:8 + | +LL | T: for<'a> Foo<&'a isize> + Bar<&'b isize>, + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: implementation of `Bar` is not general enough + --> $DIR/hrtb-perfect-forwarding.rs:43:5 + | +LL | foo_hrtb_bar_not(&mut t); + | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough + | + = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`... + = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1` + +warning: function cannot return without recursing + --> $DIR/hrtb-perfect-forwarding.rs:48:1 + | +LL | / fn foo_hrtb_bar_hrtb(mut t: T) +LL | | where +LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>, + | |_______________________________________________________^ cannot return without recursing +... +LL | foo_hrtb_bar_hrtb(&mut t); + | ------------------------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + +error: aborting due to 2 previous errors; 4 warnings emitted + diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs new file mode 100644 index 00000000000..42247798f66 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus-where-clause.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +// Test that `F : Fn(isize) -> isize + Send` is interpreted as two +// distinct bounds on `F`. + +fn foo1(f: F) + where F : FnOnce(isize) -> isize + Send +{ + bar(f); +} + +fn foo2(f: F) + where F : FnOnce(isize) -> isize + Send +{ + baz(f); +} + +fn bar(f: F) { } + +fn baz isize>(f: F) { } + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs new file mode 100644 index 00000000000..6834c392d4e --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-precedence-of-plus.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +// Test that `Fn(isize) -> isize + 'static` parses as `(Fn(isize) -> isize) + +// 'static` and not `Fn(isize) -> (isize + 'static)`. The latter would +// cause a compilation error. Issue #18772. + +fn adder(y: isize) -> Box isize + 'static> { + Box::new(move |x| y + x) +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs new file mode 100644 index 00000000000..b97fdf4df50 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-resolve-lifetime.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// A basic test of using a higher-ranked trait bound. + +// pretty-expanded FIXME #23616 + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +type FnObject<'b> = dyn for<'a> FnLike<&'a isize, &'a isize> + 'b; + +fn main() { +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-paren-notation.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-paren-notation.rs new file mode 100644 index 00000000000..d8c726cdd71 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-paren-notation.rs @@ -0,0 +1,26 @@ +// run-pass +// A basic test of using a higher-ranked trait bound. + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +type FnObject<'b> = dyn for<'a> FnLike<(&'a i32,), &'a i32> + 'b; + +struct Identity; + +impl<'a, T> FnLike<(&'a T,), &'a T> for Identity { + fn call(&self, (arg,): (&'a T,)) -> &'a T { + arg + } +} + +fn call_repeatedly(f: &FnObject) { + let x = 3; + let y = f.call((&x,)); + assert_eq!(3, *y); +} + +fn main() { + call_repeatedly(&Identity); +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs new file mode 100644 index 00000000000..41ebb3f5a14 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-trait-object-passed-to-closure.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +// Test that `&PrinterSupport`, which is really short for `&'a +// PrinterSupport<'b>`, gets properly expanded when it appears in a +// closure type. This used to result in messed up De Bruijn indices. + +// pretty-expanded FIXME #23616 + +trait PrinterSupport<'ast> { + fn ast_map(&self) -> Option<&'ast usize> { None } +} + +struct NoAnn<'ast> { + f: Option<&'ast usize> +} + +impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> { +} + +fn foo<'ast, G>(f: Option<&'ast usize>, g: G) where G: FnOnce(&dyn PrinterSupport) { + let annotation = NoAnn { f: f }; + g(&annotation) +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-type-outlives.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-type-outlives.rs new file mode 100644 index 00000000000..88d396101db --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-type-outlives.rs @@ -0,0 +1,46 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test what happens when a HR obligation is applied to an impl with +// "outlives" bounds. Currently we're pretty conservative here; this +// will probably improve in time. + +trait Foo { + fn foo(&self, x: X) { } +} + +fn want_foo() + where T : for<'a> Foo<&'a isize> +{ +} + +// Expressed as a where clause + +struct SomeStruct { + x: X +} + +impl<'a,X> Foo<&'a isize> for SomeStruct + where X : 'a +{ +} + +fn one() { + want_foo::>(); +} + +// Expressed as shorthand + +struct AnotherStruct { + x: X +} + +impl<'a,X:'a> Foo<&'a isize> for AnotherStruct +{ +} + +fn two() { + want_foo::>(); +} + +fn main() { } diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-unboxed-closure-trait.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-unboxed-closure-trait.rs new file mode 100644 index 00000000000..a4a8a5ac6cc --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-unboxed-closure-trait.rs @@ -0,0 +1,11 @@ +// run-pass +// Test HRTB used with the `Fn` trait. + +fn foo(f: F) { + let x = 22; + f(&x); +} + +fn main() { + foo(|x: &isize| println!("{}", *x)); +} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.rs new file mode 100644 index 00000000000..1a9bb252340 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.rs @@ -0,0 +1,7 @@ +fn a() where for T: Copy {} +//~^ ERROR only lifetime parameters can be used in this context + +fn b() where for [(); C]: Copy {} +//~^ ERROR only lifetime parameters can be used in this context + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.stderr new file mode 100644 index 00000000000..765ea9f7854 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-wrong-kind.stderr @@ -0,0 +1,21 @@ +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/hrtb-wrong-kind.rs:1:18 + | +LL | fn a() where for T: Copy {} + | ^ + | + = note: see issue #108185 for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable + +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/hrtb-wrong-kind.rs:4:24 + | +LL | fn b() where for [(); C]: Copy {} + | ^ + | + = note: see issue #108185 for more information + = help: add `#![feature(non_lifetime_binders)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/higher-ranked/trait-bounds/issue-100689.rs b/tests/ui/higher-ranked/trait-bounds/issue-100689.rs new file mode 100644 index 00000000000..2db7f8a354c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-100689.rs @@ -0,0 +1,29 @@ +// check-pass + +struct Foo<'a> { + foo: &'a mut usize, +} + +trait Bar<'a> { + type FooRef<'b> + where + 'a: 'b; + fn uwu(foo: Foo<'a>, f: impl for<'b> FnMut(Self::FooRef<'b>)); +} +impl<'a> Bar<'a> for () { + type FooRef<'b> + = + &'b Foo<'a> + where + 'a : 'b, + ; + + fn uwu( + foo: Foo<'a>, + mut f: impl for<'b> FnMut(&'b Foo<'a>), //relevant part + ) { + f(&foo); + } +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-102899.rs b/tests/ui/higher-ranked/trait-bounds/issue-102899.rs new file mode 100644 index 00000000000..952b81584f3 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-102899.rs @@ -0,0 +1,32 @@ +// check-pass + +pub trait BufferTrait<'buffer> { + type Subset<'channel> + where + 'buffer: 'channel; + + fn for_each_subset(&self, f: F) + where + F: for<'channel> Fn(Self::Subset<'channel>); +} + +pub struct SomeBuffer<'buffer> { + samples: &'buffer [()], +} + +impl<'buffer> BufferTrait<'buffer> for SomeBuffer<'buffer> { + type Subset<'subset> = Subset<'subset> where 'buffer: 'subset; + + fn for_each_subset(&self, _f: F) + where + F: for<'subset> Fn(Subset<'subset>), + { + todo!() + } +} + +pub struct Subset<'subset> { + buffer: &'subset [()], +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-30786.rs b/tests/ui/higher-ranked/trait-bounds/issue-30786.rs new file mode 100644 index 00000000000..4a6399c8f62 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-30786.rs @@ -0,0 +1,136 @@ +// normalize-stderr-test: "long-type-\d+" -> "long-type-hash" + +// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream Option; +} + +// Example stream +pub struct Repeat(u64); + +impl<'a> Stream for &'a mut Repeat { + type Item = &'a u64; + fn next(self) -> Option { + Some(&self.0) + } +} + +pub struct Map { + stream: S, + func: F, +} + +impl<'a, A, F, T> Stream for &'a mut Map +where + &'a mut A: Stream, + F: FnMut(<&'a mut A as Stream>::Item) -> T, +{ + type Item = T; + fn next(self) -> Option { + match self.stream.next() { + Some(item) => Some((self.func)(item)), + None => None, + } + } +} + +pub struct Filter { + stream: S, + func: F, +} + +impl<'a, A, F, T> Stream for &'a mut Filter +where + for<'b> &'b mut A: Stream, // <---- BAD + F: FnMut(&T) -> bool, +{ + type Item = <&'a mut A as Stream>::Item; + fn next(self) -> Option { + while let Some(item) = self.stream.next() { + if (self.func)(&item) { + return Some(item); + } + } + None + } +} + +pub trait StreamExt +where + for<'b> &'b mut Self: Stream, +{ + fn mapx(self, func: F) -> Map + where + Self: Sized, + for<'a> &'a mut Map: Stream, + { + Map { func: func, stream: self } + } + + fn filterx(self, func: F) -> Filter + where + Self: Sized, + for<'a> &'a mut Filter: Stream, + { + Filter { func: func, stream: self } + } + + fn countx(mut self) -> usize + where + Self: Sized, + { + let mut count = 0; + while let Some(_) = self.next() { + count += 1; + } + count + } +} + +impl StreamExt for T where for<'a> &'a mut T: Stream {} + +fn identity(x: &T) -> &T { + x +} + +fn variant1() { + let source = Repeat(10); + + // Here, the call to `mapx` returns a type `T` to which `StreamExt` + // is not applicable, because `for<'b> &'b mut T: Stream`) doesn't hold. + // + // More concretely, the type `T` is `Map`, and + // the where clause doesn't hold because the signature of the + // closure gets inferred to a signature like `|&'_ Stream| -> &'_` + // for some specific `'_`, rather than a more generic + // signature. + // + // Why *exactly* we opt for this signature is a bit unclear to me, + // we deduce it somehow from a reuqirement that `Map: Stream` I + // guess. + let map = source.mapx(|x: &_| x); + let filter = map.filterx(|x: &_| true); + //~^ ERROR the method +} + +fn variant2() { + let source = Repeat(10); + + // Here, we use a function, which is not subject to the vagaries + // of closure signature inference. In this case, we get the error + // on `countx` as, I think, the test originally expected. + let map = source.mapx(identity); + let filter = map.filterx(|x: &_| true); + let count = filter.countx(); + //~^ ERROR the method +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr new file mode 100644 index 00000000000..f32ba57200d --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr @@ -0,0 +1,46 @@ +error[E0599]: the method `filterx` exists for struct `Map`, but its trait bounds were not satisfied + --> $DIR/issue-30786.rs:120:22 + | +LL | pub struct Map { + | -------------------- + | | + | method `filterx` not found for this struct + | doesn't satisfy `_: StreamExt` +... +LL | let filter = map.filterx(|x: &_| true); + | ^^^^^^^ method cannot be called on `Map` due to unsatisfied trait bounds + | +note: the following trait bounds were not satisfied: + `&'a mut &Map: Stream` + `&'a mut &mut Map: Stream` + `&'a mut Map: Stream` + --> $DIR/issue-30786.rs:98:50 + | +LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} + | --------- - ^^^^^^ unsatisfied trait bound introduced here + +error[E0599]: the method `countx` exists for struct `Filter &u64 {identity::}>, [closure@issue-30786.rs:131:30]>`, but its trait bounds were not satisfied + --> $DIR/issue-30786.rs:132:24 + | +LL | pub struct Filter { + | ----------------------- + | | + | method `countx` not found for this struct + | doesn't satisfy `_: StreamExt` +... +LL | let count = filter.countx(); + | ^^^^^^ method cannot be called due to unsatisfied trait bounds + | + = note: the full type name has been written to '$TEST_BUILD_DIR/higher-ranked/trait-bounds/issue-30786/issue-30786.long-type-hash.txt' +note: the following trait bounds were not satisfied: + `&'a mut &Filter fn(&'a u64) -> &'a u64 {identity::}>, [closure@$DIR/issue-30786.rs:131:30: 131:37]>: Stream` + `&'a mut &mut Filter fn(&'a u64) -> &'a u64 {identity::}>, [closure@$DIR/issue-30786.rs:131:30: 131:37]>: Stream` + `&'a mut Filter fn(&'a u64) -> &'a u64 {identity::}>, [closure@$DIR/issue-30786.rs:131:30: 131:37]>: Stream` + --> $DIR/issue-30786.rs:98:50 + | +LL | impl StreamExt for T where for<'a> &'a mut T: Stream {} + | --------- - ^^^^^^ unsatisfied trait bound introduced here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/higher-ranked/trait-bounds/issue-36139-normalize-closure-sig.rs b/tests/ui/higher-ranked/trait-bounds/issue-36139-normalize-closure-sig.rs new file mode 100644 index 00000000000..2d49151ffcc --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-36139-normalize-closure-sig.rs @@ -0,0 +1,19 @@ +// run-pass +// Previously the closure's argument would be inferred to +// >::Item, causing an error in MIR type +// checking + +trait ITrait<'a> {type Item;} + +struct S {} + +impl<'a> ITrait<'a> for S { type Item = &'a mut usize; } + +fn m(_: F) + where I: for<'a> ITrait<'a>, + F: for<'a> FnMut(>::Item) { } + + +fn main() { + m::(|x| { *x += 1; }); +} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-39292.rs b/tests/ui/higher-ranked/trait-bounds/issue-39292.rs new file mode 100644 index 00000000000..968cf08916f --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-39292.rs @@ -0,0 +1,17 @@ +// run-pass +// Regression test for issue #39292. The object vtable was being +// incorrectly left with a null pointer. + +trait Foo { + fn print<'a>(&'a self) where T: 'a { println!("foo"); } +} + +impl<'a> Foo<&'a ()> for () { } + +trait Bar: for<'a> Foo<&'a ()> { } + +impl Bar for () {} + +fn main() { + (&() as &dyn Bar).print(); // Segfault +} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-42114.rs b/tests/ui/higher-ranked/trait-bounds/issue-42114.rs new file mode 100644 index 00000000000..01515fdc9d2 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-42114.rs @@ -0,0 +1,20 @@ +// check-pass + +fn lifetime<'a>() +where + &'a (): 'a, +{ + /* do nothing */ +} + +fn doesnt_work() +where + for<'a> &'a (): 'a, +{ + /* do nothing */ +} + +fn main() { + lifetime(); + doesnt_work(); +} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-43623.rs b/tests/ui/higher-ranked/trait-bounds/issue-43623.rs new file mode 100644 index 00000000000..cedcf7c361c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-43623.rs @@ -0,0 +1,21 @@ +// check-pass + +pub trait Trait<'a> { + type Assoc; +} + +pub struct Type; + +impl<'a> Trait<'a> for Type { + type Assoc = (); +} + +pub fn break_me(f: F) +where + T: for<'b> Trait<'b>, + F: for<'b> FnMut(>::Assoc), +{ + break_me::; +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-46989.rs b/tests/ui/higher-ranked/trait-bounds/issue-46989.rs new file mode 100644 index 00000000000..4a09f4be156 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-46989.rs @@ -0,0 +1,40 @@ +// Regression test for #46989: +// +// In the move to universes, this test started passing. +// It is not necessarily WRONG to do so, but it was a bit +// surprising. The reason that it passed is that when we were +// asked to prove that +// +// for<'a> fn(&'a i32): Foo +// +// we were able to use the impl below to prove +// +// fn(&'empty i32): Foo +// +// and then we were able to prove that +// +// fn(&'empty i32) = for<'a> fn(&'a i32) +// +// This last fact is somewhat surprising, but essentially "falls out" +// from handling variance correctly. In particular, consider the subtyping +// relations. First: +// +// fn(&'empty i32) <: for<'a> fn(&'a i32) +// +// This holds because -- intuitively -- a fn that takes a reference but doesn't use +// it can be given a reference with any lifetime. Similarly, the opposite direction: +// +// for<'a> fn(&'a i32) <: fn(&'empty i32) +// +// holds because 'a can be instantiated to 'empty. + +trait Foo {} + +impl Foo for fn(A) {} + +fn assert_foo() {} + +fn main() { + assert_foo::(); + //~^ ERROR implementation of `Foo` is not general enough +} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-46989.stderr b/tests/ui/higher-ranked/trait-bounds/issue-46989.stderr new file mode 100644 index 00000000000..3f874220a27 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-46989.stderr @@ -0,0 +1,11 @@ +error: implementation of `Foo` is not general enough + --> $DIR/issue-46989.rs:38:5 + | +LL | assert_foo::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo` would have to be implemented for the type `for<'a> fn(&'a i32)` + = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0` + +error: aborting due to previous error + diff --git a/tests/ui/higher-ranked/trait-bounds/issue-57639.rs b/tests/ui/higher-ranked/trait-bounds/issue-57639.rs new file mode 100644 index 00000000000..392e7233b56 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-57639.rs @@ -0,0 +1,29 @@ +// Regression test for #57639: +// +// In the move to universes, this test stopped working. The problem +// was that when the trait solver was asked to prove `for<'a> T::Item: +// Foo<'a>` as part of WF checking, it wound up "eagerly committing" +// to the where clause, which says that `T::Item: Foo<'a>`, but it +// should instead have been using the bound found in the trait +// declaration. Pre-universe, this used to work out ok because we got +// "eager errors" due to the leak check. +// +// See [this comment on GitHub][c] for more details. +// +// check-pass +// +// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861 + +trait Foo<'a> {} + +trait Bar { + type Item: for<'a> Foo<'a>; +} + +fn foo<'a, T>(_: T) +where + T: Bar, + T::Item: Foo<'a>, +{} + +fn main() { } diff --git a/tests/ui/higher-ranked/trait-bounds/issue-58451.rs b/tests/ui/higher-ranked/trait-bounds/issue-58451.rs new file mode 100644 index 00000000000..6006a108c5c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-58451.rs @@ -0,0 +1,13 @@ +// Regression test for #58451: +// +// Error reporting here encountered an ICE in the shift to universes. + +fn f(i: I) +where + I: IntoIterator, + I::Item: for<'a> Into<&'a ()>, +{} + +fn main() { + f(&[f()]); //~ ERROR function takes 1 argument +} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr new file mode 100644 index 00000000000..0f051be2128 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-58451.stderr @@ -0,0 +1,19 @@ +error[E0061]: this function takes 1 argument but 0 arguments were supplied + --> $DIR/issue-58451.rs:12:9 + | +LL | f(&[f()]); + | ^-- an argument is missing + | +note: function defined here + --> $DIR/issue-58451.rs:5:4 + | +LL | fn f(i: I) + | ^ ---- +help: provide the argument + | +LL | f(&[f(/* i */)]); + | ~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/higher-ranked/trait-bounds/issue-59311.rs b/tests/ui/higher-ranked/trait-bounds/issue-59311.rs new file mode 100644 index 00000000000..3ad548450e5 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.rs @@ -0,0 +1,22 @@ +// Regression test for #59311. The test is taken from +// rust-lang/rust/issues/71546#issuecomment-620638437 +// as they seem to have the same cause. + +// FIXME: It's not clear that this code ought to report +// an error, but the regression test is here to ensure +// that it does not ICE. See discussion on #74889 for details. + +pub trait T { + fn t(&self, _: F) {} +} + +pub fn crash(v: &V) +where + for<'a> &'a V: T + 'static, +{ + v.t(|| {}); + //~^ ERROR: higher-ranked lifetime error + //~| ERROR: higher-ranked lifetime error +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr new file mode 100644 index 00000000000..c01ab8e347c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr @@ -0,0 +1,18 @@ +error: higher-ranked lifetime error + --> $DIR/issue-59311.rs:17:5 + | +LL | v.t(|| {}); + | ^^^^^^^^^^ + | + = note: could not prove `[closure@$DIR/issue-59311.rs:17:9: 17:11] well-formed` + +error: higher-ranked lifetime error + --> $DIR/issue-59311.rs:17:9 + | +LL | v.t(|| {}); + | ^^^^^ + | + = note: could not prove `for<'a> &'a V: 'static` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/higher-ranked/trait-bounds/issue-60283.rs b/tests/ui/higher-ranked/trait-bounds/issue-60283.rs new file mode 100644 index 00000000000..05315b3f9f5 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-60283.rs @@ -0,0 +1,20 @@ +// check-pass + +pub trait Trait<'a> { + type Item; +} + +impl<'a> Trait<'a> for () { + type Item = (); +} + +pub fn foo(_: T, _: F) +where + T: for<'a> Trait<'a>, + F: for<'a> FnMut(>::Item), +{ +} + +fn main() { + foo((), drop) +} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs new file mode 100644 index 00000000000..e70f6fc3430 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.rs @@ -0,0 +1,54 @@ +trait T0<'a, A> { + type O; +} + +struct L { + f: T, +} + +// explicitly named variants of what one would normally denote by the +// unit type `()`. Why do this? So that we can differentiate them in +// the diagnostic output. +struct Unit1; +struct Unit2; +struct Unit3; +struct Unit4; + +impl<'a, A, T> T0<'a, A> for L +where + T: FnMut(A) -> Unit3, +{ + type O = T::Output; +} + +trait T1: for<'r> Ty<'r> { + fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 + where + F: for<'r> T0<'r, (>::V,), O = >::V>, + { + unimplemented!(); + } +} + +trait Ty<'a> { + type V; +} + +fn main() { + let v = Unit2.m( + L { + //~^ ERROR to be a closure that returns `Unit3`, but it returns `Unit4` + //~| ERROR type mismatch + f: |x| { + drop(x); + Unit4 + }, + }, + ); +} + +impl<'a> Ty<'a> for Unit2 { + type V = &'a u8; +} + +impl T1 for Unit2 {} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr new file mode 100644 index 00000000000..4d470ae7022 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-62203-hrtb-ice.stderr @@ -0,0 +1,66 @@ +error[E0271]: type mismatch resolving ` as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` + --> $DIR/issue-62203-hrtb-ice.rs:39:9 + | +LL | let v = Unit2.m( + | - required by a bound introduced by this call +LL | / L { +LL | | +LL | | +LL | | f: |x| { +... | +LL | | }, +LL | | }, + | |_________^ type mismatch resolving ` as T0<'r, (&u8,)>>::O == <_ as Ty<'r>>::V` + | +note: expected this to be `<_ as Ty<'_>>::V` + --> $DIR/issue-62203-hrtb-ice.rs:21:14 + | +LL | type O = T::Output; + | ^^^^^^^^^ + = note: expected associated type `<_ as Ty<'_>>::V` + found struct `Unit4` + = help: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4` or calling a method that returns `<_ as Ty<'_>>::V` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +note: required by a bound in `T1::m` + --> $DIR/issue-62203-hrtb-ice.rs:27:51 + | +LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 + | - required by a bound in this associated function +LL | where +LL | F: for<'r> T0<'r, (>::V,), O = >::V>, + | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` + +error[E0271]: expected `[closure@issue-62203-hrtb-ice.rs:42:16]` to be a closure that returns `Unit3`, but it returns `Unit4` + --> $DIR/issue-62203-hrtb-ice.rs:39:9 + | +LL | let v = Unit2.m( + | - required by a bound introduced by this call +LL | / L { +LL | | +LL | | +LL | | f: |x| { +... | +LL | | }, +LL | | }, + | |_________^ expected `Unit3`, found `Unit4` + | +note: required for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:16: 42:19]>` to implement `for<'r> T0<'r, (&'r u8,)>` + --> $DIR/issue-62203-hrtb-ice.rs:17:16 + | +LL | impl<'a, A, T> T0<'a, A> for L + | ^^^^^^^^^ ^^^^ +LL | where +LL | T: FnMut(A) -> Unit3, + | ----- unsatisfied trait bound introduced here +note: required by a bound in `T1::m` + --> $DIR/issue-62203-hrtb-ice.rs:27:12 + | +LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 + | - required by a bound in this associated function +LL | where +LL | F: for<'r> T0<'r, (>::V,), O = >::V>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/higher-ranked/trait-bounds/issue-88446.rs b/tests/ui/higher-ranked/trait-bounds/issue-88446.rs new file mode 100644 index 00000000000..571b8531757 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-88446.rs @@ -0,0 +1,35 @@ +// check-pass + +trait Yokeable<'a> { + type Output: 'a; +} +impl<'a> Yokeable<'a> for () { + type Output = (); +} + +trait DataMarker<'data> { + type Yokeable: for<'a> Yokeable<'a>; +} +impl<'data> DataMarker<'data> for () { + type Yokeable = (); +} + +struct DataPayload<'data, M>(&'data M); + +impl DataPayload<'static, ()> { + pub fn map_project_with_capture( + _: for<'a> fn( + capture: T, + std::marker::PhantomData<&'a ()>, + ) -> >::Output, + ) -> DataPayload<'static, M2> + where + M2: DataMarker<'static>, + { + todo!() + } +} + +fn main() { + let _: DataPayload<()> = DataPayload::<()>::map_project_with_capture::<_, &()>(|_, _| todo!()); +} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs b/tests/ui/higher-ranked/trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs new file mode 100644 index 00000000000..92b7c5deb81 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-88586-hr-self-outlives-in-trait-def.rs @@ -0,0 +1,13 @@ +// Regression test for #88586: a higher-ranked outlives bound on Self in a trait +// definition caused an ICE when debug_assertions were enabled. +// +// Made to pass as part of fixing #98095. +// +// check-pass + +trait A where + for<'a> Self: 'a, +{ +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-90177.rs b/tests/ui/higher-ranked/trait-bounds/issue-90177.rs new file mode 100644 index 00000000000..b151a9d3ab6 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-90177.rs @@ -0,0 +1,32 @@ +// check-pass + +trait Base<'f> { + type Assoc; + + fn do_something(&self); +} + +trait ForAnyLifetime: for<'f> Base<'f> {} + +impl ForAnyLifetime for T where T: for<'f> Base<'f> {} + +trait CanBeDynamic: ForAnyLifetime + for<'f> Base<'f, Assoc = ()> {} + +fn foo(a: &dyn CanBeDynamic) { + a.do_something(); +} + +struct S; + +impl<'a> Base<'a> for S { + type Assoc = (); + + fn do_something(&self) {} +} + +impl CanBeDynamic for S {} + +fn main() { + let s = S; + foo(&s); +} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95034.rs b/tests/ui/higher-ranked/trait-bounds/issue-95034.rs new file mode 100644 index 00000000000..af4946a187f --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-95034.rs @@ -0,0 +1,80 @@ +// check-pass +// compile-flags: --edition=2021 --crate-type=lib + +use std::{ + future::Future, + marker::PhantomData, + pin::Pin, + task::{Context, Poll}, +}; + +mod object { + use super::*; + + pub trait Object<'a> { + type Error; + type Future: Future; + fn create() -> Self::Future; + } + + impl<'a> Object<'a> for u8 { + type Error = (); + type Future = Pin>>; + fn create() -> Self::Future { + unimplemented!() + } + } + + impl<'a, E, A: Object<'a, Error = E>> Object<'a> for (A,) { + type Error = (); + type Future = CustomFut<'a, E, A>; + fn create() -> Self::Future { + unimplemented!() + } + } + + pub struct CustomFut<'f, E, A: Object<'f, Error = E>> { + ph: PhantomData<(A::Future,)>, + } + + impl<'f, E, A: Object<'f, Error = E>> Future for CustomFut<'f, E, A> { + type Output = (A,); + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { + unimplemented!() + } + } +} + +mod async_fn { + use super::*; + + pub trait AsyncFn { + type Future: Future; + fn call(&self) -> Self::Future; + } + + impl AsyncFn for F + where + F: Fn() -> Fut, + Fut: Future, + { + type Future = Fut; + fn call(&self) -> Self::Future { + (self)() + } + } +} + +pub async fn test() { + use self::{async_fn::AsyncFn, object::Object}; + + async fn create>() { + T::create().await; + } + + async fn call_async_fn(inner: impl AsyncFn) { + inner.call().await; + } + + call_async_fn(create::<(u8,)>).await; +} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr b/tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr new file mode 100644 index 00000000000..d4bc5b67220 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-95230.next.stderr @@ -0,0 +1,19 @@ +error[E0275]: overflow evaluating the requirement `for<'a> &'a mut Bar well-formed` + --> $DIR/issue-95230.rs:9:13 + | +LL | for<'a> &'a mut Self:; + | ^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_95230`) +note: required by a bound in `Bar` + --> $DIR/issue-95230.rs:9:13 + | +LL | pub struct Bar + | --- required by a bound in this struct +LL | where +LL | for<'a> &'a mut Self:; + | ^^^^^^^^^^^^ required by this bound in `Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/higher-ranked/trait-bounds/issue-95230.rs b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs new file mode 100644 index 00000000000..49a1584d54e --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/issue-95230.rs @@ -0,0 +1,11 @@ +// revisions: old next +//[next] compile-flags: -Ztrait-solver=next +//[old] check-pass +//[next] known-bug: #109764 + + +pub struct Bar +where + for<'a> &'a mut Self:; + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-44005.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-44005.rs new file mode 100644 index 00000000000..f255eac0c4b --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-44005.rs @@ -0,0 +1,31 @@ +// check-pass + +pub trait Foo<'a> { + type Bar; + fn foo(&'a self) -> Self::Bar; +} + +impl<'a, 'b, T: 'a> Foo<'a> for &'b T { + type Bar = &'a T; + fn foo(&'a self) -> &'a T { + self + } +} + +pub fn uncallable(x: T, f: F) +where + T: for<'a> Foo<'a>, + F: for<'a> Fn(>::Bar), +{ + f(x.foo()); +} + +pub fn catalyst(x: &i32) { + broken(x, |_| {}) +} + +pub fn broken(x: &i32, f: F) { + uncallable(x, |y| f(y)); +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-56556.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-56556.rs new file mode 100644 index 00000000000..4d38cb19e9b --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-56556.rs @@ -0,0 +1,30 @@ +// check-pass + +fn foo(t: T) -> usize +where + for<'a> &'a T: IntoIterator, + for<'a> <&'a T as IntoIterator>::IntoIter: ExactSizeIterator, +{ + t.into_iter().len() +} + +fn main() { + foo::>(vec![]); +} + +mod another { + use std::ops::Deref; + + fn test() + where + T: Deref, + TDeref: ?Sized, + for<'a> &'a TDeref: IntoIterator, + for<'a> <&'a TDeref as IntoIterator>::IntoIter: Clone, + { + } + + fn main() { + test::, _>(); + } +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs new file mode 100644 index 00000000000..c6f29fa5908 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-1.rs @@ -0,0 +1,88 @@ +// check-pass + +// FamilyType (GAT workaround) +pub trait FamilyLt<'a> { + type Out; +} + +struct RefMutFamily(std::marker::PhantomData, ()); +impl<'a, T: 'a> FamilyLt<'a> for RefMutFamily { + type Out = &'a mut T; +} + +pub trait Execute { + type E: Inject; + fn execute(self, value: <::I as FamilyLt>::Out); +} + +pub trait Inject +where + Self: Sized, +{ + type I: for<'a> FamilyLt<'a>; + fn inject(_: &()) -> ::Out; +} + +impl Inject for RefMutFamily { + type I = Self; + fn inject(_: &()) -> ::Out { + unimplemented!() + } +} + +// This struct is only used to give a hint to the compiler about the type `Q` +struct Annotate(std::marker::PhantomData); +impl Annotate { + fn new() -> Self { + Self(std::marker::PhantomData) + } +} + +// This function annotate a closure so it can have Higher-Rank Lifetime Bounds +// +// See 'annotate' workaround: https://github.com/rust-lang/rust/issues/58052 +fn annotate(_q: Annotate, func: F) -> impl Execute + 'static +where + F: for<'r> FnOnce(<::I as FamilyLt<'r>>::Out) + 'static, + Q: Inject + 'static, +{ + let wrapper: Wrapper = Wrapper(std::marker::PhantomData, func); + wrapper +} + +struct Wrapper(std::marker::PhantomData, F); +impl Execute for Wrapper + where + Q: Inject, + F: for<'r> FnOnce(<::I as FamilyLt<'r>>::Out), +{ + type E = Q; + + fn execute(self, value: <::I as FamilyLt>::Out) { + (self.1)(value) + } +} + +struct Task { + _processor: Box, +} + +// This function consume the closure +fn task

(processor: P) -> Task +where P: Execute + 'static { + Task { + _processor: Box::new(move || { + let q = P::E::inject(&()); + processor.execute(q); + }) + } +} + +fn main() { + task(annotate( + Annotate::>::new(), + |value: &mut usize| { + *value = 2; + } + )); +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-2.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-2.rs new file mode 100644 index 00000000000..00205473291 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-2.rs @@ -0,0 +1,33 @@ +// check-pass + +use std::marker::PhantomData; + +trait Lt<'a> { + type T; +} +struct Id(PhantomData); +impl<'a,T> Lt<'a> for Id { + type T = T; +} + +struct Ref(PhantomData) where T: ?Sized; +impl<'a,T> Lt<'a> for Ref +where T: 'a + Lt<'a> + ?Sized +{ + type T = &'a T; +} +struct Mut(PhantomData) where T: ?Sized; +impl<'a,T> Lt<'a> for Mut +where T: 'a + Lt<'a> + ?Sized +{ + type T = &'a mut T; +} + +struct C(for<'a> fn(>::T) -> O) where I: for<'a> Lt<'a>; + + +fn main() { + let c = C::,_>(|()| 3); + c.0(()); + +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.rs new file mode 100644 index 00000000000..d84e30f4984 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.rs @@ -0,0 +1,32 @@ +trait ATC<'a> { + type Type: Sized; +} + +trait WithDefault: for<'a> ATC<'a> { + fn with_default Fn(>::Type)>(f: F); +} + +fn call<'b, T: for<'a> ATC<'a>, F: for<'a> Fn(>::Type)>( + f: F, + x: >::Type, +) { + f(x); +} + +impl<'a> ATC<'a> for () { + type Type = Self; +} + +impl WithDefault for () { + fn with_default Fn(>::Type)>(f: F) { + // Errors with a bogus type mismatch. + //f(()); + // Going through another generic function works fine. + call(f, ()); + //~^ expected a + } +} + +fn main() { + // <()>::with_default(|_| {}); +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr new file mode 100644 index 00000000000..b30dd36d2ad --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-3.stderr @@ -0,0 +1,19 @@ +error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` + --> $DIR/issue-62529-3.rs:25:14 + | +LL | call(f, ()); + | ---- ^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` + | | + | required by a bound introduced by this call + | + = note: expected a closure with arguments `((),)` + found a closure with arguments `(<_ as ATC<'a>>::Type,)` +note: required by a bound in `call` + --> $DIR/issue-62529-3.rs:9:36 + | +LL | fn call<'b, T: for<'a> ATC<'a>, F: for<'a> Fn(>::Type)>( + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `call` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-4.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-4.rs new file mode 100644 index 00000000000..8c2a59868ca --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-4.rs @@ -0,0 +1,39 @@ +// check-pass + +use std::marker::PhantomData; +use std::mem; + +trait Container<'a> { + type Root: 'a; +} + +type RootOf<'a, T> = >::Root; + +struct Test<'a, T> where T: Container<'a> { + pub root: T::Root, + marker: PhantomData<&'a mut &'a mut ()>, +} + +impl<'a, 'b> Container<'b> for &'a str { + type Root = &'b str; +} + +impl<'a, T> Test<'a, T> where T: for<'b> Container<'b> { + fn new(root: RootOf<'a, T>) -> Test<'a, T> { + Test { + root: root, + marker: PhantomData + } + } + + fn with_mut(&mut self, f: F) -> R where + F: for<'b> FnOnce(&'b mut RootOf<'b, T>) -> R { + f(unsafe { mem::transmute(&mut self.root) }) + } +} + +fn main() { + let val = "root"; + let mut test: Test<&str> = Test::new(val); + test.with_mut(|_| { }); +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-5.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-5.rs new file mode 100644 index 00000000000..03f257a029c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-5.rs @@ -0,0 +1,27 @@ +// check-pass + +pub struct Struct {} + +pub trait Trait<'a> { + type Assoc; + + fn method() -> Self::Assoc; +} + +impl<'a> Trait<'a> for Struct { + type Assoc = (); + + fn method() -> Self::Assoc {} +} + +pub fn function(f: F) +where + F: for<'a> FnOnce(>::Assoc), + T: for<'b> Trait<'b>, +{ + f(T::method()); +} + +fn main() { + function::<_, Struct>(|_| {}); +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs new file mode 100644 index 00000000000..74a4785e478 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-62529-6.rs @@ -0,0 +1,77 @@ +// check-pass + +use std::cell::RefMut; + +fn main() { + StateMachine2::Init.resume(); +} + +enum StateMachine2<'a> { + Init, + #[allow(dead_code)] // match required for ICE + AfterTwoYields { + p: Backed<'a, *mut String>, + }, +} + +impl<'a> StateMachine2<'a> { + fn take(&self) -> Self { + StateMachine2::Init + } +} + +impl<'a> StateMachine2<'a> { + fn resume(&mut self) -> () { + use StateMachine2::*; + match self.take() { + AfterTwoYields { p } => { + p.with(|_| {}); + } + _ => panic!("Resume after completed."), + } + } +} + +unsafe trait Unpack<'a> { + type Unpacked: 'a; + + fn unpack(&self) -> Self::Unpacked { + unsafe { std::mem::transmute_copy(&self) } + } +} + +unsafe trait Pack { + type Packed; + + fn pack(&self) -> Self::Packed { + unsafe { std::mem::transmute_copy(&self) } + } +} + +unsafe impl<'a> Unpack<'a> for String { + type Unpacked = String; +} + +unsafe impl Pack for String { + type Packed = String; +} + +unsafe impl<'a> Unpack<'a> for *mut String { + type Unpacked = &'a mut String; +} + +unsafe impl<'a> Pack for &'a mut String { + type Packed = *mut String; +} + +struct Backed<'a, U>(RefMut<'a, Option>, U); + +impl<'a, 'b, U: Unpack<'b>> Backed<'a, U> { + fn with(self, f: F) -> Backed<'a, ()> + where + F: for<'f> FnOnce(>::Unpacked) -> (), + { + let result = f(self.1.unpack()); + Backed(self.0, result) + } +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-70120.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-70120.rs new file mode 100644 index 00000000000..3ced40230f0 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-70120.rs @@ -0,0 +1,31 @@ +// check-pass + +pub trait MyTrait<'a> { + type Output: 'a; + fn gimme_value(&self) -> Self::Output; +} + +pub struct MyStruct; + +impl<'a> MyTrait<'a> for MyStruct { + type Output = &'a usize; + fn gimme_value(&self) -> Self::Output { + unimplemented!() + } +} + +fn meow(t: T, f: F) +where + T: for<'any> MyTrait<'any>, + F: for<'any2> Fn(>::Output), +{ + let v = t.gimme_value(); + f(v); +} + +fn main() { + let struc = MyStruct; + meow(struc, |foo| { + println!("{:?}", foo); + }) +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr new file mode 100644 index 00000000000..0f38f8e3283 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr @@ -0,0 +1,79 @@ +error[E0308]: mismatched types + --> $DIR/issue-71955.rs:54:5 + | +LL | foo(bar, "string", |s| s.len() == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `for<'r, 's> FnOnce<(&'r &'s str,)>` + found type `for<'r> FnOnce<(&'r &str,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-71955.rs:54:24 + | +LL | foo(bar, "string", |s| s.len() == 5); + | ^^^^^^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-71955.rs:34:9 + | +LL | F2: FnOnce(&::Output) -> bool + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/issue-71955.rs:54:5 + | +LL | foo(bar, "string", |s| s.len() == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `FnOnce<(&&str,)>` + found type `for<'r> FnOnce<(&'r &str,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-71955.rs:54:24 + | +LL | foo(bar, "string", |s| s.len() == 5); + | ^^^^^^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-71955.rs:34:44 + | +LL | F2: FnOnce(&::Output) -> bool + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/issue-71955.rs:58:5 + | +LL | foo(baz, "string", |s| s.0.len() == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `for<'r, 's> FnOnce<(&'r Wrapper<'s>,)>` + found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-71955.rs:58:24 + | +LL | foo(baz, "string", |s| s.0.len() == 5); + | ^^^^^^^^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-71955.rs:34:9 + | +LL | F2: FnOnce(&::Output) -> bool + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/issue-71955.rs:58:5 + | +LL | foo(baz, "string", |s| s.0.len() == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected type `FnOnce<(&Wrapper<'_>,)>` + found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-71955.rs:58:24 + | +LL | foo(baz, "string", |s| s.0.len() == 5); + | ^^^^^^^^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-71955.rs:34:44 + | +LL | F2: FnOnce(&::Output) -> bool + | ^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs new file mode 100644 index 00000000000..1d90226a3f4 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.rs @@ -0,0 +1,51 @@ +// check-fail +#![feature(rustc_attrs)] + +trait Parser<'s> { + type Output; + + fn call(&self, input: &'s str) -> (&'s str, Self::Output); +} + +impl<'s, F, T> Parser<'s> for F +where F: Fn(&'s str) -> (&'s str, T) { + type Output = T; + fn call(&self, input: &'s str) -> (&'s str, T) { + self(input) + } +} + +fn foo( + f1: F1, + base: &'static str, + f2: F2 +) +where + F1: for<'a> Parser<'a>, + F2: FnOnce(&::Output) -> bool +{ + let s: String = base.to_owned(); + let str_ref = s.as_ref(); + let (remaining, produced) = f1.call(str_ref); + assert!(f2(&produced)); + assert_eq!(remaining.len(), 0); +} + +struct Wrapper<'a>(&'a str); + +fn main() { + fn bar<'a>(s: &'a str) -> (&'a str, &'a str) { + (&s[..1], &s[..]) + } + + fn baz<'a>(s: &'a str) -> (&'a str, Wrapper<'a>) { + (&s[..1], Wrapper(&s[..])) + } + + foo(bar, "string", |s| s.len() == 5); + //~^ ERROR mismatched types + //~| ERROR mismatched types + foo(baz, "string", |s| s.0.len() == 5); + //~^ ERROR mismatched types + //~| ERROR mismatched types +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr new file mode 100644 index 00000000000..4ef96cd9541 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.stderr @@ -0,0 +1,79 @@ +error[E0308]: mismatched types + --> $DIR/issue-71955.rs:45:5 + | +LL | foo(bar, "string", |s| s.len() == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> FnOnce<(&'a &'b str,)>` + found trait `for<'a> FnOnce<(&'a &str,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-71955.rs:45:24 + | +LL | foo(bar, "string", |s| s.len() == 5); + | ^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-71955.rs:25:9 + | +LL | F2: FnOnce(&::Output) -> bool + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/issue-71955.rs:45:5 + | +LL | foo(bar, "string", |s| s.len() == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> FnOnce<(&'a &'b str,)>` + found trait `for<'a> FnOnce<(&'a &str,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-71955.rs:45:24 + | +LL | foo(bar, "string", |s| s.len() == 5); + | ^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-71955.rs:25:44 + | +LL | F2: FnOnce(&::Output) -> bool + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/issue-71955.rs:48:5 + | +LL | foo(baz, "string", |s| s.0.len() == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> FnOnce<(&'a Wrapper<'b>,)>` + found trait `for<'a> FnOnce<(&'a Wrapper<'_>,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-71955.rs:48:24 + | +LL | foo(baz, "string", |s| s.0.len() == 5); + | ^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-71955.rs:25:9 + | +LL | F2: FnOnce(&::Output) -> bool + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/issue-71955.rs:48:5 + | +LL | foo(baz, "string", |s| s.0.len() == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> FnOnce<(&'a Wrapper<'b>,)>` + found trait `for<'a> FnOnce<(&'a Wrapper<'_>,)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-71955.rs:48:24 + | +LL | foo(baz, "string", |s| s.0.len() == 5); + | ^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-71955.rs:25:44 + | +LL | F2: FnOnce(&::Output) -> bool + | ^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-74261.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-74261.rs new file mode 100644 index 00000000000..93ccb42684c --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-74261.rs @@ -0,0 +1,30 @@ +// check-pass + +use std::marker::PhantomData; + +trait A<'a> { + type B; + fn b(self) -> Self::B; +} + +struct T; +struct S<'a>(PhantomData<&'a ()>); + +impl<'a> A<'a> for T { + type B = S<'a>; + fn b(self) -> Self::B { + S(PhantomData) + } +} + +fn s(t: TT, f: F) +where + TT: for<'a> A<'a>, + F: for<'a> FnOnce(>::B) +{ + f(t.b()); +} + +fn main() { + s(T, |_| {}); +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-76956.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-76956.rs new file mode 100644 index 00000000000..583470080a2 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-76956.rs @@ -0,0 +1,15 @@ +// check-pass + +use std::ops::Deref; + +struct Data { + boxed: Box<&'static i32> +} + +impl Data { + fn use_data(&self, user: impl for <'a> FnOnce( as Deref>::Target)) { + user(*self.boxed) + } +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80706.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80706.rs new file mode 100644 index 00000000000..00a866f220b --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80706.rs @@ -0,0 +1,71 @@ +// build-pass +// edition:2018 + +type BoxFuture = std::pin::Pin>>; + +fn main() { + f(); +} + +async fn f() { + run("dependency").await; +} + +struct InMemoryStorage; + +struct User<'dep> { + dep: &'dep str, +} + +impl<'a> StorageRequest for SaveUser<'a> { + fn execute(&self) -> BoxFuture> { + todo!() + } +} + +trait Storage { + type Error; +} + +impl Storage for InMemoryStorage { + type Error = String; +} + +trait StorageRequestReturnType { + type Output; +} + +trait StorageRequest: StorageRequestReturnType { + fn execute( + &self, + ) -> BoxFuture::Output, ::Error>>; +} + +struct SaveUser<'a> { + name: &'a str, +} + +impl<'a> StorageRequestReturnType for SaveUser<'a> { + type Output = (); +} + +impl<'dep> User<'dep> { + async fn save(self) + where + S: Storage, + for<'a> SaveUser<'a>: StorageRequest, + { + SaveUser { name: "Joe" } + .execute() + .await; + } +} + +async fn run(dep: &str) +where + S: Storage, + for<'a> SaveUser<'a>: StorageRequest, + for<'a> SaveUser<'a>: StorageRequestReturnType, +{ + User { dep }.save().await; +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80956.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80956.rs new file mode 100644 index 00000000000..6316ceea156 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-80956.rs @@ -0,0 +1,21 @@ +// check-pass + +trait Bar { + type Type; +} +struct Foo<'a>(&'a ()); +impl<'a> Bar for Foo<'a> { + type Type = (); +} + +fn func<'a>(_: as Bar>::Type) {} +fn assert_is_func(_: fn(A)) {} + +fn test() +where + for<'a> as Bar>::Type: Sized, +{ + assert_is_func(func); +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-81809.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-81809.rs new file mode 100644 index 00000000000..f6ab9c203b5 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-81809.rs @@ -0,0 +1,21 @@ +// check-pass + +pub trait Indexable { + type Idx; +} +impl Indexable for u8 { + type Idx = u8; +} +impl Indexable for u16 { + type Idx = u16; +} + +pub trait Indexer: std::ops::Index {} + +trait StoreIndex: Indexer + Indexer {} + +fn foo(st: &impl StoreIndex) -> &dyn StoreIndex { + st as &dyn StoreIndex +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.rs new file mode 100644 index 00000000000..8aa29926d4f --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.rs @@ -0,0 +1,19 @@ +#![feature(unboxed_closures)] + +trait SomeTrait<'a> { + type Associated; +} + +fn give_me_ice() { + callee:: >::Associated>(); + //~^ ERROR the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied [E0277] + //~| ERROR the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied [E0277] +} + +fn callee>() { + println!("{}", std::any::type_name::<>::Output>()); +} + +fn main() { + give_me_ice::<()>(); +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr new file mode 100644 index 00000000000..3240518fbbe --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-85455.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied + --> $DIR/issue-85455.rs:8:14 + | +LL | callee:: >::Associated>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> SomeTrait<'a>` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | fn give_me_ice SomeTrait<'a>>() { + | +++++++++++++++++++++++ + +error[E0277]: the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied + --> $DIR/issue-85455.rs:8:5 + | +LL | callee:: >::Associated>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> SomeTrait<'a>` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | fn give_me_ice SomeTrait<'a>>() { + | +++++++++++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.rs new file mode 100644 index 00000000000..fffb54f86ca --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.rs @@ -0,0 +1,32 @@ +trait BufferMut {} +struct Ctx(D); + +trait BufferUdpStateContext {} +impl BufferUdpStateContext for C {} + +trait StackContext +where + Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>, +{ + type Dispatcher; +} + +trait TimerContext { + type Handler; +} +impl TimerContext for C +where + C: StackContext, + //~^ ERROR: is not satisfied [E0277] +{ + type Handler = Ctx; + //~^ ERROR: is not satisfied [E0277] +} + +struct EthernetWorker(C) +where + Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>; +impl EthernetWorker {} +//~^ ERROR: is not satisfied [E0277] + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr new file mode 100644 index 00000000000..edef6ccd34e --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89118.stderr @@ -0,0 +1,69 @@ +error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied + --> $DIR/issue-89118.rs:19:8 + | +LL | C: StackContext, + | ^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` + | +note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` + --> $DIR/issue-89118.rs:5:23 + | +LL | impl BufferUdpStateContext for C {} + | --------- ^^^^^^^^^^^^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `StackContext` + --> $DIR/issue-89118.rs:9:14 + | +LL | trait StackContext + | ------------ required by a bound in this trait +LL | where +LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext` + +error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied + --> $DIR/issue-89118.rs:29:9 + | +LL | impl EthernetWorker {} + | ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` + | +note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` + --> $DIR/issue-89118.rs:5:23 + | +LL | impl BufferUdpStateContext for C {} + | --------- ^^^^^^^^^^^^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `EthernetWorker` + --> $DIR/issue-89118.rs:28:14 + | +LL | struct EthernetWorker(C) + | -------------- required by a bound in this struct +LL | where +LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `EthernetWorker` + +error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied + --> $DIR/issue-89118.rs:22:20 + | +LL | type Handler = Ctx; + | ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` + | +note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` + --> $DIR/issue-89118.rs:5:23 + | +LL | impl BufferUdpStateContext for C {} + | --------- ^^^^^^^^^^^^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `StackContext` + --> $DIR/issue-89118.rs:9:14 + | +LL | trait StackContext + | ------------ required by a bound in this trait +LL | where +LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs new file mode 100644 index 00000000000..f7e467b3786 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs @@ -0,0 +1,44 @@ +// check-pass + +#![allow(unused)] + +trait MiniYokeable<'a> { + type Output; +} + +struct MiniYoke MiniYokeable<'a>> { + pub yokeable: Y, +} + +fn map_project_broken( + source: MiniYoke, + f: impl for<'a> FnOnce( + >::Output, + core::marker::PhantomData<&'a ()>, + ) ->

>::Output, +) -> MiniYoke

+where + Y: for<'a> MiniYokeable<'a>, + P: for<'a> MiniYokeable<'a> +{ + unimplemented!() +} + +struct Bar<'a> { + string_1: &'a str, + string_2: &'a str, +} + +impl<'a> MiniYokeable<'a> for Bar<'static> { + type Output = Bar<'a>; +} + +impl<'a> MiniYokeable<'a> for &'static str { + type Output = &'a str; +} + +fn demo_broken(bar: MiniYoke>) -> MiniYoke<&'static str> { + map_project_broken(bar, |bar, _| bar.string_1) +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90612.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90612.rs new file mode 100644 index 00000000000..effc329456d --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90612.rs @@ -0,0 +1,41 @@ +// check-pass + +use std::marker::PhantomData; + +trait Family: Sized { + type Item<'a>; + + fn apply_all(&self, f: F) + where + F: FamilyItemFn { } +} + +struct Array(PhantomData); + +impl Family for Array { + type Item<'a> = &'a T; +} + +trait FamilyItemFn { + fn apply(&self, item: T::Item<'_>); +} + +impl FamilyItemFn for F +where + T: Family, + for<'a> F: Fn(T::Item<'a>) +{ + fn apply(&self, item: T::Item<'_>) { + (*self)(item); + } +} + +fn process(array: Array) { + // Works + array.apply_all(|x: &T| { }); + + // ICE: NoSolution + array.apply_all(|x: as Family>::Item<'_>| { }); +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs new file mode 100644 index 00000000000..628b5cba104 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs @@ -0,0 +1,35 @@ +//check-pass + +trait Yokeable<'a>: 'static { + type Output: 'a; +} + +trait IsCovariant<'a> {} + +struct Yoke Yokeable<'a>> { + data: Y, +} + +impl Yokeable<'a>> Yoke { + fn project Yokeable<'a>>(&self, _f: for<'a> fn(>::Output, &'a ()) + -> >::Output) -> Yoke { + + unimplemented!() + } +} + +fn _upcast(x: Yoke) -> Yoke + 'static>> where + Y: for<'a> Yokeable<'a>, + for<'a> >::Output: IsCovariant<'a> + { + x.project(|data, _| { + Box::new(data) + }) +} + + +impl<'a> Yokeable<'a> for Box + 'static> { + type Output = Box + 'a>; +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90875.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90875.rs new file mode 100644 index 00000000000..ffd6857d84a --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90875.rs @@ -0,0 +1,31 @@ +// check-pass + +trait Variable<'a> { + type Type; +} + +impl Variable<'_> for () { + type Type = (); +} + +fn check(_: F) +where + F: Fn(T), // <- if removed, all fn_* then require type annotations + F: for<'a> Fn(>::Type), + T: for<'a> Variable<'a>, +{ +} + +fn test(arg: impl Fn(())) { + fn fn_1(_: ()) {} + let fn_2 = |_: ()| (); + let fn_3 = |a| fn_1(a); + let fn_4 = arg; + + check(fn_1); // Error + check(fn_2); // Ok + check(fn_3); // Ok + check(fn_4); // Error +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs new file mode 100644 index 00000000000..ab9d9a7ce6f --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs @@ -0,0 +1,53 @@ +// check-fail +// known-bug: #90950 + +trait Yokeable<'a>: 'static { + type Output: 'a; +} + + +trait IsCovariant<'a> {} + +struct Yoke Yokeable<'a>> { + data: Y, +} + + +// impl Yokeable<'a>> Yoke { +// fn project Yokeable<'a>>( +// &self, +// f: for<'a> fn(>::Output, &'a (), +// ) -> >::Output) -> Yoke { +// unimplemented!() +// } +// } + +fn upcast(x: Yoke) -> Yoke + 'static>> where + Y: for<'a> Yokeable<'a>, + for<'a> >::Output: IsCovariant<'a> + { + // x.project(|data, _| { + // Box::new(data) + // }) + unimplemented!() +} + + +impl<'a> Yokeable<'a> for Box + 'static> { + type Output = Box + 'a>; +} + +// this impl is mostly an example and unnecessary for the pure repro +use std::borrow::*; +impl<'a, T: ToOwned + ?Sized> Yokeable<'a> for Cow<'static, T> { + type Output = Cow<'a, T>; +} +impl<'a, T: ToOwned + ?Sized> IsCovariant<'a> for Cow<'a, T> {} + + + +fn upcast_yoke(y: Yoke>) -> Yoke + 'static>> { + upcast(y) +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr new file mode 100644 index 00000000000..5be33bccdc3 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `for<'a> <_ as Yokeable<'a>>::Output: IsCovariant<'a>` is not satisfied + --> $DIR/issue-90950.rs:50:12 + | +LL | upcast(y) + | ------ ^ the trait `for<'a> IsCovariant<'a>` is not implemented for `<_ as Yokeable<'a>>::Output` + | | + | required by a bound introduced by this call + | + = help: the trait `IsCovariant<'a>` is implemented for `std::borrow::Cow<'a, T>` +note: required by a bound in `upcast` + --> $DIR/issue-90950.rs:27:42 + | +LL | fn upcast(x: Yoke) -> Yoke + 'static>> where + | ------ required by a bound in this function +LL | Y: for<'a> Yokeable<'a>, +LL | for<'a> >::Output: IsCovariant<'a> + | ^^^^^^^^^^^^^^^ required by this bound in `upcast` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs new file mode 100644 index 00000000000..7693b118247 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs @@ -0,0 +1,23 @@ +// check-fail +// known-bug: #89196 + +// Should pass, but we normalize and check bounds before we resolve the generics +// of the function (which we know because of the return type). + +trait Trait<'a> { + type Out; +} + +impl<'a, T> Trait<'a> for T { + type Out = T; +} + +fn weird_bound() -> X + where + for<'a> X: Trait<'a>, + for<'a> >::Out: Copy +{ todo!() } + +fn main() { + let _: () = weird_bound(); +} diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr new file mode 100644 index 00000000000..73388a72574 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `for<'a> <_ as Trait<'a>>::Out: Copy` is not satisfied + --> $DIR/norm-before-method-resolution.rs:22:17 + | +LL | let _: () = weird_bound(); + | ^^^^^^^^^^^ the trait `for<'a> Copy` is not implemented for `<_ as Trait<'a>>::Out` + | +note: required by a bound in `weird_bound` + --> $DIR/norm-before-method-resolution.rs:18:40 + | +LL | fn weird_bound() -> X + | ----------- required by a bound in this function +... +LL | for<'a> >::Out: Copy + | ^^^^ required by this bound in `weird_bound` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr b/tests/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr deleted file mode 100644 index b7264c7e933..00000000000 --- a/tests/ui/hr-subtype/hr-subtype.bound_a_b_ret_a_vs_bound_a_ret_a.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/hr-subtype.rs:54:13 - | -LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other -... -LL | / check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, -LL | | for<'a> fn(&'a u32, &'a u32) -> &'a u32) } - | |_____________________________________________- in this macro invocation - | - = note: expected enum `Option fn(&'a u32, &'b u32) -> &'a u32>` - found enum `Option fn(&'a u32, &'a u32) -> &'a u32>` - = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr b/tests/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr deleted file mode 100644 index 2355979b0f9..00000000000 --- a/tests/ui/hr-subtype/hr-subtype.bound_a_vs_free_x.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/hr-subtype.rs:54:13 - | -LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other -... -LL | / check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), -LL | | fn(&'x u32)) } - | |______________- in this macro invocation - | - = note: expected enum `Option fn(&'a u32)>` - found enum `Option` - = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr b/tests/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr deleted file mode 100644 index a73c03feb87..00000000000 --- a/tests/ui/hr-subtype/hr-subtype.bound_inv_a_b_vs_bound_inv_a.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/hr-subtype.rs:54:13 - | -LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other -... -LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), -LL | | for<'a> fn(Inv<'a>, Inv<'a>)) } - | |__________________________________- in this macro invocation - | - = note: expected enum `Option fn(Inv<'a>, Inv<'b>)>` - found enum `Option fn(Inv<'a>, Inv<'a>)>` - = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0308]: mismatched types - --> $DIR/hr-subtype.rs:54:13 - | -LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other -... -LL | / check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), -LL | | for<'a> fn(Inv<'a>, Inv<'a>)) } - | |__________________________________- in this macro invocation - | - = note: expected enum `Option fn(Inv<'a>, Inv<'b>)>` - found enum `Option fn(Inv<'a>, Inv<'a>)>` - = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr b/tests/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr deleted file mode 100644 index 31d36d7168b..00000000000 --- a/tests/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr +++ /dev/null @@ -1,42 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/hr-subtype.rs:48:13 - | -LL | fn subtype<'x, 'y: 'x, 'z: 'y>() { - | -- -- lifetime `'y` defined here - | | - | lifetime `'x` defined here -LL | gimme::<$t2>(None::<$t1>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` -... -LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), -LL | | fn(Inv<'y>)) } - | |______________- in this macro invocation - | - = help: consider adding the following bound: `'x: 'y` - = note: requirement occurs because of the type `Inv<'_>`, which makes the generic argument `'_` invariant - = note: the struct `Inv<'a>` is invariant over the parameter `'a` - = help: see for more information about variance - = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: lifetime may not live long enough - --> $DIR/hr-subtype.rs:54:13 - | -LL | fn supertype<'x, 'y: 'x, 'z: 'y>() { - | -- -- lifetime `'y` defined here - | | - | lifetime `'x` defined here -LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` -... -LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), -LL | | fn(Inv<'y>)) } - | |______________- in this macro invocation - | - = help: consider adding the following bound: `'x: 'y` - = note: requirement occurs because of the type `Inv<'_>`, which makes the generic argument `'_` invariant - = note: the struct `Inv<'a>` is invariant over the parameter `'a` - = help: see for more information about variance - = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors - diff --git a/tests/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr b/tests/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr deleted file mode 100644 index 269cde54c7e..00000000000 --- a/tests/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/hr-subtype.rs:54:13 - | -LL | fn supertype<'x, 'y: 'x, 'z: 'y>() { - | -- -- lifetime `'y` defined here - | | - | lifetime `'x` defined here -LL | gimme::<$t1>(None::<$t2>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y` -... -LL | / check! { free_x_vs_free_y: (fn(&'x u32), -LL | | fn(&'y u32)) } - | |______________- in this macro invocation - | - = help: consider adding the following bound: `'x: 'y` - = note: this error originates in the macro `check` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to previous error - diff --git a/tests/ui/hr-subtype/hr-subtype.rs b/tests/ui/hr-subtype/hr-subtype.rs deleted file mode 100644 index c770e0de85c..00000000000 --- a/tests/ui/hr-subtype/hr-subtype.rs +++ /dev/null @@ -1,111 +0,0 @@ -// Targeted tests for the higher-ranked subtyping code. - -#![allow(dead_code)] - -// revisions: bound_a_vs_bound_a -// revisions: bound_a_vs_bound_b -// revisions: bound_inv_a_vs_bound_inv_b -// revisions: bound_co_a_vs_bound_co_b -// revisions: bound_a_vs_free_x -// revisions: free_x_vs_free_x -// revisions: free_x_vs_free_y -// revisions: free_inv_x_vs_free_inv_y -// revisions: bound_a_b_vs_bound_a -// revisions: bound_co_a_b_vs_bound_co_a -// revisions: bound_contra_a_contra_b_ret_co_a -// revisions: bound_co_a_co_b_ret_contra_a -// revisions: bound_inv_a_b_vs_bound_inv_a -// revisions: bound_a_b_ret_a_vs_bound_a_ret_a - -//[bound_a_vs_bound_a] check-pass -//[bound_a_vs_bound_b] check-pass -//[bound_inv_a_vs_bound_inv_b] check-pass -//[bound_co_a_vs_bound_co_b] check-pass -//[free_x_vs_free_x] check-pass -//[bound_co_a_b_vs_bound_co_a] check-pass -//[bound_co_a_co_b_ret_contra_a] check-pass -//[bound_a_b_vs_bound_a] check-pass -//[bound_contra_a_contra_b_ret_co_a] check-pass - -fn gimme(_: Option) {} - -struct Inv<'a> { - x: *mut &'a u32, -} - -struct Co<'a> { - x: fn(&'a u32), -} - -struct Contra<'a> { - x: &'a u32, -} - -macro_rules! check { - ($rev:ident: ($t1:ty, $t2:ty)) => { - #[cfg($rev)] - fn subtype<'x, 'y: 'x, 'z: 'y>() { - gimme::<$t2>(None::<$t1>); - //[free_inv_x_vs_free_inv_y]~^ ERROR - } - - #[cfg($rev)] - fn supertype<'x, 'y: 'x, 'z: 'y>() { - gimme::<$t1>(None::<$t2>); - //[bound_a_vs_free_x]~^ ERROR - //[free_x_vs_free_y]~^^ ERROR - //[bound_inv_a_b_vs_bound_inv_a]~^^^ ERROR - //[bound_inv_a_b_vs_bound_inv_a]~| ERROR - //[bound_a_b_ret_a_vs_bound_a_ret_a]~^^^^^ ERROR - //[free_inv_x_vs_free_inv_y]~^^^^^^ ERROR - } - }; -} - -// If both have bound regions, they are equivalent, regardless of -// variant. -check! { bound_a_vs_bound_a: (for<'a> fn(&'a u32), -for<'a> fn(&'a u32)) } -check! { bound_a_vs_bound_b: (for<'a> fn(&'a u32), -for<'b> fn(&'b u32)) } -check! { bound_inv_a_vs_bound_inv_b: (for<'a> fn(Inv<'a>), -for<'b> fn(Inv<'b>)) } -check! { bound_co_a_vs_bound_co_b: (for<'a> fn(Co<'a>), -for<'b> fn(Co<'b>)) } - -// Bound is a subtype of free. -check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), -fn(&'x u32)) } - -// Two free regions are relatable if subtyping holds. -check! { free_x_vs_free_x: (fn(&'x u32), -fn(&'x u32)) } -check! { free_x_vs_free_y: (fn(&'x u32), -fn(&'y u32)) } -check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), -fn(Inv<'y>)) } - -// Somewhat surprisingly, a fn taking two distinct bound lifetimes and -// a fn taking one bound lifetime can be interchangeable, but only if -// we are co- or contra-variant with respect to both lifetimes. -// -// The reason is: -// - if we are covariant, then 'a and 'b can be set to the call-site -// intersection; -// - if we are contravariant, then 'a can be inferred to 'static. -check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32), -for<'a> fn(&'a u32, &'a u32)) } -check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>), -for<'a> fn(Co<'a>, Co<'a>)) } -check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>, -for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) } -check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>, -for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) } - -// If we make those lifetimes invariant, then the two types are not interchangeable. -check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), -for<'a> fn(Inv<'a>, Inv<'a>)) } -check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, -for<'a> fn(&'a u32, &'a u32) -> &'a u32) } - -fn main() {} diff --git a/tests/ui/hr-subtype/placeholder-pattern-fail.rs b/tests/ui/hr-subtype/placeholder-pattern-fail.rs deleted file mode 100644 index bd4533e0433..00000000000 --- a/tests/ui/hr-subtype/placeholder-pattern-fail.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Check that incorrect higher ranked subtyping -// causes an error. -struct Inv<'a>(fn(&'a ()) -> &'a ()); -fn hr_subtype<'c>(f: for<'a, 'b> fn(Inv<'a>, Inv<'a>)) { - // ok - let _: for<'a> fn(Inv<'a>, Inv<'a>) = f; - let sub: for<'a> fn(Inv<'a>, Inv<'a>) = f; - // no - let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; - //~^ ERROR mismatched types -} - -fn simple1<'c>(x: (&'c i32,)) { - let _x: (&'static i32,) = x; -} - -fn simple2<'c>(x: (&'c i32,)) { - let _: (&'static i32,) = x; -} - -fn main() { - hr_subtype(|_, _| {}); - simple1((&3,)); - simple2((&3,)); -} diff --git a/tests/ui/hr-subtype/placeholder-pattern-fail.stderr b/tests/ui/hr-subtype/placeholder-pattern-fail.stderr deleted file mode 100644 index 73b0a317364..00000000000 --- a/tests/ui/hr-subtype/placeholder-pattern-fail.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/placeholder-pattern-fail.rs:9:47 - | -LL | let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub; - | ^^^ one type is more general than the other - | - = note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)` - found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/hr-subtype/placeholder-pattern.rs b/tests/ui/hr-subtype/placeholder-pattern.rs deleted file mode 100644 index 061e66e54d2..00000000000 --- a/tests/ui/hr-subtype/placeholder-pattern.rs +++ /dev/null @@ -1,18 +0,0 @@ -// check-pass -// Check that higher ranked subtyping correctly works when using -// placeholder patterns. -fn hr_subtype<'c>(f: for<'a, 'b> fn(&'a (), &'b ())) { - let _: for<'a> fn(&'a (), &'a ()) = f; - let _: for<'a, 'b> fn(&'a (), &'b ()) = f; - let _: for<'a> fn(&'a (), &'c ()) = f; - let _: fn(&'c (), &'c ()) = f; -} - -fn simple<'c>(x: (&'static i32,)) { - let _: (&'c i32,) = x; -} - -fn main() { - hr_subtype(|_, _| {}); - simple((&3,)); -} diff --git a/tests/ui/hr-subtype/return-static.rs b/tests/ui/hr-subtype/return-static.rs deleted file mode 100644 index 6455854f34d..00000000000 --- a/tests/ui/hr-subtype/return-static.rs +++ /dev/null @@ -1,13 +0,0 @@ -// check-pass - -fn make() -> T { - panic!() -} - -fn take(x: T) {} - -fn main() { - let x: for<'a> fn(&'a u32) -> _ = make(); - let y: &'static u32 = x(&22); - take:: fn(&'b u32) -> &'b u32>(x); -} -- cgit 1.4.1-3-g733a5

(processor: P) -> Task -where P: Execute + 'static { - Task { - _processor: Box::new(move || { - let q = P::E::inject(&()); - processor.execute(q); - }) - } -} - -fn main() { - task(annotate( - Annotate::>::new(), - |value: &mut usize| { - *value = 2; - } - )); -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-2.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-2.rs deleted file mode 100644 index 00205473291..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-2.rs +++ /dev/null @@ -1,33 +0,0 @@ -// check-pass - -use std::marker::PhantomData; - -trait Lt<'a> { - type T; -} -struct Id(PhantomData); -impl<'a,T> Lt<'a> for Id { - type T = T; -} - -struct Ref(PhantomData) where T: ?Sized; -impl<'a,T> Lt<'a> for Ref -where T: 'a + Lt<'a> + ?Sized -{ - type T = &'a T; -} -struct Mut(PhantomData) where T: ?Sized; -impl<'a,T> Lt<'a> for Mut -where T: 'a + Lt<'a> + ?Sized -{ - type T = &'a mut T; -} - -struct C(for<'a> fn(>::T) -> O) where I: for<'a> Lt<'a>; - - -fn main() { - let c = C::,_>(|()| 3); - c.0(()); - -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.rs deleted file mode 100644 index d84e30f4984..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.rs +++ /dev/null @@ -1,32 +0,0 @@ -trait ATC<'a> { - type Type: Sized; -} - -trait WithDefault: for<'a> ATC<'a> { - fn with_default Fn(>::Type)>(f: F); -} - -fn call<'b, T: for<'a> ATC<'a>, F: for<'a> Fn(>::Type)>( - f: F, - x: >::Type, -) { - f(x); -} - -impl<'a> ATC<'a> for () { - type Type = Self; -} - -impl WithDefault for () { - fn with_default Fn(>::Type)>(f: F) { - // Errors with a bogus type mismatch. - //f(()); - // Going through another generic function works fine. - call(f, ()); - //~^ expected a - } -} - -fn main() { - // <()>::with_default(|_| {}); -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr deleted file mode 100644 index b30dd36d2ad..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-3.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` - --> $DIR/issue-62529-3.rs:25:14 - | -LL | call(f, ()); - | ---- ^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F` - | | - | required by a bound introduced by this call - | - = note: expected a closure with arguments `((),)` - found a closure with arguments `(<_ as ATC<'a>>::Type,)` -note: required by a bound in `call` - --> $DIR/issue-62529-3.rs:9:36 - | -LL | fn call<'b, T: for<'a> ATC<'a>, F: for<'a> Fn(>::Type)>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `call` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-4.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-4.rs deleted file mode 100644 index 8c2a59868ca..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-4.rs +++ /dev/null @@ -1,39 +0,0 @@ -// check-pass - -use std::marker::PhantomData; -use std::mem; - -trait Container<'a> { - type Root: 'a; -} - -type RootOf<'a, T> = >::Root; - -struct Test<'a, T> where T: Container<'a> { - pub root: T::Root, - marker: PhantomData<&'a mut &'a mut ()>, -} - -impl<'a, 'b> Container<'b> for &'a str { - type Root = &'b str; -} - -impl<'a, T> Test<'a, T> where T: for<'b> Container<'b> { - fn new(root: RootOf<'a, T>) -> Test<'a, T> { - Test { - root: root, - marker: PhantomData - } - } - - fn with_mut(&mut self, f: F) -> R where - F: for<'b> FnOnce(&'b mut RootOf<'b, T>) -> R { - f(unsafe { mem::transmute(&mut self.root) }) - } -} - -fn main() { - let val = "root"; - let mut test: Test<&str> = Test::new(val); - test.with_mut(|_| { }); -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-5.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-5.rs deleted file mode 100644 index 03f257a029c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-5.rs +++ /dev/null @@ -1,27 +0,0 @@ -// check-pass - -pub struct Struct {} - -pub trait Trait<'a> { - type Assoc; - - fn method() -> Self::Assoc; -} - -impl<'a> Trait<'a> for Struct { - type Assoc = (); - - fn method() -> Self::Assoc {} -} - -pub fn function(f: F) -where - F: for<'a> FnOnce(>::Assoc), - T: for<'b> Trait<'b>, -{ - f(T::method()); -} - -fn main() { - function::<_, Struct>(|_| {}); -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-6.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-6.rs deleted file mode 100644 index 74a4785e478..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-6.rs +++ /dev/null @@ -1,77 +0,0 @@ -// check-pass - -use std::cell::RefMut; - -fn main() { - StateMachine2::Init.resume(); -} - -enum StateMachine2<'a> { - Init, - #[allow(dead_code)] // match required for ICE - AfterTwoYields { - p: Backed<'a, *mut String>, - }, -} - -impl<'a> StateMachine2<'a> { - fn take(&self) -> Self { - StateMachine2::Init - } -} - -impl<'a> StateMachine2<'a> { - fn resume(&mut self) -> () { - use StateMachine2::*; - match self.take() { - AfterTwoYields { p } => { - p.with(|_| {}); - } - _ => panic!("Resume after completed."), - } - } -} - -unsafe trait Unpack<'a> { - type Unpacked: 'a; - - fn unpack(&self) -> Self::Unpacked { - unsafe { std::mem::transmute_copy(&self) } - } -} - -unsafe trait Pack { - type Packed; - - fn pack(&self) -> Self::Packed { - unsafe { std::mem::transmute_copy(&self) } - } -} - -unsafe impl<'a> Unpack<'a> for String { - type Unpacked = String; -} - -unsafe impl Pack for String { - type Packed = String; -} - -unsafe impl<'a> Unpack<'a> for *mut String { - type Unpacked = &'a mut String; -} - -unsafe impl<'a> Pack for &'a mut String { - type Packed = *mut String; -} - -struct Backed<'a, U>(RefMut<'a, Option>, U); - -impl<'a, 'b, U: Unpack<'b>> Backed<'a, U> { - fn with(self, f: F) -> Backed<'a, ()> - where - F: for<'f> FnOnce(>::Unpacked) -> (), - { - let result = f(self.1.unpack()); - Backed(self.0, result) - } -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.rs deleted file mode 100644 index 3ced40230f0..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.rs +++ /dev/null @@ -1,31 +0,0 @@ -// check-pass - -pub trait MyTrait<'a> { - type Output: 'a; - fn gimme_value(&self) -> Self::Output; -} - -pub struct MyStruct; - -impl<'a> MyTrait<'a> for MyStruct { - type Output = &'a usize; - fn gimme_value(&self) -> Self::Output { - unimplemented!() - } -} - -fn meow(t: T, f: F) -where - T: for<'any> MyTrait<'any>, - F: for<'any2> Fn(>::Output), -{ - let v = t.gimme_value(); - f(v); -} - -fn main() { - let struc = MyStruct; - meow(struc, |foo| { - println!("{:?}", foo); - }) -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr deleted file mode 100644 index 0f38f8e3283..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr +++ /dev/null @@ -1,79 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:54:5 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r, 's> FnOnce<(&'r &'s str,)>` - found type `for<'r> FnOnce<(&'r &str,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:54:24 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:9 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:54:5 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `FnOnce<(&&str,)>` - found type `for<'r> FnOnce<(&'r &str,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:54:24 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:44 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:58:5 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r, 's> FnOnce<(&'r Wrapper<'s>,)>` - found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:58:24 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:9 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:58:5 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `FnOnce<(&Wrapper<'_>,)>` - found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:58:24 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:44 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^ - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs deleted file mode 100644 index 1d90226a3f4..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs +++ /dev/null @@ -1,51 +0,0 @@ -// check-fail -#![feature(rustc_attrs)] - -trait Parser<'s> { - type Output; - - fn call(&self, input: &'s str) -> (&'s str, Self::Output); -} - -impl<'s, F, T> Parser<'s> for F -where F: Fn(&'s str) -> (&'s str, T) { - type Output = T; - fn call(&self, input: &'s str) -> (&'s str, T) { - self(input) - } -} - -fn foo( - f1: F1, - base: &'static str, - f2: F2 -) -where - F1: for<'a> Parser<'a>, - F2: FnOnce(&::Output) -> bool -{ - let s: String = base.to_owned(); - let str_ref = s.as_ref(); - let (remaining, produced) = f1.call(str_ref); - assert!(f2(&produced)); - assert_eq!(remaining.len(), 0); -} - -struct Wrapper<'a>(&'a str); - -fn main() { - fn bar<'a>(s: &'a str) -> (&'a str, &'a str) { - (&s[..1], &s[..]) - } - - fn baz<'a>(s: &'a str) -> (&'a str, Wrapper<'a>) { - (&s[..1], Wrapper(&s[..])) - } - - foo(bar, "string", |s| s.len() == 5); - //~^ ERROR mismatched types - //~| ERROR mismatched types - foo(baz, "string", |s| s.0.len() == 5); - //~^ ERROR mismatched types - //~| ERROR mismatched types -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.stderr deleted file mode 100644 index 4ef96cd9541..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.stderr +++ /dev/null @@ -1,79 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:45:5 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce<(&'a &'b str,)>` - found trait `for<'a> FnOnce<(&'a &str,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:45:24 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:25:9 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:45:5 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce<(&'a &'b str,)>` - found trait `for<'a> FnOnce<(&'a &str,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:45:24 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:25:44 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:48:5 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce<(&'a Wrapper<'b>,)>` - found trait `for<'a> FnOnce<(&'a Wrapper<'_>,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:48:24 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:25:9 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:48:5 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected trait `for<'a, 'b> FnOnce<(&'a Wrapper<'b>,)>` - found trait `for<'a> FnOnce<(&'a Wrapper<'_>,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:48:24 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:25:44 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^ - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs deleted file mode 100644 index 93ccb42684c..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-74261.rs +++ /dev/null @@ -1,30 +0,0 @@ -// check-pass - -use std::marker::PhantomData; - -trait A<'a> { - type B; - fn b(self) -> Self::B; -} - -struct T; -struct S<'a>(PhantomData<&'a ()>); - -impl<'a> A<'a> for T { - type B = S<'a>; - fn b(self) -> Self::B { - S(PhantomData) - } -} - -fn s(t: TT, f: F) -where - TT: for<'a> A<'a>, - F: for<'a> FnOnce(>::B) -{ - f(t.b()); -} - -fn main() { - s(T, |_| {}); -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-76956.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-76956.rs deleted file mode 100644 index 583470080a2..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-76956.rs +++ /dev/null @@ -1,15 +0,0 @@ -// check-pass - -use std::ops::Deref; - -struct Data { - boxed: Box<&'static i32> -} - -impl Data { - fn use_data(&self, user: impl for <'a> FnOnce( as Deref>::Target)) { - user(*self.boxed) - } -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80706.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80706.rs deleted file mode 100644 index 00a866f220b..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80706.rs +++ /dev/null @@ -1,71 +0,0 @@ -// build-pass -// edition:2018 - -type BoxFuture = std::pin::Pin>>; - -fn main() { - f(); -} - -async fn f() { - run("dependency").await; -} - -struct InMemoryStorage; - -struct User<'dep> { - dep: &'dep str, -} - -impl<'a> StorageRequest for SaveUser<'a> { - fn execute(&self) -> BoxFuture> { - todo!() - } -} - -trait Storage { - type Error; -} - -impl Storage for InMemoryStorage { - type Error = String; -} - -trait StorageRequestReturnType { - type Output; -} - -trait StorageRequest: StorageRequestReturnType { - fn execute( - &self, - ) -> BoxFuture::Output, ::Error>>; -} - -struct SaveUser<'a> { - name: &'a str, -} - -impl<'a> StorageRequestReturnType for SaveUser<'a> { - type Output = (); -} - -impl<'dep> User<'dep> { - async fn save(self) - where - S: Storage, - for<'a> SaveUser<'a>: StorageRequest, - { - SaveUser { name: "Joe" } - .execute() - .await; - } -} - -async fn run(dep: &str) -where - S: Storage, - for<'a> SaveUser<'a>: StorageRequest, - for<'a> SaveUser<'a>: StorageRequestReturnType, -{ - User { dep }.save().await; -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80956.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80956.rs deleted file mode 100644 index 6316ceea156..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80956.rs +++ /dev/null @@ -1,21 +0,0 @@ -// check-pass - -trait Bar { - type Type; -} -struct Foo<'a>(&'a ()); -impl<'a> Bar for Foo<'a> { - type Type = (); -} - -fn func<'a>(_: as Bar>::Type) {} -fn assert_is_func(_: fn(A)) {} - -fn test() -where - for<'a> as Bar>::Type: Sized, -{ - assert_is_func(func); -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-81809.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-81809.rs deleted file mode 100644 index f6ab9c203b5..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-81809.rs +++ /dev/null @@ -1,21 +0,0 @@ -// check-pass - -pub trait Indexable { - type Idx; -} -impl Indexable for u8 { - type Idx = u8; -} -impl Indexable for u16 { - type Idx = u16; -} - -pub trait Indexer: std::ops::Index {} - -trait StoreIndex: Indexer + Indexer {} - -fn foo(st: &impl StoreIndex) -> &dyn StoreIndex { - st as &dyn StoreIndex -} - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs deleted file mode 100644 index 8aa29926d4f..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![feature(unboxed_closures)] - -trait SomeTrait<'a> { - type Associated; -} - -fn give_me_ice() { - callee:: >::Associated>(); - //~^ ERROR the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied [E0277] - //~| ERROR the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied [E0277] -} - -fn callee>() { - println!("{}", std::any::type_name::<>::Output>()); -} - -fn main() { - give_me_ice::<()>(); -} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr deleted file mode 100644 index 3240518fbbe..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error[E0277]: the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied - --> $DIR/issue-85455.rs:8:14 - | -LL | callee:: >::Associated>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> SomeTrait<'a>` is not implemented for `T` - | -help: consider restricting type parameter `T` - | -LL | fn give_me_ice SomeTrait<'a>>() { - | +++++++++++++++++++++++ - -error[E0277]: the trait bound `for<'a> T: SomeTrait<'a>` is not satisfied - --> $DIR/issue-85455.rs:8:5 - | -LL | callee:: >::Associated>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> SomeTrait<'a>` is not implemented for `T` - | -help: consider restricting type parameter `T` - | -LL | fn give_me_ice SomeTrait<'a>>() { - | +++++++++++++++++++++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs deleted file mode 100644 index fffb54f86ca..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.rs +++ /dev/null @@ -1,32 +0,0 @@ -trait BufferMut {} -struct Ctx(D); - -trait BufferUdpStateContext {} -impl BufferUdpStateContext for C {} - -trait StackContext -where - Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>, -{ - type Dispatcher; -} - -trait TimerContext { - type Handler; -} -impl TimerContext for C -where - C: StackContext, - //~^ ERROR: is not satisfied [E0277] -{ - type Handler = Ctx; - //~^ ERROR: is not satisfied [E0277] -} - -struct EthernetWorker(C) -where - Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>; -impl EthernetWorker {} -//~^ ERROR: is not satisfied [E0277] - -fn main() {} diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr deleted file mode 100644 index edef6ccd34e..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr +++ /dev/null @@ -1,69 +0,0 @@ -error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied - --> $DIR/issue-89118.rs:19:8 - | -LL | C: StackContext, - | ^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` - | -note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` - --> $DIR/issue-89118.rs:5:23 - | -LL | impl BufferUdpStateContext for C {} - | --------- ^^^^^^^^^^^^^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `StackContext` - --> $DIR/issue-89118.rs:9:14 - | -LL | trait StackContext - | ------------ required by a bound in this trait -LL | where -LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext` - -error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied - --> $DIR/issue-89118.rs:29:9 - | -LL | impl EthernetWorker {} - | ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` - | -note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` - --> $DIR/issue-89118.rs:5:23 - | -LL | impl BufferUdpStateContext for C {} - | --------- ^^^^^^^^^^^^^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `EthernetWorker` - --> $DIR/issue-89118.rs:28:14 - | -LL | struct EthernetWorker(C) - | -------------- required by a bound in this struct -LL | where -LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `EthernetWorker` - -error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied - --> $DIR/issue-89118.rs:22:20 - | -LL | type Handler = Ctx; - | ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()` - | -note: required for `Ctx<()>` to implement `for<'a> BufferUdpStateContext<&'a ()>` - --> $DIR/issue-89118.rs:5:23 - | -LL | impl BufferUdpStateContext for C {} - | --------- ^^^^^^^^^^^^^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `StackContext` - --> $DIR/issue-89118.rs:9:14 - | -LL | trait StackContext - | ------------ required by a bound in this trait -LL | where -LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs deleted file mode 100644 index f7e467b3786..00000000000 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89436.rs +++ /dev/null @@ -1,44 +0,0 @@ -// check-pass - -#![allow(unused)] - -trait MiniYokeable<'a> { - type Output; -} - -struct MiniYoke MiniYokeable<'a>> { - pub yokeable: Y, -} - -fn map_project_broken( - source: MiniYoke, - f: impl for<'a> FnOnce( - >::Output, - core::marker::PhantomData<&'a ()>, - ) ->