summaryrefslogtreecommitdiffstats
path: root/tests/ui/generic-associated-types
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/generic-associated-types')
-rw-r--r--tests/ui/generic-associated-types/anonymize-bound-vars.rs13
-rw-r--r--tests/ui/generic-associated-types/auxiliary/foo_defn.rs6
-rw-r--r--tests/ui/generic-associated-types/bugs/hrtb-implied-1.rs34
-rw-r--r--tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr20
-rw-r--r--tests/ui/generic-associated-types/bugs/hrtb-implied-2.rs39
-rw-r--r--tests/ui/generic-associated-types/bugs/hrtb-implied-2.stderr22
-rw-r--r--tests/ui/generic-associated-types/bugs/hrtb-implied-3.rs23
-rw-r--r--tests/ui/generic-associated-types/bugs/hrtb-implied-3.stderr22
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-100013.rs35
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-100013.stderr78
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-80626.rs12
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-87735.rs44
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-87735.stderr9
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-87755.rs19
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-87755.stderr9
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-87803.rs25
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-87803.stderr12
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88382.rs29
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88382.stderr22
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88460.rs29
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88460.stderr21
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88526.rs33
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88526.stderr9
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-91762.rs28
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-91762.stderr14
-rw-r--r--tests/ui/generic-associated-types/collections-project-default.rs70
-rw-r--r--tests/ui/generic-associated-types/collections-project-default.stderr15
-rw-r--r--tests/ui/generic-associated-types/collections.rs69
-rw-r--r--tests/ui/generic-associated-types/collectivity-regression.rs22
-rw-r--r--tests/ui/generic-associated-types/collectivity-regression.stderr24
-rw-r--r--tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs20
-rw-r--r--tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs20
-rw-r--r--tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs25
-rw-r--r--tests/ui/generic-associated-types/const_params_have_right_type.rs10
-rw-r--r--tests/ui/generic-associated-types/const_params_have_right_type.stderr16
-rw-r--r--tests/ui/generic-associated-types/constraint-assoc-type-suggestion.rs14
-rw-r--r--tests/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr18
-rw-r--r--tests/ui/generic-associated-types/construct_with_other_type.rs22
-rw-r--r--tests/ui/generic-associated-types/cross-crate-bounds.rs32
-rw-r--r--tests/ui/generic-associated-types/cross-crate-bounds.stderr15
-rw-r--r--tests/ui/generic-associated-types/elided-in-expr-position.rs37
-rw-r--r--tests/ui/generic-associated-types/elided-in-expr-position.stderr35
-rw-r--r--tests/ui/generic-associated-types/empty_generics.rs6
-rw-r--r--tests/ui/generic-associated-types/empty_generics.stderr13
-rw-r--r--tests/ui/generic-associated-types/equality-bound.rs15
-rw-r--r--tests/ui/generic-associated-types/equality-bound.stderr43
-rw-r--r--tests/ui/generic-associated-types/extended/lending_iterator.base.stderr12
-rw-r--r--tests/ui/generic-associated-types/extended/lending_iterator.rs38
-rw-r--r--tests/ui/generic-associated-types/extended/lending_iterator_2.base.stderr12
-rw-r--r--tests/ui/generic-associated-types/extended/lending_iterator_2.rs30
-rw-r--r--tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs9
-rw-r--r--tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr26
-rw-r--r--tests/ui/generic-associated-types/gat-in-trait-path.base.stderr18
-rw-r--r--tests/ui/generic-associated-types/gat-in-trait-path.rs33
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs14
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr25
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs15
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr35
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs16
-rw-r--r--tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr74
-rw-r--r--tests/ui/generic-associated-types/generic-associated-type-bounds.rs32
-rw-r--r--tests/ui/generic-associated-types/generic-associated-types-where.rs26
-rw-r--r--tests/ui/generic-associated-types/generic-associated-types-where.stderr25
-rw-r--r--tests/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs13
-rw-r--r--tests/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr38
-rw-r--r--tests/ui/generic-associated-types/impl_bounds.rs24
-rw-r--r--tests/ui/generic-associated-types/impl_bounds.stderr77
-rw-r--r--tests/ui/generic-associated-types/impl_bounds_ok.rs29
-rw-r--r--tests/ui/generic-associated-types/issue-101020.rs35
-rw-r--r--tests/ui/generic-associated-types/issue-101020.stderr23
-rw-r--r--tests/ui/generic-associated-types/issue-102114.rs16
-rw-r--r--tests/ui/generic-associated-types/issue-102114.stderr12
-rw-r--r--tests/ui/generic-associated-types/issue-102333.rs15
-rw-r--r--tests/ui/generic-associated-types/issue-102335-gat.rs12
-rw-r--r--tests/ui/generic-associated-types/issue-102335-gat.stderr9
-rw-r--r--tests/ui/generic-associated-types/issue-47206-where-clause.rs14
-rw-r--r--tests/ui/generic-associated-types/issue-47206-where-clause.stderr12
-rw-r--r--tests/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs7
-rw-r--r--tests/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs11
-rw-r--r--tests/ui/generic-associated-types/issue-67424.rs12
-rw-r--r--tests/ui/generic-associated-types/issue-67510-pass.base.stderr18
-rw-r--r--tests/ui/generic-associated-types/issue-67510-pass.rs15
-rw-r--r--tests/ui/generic-associated-types/issue-67510.rs10
-rw-r--r--tests/ui/generic-associated-types/issue-67510.stderr50
-rw-r--r--tests/ui/generic-associated-types/issue-68641-check-gat-bounds.rs29
-rw-r--r--tests/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr19
-rw-r--r--tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs18
-rw-r--r--tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr20
-rw-r--r--tests/ui/generic-associated-types/issue-68643-broken-mir.rs18
-rw-r--r--tests/ui/generic-associated-types/issue-68643-broken-mir.stderr20
-rw-r--r--tests/ui/generic-associated-types/issue-68644-codegen-selection.rs18
-rw-r--r--tests/ui/generic-associated-types/issue-68644-codegen-selection.stderr20
-rw-r--r--tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs18
-rw-r--r--tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr20
-rw-r--r--tests/ui/generic-associated-types/issue-68648-1.rs22
-rw-r--r--tests/ui/generic-associated-types/issue-68648-2.rs21
-rw-r--r--tests/ui/generic-associated-types/issue-68648-2.stderr21
-rw-r--r--tests/ui/generic-associated-types/issue-68649-pass.rs22
-rw-r--r--tests/ui/generic-associated-types/issue-68653.rs13
-rw-r--r--tests/ui/generic-associated-types/issue-68656-unsized-values.rs19
-rw-r--r--tests/ui/generic-associated-types/issue-68656-unsized-values.stderr23
-rw-r--r--tests/ui/generic-associated-types/issue-70303.rs57
-rw-r--r--tests/ui/generic-associated-types/issue-70304.rs55
-rw-r--r--tests/ui/generic-associated-types/issue-70304.stderr33
-rw-r--r--tests/ui/generic-associated-types/issue-71176.rs18
-rw-r--r--tests/ui/generic-associated-types/issue-71176.stderr19
-rw-r--r--tests/ui/generic-associated-types/issue-74684-1.rs23
-rw-r--r--tests/ui/generic-associated-types/issue-74684-1.stderr18
-rw-r--r--tests/ui/generic-associated-types/issue-74684-2.rs23
-rw-r--r--tests/ui/generic-associated-types/issue-74684-2.stderr22
-rw-r--r--tests/ui/generic-associated-types/issue-74816.rs21
-rw-r--r--tests/ui/generic-associated-types/issue-74816.stderr35
-rw-r--r--tests/ui/generic-associated-types/issue-74824.rs25
-rw-r--r--tests/ui/generic-associated-types/issue-74824.stderr33
-rw-r--r--tests/ui/generic-associated-types/issue-76407.rs25
-rw-r--r--tests/ui/generic-associated-types/issue-76535.base.stderr52
-rw-r--r--tests/ui/generic-associated-types/issue-76535.extended.stderr19
-rw-r--r--tests/ui/generic-associated-types/issue-76535.rs43
-rw-r--r--tests/ui/generic-associated-types/issue-76826.rs42
-rw-r--r--tests/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs38
-rw-r--r--tests/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr87
-rw-r--r--tests/ui/generic-associated-types/issue-78671.base.stderr35
-rw-r--r--tests/ui/generic-associated-types/issue-78671.extended.stderr19
-rw-r--r--tests/ui/generic-associated-types/issue-78671.rs17
-rw-r--r--tests/ui/generic-associated-types/issue-79422.base.stderr52
-rw-r--r--tests/ui/generic-associated-types/issue-79422.extended.stderr35
-rw-r--r--tests/ui/generic-associated-types/issue-79422.rs50
-rw-r--r--tests/ui/generic-associated-types/issue-79636-1.rs21
-rw-r--r--tests/ui/generic-associated-types/issue-79636-1.stderr19
-rw-r--r--tests/ui/generic-associated-types/issue-79636-2.rs15
-rw-r--r--tests/ui/generic-associated-types/issue-79636-2.stderr19
-rw-r--r--tests/ui/generic-associated-types/issue-80433-reduced.rs21
-rw-r--r--tests/ui/generic-associated-types/issue-80433.rs32
-rw-r--r--tests/ui/generic-associated-types/issue-80433.stderr19
-rw-r--r--tests/ui/generic-associated-types/issue-81487.rs17
-rw-r--r--tests/ui/generic-associated-types/issue-81712-cyclic-traits.rs18
-rw-r--r--tests/ui/generic-associated-types/issue-81712-cyclic-traits.stderr19
-rw-r--r--tests/ui/generic-associated-types/issue-81862.rs10
-rw-r--r--tests/ui/generic-associated-types/issue-81862.stderr19
-rw-r--r--tests/ui/generic-associated-types/issue-84931.rs21
-rw-r--r--tests/ui/generic-associated-types/issue-84931.stderr11
-rw-r--r--tests/ui/generic-associated-types/issue-85921.rs17
-rw-r--r--tests/ui/generic-associated-types/issue-86218-2.rs23
-rw-r--r--tests/ui/generic-associated-types/issue-86218.rs24
-rw-r--r--tests/ui/generic-associated-types/issue-86483.rs14
-rw-r--r--tests/ui/generic-associated-types/issue-86787.rs37
-rw-r--r--tests/ui/generic-associated-types/issue-86787.stderr13
-rw-r--r--tests/ui/generic-associated-types/issue-87258_a.rs24
-rw-r--r--tests/ui/generic-associated-types/issue-87258_a.stderr10
-rw-r--r--tests/ui/generic-associated-types/issue-87258_b.rs26
-rw-r--r--tests/ui/generic-associated-types/issue-87258_b.stderr10
-rw-r--r--tests/ui/generic-associated-types/issue-87429-2.rs18
-rw-r--r--tests/ui/generic-associated-types/issue-87429-associated-type-default.rs17
-rw-r--r--tests/ui/generic-associated-types/issue-87429-associated-type-default.stderr20
-rw-r--r--tests/ui/generic-associated-types/issue-87429-specialization.rs24
-rw-r--r--tests/ui/generic-associated-types/issue-87429-specialization.stderr30
-rw-r--r--tests/ui/generic-associated-types/issue-87429.rs13
-rw-r--r--tests/ui/generic-associated-types/issue-87748.rs21
-rw-r--r--tests/ui/generic-associated-types/issue-87750.rs24
-rw-r--r--tests/ui/generic-associated-types/issue-88287.rs39
-rw-r--r--tests/ui/generic-associated-types/issue-88287.stderr27
-rw-r--r--tests/ui/generic-associated-types/issue-88360.rs18
-rw-r--r--tests/ui/generic-associated-types/issue-88360.stderr20
-rw-r--r--tests/ui/generic-associated-types/issue-88405.rs14
-rw-r--r--tests/ui/generic-associated-types/issue-88459.rs17
-rw-r--r--tests/ui/generic-associated-types/issue-88595.rs21
-rw-r--r--tests/ui/generic-associated-types/issue-88595.stderr16
-rw-r--r--tests/ui/generic-associated-types/issue-89008.rs37
-rw-r--r--tests/ui/generic-associated-types/issue-89352.rs30
-rw-r--r--tests/ui/generic-associated-types/issue-90014.rs21
-rw-r--r--tests/ui/generic-associated-types/issue-90014.stderr22
-rw-r--r--tests/ui/generic-associated-types/issue-90729.rs36
-rw-r--r--tests/ui/generic-associated-types/issue-91139.migrate.stderr8
-rw-r--r--tests/ui/generic-associated-types/issue-91139.rs27
-rw-r--r--tests/ui/generic-associated-types/issue-91139.stderr14
-rw-r--r--tests/ui/generic-associated-types/issue-91883.rs40
-rw-r--r--tests/ui/generic-associated-types/issue-91883.stderr27
-rw-r--r--tests/ui/generic-associated-types/issue-92033.rs37
-rw-r--r--tests/ui/generic-associated-types/issue-92033.stderr22
-rw-r--r--tests/ui/generic-associated-types/issue-92096.migrate.stderr24
-rw-r--r--tests/ui/generic-associated-types/issue-92096.rs28
-rw-r--r--tests/ui/generic-associated-types/issue-92096.stderr8
-rw-r--r--tests/ui/generic-associated-types/issue-92280.rs24
-rw-r--r--tests/ui/generic-associated-types/issue-92954.rs8
-rw-r--r--tests/ui/generic-associated-types/issue-93141.rs23
-rw-r--r--tests/ui/generic-associated-types/issue-93262.rs19
-rw-r--r--tests/ui/generic-associated-types/issue-93340.rs18
-rw-r--r--tests/ui/generic-associated-types/issue-93341.rs54
-rw-r--r--tests/ui/generic-associated-types/issue-93342.rs55
-rw-r--r--tests/ui/generic-associated-types/issue-93874.rs33
-rw-r--r--tests/ui/generic-associated-types/issue-95305.rs19
-rw-r--r--tests/ui/generic-associated-types/issue-95305.stderr9
-rw-r--r--tests/ui/generic-associated-types/iterable.rs44
-rw-r--r--tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs33
-rw-r--r--tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr24
-rw-r--r--tests/ui/generic-associated-types/mismatched-where-clause-regions.rs12
-rw-r--r--tests/ui/generic-associated-types/mismatched-where-clause-regions.stderr17
-rw-r--r--tests/ui/generic-associated-types/missing-bounds.fixed46
-rw-r--r--tests/ui/generic-associated-types/missing-bounds.rs46
-rw-r--r--tests/ui/generic-associated-types/missing-bounds.stderr105
-rw-r--r--tests/ui/generic-associated-types/missing-where-clause-on-trait.rs11
-rw-r--r--tests/ui/generic-associated-types/missing-where-clause-on-trait.stderr18
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_args.rs20
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_args.stderr55
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_const.rs10
-rw-r--r--tests/ui/generic-associated-types/missing_lifetime_const.stderr19
-rw-r--r--tests/ui/generic-associated-types/own-bound-span.rs17
-rw-r--r--tests/ui/generic-associated-types/own-bound-span.stderr15
-rw-r--r--tests/ui/generic-associated-types/parameter_number_and_kind.rs18
-rw-r--r--tests/ui/generic-associated-types/parameter_number_and_kind.stderr47
-rw-r--r--tests/ui/generic-associated-types/parameter_number_and_kind_impl.rs33
-rw-r--r--tests/ui/generic-associated-types/parameter_number_and_kind_impl.stderr62
-rw-r--r--tests/ui/generic-associated-types/parse/in-trait-impl.rs8
-rw-r--r--tests/ui/generic-associated-types/parse/in-trait.rs22
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-expected-token.rs8
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-expected-token.stderr10
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-expressions.rs20
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-expressions.stderr23
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs18
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr43
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-segments.rs32
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-segments.stderr41
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs11
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr33
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-types.rs20
-rw-r--r--tests/ui/generic-associated-types/parse/trait-path-types.stderr41
-rw-r--r--tests/ui/generic-associated-types/pointer_family.rs34
-rw-r--r--tests/ui/generic-associated-types/projection-bound-cycle-generic.rs59
-rw-r--r--tests/ui/generic-associated-types/projection-bound-cycle-generic.stderr9
-rw-r--r--tests/ui/generic-associated-types/projection-bound-cycle.rs62
-rw-r--r--tests/ui/generic-associated-types/projection-bound-cycle.stderr9
-rw-r--r--tests/ui/generic-associated-types/projection-type-lifetime-mismatch.rs33
-rw-r--r--tests/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr26
-rw-r--r--tests/ui/generic-associated-types/self-outlives-lint.rs224
-rw-r--r--tests/ui/generic-associated-types/self-outlives-lint.stderr178
-rw-r--r--tests/ui/generic-associated-types/shadowing.rs29
-rw-r--r--tests/ui/generic-associated-types/shadowing.stderr36
-rw-r--r--tests/ui/generic-associated-types/streaming_iterator.rs74
-rw-r--r--tests/ui/generic-associated-types/trait-objects.base.stderr18
-rw-r--r--tests/ui/generic-associated-types/trait-objects.extended.stderr19
-rw-r--r--tests/ui/generic-associated-types/trait-objects.rs19
-rw-r--r--tests/ui/generic-associated-types/type-param-defaults.rs34
-rw-r--r--tests/ui/generic-associated-types/type-param-defaults.stderr20
-rw-r--r--tests/ui/generic-associated-types/unsatified-item-lifetime-bound.rs25
-rw-r--r--tests/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr50
-rw-r--r--tests/ui/generic-associated-types/unsatisfied-outlives-bound.rs19
-rw-r--r--tests/ui/generic-associated-types/unsatisfied-outlives-bound.stderr27
-rw-r--r--tests/ui/generic-associated-types/variance_constraints.rs22
248 files changed, 6726 insertions, 0 deletions
diff --git a/tests/ui/generic-associated-types/anonymize-bound-vars.rs b/tests/ui/generic-associated-types/anonymize-bound-vars.rs
new file mode 100644
index 000000000..eb7a12412
--- /dev/null
+++ b/tests/ui/generic-associated-types/anonymize-bound-vars.rs
@@ -0,0 +1,13 @@
+// check-pass
+//
+// regression test for #98702
+
+trait Foo {
+ type Assoc<T>;
+}
+
+impl Foo for () {
+ type Assoc<T> = [T; 2*2];
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/auxiliary/foo_defn.rs b/tests/ui/generic-associated-types/auxiliary/foo_defn.rs
new file mode 100644
index 000000000..21a9b3b89
--- /dev/null
+++ b/tests/ui/generic-associated-types/auxiliary/foo_defn.rs
@@ -0,0 +1,6 @@
+use std::{future::Future, pin::Pin};
+
+pub trait Foo {
+ type Bar: AsRef<()>;
+ fn foo(&self) -> Pin<Box<dyn Future<Output = Self::Bar> + '_>>;
+}
diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.rs b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.rs
new file mode 100644
index 000000000..5101de19d
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.rs
@@ -0,0 +1,34 @@
+// check-fail
+// known-bug: unknown
+
+// This gives us problems because `for<'a> I::Item<'a>: Debug` should mean "for
+// all 'a where I::Item<'a> is WF", but really means "for all 'a possible"
+
+use std::fmt::Debug;
+
+pub trait LendingIterator {
+ type Item<'this>
+ where
+ Self: 'this;
+}
+
+pub struct WindowsMut<'x> {
+ slice: &'x (),
+}
+
+impl<'y> LendingIterator for WindowsMut<'y> {
+ type Item<'this> = &'this mut () where 'y: 'this;
+}
+
+fn print_items<I>(_iter: I)
+where
+ I: LendingIterator,
+ for<'a> I::Item<'a>: Debug,
+{
+}
+
+fn main() {
+ let slice = &mut ();
+ let windows = WindowsMut { slice };
+ print_items::<WindowsMut<'_>>(windows);
+}
diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
new file mode 100644
index 000000000..362aeae23
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr
@@ -0,0 +1,20 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/hrtb-implied-1.rs:31:22
+ |
+LL | let slice = &mut ();
+ | ^^ creates a temporary value which is freed while still in use
+LL | let windows = WindowsMut { slice };
+LL | print_items::<WindowsMut<'_>>(windows);
+ | -------------------------------------- argument requires that borrow lasts for `'static`
+LL | }
+ | - temporary value is freed at the end of this statement
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/hrtb-implied-1.rs:26:26
+ |
+LL | for<'a> I::Item<'a>: Debug,
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-2.rs b/tests/ui/generic-associated-types/bugs/hrtb-implied-2.rs
new file mode 100644
index 000000000..3174227a7
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-2.rs
@@ -0,0 +1,39 @@
+// check-fail
+// known-bug: unknown
+
+// This gives us problems because `for<'a> I::Item<'a>: Debug` should mean "for
+// all 'a where I::Item<'a> is WF", but really means "for all 'a possible"
+
+trait LendingIterator: Sized {
+ type Item<'a>
+ where
+ Self: 'a;
+ fn next(&mut self) -> Self::Item<'_>;
+}
+fn fails<I: LendingIterator, F>(iter: &mut I, f: F) -> bool
+where
+ F: FnMut(I::Item<'_>),
+{
+ let mut iter2 = Eat(iter, f);
+ let _next = iter2.next();
+ true
+}
+impl<I: LendingIterator> LendingIterator for &mut I {
+ type Item<'a> = I::Item<'a> where Self:'a;
+ fn next(&mut self) -> Self::Item<'_> {
+ (**self).next()
+ }
+}
+
+struct Eat<I, F>(I, F);
+impl<I: LendingIterator, F> Iterator for Eat<I, F>
+where
+ F: FnMut(I::Item<'_>),
+{
+ type Item = ();
+ fn next(&mut self) -> Option<Self::Item> {
+ None
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-2.stderr b/tests/ui/generic-associated-types/bugs/hrtb-implied-2.stderr
new file mode 100644
index 000000000..1ee270398
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-2.stderr
@@ -0,0 +1,22 @@
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/hrtb-implied-2.rs:18:17
+ |
+LL | fn fails<I: LendingIterator, F>(iter: &mut I, f: F) -> bool
+ | ---- - let's call the lifetime of this reference `'1`
+ | |
+ | `iter` is a reference that is only valid in the function body
+...
+LL | let _next = iter2.next();
+ | ^^^^^^^^^^^^
+ | |
+ | `iter` escapes the function body here
+ | argument requires that `'1` must outlive `'static`
+ |
+ = note: requirement occurs because of a mutable reference to `Eat<&mut I, F>`
+ = note: mutable references are invariant over their type parameter
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+ = note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0521`.
diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-3.rs b/tests/ui/generic-associated-types/bugs/hrtb-implied-3.rs
new file mode 100644
index 000000000..bc9e6c8ae
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-3.rs
@@ -0,0 +1,23 @@
+trait LendingIterator {
+ type Item<'a>
+ where
+ Self: 'a;
+}
+
+impl LendingIterator for &str {
+ type Item<'a> = () where Self:'a;
+}
+
+fn trivial_bound<I>(_: I)
+where
+ I: LendingIterator,
+ for<'a> I::Item<'a>: Sized,
+{
+}
+
+fn fails(iter: &str) {
+ trivial_bound(iter);
+ //~^ borrowed data escapes
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-3.stderr b/tests/ui/generic-associated-types/bugs/hrtb-implied-3.stderr
new file mode 100644
index 000000000..c67e02437
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-3.stderr
@@ -0,0 +1,22 @@
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/hrtb-implied-3.rs:19:5
+ |
+LL | fn fails(iter: &str) {
+ | ---- - let's call the lifetime of this reference `'1`
+ | |
+ | `iter` is a reference that is only valid in the function body
+LL | trivial_bound(iter);
+ | ^^^^^^^^^^^^^^^^^^^
+ | |
+ | `iter` escapes the function body here
+ | argument requires that `'1` must outlive `'static`
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/hrtb-implied-3.rs:14:26
+ |
+LL | for<'a> I::Item<'a>: Sized,
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0521`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-100013.rs b/tests/ui/generic-associated-types/bugs/issue-100013.rs
new file mode 100644
index 000000000..973c548d7
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-100013.rs
@@ -0,0 +1,35 @@
+// check-fail
+// known-bug: unknown
+// edition: 2021
+
+// We really should accept this, but we need implied bounds between the regions
+// in a generator interior.
+
+pub trait FutureIterator {
+ type Future<'s, 'cx>: Send
+ where
+ 's: 'cx;
+}
+
+fn call<I: FutureIterator>() -> impl Send {
+ async { // a generator checked for autotrait impl `Send`
+ let x = None::<I::Future<'_, '_>>; // a type referencing GAT
+ async {}.await; // a yield point
+ }
+}
+
+fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
+ async { // a generator checked for autotrait impl `Send`
+ let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+ async {}.await; // a yield point
+ }
+}
+
+fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
+ async { // a generator checked for autotrait impl `Send`
+ let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+ async {}.await; // a yield point
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/bugs/issue-100013.stderr b/tests/ui/generic-associated-types/bugs/issue-100013.stderr
new file mode 100644
index 000000000..9db124a81
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-100013.stderr
@@ -0,0 +1,78 @@
+error: lifetime bound not satisfied
+ --> $DIR/issue-100013.rs:15:5
+ |
+LL | / async { // a generator checked for autotrait impl `Send`
+LL | | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
+LL | | async {}.await; // a yield point
+LL | | }
+ | |_____^
+ |
+note: the lifetime defined here...
+ --> $DIR/issue-100013.rs:16:38
+ |
+LL | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
+ | ^^
+note: ...must outlive the lifetime defined here
+ --> $DIR/issue-100013.rs:16:34
+ |
+LL | let x = None::<I::Future<'_, '_>>; // a type referencing GAT
+ | ^^
+ = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: lifetime bound not satisfied
+ --> $DIR/issue-100013.rs:22:5
+ |
+LL | / async { // a generator checked for autotrait impl `Send`
+LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+LL | | async {}.await; // a yield point
+LL | | }
+ | |_____^
+ |
+note: the lifetime defined here...
+ --> $DIR/issue-100013.rs:21:14
+ |
+LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
+ | ^^
+note: ...must outlive the lifetime defined here
+ --> $DIR/issue-100013.rs:21:10
+ |
+LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
+ | ^^
+ = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: lifetime may not live long enough
+ --> $DIR/issue-100013.rs:23:17
+ |
+LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | async { // a generator checked for autotrait impl `Send`
+LL | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime bound not satisfied
+ --> $DIR/issue-100013.rs:29:5
+ |
+LL | / async { // a generator checked for autotrait impl `Send`
+LL | | let x = None::<I::Future<'a, 'b>>; // a type referencing GAT
+LL | | async {}.await; // a yield point
+LL | | }
+ | |_____^
+ |
+note: the lifetime defined here...
+ --> $DIR/issue-100013.rs:28:18
+ |
+LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
+ | ^^
+note: ...must outlive the lifetime defined here
+ --> $DIR/issue-100013.rs:28:10
+ |
+LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
+ | ^^
+ = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/generic-associated-types/bugs/issue-80626.rs b/tests/ui/generic-associated-types/bugs/issue-80626.rs
new file mode 100644
index 000000000..d6e18010f
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-80626.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+trait Allocator {
+ type Allocated<T>;
+}
+
+enum LinkedList<A: Allocator> {
+ Head,
+ Next(A::Allocated<Self>),
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/bugs/issue-87735.rs b/tests/ui/generic-associated-types/bugs/issue-87735.rs
new file mode 100644
index 000000000..80737a798
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-87735.rs
@@ -0,0 +1,44 @@
+// check-fail
+// known-bug: #87735, #88526
+
+// This should pass, but we need an extension of implied bounds (probably).
+
+pub trait AsRef2 {
+ type Output<'a> where Self: 'a;
+
+ fn as_ref2<'a>(&'a self) -> Self::Output<'a>;
+}
+
+impl<T> AsRef2 for Vec<T> {
+ type Output<'a> = &'a [T] where Self: 'a;
+
+ fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
+ &self[..]
+ }
+}
+
+#[derive(Debug)]
+struct Foo<T>(T);
+#[derive(Debug)]
+struct FooRef<'a, U>(&'a [U]);
+
+impl<'b, T, U> AsRef2 for Foo<T>
+where
+ // * `for<'b, 'c> T: AsRef2<Output<'b> = &'c [U]>>` does not work
+ //
+ // * `U` is unconstrained but should be allowed in this context because `Output` is
+ // an associated type
+ T: AsRef2<Output<'b> = &'b [U]>,
+ U: 'b
+{
+ type Output<'a> = FooRef<'a, U> where Self: 'a;
+
+ fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
+ FooRef(self.0.as_ref2())
+ }
+}
+
+fn main() {
+ let foo = Foo(vec![1, 2, 3]);
+ dbg!(foo.as_ref2());
+}
diff --git a/tests/ui/generic-associated-types/bugs/issue-87735.stderr b/tests/ui/generic-associated-types/bugs/issue-87735.stderr
new file mode 100644
index 000000000..ebe2054ce
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-87735.stderr
@@ -0,0 +1,9 @@
+error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-87735.rs:25:13
+ |
+LL | impl<'b, T, U> AsRef2 for Foo<T>
+ | ^ unconstrained type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-87755.rs b/tests/ui/generic-associated-types/bugs/issue-87755.rs
new file mode 100644
index 000000000..cda722d2f
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-87755.rs
@@ -0,0 +1,19 @@
+// check-fail
+// known-bug: #87755
+
+// This should pass.
+
+use std::fmt::Debug;
+
+trait Foo {
+ type Ass where Self::Ass: Debug;
+}
+
+#[derive(Debug)]
+struct Bar;
+
+impl Foo for Bar {
+ type Ass = Bar;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/bugs/issue-87755.stderr b/tests/ui/generic-associated-types/bugs/issue-87755.stderr
new file mode 100644
index 000000000..5e94db9b0
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-87755.stderr
@@ -0,0 +1,9 @@
+error[E0275]: overflow evaluating the requirement `<Bar as Foo>::Ass == _`
+ --> $DIR/issue-87755.rs:16:16
+ |
+LL | type Ass = Bar;
+ | ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-87803.rs b/tests/ui/generic-associated-types/bugs/issue-87803.rs
new file mode 100644
index 000000000..56237e387
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-87803.rs
@@ -0,0 +1,25 @@
+// check-fail
+// known-bug: #87803
+
+// This should pass, but using a type alias vs a reference directly
+// changes late-bound -> early-bound.
+
+trait Scanner {
+ type Input<'a>;
+ type Token<'a>;
+
+ fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>;
+}
+
+struct IdScanner();
+
+impl Scanner for IdScanner {
+ type Input<'a> = &'a str;
+ type Token<'a> = &'a str;
+
+ fn scan<'a>(&mut self, s : &'a str) -> &'a str {
+ s
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/bugs/issue-87803.stderr b/tests/ui/generic-associated-types/bugs/issue-87803.stderr
new file mode 100644
index 000000000..fe2abdedb
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-87803.stderr
@@ -0,0 +1,12 @@
+error[E0195]: lifetime parameters or bounds on method `scan` do not match the trait declaration
+ --> $DIR/issue-87803.rs:20:12
+ |
+LL | fn scan<'a>(&mut self, i : Self::Input<'a>) -> Self::Token<'a>;
+ | ---- lifetimes in impl do not match this method in trait
+...
+LL | fn scan<'a>(&mut self, s : &'a str) -> &'a str {
+ | ^^^^ lifetimes do not match method in trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0195`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-88382.rs b/tests/ui/generic-associated-types/bugs/issue-88382.rs
new file mode 100644
index 000000000..8f8cc4523
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-88382.rs
@@ -0,0 +1,29 @@
+// check-fail
+// known-bug: #88382
+
+// This should pass, but has a missed normalization due to HRTB.
+
+trait Iterable {
+ type Iterator<'a> where Self: 'a;
+ fn iter(&self) -> Self::Iterator<'_>;
+}
+
+struct SomeImplementation();
+
+impl Iterable for SomeImplementation {
+ type Iterator<'a> = std::iter::Empty<usize>;
+ fn iter(&self) -> Self::Iterator<'_> {
+ std::iter::empty()
+ }
+}
+
+fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
+ f(&mut i.iter());
+}
+
+fn main() {
+ do_something(SomeImplementation(), |_| ());
+ do_something(SomeImplementation(), test);
+}
+
+fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
diff --git a/tests/ui/generic-associated-types/bugs/issue-88382.stderr b/tests/ui/generic-associated-types/bugs/issue-88382.stderr
new file mode 100644
index 000000000..a9a70bb71
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-88382.stderr
@@ -0,0 +1,22 @@
+error[E0631]: type mismatch in function arguments
+ --> $DIR/issue-88382.rs:26:40
+ |
+LL | do_something(SomeImplementation(), test);
+ | ------------ ^^^^ expected due to this
+ | |
+ | required by a bound introduced by this call
+...
+LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
+ | ------------------------------------------------- found signature defined here
+ |
+ = note: expected function signature `for<'a> fn(&'a mut std::iter::Empty<usize>) -> _`
+ found function signature `for<'a, 'b> fn(&'b mut <_ as Iterable>::Iterator<'a>) -> _`
+note: required by a bound in `do_something`
+ --> $DIR/issue-88382.rs:20:48
+ |
+LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0631`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-88460.rs b/tests/ui/generic-associated-types/bugs/issue-88460.rs
new file mode 100644
index 000000000..224e696ad
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-88460.rs
@@ -0,0 +1,29 @@
+// check-fail
+// known-bug: #88460
+
+// This should pass, but has a missed normalization due to HRTB.
+
+pub trait Marker {}
+
+pub trait Trait {
+ type Assoc<'a>;
+}
+
+fn test<T>(value: T)
+where
+ T: Trait,
+ for<'a> T::Assoc<'a>: Marker,
+{
+}
+
+impl Marker for () {}
+
+struct Foo;
+
+impl Trait for Foo {
+ type Assoc<'a> = ();
+}
+
+fn main() {
+ test(Foo);
+}
diff --git a/tests/ui/generic-associated-types/bugs/issue-88460.stderr b/tests/ui/generic-associated-types/bugs/issue-88460.stderr
new file mode 100644
index 000000000..6612c4b49
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-88460.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
+ --> $DIR/issue-88460.rs:28:10
+ |
+LL | test(Foo);
+ | ---- ^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Marker` is implemented for `()`
+note: required by a bound in `test`
+ --> $DIR/issue-88460.rs:15:27
+ |
+LL | fn test<T>(value: T)
+ | ---- required by a bound in this
+...
+LL | for<'a> T::Assoc<'a>: Marker,
+ | ^^^^^^ required by this bound in `test`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-88526.rs b/tests/ui/generic-associated-types/bugs/issue-88526.rs
new file mode 100644
index 000000000..99397744f
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-88526.rs
@@ -0,0 +1,33 @@
+// check-fail
+// known-bug: #88526
+
+// This should pass, but requires more logic.
+
+trait A {
+ type I<'a>;
+}
+
+pub struct TestA<F>
+{
+ f: F,
+}
+
+impl<F> A for TestA<F> {
+ type I<'a> = &'a F;
+}
+
+struct TestB<Q, F>
+{
+ q: Q,
+ f: F,
+}
+
+impl<'q, Q, I, F> A for TestB<Q, F>
+where
+ Q: A<I<'q> = &'q I>,
+ F: Fn(I),
+{
+ type I<'a> = ();
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/bugs/issue-88526.stderr b/tests/ui/generic-associated-types/bugs/issue-88526.stderr
new file mode 100644
index 000000000..56857c655
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-88526.stderr
@@ -0,0 +1,9 @@
+error[E0207]: the type parameter `I` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-88526.rs:25:13
+ |
+LL | impl<'q, Q, I, F> A for TestB<Q, F>
+ | ^ unconstrained type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-91762.rs b/tests/ui/generic-associated-types/bugs/issue-91762.rs
new file mode 100644
index 000000000..8f2cc4550
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-91762.rs
@@ -0,0 +1,28 @@
+// check-fail
+// known-bug: unknown
+
+// We almost certainly want this to pass, but
+// it's particularly difficult currently, because we need a way of specifying
+// that `<Self::Base as Functor>::With<T> = Self` without using that when we have
+// a `U`. See `https://github.com/rust-lang/rust/pull/92728` for a (hacky)
+// solution. This might be better to just wait for Chalk.
+
+pub trait Functor {
+ type With<T>;
+
+ fn fmap<T, U>(this: Self::With<T>) -> Self::With<U>;
+}
+
+pub trait FunctorExt<T>: Sized {
+ type Base: Functor<With<T> = Self>;
+
+ fn fmap<U>(self) {
+ let arg: <Self::Base as Functor>::With<T>;
+ let ret: <Self::Base as Functor>::With<U>;
+
+ arg = self;
+ ret = <Self::Base as Functor>::fmap(arg);
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/bugs/issue-91762.stderr b/tests/ui/generic-associated-types/bugs/issue-91762.stderr
new file mode 100644
index 000000000..1272c8b8a
--- /dev/null
+++ b/tests/ui/generic-associated-types/bugs/issue-91762.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/issue-91762.rs:24:15
+ |
+LL | ret = <Self::Base as Functor>::fmap(arg);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `fmap`
+ |
+help: consider specifying the generic arguments
+ |
+LL | ret = <Self::Base as Functor>::fmap::<T, U>(arg);
+ | ++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/generic-associated-types/collections-project-default.rs b/tests/ui/generic-associated-types/collections-project-default.rs
new file mode 100644
index 000000000..e08aa18cf
--- /dev/null
+++ b/tests/ui/generic-associated-types/collections-project-default.rs
@@ -0,0 +1,70 @@
+#![feature(associated_type_defaults)]
+
+// A Collection trait and collection families. Based on
+// https://smallcultfollowing.com/babysteps/blog/2016/11/03/
+// associated-type-constructors-part-2-family-traits/
+
+// check that we don't normalize with trait defaults.
+
+trait Collection<T> {
+ type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter, Self: 'iter;
+ type Family: CollectionFamily;
+ // Test associated type defaults with parameters
+ type Sibling<U>: Collection<U> =
+ <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
+
+ fn empty() -> Self;
+
+ fn add(&mut self, value: T);
+
+ fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>;
+}
+
+trait CollectionFamily {
+ type Member<T>: Collection<T, Family = Self>;
+}
+
+struct VecFamily;
+
+impl CollectionFamily for VecFamily {
+ type Member<T> = Vec<T>;
+}
+
+impl<T> Collection<T> for Vec<T> {
+ type Iter<'iter> = std::slice::Iter<'iter, T> where T: 'iter;
+ type Family = VecFamily;
+
+ fn empty() -> Self {
+ Vec::new()
+ }
+
+ fn add(&mut self, value: T) {
+ self.push(value)
+ }
+
+ fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> {
+ self.iter()
+ }
+}
+
+fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
+where
+ C: Collection<i32>,
+{
+ let mut res = <C::Family as CollectionFamily>::Member::<f32>::empty();
+ for &v in ints.iterate() {
+ res.add(v as f32);
+ }
+ res
+ //~^ ERROR mismatched types
+}
+
+fn use_floatify() {
+ let a = vec![1i32, 2, 3];
+ let c = floatify_sibling(&a);
+ assert_eq!(Some(&1.0), c.iterate().next());
+}
+
+fn main() {
+ use_floatify();
+}
diff --git a/tests/ui/generic-associated-types/collections-project-default.stderr b/tests/ui/generic-associated-types/collections-project-default.stderr
new file mode 100644
index 000000000..5701017dc
--- /dev/null
+++ b/tests/ui/generic-associated-types/collections-project-default.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+ --> $DIR/collections-project-default.rs:58:5
+ |
+LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
+ | ------------------------------------ expected `<C as Collection<i32>>::Sibling<f32>` because of return type
+...
+LL | res
+ | ^^^ expected Collection::Sibling, found CollectionFamily::Member
+ |
+ = note: expected associated type `<C as Collection<i32>>::Sibling<f32>`
+ found associated type `<<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/generic-associated-types/collections.rs b/tests/ui/generic-associated-types/collections.rs
new file mode 100644
index 000000000..15f429afb
--- /dev/null
+++ b/tests/ui/generic-associated-types/collections.rs
@@ -0,0 +1,69 @@
+#![feature(associated_type_defaults)]
+
+// A Collection trait and collection families. Based on
+// https://smallcultfollowing.com/babysteps/blog/2016/11/03/
+// associated-type-constructors-part-2-family-traits/
+
+// run-pass
+
+trait Collection<T> {
+ type Iter<'iter>: Iterator<Item=&'iter T> where T: 'iter, Self: 'iter;
+ type Family: CollectionFamily;
+ // Test associated type defaults with parameters
+ type Sibling<U>: Collection<U> =
+ <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
+
+ fn empty() -> Self;
+
+ fn add(&mut self, value: T);
+
+ fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>;
+}
+
+trait CollectionFamily {
+ type Member<T>: Collection<T, Family = Self>;
+}
+
+struct VecFamily;
+
+impl CollectionFamily for VecFamily {
+ type Member<T> = Vec<T>;
+}
+
+impl<T> Collection<T> for Vec<T> {
+ type Iter<'iter> = std::slice::Iter<'iter, T> where T: 'iter;
+ type Family = VecFamily;
+
+ fn empty() -> Self {
+ Vec::new()
+ }
+
+ fn add(&mut self, value: T) {
+ self.push(value)
+ }
+
+ fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> {
+ self.iter()
+ }
+}
+
+fn floatify<C>(ints: &C) -> <<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>
+where
+ C: Collection<i32>,
+{
+ let mut res = <C::Family as CollectionFamily>::Member::<f32>::empty();
+ for &v in ints.iterate() {
+ res.add(v as f32);
+ }
+ res
+}
+
+fn use_floatify() {
+ let a = vec![1, 2, 3];
+ let b = floatify(&a);
+ assert_eq!(Some(&1.0), b.iterate().next());
+}
+
+fn main() {
+ use_floatify();
+}
diff --git a/tests/ui/generic-associated-types/collectivity-regression.rs b/tests/ui/generic-associated-types/collectivity-regression.rs
new file mode 100644
index 000000000..54154f9d1
--- /dev/null
+++ b/tests/ui/generic-associated-types/collectivity-regression.rs
@@ -0,0 +1,22 @@
+// Regression test from https://github.com/rust-lang/rust/pull/98109
+
+pub trait Get {
+ type Value<'a>
+ where
+ Self: 'a;
+}
+
+fn multiply_at<T>(x: T)
+where
+ for<'a> T: Get<Value<'a> = ()>,
+{
+ || {
+ //~^ `T` does not live long enough
+ //
+ // FIXME(#98437). This regressed at some point and
+ // probably should work.
+ let _x = x;
+ };
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/collectivity-regression.stderr b/tests/ui/generic-associated-types/collectivity-regression.stderr
new file mode 100644
index 000000000..a085096e1
--- /dev/null
+++ b/tests/ui/generic-associated-types/collectivity-regression.stderr
@@ -0,0 +1,24 @@
+error: `T` does not live long enough
+ --> $DIR/collectivity-regression.rs:13:5
+ |
+LL | / || {
+LL | |
+LL | | //
+LL | | // FIXME(#98437). This regressed at some point and
+LL | | // probably should work.
+LL | | let _x = x;
+LL | | };
+ | |_____^
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/collectivity-regression.rs:11:16
+ |
+LL | for<'a> T: Get<Value<'a> = ()>,
+ | ^^^^^^^^^^^^^^^^^^^
+help: consider restricting the type parameter to the `'static` lifetime
+ |
+LL | for<'a> T: Get<Value<'a> = ()> + 'static,
+ | +++++++++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs b/tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs
new file mode 100644
index 000000000..c5f9a25a6
--- /dev/null
+++ b/tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs
@@ -0,0 +1,20 @@
+// run-pass
+
+// This test unsures that with_opt_const_param returns the
+// def_id of the N param in the Foo::Assoc GAT.
+
+trait Foo {
+ type Assoc<const N: usize>;
+ fn foo(&self) -> Self::Assoc<3>;
+}
+
+impl Foo for () {
+ type Assoc<const N: usize> = [(); N];
+ fn foo(&self) -> Self::Assoc<3> {
+ [(); 3]
+ }
+}
+
+fn main() {
+ assert_eq!(().foo(), [(); 3]);
+}
diff --git a/tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs b/tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs
new file mode 100644
index 000000000..cd7941ed9
--- /dev/null
+++ b/tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs
@@ -0,0 +1,20 @@
+// run-pass
+
+// This test unsures that with_opt_const_param returns the
+// def_id of the N param in the Foo::Assoc GAT.
+
+trait Foo {
+ type Assoc<const N: usize>;
+ fn foo<const N: usize>(&self) -> Self::Assoc<N>;
+}
+
+impl Foo for () {
+ type Assoc<const N: usize> = [(); N];
+ fn foo<const N: usize>(&self) -> Self::Assoc<N> {
+ [(); N]
+ }
+}
+
+fn main() {
+ assert_eq!(().foo::<10>(), [(); 10]);
+}
diff --git a/tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs b/tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs
new file mode 100644
index 000000000..db61fc080
--- /dev/null
+++ b/tests/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+// This test unsures that with_opt_const_param returns the
+// def_id of the N param in the Bar::Assoc GAT.
+
+trait Bar {
+ type Assoc<const N: usize>;
+}
+trait Foo: Bar {
+ fn foo(&self) -> Self::Assoc<3>;
+}
+
+impl Bar for () {
+ type Assoc<const N: usize> = [(); N];
+}
+
+impl Foo for () {
+ fn foo(&self) -> Self::Assoc<3> {
+ [(); 3]
+ }
+}
+
+fn main() {
+ assert_eq!(().foo(), [(); 3]);
+}
diff --git a/tests/ui/generic-associated-types/const_params_have_right_type.rs b/tests/ui/generic-associated-types/const_params_have_right_type.rs
new file mode 100644
index 000000000..d2cb12697
--- /dev/null
+++ b/tests/ui/generic-associated-types/const_params_have_right_type.rs
@@ -0,0 +1,10 @@
+trait Trait {
+ type Foo<const N: u8>;
+}
+
+impl Trait for () {
+ type Foo<const N: u64> = u32;
+ //~^ error: type `Foo` has an incompatible generic parameter for trait
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/const_params_have_right_type.stderr b/tests/ui/generic-associated-types/const_params_have_right_type.stderr
new file mode 100644
index 000000000..fdedd3bf5
--- /dev/null
+++ b/tests/ui/generic-associated-types/const_params_have_right_type.stderr
@@ -0,0 +1,16 @@
+error[E0053]: type `Foo` has an incompatible generic parameter for trait `Trait`
+ --> $DIR/const_params_have_right_type.rs:6:14
+ |
+LL | trait Trait {
+ | -----
+LL | type Foo<const N: u8>;
+ | ----------- expected const parameter of type `u8`
+...
+LL | impl Trait for () {
+ | -----------------
+LL | type Foo<const N: u64> = u32;
+ | ^^^^^^^^^^^^ found const parameter of type `u64`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/generic-associated-types/constraint-assoc-type-suggestion.rs b/tests/ui/generic-associated-types/constraint-assoc-type-suggestion.rs
new file mode 100644
index 000000000..c78a54997
--- /dev/null
+++ b/tests/ui/generic-associated-types/constraint-assoc-type-suggestion.rs
@@ -0,0 +1,14 @@
+// Test that correct syntax is used in suggestion to constrain associated type
+
+trait X {
+ type Y<T>;
+}
+
+fn f<T: X>(a: T::Y<i32>) {
+ //~^ HELP consider constraining the associated type `<T as X>::Y<i32>` to `Vec<i32>`
+ //~| SUGGESTION Y<i32> = Vec<i32>>
+ let b: Vec<i32> = a;
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr b/tests/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr
new file mode 100644
index 000000000..96c4330fe
--- /dev/null
+++ b/tests/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+ --> $DIR/constraint-assoc-type-suggestion.rs:10:23
+ |
+LL | let b: Vec<i32> = a;
+ | -------- ^ expected struct `Vec`, found associated type
+ | |
+ | expected due to this
+ |
+ = note: expected struct `Vec<i32>`
+ found associated type `<T as X>::Y<i32>`
+help: consider constraining the associated type `<T as X>::Y<i32>` to `Vec<i32>`
+ |
+LL | fn f<T: X<Y<i32> = Vec<i32>>>(a: T::Y<i32>) {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/generic-associated-types/construct_with_other_type.rs b/tests/ui/generic-associated-types/construct_with_other_type.rs
new file mode 100644
index 000000000..5cb07f558
--- /dev/null
+++ b/tests/ui/generic-associated-types/construct_with_other_type.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+use std::ops::Deref;
+
+trait Foo {
+ type Bar<'a, 'b>;
+}
+
+trait Baz {
+ type Quux<'a>: Foo where Self: 'a;
+
+ // This weird type tests that we can use universal function call syntax to access the Item on
+ type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>> where Self: 'a;
+}
+
+impl<T> Baz for T where T: Foo {
+ type Quux<'a> = T where T: 'a;
+
+ type Baa<'a> = &'a <T as Foo>::Bar<'a, 'static> where T: 'a;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/cross-crate-bounds.rs b/tests/ui/generic-associated-types/cross-crate-bounds.rs
new file mode 100644
index 000000000..8934a07fd
--- /dev/null
+++ b/tests/ui/generic-associated-types/cross-crate-bounds.rs
@@ -0,0 +1,32 @@
+// regression test for #73816
+// We handled bounds differently when `feature(generic_associated_types)` was enabled
+
+// edition:2018
+// aux-build:foo_defn.rs
+
+extern crate foo_defn;
+
+use foo_defn::Foo;
+use std::{future::Future, pin::Pin};
+
+pub struct FooImpl;
+
+impl Foo for FooImpl {
+ type Bar = ();
+ //~^ ERROR the trait bound `(): AsRef<()>` is not satisfied
+ fn foo(&self) -> Pin<Box<dyn Future<Output = Self::Bar> + '_>> {
+ panic!()
+ }
+}
+
+async fn foo() {
+ bar(&FooImpl).await;
+}
+
+async fn bar<F: Foo>(foo: &F) {
+ foo.foo().await.as_ref();
+}
+
+fn main() {
+ // futures::executor::block_on(foo());
+}
diff --git a/tests/ui/generic-associated-types/cross-crate-bounds.stderr b/tests/ui/generic-associated-types/cross-crate-bounds.stderr
new file mode 100644
index 000000000..83ee04d5a
--- /dev/null
+++ b/tests/ui/generic-associated-types/cross-crate-bounds.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `(): AsRef<()>` is not satisfied
+ --> $DIR/cross-crate-bounds.rs:15:16
+ |
+LL | type Bar = ();
+ | ^^ the trait `AsRef<()>` is not implemented for `()`
+ |
+note: required by a bound in `foo_defn::Foo::Bar`
+ --> $DIR/auxiliary/foo_defn.rs:4:15
+ |
+LL | type Bar: AsRef<()>;
+ | ^^^^^^^^^ required by this bound in `Foo::Bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/elided-in-expr-position.rs b/tests/ui/generic-associated-types/elided-in-expr-position.rs
new file mode 100644
index 000000000..e40093305
--- /dev/null
+++ b/tests/ui/generic-associated-types/elided-in-expr-position.rs
@@ -0,0 +1,37 @@
+#![allow(unused)]
+
+pub trait Trait {
+ type Assoc<'a> where Self: 'a;
+
+ fn f(&self) -> Self::Assoc<'_>;
+
+ // Disallow elision in return position, for now
+ fn g(&self) -> Self::Assoc;
+ //~^ ERROR missing generics for associated type `Trait::Assoc`
+}
+
+pub struct Struct {
+ item: f32
+}
+
+pub struct GenericStruct<'a> {
+ ref_item: &'a f32
+}
+
+impl Trait for Struct {
+ type Assoc<'a> = GenericStruct<'a>;
+
+ fn f(&self) -> Self::Assoc<'_> {
+ Self::Assoc {
+ ref_item: &self.item
+ }
+ }
+
+ // Disallow elision in return position, for now
+ fn g(&self) -> Self::Assoc {
+ //~^ ERROR missing generics for associated type `Trait::Assoc`
+ todo!()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/elided-in-expr-position.stderr b/tests/ui/generic-associated-types/elided-in-expr-position.stderr
new file mode 100644
index 000000000..842b23bd4
--- /dev/null
+++ b/tests/ui/generic-associated-types/elided-in-expr-position.stderr
@@ -0,0 +1,35 @@
+error[E0107]: missing generics for associated type `Trait::Assoc`
+ --> $DIR/elided-in-expr-position.rs:9:26
+ |
+LL | fn g(&self) -> Self::Assoc;
+ | ^^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/elided-in-expr-position.rs:4:10
+ |
+LL | type Assoc<'a> where Self: 'a;
+ | ^^^^^ --
+help: add missing lifetime argument
+ |
+LL | fn g(&self) -> Self::Assoc<'_>;
+ | ++++
+
+error[E0107]: missing generics for associated type `Trait::Assoc`
+ --> $DIR/elided-in-expr-position.rs:31:26
+ |
+LL | fn g(&self) -> Self::Assoc {
+ | ^^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/elided-in-expr-position.rs:4:10
+ |
+LL | type Assoc<'a> where Self: 'a;
+ | ^^^^^ --
+help: add missing lifetime argument
+ |
+LL | fn g(&self) -> Self::Assoc<'_> {
+ | ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/empty_generics.rs b/tests/ui/generic-associated-types/empty_generics.rs
new file mode 100644
index 000000000..964c2972d
--- /dev/null
+++ b/tests/ui/generic-associated-types/empty_generics.rs
@@ -0,0 +1,6 @@
+trait Foo {
+ type Bar<,>;
+ //~^ ERROR expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/empty_generics.stderr b/tests/ui/generic-associated-types/empty_generics.stderr
new file mode 100644
index 000000000..b753181cf
--- /dev/null
+++ b/tests/ui/generic-associated-types/empty_generics.stderr
@@ -0,0 +1,13 @@
+error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
+ --> $DIR/empty_generics.rs:2:14
+ |
+LL | trait Foo {
+ | - while parsing this item list starting here
+LL | type Bar<,>;
+ | ^ expected one of `#`, `>`, `const`, identifier, or lifetime
+LL |
+LL | }
+ | - the item list ends here
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-associated-types/equality-bound.rs b/tests/ui/generic-associated-types/equality-bound.rs
new file mode 100644
index 000000000..fcc2da801
--- /dev/null
+++ b/tests/ui/generic-associated-types/equality-bound.rs
@@ -0,0 +1,15 @@
+fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
+//~^ ERROR equality constraints are not yet supported in `where` clauses
+ panic!()
+}
+fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
+//~^ ERROR equality constraints are not yet supported in `where` clauses
+ panic!()
+}
+fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
+//~^ ERROR equality constraints are not yet supported in `where` clauses
+//~| ERROR failed to resolve: use of undeclared type `I`
+ panic!()
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr
new file mode 100644
index 000000000..d78f7a7fb
--- /dev/null
+++ b/tests/ui/generic-associated-types/equality-bound.stderr
@@ -0,0 +1,43 @@
+error: equality constraints are not yet supported in `where` clauses
+ --> $DIR/equality-bound.rs:1:51
+ |
+LL | fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
+ | ^^^^^^^^^^^^^ not supported
+ |
+ = note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
+help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax
+ |
+LL - fn sum<I: Iterator<Item = ()>>(i: I) -> i32 where I::Item = i32 {
+LL + fn sum<I: Iterator<Item = (), Item = i32>>(i: I) -> i32 where {
+ |
+
+error: equality constraints are not yet supported in `where` clauses
+ --> $DIR/equality-bound.rs:5:41
+ |
+LL | fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
+ | ^^^^^^^^^^^^^ not supported
+ |
+ = note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
+help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax
+ |
+LL - fn sum2<I: Iterator>(i: I) -> i32 where I::Item = i32 {
+LL + fn sum2<I: Iterator<Item = i32>>(i: I) -> i32 where {
+ |
+
+error: equality constraints are not yet supported in `where` clauses
+ --> $DIR/equality-bound.rs:9:41
+ |
+LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
+ | ^^^^^^^^^^^^^ not supported
+ |
+ = note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
+
+error[E0433]: failed to resolve: use of undeclared type `I`
+ --> $DIR/equality-bound.rs:9:41
+ |
+LL | fn sum3<J: Iterator>(i: J) -> i32 where I::Item = i32 {
+ | ^ use of undeclared type `I`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/generic-associated-types/extended/lending_iterator.base.stderr b/tests/ui/generic-associated-types/extended/lending_iterator.base.stderr
new file mode 100644
index 000000000..614c4a34c
--- /dev/null
+++ b/tests/ui/generic-associated-types/extended/lending_iterator.base.stderr
@@ -0,0 +1,12 @@
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/lending_iterator.rs:13:45
+ |
+LL | fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+ | ------------------------------------------------------------------------ definition of `from_iter` from trait
+...
+LL | fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
+ | ^^^^^^^^^^^^ impl has extra requirement `I: 'x`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/tests/ui/generic-associated-types/extended/lending_iterator.rs b/tests/ui/generic-associated-types/extended/lending_iterator.rs
new file mode 100644
index 000000000..247761dd0
--- /dev/null
+++ b/tests/ui/generic-associated-types/extended/lending_iterator.rs
@@ -0,0 +1,38 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+pub trait FromLendingIterator<A>: Sized {
+ fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+}
+
+impl<A> FromLendingIterator<A> for Vec<A> {
+ fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
+ //[base]~^ impl has stricter
+ let mut v = vec![];
+ while let Some(item) = iter.next() {
+ v.push(item);
+ }
+ v
+ }
+}
+
+pub trait LendingIterator {
+ type Item<'z>
+ where
+ Self: 'z;
+ fn next(&mut self) -> Option<Self::Item<'_>>;
+
+ fn collect<A, B: FromLendingIterator<A>>(self) -> B
+ where
+ Self: Sized,
+ Self: for<'q> LendingIterator<Item<'q> = A>,
+ {
+ <B as FromLendingIterator<A>>::from_iter(self)
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/extended/lending_iterator_2.base.stderr b/tests/ui/generic-associated-types/extended/lending_iterator_2.base.stderr
new file mode 100644
index 000000000..f6b0b644e
--- /dev/null
+++ b/tests/ui/generic-associated-types/extended/lending_iterator_2.base.stderr
@@ -0,0 +1,12 @@
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/lending_iterator_2.rs:13:45
+ |
+LL | fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+ | ------------------------------------------------------------------------ definition of `from_iter` from trait
+...
+LL | fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
+ | ^^^^^^^^^^^^ impl has extra requirement `I: 'x`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/tests/ui/generic-associated-types/extended/lending_iterator_2.rs b/tests/ui/generic-associated-types/extended/lending_iterator_2.rs
new file mode 100644
index 000000000..eb9c0456a
--- /dev/null
+++ b/tests/ui/generic-associated-types/extended/lending_iterator_2.rs
@@ -0,0 +1,30 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+pub trait FromLendingIterator<A>: Sized {
+ fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self;
+}
+
+impl<A> FromLendingIterator<A> for Vec<A> {
+ fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
+ //[base]~^ impl has stricter
+ let mut v = vec![];
+ while let Some(item) = iter.next() {
+ v.push(item);
+ }
+ v
+ }
+}
+
+pub trait LendingIterator {
+ type Item<'a>
+ where
+ Self: 'a;
+ fn next(&mut self) -> Option<Self::Item<'_>>;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs
new file mode 100644
index 000000000..86b164ba7
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs
@@ -0,0 +1,9 @@
+trait X {
+ type Y<'x>;
+}
+
+fn main() {
+ fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
+ //~^ ERROR: use of undeclared lifetime name `'x`
+ //~| ERROR: binding for associated type `Y` references lifetime
+}
diff --git a/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr
new file mode 100644
index 000000000..b77f10084
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr
@@ -0,0 +1,26 @@
+error[E0261]: use of undeclared lifetime name `'x`
+ --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:35
+ |
+LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
+ | ^^ undeclared lifetime
+ |
+ = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
+help: consider making the bound lifetime-generic with a new `'x` lifetime
+ |
+LL | fn _f(arg : Box<dyn for<'x, 'a> X<Y<'x> = &'a [u32]>>) {}
+ | +++
+help: consider introducing lifetime `'x` here
+ |
+LL | fn _f<'x>(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
+ | ++++
+
+error[E0582]: binding for associated type `Y` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/gat-in-trait-path-undeclared-lifetime.rs:6:33
+ |
+LL | fn _f(arg : Box<dyn for<'a> X<Y<'x> = &'a [u32]>>) {}
+ | ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0261, E0582.
+For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr
new file mode 100644
index 000000000..fd54faaf3
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr
@@ -0,0 +1,18 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/gat-in-trait-path.rs:26:17
+ |
+LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/gat-in-trait-path.rs:10:10
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | type A<'a> where Self: 'a;
+ | ^ ...because it contains the generic associated type `A`
+ = help: consider moving `A` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.rs b/tests/ui/generic-associated-types/gat-in-trait-path.rs
new file mode 100644
index 000000000..c55f5a726
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-in-trait-path.rs
@@ -0,0 +1,33 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![feature(associated_type_defaults)]
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+trait Foo {
+ type A<'a> where Self: 'a;
+}
+
+struct Fooy;
+
+impl Foo for Fooy {
+ type A<'a> = &'a ();
+}
+
+#[derive(Clone)]
+struct Fooer<T>(T);
+
+impl<T> Foo for Fooer<T> {
+ type A<'x> = &'x () where T: 'x;
+}
+
+fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
+//[base]~^ the trait `Foo` cannot be made into an object
+
+
+fn main() {
+ let foo = Fooer(5);
+ f(Box::new(foo));
+}
diff --git a/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs b/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs
new file mode 100644
index 000000000..d00c036fb
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs
@@ -0,0 +1,14 @@
+trait Foo {
+ type F<'a>;
+
+ fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t }
+}
+
+impl <T, T1> Foo for T {
+ //~^ ERROR: the type parameter `T1` is not constrained
+ type F<T1> = &[u8];
+ //~^ ERROR: the name `T1` is already used for
+ //~| ERROR: `&` without an explicit lifetime name cannot be used here
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr b/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr
new file mode 100644
index 000000000..cb2b9f32b
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr
@@ -0,0 +1,25 @@
+error[E0403]: the name `T1` is already used for a generic parameter in this item's generic parameters
+ --> $DIR/gat-trait-path-generic-type-arg.rs:9:12
+ |
+LL | impl <T, T1> Foo for T {
+ | -- first use of `T1`
+LL |
+LL | type F<T1> = &[u8];
+ | ^^ already used
+
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+ --> $DIR/gat-trait-path-generic-type-arg.rs:9:18
+ |
+LL | type F<T1> = &[u8];
+ | ^ explicit lifetime name needed here
+
+error[E0207]: the type parameter `T1` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/gat-trait-path-generic-type-arg.rs:7:10
+ |
+LL | impl <T, T1> Foo for T {
+ | ^^ unconstrained type parameter
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0207, E0403, E0637.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
new file mode 100644
index 000000000..83b86f04a
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
@@ -0,0 +1,15 @@
+trait X {
+ type Y<'a>;
+
+ fn foo<'a>(t : Self::Y<'a>) -> Self::Y<'a> { t }
+}
+
+impl<T> X for T {
+ fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
+ //~^ ERROR missing generics for associated type
+ //~^^ ERROR missing generics for associated type
+ t
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
new file mode 100644
index 000000000..499221637
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
@@ -0,0 +1,35 @@
+error[E0107]: missing generics for associated type `X::Y`
+ --> $DIR/gat-trait-path-missing-lifetime.rs:8:20
+ |
+LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
+ | ^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/gat-trait-path-missing-lifetime.rs:2:8
+ |
+LL | type Y<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | fn foo<'a, T1: X<Y<'a> = T1>>(t : T1) -> T1::Y<'a> {
+ | ++++
+
+error[E0107]: missing generics for associated type `X::Y`
+ --> $DIR/gat-trait-path-missing-lifetime.rs:8:20
+ |
+LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
+ | ^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/gat-trait-path-missing-lifetime.rs:2:8
+ |
+LL | type Y<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | fn foo<'a, T1: X<Y<'a> = T1>>(t : T1) -> T1::Y<'a> {
+ | ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
new file mode 100644
index 000000000..9eb069637
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
@@ -0,0 +1,16 @@
+trait X {
+ type Y<'a>;
+}
+
+fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
+ //~^ ERROR: lifetime in trait object type must be followed by `+`
+ //~| ERROR: parenthesized generic arguments cannot be used
+ //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
+ //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
+
+
+fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
+ //~^ ERROR: parenthesized generic arguments cannot be used
+ //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
new file mode 100644
index 000000000..165779796
--- /dev/null
+++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
@@ -0,0 +1,74 @@
+error: lifetime in trait object type must be followed by `+`
+ --> $DIR/gat-trait-path-parenthesised-args.rs:5:29
+ |
+LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
+ | ^^
+
+error: parenthesized generic arguments cannot be used in associated type constraints
+ --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
+ |
+LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
+ | ^^^^^
+ |
+help: use angle brackets instead
+ |
+LL | fn foo<'a>(arg: Box<dyn X<Y<'a> = &'a ()>>) {}
+ | ~ ~
+
+error: parenthesized generic arguments cannot be used in associated type constraints
+ --> $DIR/gat-trait-path-parenthesised-args.rs:12:27
+ |
+LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
+ | ^--
+ | |
+ | help: remove these parentheses
+
+error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+ --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
+ |
+LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
+ | ^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
+ |
+LL | type Y<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | fn foo<'a>(arg: Box<dyn X<Y('_, 'a) = &'a ()>>) {}
+ | +++
+
+error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/gat-trait-path-parenthesised-args.rs:5:27
+ |
+LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
+ | ^---- help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: associated type defined here, with 0 generic parameters
+ --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
+ |
+LL | type Y<'a>;
+ | ^
+
+error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+ --> $DIR/gat-trait-path-parenthesised-args.rs:12:27
+ |
+LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {}
+ | ^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/gat-trait-path-parenthesised-args.rs:2:8
+ |
+LL | type Y<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | fn bar<'a>(arg: Box<dyn X<Y('_) = ()>>) {}
+ | ++
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/generic-associated-type-bounds.rs b/tests/ui/generic-associated-types/generic-associated-type-bounds.rs
new file mode 100644
index 000000000..fdc5a7267
--- /dev/null
+++ b/tests/ui/generic-associated-types/generic-associated-type-bounds.rs
@@ -0,0 +1,32 @@
+// run-pass
+
+pub trait X {
+ type Y<'a> where Self: 'a;
+ fn m(&self) -> Self::Y<'_>;
+}
+
+impl X for () {
+ type Y<'a> = &'a ();
+
+ fn m(&self) -> Self::Y<'_> {
+ self
+ }
+}
+
+fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &() {
+ x.m()
+}
+
+fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &() {
+ x.m()
+}
+
+fn h(x: &()) -> &() {
+ x.m()
+}
+
+fn main() {
+ f(&());
+ g(&());
+ h(&());
+}
diff --git a/tests/ui/generic-associated-types/generic-associated-types-where.rs b/tests/ui/generic-associated-types/generic-associated-types-where.rs
new file mode 100644
index 000000000..bbdfffafe
--- /dev/null
+++ b/tests/ui/generic-associated-types/generic-associated-types-where.rs
@@ -0,0 +1,26 @@
+// Checking the interaction with this other feature
+#![feature(associated_type_defaults)]
+
+use std::fmt::{Display, Debug};
+
+trait Foo {
+ type Assoc where Self: Sized;
+ type Assoc2<T> where T: Display;
+ type Assoc3<T>;
+ type WithDefault<'a, T: Debug + 'a>: ?Sized = dyn Iterator<Item=T>;
+ type NoGenerics;
+}
+
+struct Bar;
+
+impl Foo for Bar {
+ type Assoc = usize;
+ type Assoc2<T> = Vec<T>;
+ //~^ ERROR `T` doesn't implement `std::fmt::Display`
+ type Assoc3<T> = Vec<T> where T: Iterator;
+ //~^ ERROR impl has stricter requirements than trait
+ type WithDefault<'a, T: Debug + 'a> = &'a dyn Iterator<Item=T>;
+ type NoGenerics = ::std::cell::Cell<i32>;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/generic-associated-types-where.stderr b/tests/ui/generic-associated-types/generic-associated-types-where.stderr
new file mode 100644
index 000000000..9a745c099
--- /dev/null
+++ b/tests/ui/generic-associated-types/generic-associated-types-where.stderr
@@ -0,0 +1,25 @@
+error[E0277]: `T` doesn't implement `std::fmt::Display`
+ --> $DIR/generic-associated-types-where.rs:18:22
+ |
+LL | type Assoc2<T> = Vec<T>;
+ | ^^^^^^ `T` cannot be formatted with the default formatter
+ |
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+help: consider restricting type parameter `T`
+ |
+LL | type Assoc2<T: std::fmt::Display> = Vec<T>;
+ | +++++++++++++++++++
+
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/generic-associated-types-where.rs:20:38
+ |
+LL | type Assoc3<T>;
+ | -------------- definition of `Assoc3` from trait
+...
+LL | type Assoc3<T> = Vec<T> where T: Iterator;
+ | ^^^^^^^^ impl has extra requirement `T: Iterator`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0276, E0277.
+For more information about an error, try `rustc --explain E0276`.
diff --git a/tests/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs b/tests/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
new file mode 100644
index 000000000..2cb218bf8
--- /dev/null
+++ b/tests/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
@@ -0,0 +1,13 @@
+use std::ops::Deref;
+
+trait Iterable {
+ type Item<'a>;
+ type Iter<'a>: Iterator<Item = Self::Item<'a>>
+ + Deref<Target = Self::Item<'b>>;
+ //~^ ERROR undeclared lifetime
+
+ fn iter<'a>(&'a self) -> Self::Iter<'undeclared>;
+ //~^ ERROR undeclared lifetime
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/tests/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
new file mode 100644
index 000000000..396ff15ab
--- /dev/null
+++ b/tests/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
@@ -0,0 +1,38 @@
+error[E0261]: use of undeclared lifetime name `'b`
+ --> $DIR/generic_associated_type_undeclared_lifetimes.rs:6:37
+ |
+LL | + Deref<Target = Self::Item<'b>>;
+ | ^^ undeclared lifetime
+ |
+ = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
+help: consider making the bound lifetime-generic with a new `'b` lifetime
+ |
+LL | + for<'b> Deref<Target = Self::Item<'b>>;
+ | +++++++
+help: consider introducing lifetime `'b` here
+ |
+LL | type Iter<'b, 'a>: Iterator<Item = Self::Item<'a>>
+ | +++
+help: consider introducing lifetime `'b` here
+ |
+LL | trait Iterable<'b> {
+ | ++++
+
+error[E0261]: use of undeclared lifetime name `'undeclared`
+ --> $DIR/generic_associated_type_undeclared_lifetimes.rs:9:41
+ |
+LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>;
+ | ^^^^^^^^^^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'undeclared` here
+ |
+LL | fn iter<'undeclared, 'a>(&'a self) -> Self::Iter<'undeclared>;
+ | ++++++++++++
+help: consider introducing lifetime `'undeclared` here
+ |
+LL | trait Iterable<'undeclared> {
+ | +++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/generic-associated-types/impl_bounds.rs b/tests/ui/generic-associated-types/impl_bounds.rs
new file mode 100644
index 000000000..e45bdcf92
--- /dev/null
+++ b/tests/ui/generic-associated-types/impl_bounds.rs
@@ -0,0 +1,24 @@
+#![feature(associated_type_defaults)]
+
+trait Foo {
+ type A<'a> where Self: 'a;
+ type B<'a, 'b> where 'a: 'b;
+ type C where Self: Clone;
+ fn d() where Self: Clone;
+}
+
+#[derive(Copy, Clone)]
+struct Fooy<T>(T);
+
+impl<T> Foo for Fooy<T> {
+ type A<'a> = (&'a ()) where Self: 'static;
+ //~^ ERROR impl has stricter requirements than trait
+ type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
+ //~^ ERROR impl has stricter requirements than trait
+ type C = String where Self: Copy;
+ //~^ ERROR the trait bound `T: Copy` is not satisfied
+ fn d() where Self: Copy {}
+ //~^ ERROR the trait bound `T: Copy` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/impl_bounds.stderr b/tests/ui/generic-associated-types/impl_bounds.stderr
new file mode 100644
index 000000000..261070d1d
--- /dev/null
+++ b/tests/ui/generic-associated-types/impl_bounds.stderr
@@ -0,0 +1,77 @@
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/impl_bounds.rs:14:39
+ |
+LL | type A<'a> where Self: 'a;
+ | ---------- definition of `A` from trait
+...
+LL | type A<'a> = (&'a ()) where Self: 'static;
+ | ^^^^^^^ impl has extra requirement `T: 'static`
+
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/impl_bounds.rs:16:48
+ |
+LL | type B<'a, 'b> where 'a: 'b;
+ | -------------- definition of `B` from trait
+...
+LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
+ | ^^ impl has extra requirement `'b: 'a`
+ |
+help: copy the `where` clause predicates from the trait
+ |
+LL | type B<'a, 'b> = (&'a(), &'b ()) where 'a: 'b;
+ | ~~~~~~~~~~~~
+
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/impl_bounds.rs:18:33
+ |
+LL | type C = String where Self: Copy;
+ | ^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required for `Fooy<T>` to implement `Copy`
+ --> $DIR/impl_bounds.rs:10:10
+ |
+LL | #[derive(Copy, Clone)]
+ | ^^^^ unsatisfied trait bound introduced in this `derive` macro
+note: the requirement `Fooy<T>: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type
+ --> $DIR/impl_bounds.rs:6:10
+ |
+LL | trait Foo {
+ | --- in this trait
+...
+LL | type C where Self: Clone;
+ | ^ this trait's associated type doesn't have the requirement `Fooy<T>: Copy`
+ = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider restricting type parameter `T`
+ |
+LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
+ | +++++++++++++++++++
+
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/impl_bounds.rs:20:24
+ |
+LL | fn d() where Self: Copy {}
+ | ^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required for `Fooy<T>` to implement `Copy`
+ --> $DIR/impl_bounds.rs:10:10
+ |
+LL | #[derive(Copy, Clone)]
+ | ^^^^ unsatisfied trait bound introduced in this `derive` macro
+note: the requirement `Fooy<T>: Copy` appears on the `impl`'s method `d` but not on the corresponding trait's method
+ --> $DIR/impl_bounds.rs:7:8
+ |
+LL | trait Foo {
+ | --- in this trait
+...
+LL | fn d() where Self: Clone;
+ | ^ this trait's method doesn't have the requirement `Fooy<T>: Copy`
+ = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider restricting type parameter `T`
+ |
+LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
+ | +++++++++++++++++++
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0276, E0277.
+For more information about an error, try `rustc --explain E0276`.
diff --git a/tests/ui/generic-associated-types/impl_bounds_ok.rs b/tests/ui/generic-associated-types/impl_bounds_ok.rs
new file mode 100644
index 000000000..88f829ea2
--- /dev/null
+++ b/tests/ui/generic-associated-types/impl_bounds_ok.rs
@@ -0,0 +1,29 @@
+// check-pass
+
+#![feature(associated_type_defaults)]
+
+trait Foo {
+ type A<'a> where Self: 'a;
+ type B<'a, 'b> where 'a: 'b;
+ type C where Self: Clone;
+}
+
+#[derive(Clone)]
+struct Fooy;
+
+impl Foo for Fooy {
+ type A<'a> = (&'a ());
+ type B<'a: 'b, 'b> = (&'a(), &'b ());
+ type C = String;
+}
+
+#[derive(Clone)]
+struct Fooer<T>(T);
+
+impl<T> Foo for Fooer<T> {
+ type A<'x> = (&'x ()) where T: 'x;
+ type B<'u, 'v> = (&'v &'u ()) where 'u: 'v;
+ type C = String where Self: Clone + ToOwned;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-101020.rs b/tests/ui/generic-associated-types/issue-101020.rs
new file mode 100644
index 000000000..80d0fa5ad
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-101020.rs
@@ -0,0 +1,35 @@
+pub trait LendingIterator {
+ type Item<'a>
+ where
+ Self: 'a;
+
+ fn consume<F>(self, _f: F)
+ where
+ Self: Sized,
+ for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>,
+ {
+ }
+}
+
+impl<I: LendingIterator + ?Sized> LendingIterator for &mut I {
+ type Item<'a> = I::Item<'a> where Self: 'a;
+}
+struct EmptyIter;
+impl LendingIterator for EmptyIter {
+ type Item<'a> = &'a mut () where Self:'a;
+}
+pub trait FuncInput<'a, F>
+where
+ F: Foo<Self>,
+ Self: Sized,
+{
+}
+impl<'a, T, F: 'a> FuncInput<'a, F> for T where F: Foo<T> {}
+trait Foo<T> {}
+
+fn map_test() {
+ (&mut EmptyIter).consume(());
+ //~^ ERROR the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-101020.stderr b/tests/ui/generic-associated-types/issue-101020.stderr
new file mode 100644
index 000000000..1f9273a8c
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-101020.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied
+ --> $DIR/issue-101020.rs:31:22
+ |
+LL | (&mut EmptyIter).consume(());
+ | ^^^^^^^ the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()`
+ |
+note: required for `&'a mut ()` to implement `for<'a> FuncInput<'a, &'a mut ()>`
+ --> $DIR/issue-101020.rs:27:20
+ |
+LL | impl<'a, T, F: 'a> FuncInput<'a, F> for T where F: Foo<T> {}
+ | ^^^^^^^^^^^^^^^^ ^ ------ unsatisfied trait bound introduced here
+note: required by a bound in `LendingIterator::consume`
+ --> $DIR/issue-101020.rs:9:33
+ |
+LL | fn consume<F>(self, _f: F)
+ | ------- required by a bound in this
+...
+LL | for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `LendingIterator::consume`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-102114.rs b/tests/ui/generic-associated-types/issue-102114.rs
new file mode 100644
index 000000000..de31737ef
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-102114.rs
@@ -0,0 +1,16 @@
+trait A {
+ type B<'b>;
+ fn a() -> Self::B<'static>;
+}
+
+struct C;
+
+struct Wrapper<T>(T);
+
+impl A for C {
+ type B<T> = Wrapper<T>;
+ //~^ ERROR type `B` has 1 type parameter but its trait declaration has 0 type parameters
+ fn a() -> Self::B<'static> {}
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-102114.stderr b/tests/ui/generic-associated-types/issue-102114.stderr
new file mode 100644
index 000000000..8e41dee54
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-102114.stderr
@@ -0,0 +1,12 @@
+error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
+ --> $DIR/issue-102114.rs:11:12
+ |
+LL | type B<'b>;
+ | -- expected 0 type parameters
+...
+LL | type B<T> = Wrapper<T>;
+ | ^ found 1 type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0049`.
diff --git a/tests/ui/generic-associated-types/issue-102333.rs b/tests/ui/generic-associated-types/issue-102333.rs
new file mode 100644
index 000000000..6c7256332
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-102333.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+trait A {
+ type T: B<U<1i32> = ()>;
+}
+
+trait B {
+ type U<const C: i32>;
+}
+
+fn f<T: A>() {
+ let _: <<T as A>::T as B>::U<1i32> = ();
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-102335-gat.rs b/tests/ui/generic-associated-types/issue-102335-gat.rs
new file mode 100644
index 000000000..a7255fdcb
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-102335-gat.rs
@@ -0,0 +1,12 @@
+trait T {
+ type A: S<C<(), i32 = ()> = ()>;
+ //~^ ERROR associated type bindings are not allowed here
+}
+
+trait Q {}
+
+trait S {
+ type C<T>: Q;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-102335-gat.stderr b/tests/ui/generic-associated-types/issue-102335-gat.stderr
new file mode 100644
index 000000000..7a7900a1e
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-102335-gat.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/issue-102335-gat.rs:2:21
+ |
+LL | type A: S<C<(), i32 = ()> = ()>;
+ | ^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/tests/ui/generic-associated-types/issue-47206-where-clause.rs b/tests/ui/generic-associated-types/issue-47206-where-clause.rs
new file mode 100644
index 000000000..3d1b88ddf
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-47206-where-clause.rs
@@ -0,0 +1,14 @@
+// Check that this program doesn't cause the compiler to error without output.
+
+trait Foo {
+ type Assoc3<T>;
+}
+
+struct Bar;
+
+impl Foo for Bar {
+ type Assoc3<T> = Vec<T> where T: Iterator;
+ //~^ ERROR impl has stricter requirements than trait
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-47206-where-clause.stderr b/tests/ui/generic-associated-types/issue-47206-where-clause.stderr
new file mode 100644
index 000000000..7006744df
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-47206-where-clause.stderr
@@ -0,0 +1,12 @@
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/issue-47206-where-clause.rs:10:38
+ |
+LL | type Assoc3<T>;
+ | -------------- definition of `Assoc3` from trait
+...
+LL | type Assoc3<T> = Vec<T> where T: Iterator;
+ | ^^^^^^^^ impl has extra requirement `T: Iterator`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/tests/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs b/tests/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs
new file mode 100644
index 000000000..625ccfe89
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+trait Cert {
+ type PublicKey<'a>: From<&'a [u8]>;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs b/tests/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs
new file mode 100644
index 000000000..c1140bff8
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+trait Iterator {
+ type Item<'a>: 'a;
+}
+
+impl Iterator for () {
+ type Item<'a> = &'a ();
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-67424.rs b/tests/ui/generic-associated-types/issue-67424.rs
new file mode 100644
index 000000000..b6c7c70cd
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-67424.rs
@@ -0,0 +1,12 @@
+// check-pass
+// Fixed by #67160
+
+trait Trait1 {
+ type A;
+}
+
+trait Trait2 {
+ type Type1<B>: Trait1<A=B>;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-67510-pass.base.stderr b/tests/ui/generic-associated-types/issue-67510-pass.base.stderr
new file mode 100644
index 000000000..4cc68530e
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-67510-pass.base.stderr
@@ -0,0 +1,18 @@
+error[E0038]: the trait `X` cannot be made into an object
+ --> $DIR/issue-67510-pass.rs:12:23
+ |
+LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
+ | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-67510-pass.rs:9:10
+ |
+LL | trait X {
+ | - this trait cannot be made into an object...
+LL | type Y<'a>;
+ | ^ ...because it contains the generic associated type `Y`
+ = help: consider moving `Y` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/generic-associated-types/issue-67510-pass.rs b/tests/ui/generic-associated-types/issue-67510-pass.rs
new file mode 100644
index 000000000..66ce3e807
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-67510-pass.rs
@@ -0,0 +1,15 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+trait X {
+ type Y<'a>;
+}
+
+fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
+//[base]~^ ERROR the trait `X` cannot be made into an object
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-67510.rs b/tests/ui/generic-associated-types/issue-67510.rs
new file mode 100644
index 000000000..ab5c25d74
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-67510.rs
@@ -0,0 +1,10 @@
+trait X {
+ type Y<'a>;
+}
+
+fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
+//~^ ERROR: use of undeclared lifetime name `'a`
+//~| ERROR: use of undeclared lifetime name `'a`
+//~| ERROR: the trait `X` cannot be made into an object [E0038]
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-67510.stderr b/tests/ui/generic-associated-types/issue-67510.stderr
new file mode 100644
index 000000000..d25c5b0f3
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-67510.stderr
@@ -0,0 +1,50 @@
+error[E0261]: use of undeclared lifetime name `'a`
+ --> $DIR/issue-67510.rs:5:21
+ |
+LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
+ | ^^ undeclared lifetime
+ |
+ = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
+help: consider making the bound lifetime-generic with a new `'a` lifetime
+ |
+LL | fn f(x: Box<dyn for<'a> X<Y<'a> = &'a ()>>) {}
+ | +++++++
+help: consider introducing lifetime `'a` here
+ |
+LL | fn f<'a>(x: Box<dyn X<Y<'a> = &'a ()>>) {}
+ | ++++
+
+error[E0261]: use of undeclared lifetime name `'a`
+ --> $DIR/issue-67510.rs:5:28
+ |
+LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
+ | ^^ undeclared lifetime
+ |
+help: consider making the bound lifetime-generic with a new `'a` lifetime
+ |
+LL | fn f(x: Box<dyn for<'a> X<Y<'a> = &'a ()>>) {}
+ | +++++++
+help: consider introducing lifetime `'a` here
+ |
+LL | fn f<'a>(x: Box<dyn X<Y<'a> = &'a ()>>) {}
+ | ++++
+
+error[E0038]: the trait `X` cannot be made into an object
+ --> $DIR/issue-67510.rs:5:13
+ |
+LL | fn f(x: Box<dyn X<Y<'a> = &'a ()>>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-67510.rs:2:10
+ |
+LL | trait X {
+ | - this trait cannot be made into an object...
+LL | type Y<'a>;
+ | ^ ...because it contains the generic associated type `Y`
+ = help: consider moving `Y` to another trait
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0038, E0261.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/generic-associated-types/issue-68641-check-gat-bounds.rs b/tests/ui/generic-associated-types/issue-68641-check-gat-bounds.rs
new file mode 100644
index 000000000..f1e779fcb
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68641-check-gat-bounds.rs
@@ -0,0 +1,29 @@
+// Regression test for #68641
+
+trait UnsafeCopy {
+ type Item<'a>: Copy;
+
+ fn copy<'a>(item: &Self::Item<'a>) -> Self::Item<'a> {
+ *item
+ }
+}
+
+impl<T> UnsafeCopy for T {
+ type Item<'a> = T;
+ //~^ ERROR the trait bound `T: Copy` is not satisfied
+}
+
+fn main() {
+ let mut s = String::from("Hello world!");
+
+ let copy = String::copy(&s);
+
+ // Do we indeed point to the samme memory?
+ assert!(s.as_ptr() == copy.as_ptr());
+
+ // Any use of `copy` is certeinly UB after this
+ drop(s);
+
+ // UB UB UB UB UB!!
+ println!("{}", copy);
+}
diff --git a/tests/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr b/tests/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr
new file mode 100644
index 000000000..6bb7492af
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/issue-68641-check-gat-bounds.rs:12:21
+ |
+LL | type Item<'a> = T;
+ | ^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `UnsafeCopy::Item`
+ --> $DIR/issue-68641-check-gat-bounds.rs:4:20
+ |
+LL | type Item<'a>: Copy;
+ | ^^^^ required by this bound in `UnsafeCopy::Item`
+help: consider restricting type parameter `T`
+ |
+LL | impl<T: std::marker::Copy> UnsafeCopy for T {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs b/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs
new file mode 100644
index 000000000..f5502adee
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs
@@ -0,0 +1,18 @@
+// Regression test for #68642
+
+trait Fun {
+ type F<'a>: Fn() -> u32;
+
+ fn callme<'a>(f: Self::F<'a>) -> u32 {
+ f()
+ }
+}
+
+impl<T> Fun for T {
+ type F<'a> = Self;
+ //~^ ERROR expected a `Fn<()>` closure, found `T`
+}
+
+fn main() {
+ <fn() -> usize>::callme(|| 1);
+}
diff --git a/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr b/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr
new file mode 100644
index 000000000..07452137b
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr
@@ -0,0 +1,20 @@
+error[E0277]: expected a `Fn<()>` closure, found `T`
+ --> $DIR/issue-68642-broken-llvm-ir.rs:12:18
+ |
+LL | type F<'a> = Self;
+ | ^^^^ expected an `Fn<()>` closure, found `T`
+ |
+ = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
+note: required by a bound in `Fun::F`
+ --> $DIR/issue-68642-broken-llvm-ir.rs:4:17
+ |
+LL | type F<'a>: Fn() -> u32;
+ | ^^^^^^^^^^^ required by this bound in `Fun::F`
+help: consider restricting type parameter `T`
+ |
+LL | impl<T: std::ops::Fn<()>> Fun for T {
+ | ++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-68643-broken-mir.rs b/tests/ui/generic-associated-types/issue-68643-broken-mir.rs
new file mode 100644
index 000000000..6050a8bf5
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68643-broken-mir.rs
@@ -0,0 +1,18 @@
+// Regression test for #68643
+
+trait Fun {
+ type F<'a>: Fn() -> u32;
+
+ fn callme<'a>(f: Self::F<'a>) -> u32 {
+ f()
+ }
+}
+
+impl<T> Fun for T {
+ type F<'a> = Self;
+ //~^ ERROR expected a `Fn<()>` closure, found `T`
+}
+
+pub fn main() {
+ <fn()>::callme(|| {});
+}
diff --git a/tests/ui/generic-associated-types/issue-68643-broken-mir.stderr b/tests/ui/generic-associated-types/issue-68643-broken-mir.stderr
new file mode 100644
index 000000000..31ded5dab
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68643-broken-mir.stderr
@@ -0,0 +1,20 @@
+error[E0277]: expected a `Fn<()>` closure, found `T`
+ --> $DIR/issue-68643-broken-mir.rs:12:18
+ |
+LL | type F<'a> = Self;
+ | ^^^^ expected an `Fn<()>` closure, found `T`
+ |
+ = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
+note: required by a bound in `Fun::F`
+ --> $DIR/issue-68643-broken-mir.rs:4:17
+ |
+LL | type F<'a>: Fn() -> u32;
+ | ^^^^^^^^^^^ required by this bound in `Fun::F`
+help: consider restricting type parameter `T`
+ |
+LL | impl<T: std::ops::Fn<()>> Fun for T {
+ | ++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-68644-codegen-selection.rs b/tests/ui/generic-associated-types/issue-68644-codegen-selection.rs
new file mode 100644
index 000000000..898cfa1e7
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68644-codegen-selection.rs
@@ -0,0 +1,18 @@
+// Regression test for #68644
+
+trait Fun {
+ type F<'a>: Fn() -> u32;
+
+ fn callme<'a>(f: Self::F<'a>) -> u32 {
+ f()
+ }
+}
+
+impl<T> Fun for T {
+ type F<'a> = Self;
+ //~^ ERROR expected a `Fn<()>` closure, found `T`
+}
+
+fn main() {
+ <u8>::callme(0);
+}
diff --git a/tests/ui/generic-associated-types/issue-68644-codegen-selection.stderr b/tests/ui/generic-associated-types/issue-68644-codegen-selection.stderr
new file mode 100644
index 000000000..e2f9930cc
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68644-codegen-selection.stderr
@@ -0,0 +1,20 @@
+error[E0277]: expected a `Fn<()>` closure, found `T`
+ --> $DIR/issue-68644-codegen-selection.rs:12:18
+ |
+LL | type F<'a> = Self;
+ | ^^^^ expected an `Fn<()>` closure, found `T`
+ |
+ = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
+note: required by a bound in `Fun::F`
+ --> $DIR/issue-68644-codegen-selection.rs:4:17
+ |
+LL | type F<'a>: Fn() -> u32;
+ | ^^^^^^^^^^^ required by this bound in `Fun::F`
+help: consider restricting type parameter `T`
+ |
+LL | impl<T: std::ops::Fn<()>> Fun for T {
+ | ++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs b/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs
new file mode 100644
index 000000000..60b065bfc
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs
@@ -0,0 +1,18 @@
+// Regression test for #68645
+
+trait Fun {
+ type F<'a>: Fn() -> u32;
+
+ fn callme<'a>(f: Self::F<'a>) -> u32 {
+ f()
+ }
+}
+
+impl<T> Fun for T {
+ type F<'a> = Self;
+ //~^ ERROR expected a `Fn<()>` closure, found `T`
+}
+
+fn main() {
+ <&dyn Iterator<Item = u8>>::callme(&std::iter::once(1));
+}
diff --git a/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr b/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr
new file mode 100644
index 000000000..0065368ad
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr
@@ -0,0 +1,20 @@
+error[E0277]: expected a `Fn<()>` closure, found `T`
+ --> $DIR/issue-68645-codegen-fulfillment.rs:12:18
+ |
+LL | type F<'a> = Self;
+ | ^^^^ expected an `Fn<()>` closure, found `T`
+ |
+ = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
+note: required by a bound in `Fun::F`
+ --> $DIR/issue-68645-codegen-fulfillment.rs:4:17
+ |
+LL | type F<'a>: Fn() -> u32;
+ | ^^^^^^^^^^^ required by this bound in `Fun::F`
+help: consider restricting type parameter `T`
+ |
+LL | impl<T: std::ops::Fn<()>> Fun for T {
+ | ++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-68648-1.rs b/tests/ui/generic-associated-types/issue-68648-1.rs
new file mode 100644
index 000000000..0df41bab3
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68648-1.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+trait Fun {
+ type F<'a>;
+
+ fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t }
+}
+
+impl <T> Fun for T {
+ type F<'a> = Self;
+}
+
+fn bug<'a, T: for<'b> Fun<F<'b> = T>>(t: T) -> T::F<'a> {
+ T::identity(t)
+}
+
+
+fn main() {
+ let x = 10;
+
+ bug(x);
+}
diff --git a/tests/ui/generic-associated-types/issue-68648-2.rs b/tests/ui/generic-associated-types/issue-68648-2.rs
new file mode 100644
index 000000000..0f963d58f
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68648-2.rs
@@ -0,0 +1,21 @@
+trait Fun {
+ type F<'a>;
+
+ fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t }
+}
+
+impl <T> Fun for T {
+ type F<'a> = Self;
+}
+
+fn bug<'a, T: Fun<F<'a> = T>>(t: T) -> T::F<'a> {
+ T::identity(())
+ //~^ ERROR: mismatched types
+}
+
+
+fn main() {
+ let x = 10;
+
+ bug(x);
+}
diff --git a/tests/ui/generic-associated-types/issue-68648-2.stderr b/tests/ui/generic-associated-types/issue-68648-2.stderr
new file mode 100644
index 000000000..b2bef19eb
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68648-2.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-68648-2.rs:12:17
+ |
+LL | fn bug<'a, T: Fun<F<'a> = T>>(t: T) -> T::F<'a> {
+ | - this type parameter
+LL | T::identity(())
+ | ----------- ^^ expected type parameter `T`, found `()`
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected type parameter `T`
+ found unit type `()`
+note: associated function defined here
+ --> $DIR/issue-68648-2.rs:4:8
+ |
+LL | fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t }
+ | ^^^^^^^^ --------------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/generic-associated-types/issue-68649-pass.rs b/tests/ui/generic-associated-types/issue-68649-pass.rs
new file mode 100644
index 000000000..772743877
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68649-pass.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+trait Fun {
+ type F<'a>;
+
+ fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t }
+}
+
+impl <T> Fun for T {
+ type F<'a> = Self;
+}
+
+fn bug<'a, T: Fun<F<'a> = T>>(t: T) -> T::F<'a> {
+ T::identity(t)
+}
+
+
+fn main() {
+ let x = 10;
+
+ bug(x);
+}
diff --git a/tests/ui/generic-associated-types/issue-68653.rs b/tests/ui/generic-associated-types/issue-68653.rs
new file mode 100644
index 000000000..170b87cf2
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68653.rs
@@ -0,0 +1,13 @@
+// A regression test for #68653, which was fixed by #68938.
+
+// check-pass
+
+trait Fun {
+ type F<'a: 'a>;
+}
+
+impl <T> Fun for T {
+ type F<'a> = Self;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-68656-unsized-values.rs b/tests/ui/generic-associated-types/issue-68656-unsized-values.rs
new file mode 100644
index 000000000..607cfed0b
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68656-unsized-values.rs
@@ -0,0 +1,19 @@
+// Regression test for #68656
+
+trait UnsafeCopy<T: Copy> {
+ type Item<'a>: std::ops::Deref<Target = T>;
+
+ fn bug<'a>(item: &Self::Item<'a>) -> () {
+ let x: T = **item;
+ &x as *const _;
+ }
+}
+
+impl<T: Copy + std::ops::Deref> UnsafeCopy<T> for T {
+ type Item<'a> = T;
+ //~^ ERROR type mismatch resolving `<T as Deref>::Target == T`
+}
+
+fn main() {
+ <&'static str>::bug(&"");
+}
diff --git a/tests/ui/generic-associated-types/issue-68656-unsized-values.stderr b/tests/ui/generic-associated-types/issue-68656-unsized-values.stderr
new file mode 100644
index 000000000..e8770aedf
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-68656-unsized-values.stderr
@@ -0,0 +1,23 @@
+error[E0271]: type mismatch resolving `<T as Deref>::Target == T`
+ --> $DIR/issue-68656-unsized-values.rs:13:21
+ |
+LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<T> for T {
+ | - this type parameter
+LL | type Item<'a> = T;
+ | ^ expected type parameter `T`, found associated type
+ |
+ = note: expected type parameter `T`
+ found associated type `<T as Deref>::Target`
+note: required by a bound in `UnsafeCopy::Item`
+ --> $DIR/issue-68656-unsized-values.rs:4:36
+ |
+LL | type Item<'a>: std::ops::Deref<Target = T>;
+ | ^^^^^^^^^^ required by this bound in `UnsafeCopy::Item`
+help: consider further restricting this bound
+ |
+LL | impl<T: Copy + std::ops::Deref + Deref<Target = T>> UnsafeCopy<T> for T {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/generic-associated-types/issue-70303.rs b/tests/ui/generic-associated-types/issue-70303.rs
new file mode 100644
index 000000000..0edff5e4e
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-70303.rs
@@ -0,0 +1,57 @@
+// check-pass
+
+trait Document {
+ type Cursor<'a>: DocCursor<'a> where Self: 'a;
+
+ fn cursor(&self) -> Self::Cursor<'_>;
+}
+
+struct DocumentImpl {}
+
+impl Document for DocumentImpl {
+ type Cursor<'a> = DocCursorImpl<'a>;
+
+ fn cursor(&self) -> Self::Cursor<'_> {
+ DocCursorImpl {
+ document: &self,
+ }
+ }
+}
+
+
+trait DocCursor<'a> {}
+
+struct DocCursorImpl<'a> {
+ document: &'a DocumentImpl,
+}
+
+impl<'a> DocCursor<'a> for DocCursorImpl<'a> {}
+
+struct Lexer<'d, Cursor>
+where
+ Cursor: DocCursor<'d>,
+{
+ cursor: Cursor,
+ _phantom: std::marker::PhantomData<&'d ()>,
+}
+
+
+impl<'d, Cursor> Lexer<'d, Cursor>
+where
+ Cursor: DocCursor<'d>,
+{
+ pub fn from<Doc>(document: &'d Doc) -> Lexer<'d, Cursor>
+ where
+ Doc: Document<Cursor<'d> = Cursor>,
+ {
+ Lexer {
+ cursor: document.cursor(),
+ _phantom: std::marker::PhantomData,
+ }
+ }
+}
+
+pub fn main() {
+ let doc = DocumentImpl {};
+ let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc);
+}
diff --git a/tests/ui/generic-associated-types/issue-70304.rs b/tests/ui/generic-associated-types/issue-70304.rs
new file mode 100644
index 000000000..8898d4c7d
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-70304.rs
@@ -0,0 +1,55 @@
+trait Document {
+ type Cursor<'a>: DocCursor<'a>;
+ //~^ ERROR: missing required bound on `Cursor`
+
+ fn cursor(&self) -> Self::Cursor<'_>;
+}
+
+struct DocumentImpl {}
+
+impl Document for DocumentImpl {
+ type Cursor<'a> = DocCursorImpl<'a>;
+
+ fn cursor(&self) -> Self::Cursor<'_> {
+ DocCursorImpl { document: &self }
+ }
+}
+
+trait DocCursor<'a> {}
+
+struct DocCursorImpl<'a> {
+ document: &'a DocumentImpl,
+}
+
+impl<'a> DocCursor<'a> for DocCursorImpl<'a> {}
+
+struct Lexer<'d, Cursor>
+where
+ Cursor: DocCursor<'d>,
+{
+ cursor: Cursor,
+ _phantom: std::marker::PhantomData<&'d ()>,
+}
+
+impl<'d, Cursor> Lexer<'d, Cursor>
+where
+ Cursor: DocCursor<'d>,
+{
+ pub fn from<Doc>(document: &'d Doc) -> Lexer<'d, Cursor>
+ where
+ Doc: Document<Cursor<'d> = Cursor>,
+ {
+ Lexer { cursor: document.cursor(), _phantom: std::marker::PhantomData }
+ }
+}
+
+fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
+ //~^ ERROR `'_` cannot be used here [E0637]
+ //~| ERROR: missing lifetime specifier
+ DocumentImpl {}
+}
+
+pub fn main() {
+ let doc = create_doc();
+ let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc);
+}
diff --git a/tests/ui/generic-associated-types/issue-70304.stderr b/tests/ui/generic-associated-types/issue-70304.stderr
new file mode 100644
index 000000000..99339e968
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-70304.stderr
@@ -0,0 +1,33 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/issue-70304.rs:46:41
+ |
+LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/issue-70304.rs:46:61
+ |
+LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
+ | ^^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'static>> {
+ | ~~~~~~~
+
+error: missing required bound on `Cursor`
+ --> $DIR/issue-70304.rs:2:5
+ |
+LL | type Cursor<'a>: DocCursor<'a>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'a`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0106, E0637.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs
new file mode 100644
index 000000000..f0e162d82
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-71176.rs
@@ -0,0 +1,18 @@
+trait Provider {
+ type A<'a>;
+}
+
+impl Provider for () {
+ type A<'a> = ();
+}
+
+struct Holder<B> {
+ inner: Box<dyn Provider<A = B>>,
+ //~^ ERROR: missing generics for associated type
+}
+
+fn main() {
+ Holder {
+ inner: Box::new(()),
+ };
+}
diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr
new file mode 100644
index 000000000..4b4fe43e8
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-71176.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `Provider::A`
+ --> $DIR/issue-71176.rs:10:27
+ |
+LL | inner: Box<dyn Provider<A = B>>,
+ | ^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/issue-71176.rs:2:10
+ |
+LL | type A<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | inner: Box<dyn Provider<A<'a> = B>>,
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-74684-1.rs b/tests/ui/generic-associated-types/issue-74684-1.rs
new file mode 100644
index 000000000..e9ec80074
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-74684-1.rs
@@ -0,0 +1,23 @@
+trait Fun {
+ type F<'a>: ?Sized;
+
+ fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t }
+}
+
+impl <T> Fun for T {
+ type F<'a> = [u8];
+}
+
+fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(_ : Box<T>) -> &'static T::F<'a> {
+ let a = [0; 1];
+ let _x = T::identity(&a);
+ //~^ ERROR: `a` does not live long enough
+ todo!()
+}
+
+
+fn main() {
+ let x = 10;
+
+ bug(Box::new(x));
+}
diff --git a/tests/ui/generic-associated-types/issue-74684-1.stderr b/tests/ui/generic-associated-types/issue-74684-1.stderr
new file mode 100644
index 000000000..cacc97307
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-74684-1.stderr
@@ -0,0 +1,18 @@
+error[E0597]: `a` does not live long enough
+ --> $DIR/issue-74684-1.rs:13:26
+ |
+LL | fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(_ : Box<T>) -> &'static T::F<'a> {
+ | -- lifetime `'a` defined here
+LL | let a = [0; 1];
+LL | let _x = T::identity(&a);
+ | ------------^^-
+ | | |
+ | | borrowed value does not live long enough
+ | argument requires that `a` is borrowed for `'a`
+...
+LL | }
+ | - `a` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/generic-associated-types/issue-74684-2.rs b/tests/ui/generic-associated-types/issue-74684-2.rs
new file mode 100644
index 000000000..ff243af2c
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-74684-2.rs
@@ -0,0 +1,23 @@
+trait Fun {
+ type F<'a>: ?Sized;
+
+ fn identity<'a>(t: &'a Self::F<'a>) -> &'a Self::F<'a> { t }
+}
+
+impl <T> Fun for T {
+ type F<'a> = i32;
+}
+
+fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(t: Box<T>) -> &'static T::F<'a> {
+ let a = [0; 1];
+ let x = T::identity(&a);
+ todo!()
+}
+
+
+fn main() {
+ let x = 10;
+
+ bug(Box::new(x));
+ //~^ ERROR: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+}
diff --git a/tests/ui/generic-associated-types/issue-74684-2.stderr b/tests/ui/generic-associated-types/issue-74684-2.stderr
new file mode 100644
index 000000000..59b85abf5
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-74684-2.stderr
@@ -0,0 +1,22 @@
+error[E0271]: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+ --> $DIR/issue-74684-2.rs:21:9
+ |
+LL | bug(Box::new(x));
+ | --- ^^^^^^^^^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+ | |
+ | required by a bound introduced by this call
+ |
+note: expected this to be `[u8]`
+ --> $DIR/issue-74684-2.rs:8:18
+ |
+LL | type F<'a> = i32;
+ | ^^^
+note: required by a bound in `bug`
+ --> $DIR/issue-74684-2.rs:11:28
+ |
+LL | fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(t: Box<T>) -> &'static T::F<'a> {
+ | ^^^^^^^^^^^^ required by this bound in `bug`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/generic-associated-types/issue-74816.rs b/tests/ui/generic-associated-types/issue-74816.rs
new file mode 100644
index 000000000..344afb87f
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-74816.rs
@@ -0,0 +1,21 @@
+#![feature(associated_type_defaults)]
+
+trait Trait1 {
+ fn foo();
+}
+
+trait Trait2 {
+ type Associated: Trait1 = Self;
+ //~^ ERROR: the trait bound `Self: Trait1` is not satisfied
+ //~| the size for values of type `Self` cannot be known
+}
+
+impl Trait2 for () {}
+
+fn call_foo<T: Trait2>() {
+ T::Associated::foo()
+}
+
+fn main() {
+ call_foo::<()>()
+}
diff --git a/tests/ui/generic-associated-types/issue-74816.stderr b/tests/ui/generic-associated-types/issue-74816.stderr
new file mode 100644
index 000000000..45018e697
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-74816.stderr
@@ -0,0 +1,35 @@
+error[E0277]: the trait bound `Self: Trait1` is not satisfied
+ --> $DIR/issue-74816.rs:8:31
+ |
+LL | type Associated: Trait1 = Self;
+ | ^^^^ the trait `Trait1` is not implemented for `Self`
+ |
+note: required by a bound in `Trait2::Associated`
+ --> $DIR/issue-74816.rs:8:22
+ |
+LL | type Associated: Trait1 = Self;
+ | ^^^^^^ required by this bound in `Trait2::Associated`
+help: consider further restricting `Self`
+ |
+LL | trait Trait2: Trait1 {
+ | ++++++++
+
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+ --> $DIR/issue-74816.rs:8:31
+ |
+LL | type Associated: Trait1 = Self;
+ | ^^^^ doesn't have a size known at compile-time
+ |
+note: required by a bound in `Trait2::Associated`
+ --> $DIR/issue-74816.rs:8:5
+ |
+LL | type Associated: Trait1 = Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
+help: consider further restricting `Self`
+ |
+LL | trait Trait2: Sized {
+ | +++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-74824.rs b/tests/ui/generic-associated-types/issue-74824.rs
new file mode 100644
index 000000000..10c45d133
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-74824.rs
@@ -0,0 +1,25 @@
+#![feature(associated_type_defaults)]
+
+use std::ops::Deref;
+
+trait UnsafeCopy {
+ type Copy<T>: Copy = Box<T>;
+ //~^ ERROR the trait bound `Box<T>: Copy` is not satisfied
+ //~^^ ERROR the trait bound `T: Clone` is not satisfied
+ fn copy<T>(x: &Self::Copy<T>) -> Self::Copy<T> {
+ *x
+ }
+}
+
+impl<T> UnsafeCopy for T {}
+
+fn main() {
+ let b = Box::new(42usize);
+ let copy = <()>::copy(&b);
+
+ let raw_b = Box::deref(&b) as *const _;
+ let raw_copy = Box::deref(&copy) as *const _;
+
+ // assert the addresses.
+ assert_eq!(raw_b, raw_copy);
+}
diff --git a/tests/ui/generic-associated-types/issue-74824.stderr b/tests/ui/generic-associated-types/issue-74824.stderr
new file mode 100644
index 000000000..e5638d90e
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-74824.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the trait bound `Box<T>: Copy` is not satisfied
+ --> $DIR/issue-74824.rs:6:26
+ |
+LL | type Copy<T>: Copy = Box<T>;
+ | ^^^^^^ the trait `Copy` is not implemented for `Box<T>`
+ |
+note: required by a bound in `UnsafeCopy::Copy`
+ --> $DIR/issue-74824.rs:6:19
+ |
+LL | type Copy<T>: Copy = Box<T>;
+ | ^^^^ required by this bound in `UnsafeCopy::Copy`
+
+error[E0277]: the trait bound `T: Clone` is not satisfied
+ --> $DIR/issue-74824.rs:6:26
+ |
+LL | type Copy<T>: Copy = Box<T>;
+ | ^^^^^^ the trait `Clone` is not implemented for `T`
+ |
+ = note: required for `Box<T>` to implement `Clone`
+ = note: required for `<Self as UnsafeCopy>::Copy<T>` to implement `Copy`
+note: required by a bound in `UnsafeCopy::Copy`
+ --> $DIR/issue-74824.rs:6:19
+ |
+LL | type Copy<T>: Copy = Box<T>;
+ | ^^^^ required by this bound in `UnsafeCopy::Copy`
+help: consider restricting type parameter `T`
+ |
+LL | type Copy<T: std::clone::Clone>: Copy = Box<T>;
+ | +++++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-76407.rs b/tests/ui/generic-associated-types/issue-76407.rs
new file mode 100644
index 000000000..9556ec6da
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-76407.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+trait Marker {}
+
+impl Marker for u32 {}
+
+trait MyTrait {
+ type Item<'a>;
+}
+
+struct MyStruct;
+
+impl MyTrait for MyStruct {
+ type Item<'a> = u32;
+}
+
+fn ty_check<T>()
+where
+ T: MyTrait,
+ for<'a> T::Item<'a>: Marker
+{}
+
+fn main() {
+ ty_check::<MyStruct>();
+}
diff --git a/tests/ui/generic-associated-types/issue-76535.base.stderr b/tests/ui/generic-associated-types/issue-76535.base.stderr
new file mode 100644
index 000000000..52c6e3eec
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-76535.base.stderr
@@ -0,0 +1,52 @@
+error[E0107]: missing generics for associated type `SuperTrait::SubType`
+ --> $DIR/issue-76535.rs:39:33
+ |
+LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
+ | ^^^^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/issue-76535.rs:9:10
+ |
+LL | type SubType<'a>: SubTrait where Self: 'a;
+ | ^^^^^^^ --
+help: add missing lifetime argument
+ |
+LL | let sub: Box<dyn SuperTrait<SubType<'a> = SubStruct>> = Box::new(SuperStruct::new(0));
+ | ++++
+
+error[E0038]: the trait `SuperTrait` cannot be made into an object
+ --> $DIR/issue-76535.rs:39:14
+ |
+LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-76535.rs:9:10
+ |
+LL | pub trait SuperTrait {
+ | ---------- this trait cannot be made into an object...
+LL | type SubType<'a>: SubTrait where Self: 'a;
+ | ^^^^^^^ ...because it contains the generic associated type `SubType`
+ = help: consider moving `SubType` to another trait
+
+error[E0038]: the trait `SuperTrait` cannot be made into an object
+ --> $DIR/issue-76535.rs:39:57
+ |
+LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-76535.rs:9:10
+ |
+LL | pub trait SuperTrait {
+ | ---------- this trait cannot be made into an object...
+LL | type SubType<'a>: SubTrait where Self: 'a;
+ | ^^^^^^^ ...because it contains the generic associated type `SubType`
+ = help: consider moving `SubType` to another trait
+ = note: required for `Box<SuperStruct>` to implement `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>`
+ = note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0038, E0107.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/generic-associated-types/issue-76535.extended.stderr b/tests/ui/generic-associated-types/issue-76535.extended.stderr
new file mode 100644
index 000000000..369b86d29
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-76535.extended.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `SuperTrait::SubType`
+ --> $DIR/issue-76535.rs:39:33
+ |
+LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
+ | ^^^^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/issue-76535.rs:9:10
+ |
+LL | type SubType<'a>: SubTrait where Self: 'a;
+ | ^^^^^^^ --
+help: add missing lifetime argument
+ |
+LL | let sub: Box<dyn SuperTrait<SubType<'a> = SubStruct>> = Box::new(SuperStruct::new(0));
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-76535.rs b/tests/ui/generic-associated-types/issue-76535.rs
new file mode 100644
index 000000000..2457a05a0
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-76535.rs
@@ -0,0 +1,43 @@
+// revisions: base extended
+
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+pub trait SubTrait {}
+
+pub trait SuperTrait {
+ type SubType<'a>: SubTrait where Self: 'a;
+
+ fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>;
+}
+
+pub struct SubStruct<'a> {
+ sup: &'a mut SuperStruct,
+}
+
+impl<'a> SubTrait for SubStruct<'a> {}
+
+pub struct SuperStruct {
+ value: u8,
+}
+
+impl SuperStruct {
+ pub fn new(value: u8) -> SuperStruct {
+ SuperStruct { value }
+ }
+}
+
+impl SuperTrait for SuperStruct {
+ type SubType<'a> = SubStruct<'a>;
+
+ fn get_sub<'a>(&'a mut self) -> Self::SubType<'a> {
+ SubStruct { sup: self }
+ }
+}
+
+fn main() {
+ let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
+ //~^ ERROR missing generics for associated type
+ //[base]~^^ ERROR the trait
+ //[base]~| ERROR the trait
+}
diff --git a/tests/ui/generic-associated-types/issue-76826.rs b/tests/ui/generic-associated-types/issue-76826.rs
new file mode 100644
index 000000000..ead78453e
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-76826.rs
@@ -0,0 +1,42 @@
+// run-pass
+
+pub trait Iter {
+ type Item<'a> where Self: 'a;
+
+ fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
+
+ fn for_each<F>(mut self, mut f: F)
+ where Self: Sized, F: for<'a> FnMut(Self::Item<'a>)
+ {
+ while let Some(item) = self.next() {
+ f(item);
+ }
+ }
+}
+
+pub struct Windows<T> {
+ items: Vec<T>,
+ start: usize,
+ len: usize,
+}
+
+impl<T> Windows<T> {
+ pub fn new(items: Vec<T>, len: usize) -> Self {
+ Self { items, start: 0, len }
+ }
+}
+
+impl<T> Iter for Windows<T> {
+ type Item<'a> = &'a mut [T] where T: 'a;
+
+ fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
+ let slice = self.items.get_mut(self.start..self.start + self.len)?;
+ self.start += 1;
+ Some(slice)
+ }
+}
+
+fn main() {
+ Windows::new(vec![1, 2, 3, 4, 5], 3)
+ .for_each(|slice| println!("{:?}", slice));
+}
diff --git a/tests/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs b/tests/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
new file mode 100644
index 000000000..fd3b967d9
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
@@ -0,0 +1,38 @@
+// Test for diagnostics when we have mismatched lifetime due to implicit 'static lifetime in GATs
+
+// check-fail
+
+pub trait A {}
+impl A for &dyn A {}
+impl A for Box<dyn A> {}
+
+pub trait B {
+ type T<'a>: A;
+}
+
+impl B for () {
+ // `'a` doesn't match implicit `'static`: suggest `'_`
+ type T<'a> = Box<dyn A + 'a>; //~ incompatible lifetime on type
+}
+
+trait C {}
+impl C for Box<dyn A + 'static> {}
+pub trait D {
+ type T<'a>: C;
+}
+impl D for () {
+ // `'a` doesn't match explicit `'static`: we *should* suggest removing `'static`
+ type T<'a> = Box<dyn A + 'a>; //~ incompatible lifetime on type
+}
+
+trait E {}
+impl E for (Box<dyn A>, Box<dyn A>) {}
+pub trait F {
+ type T<'a>: E;
+}
+impl F for () {
+ // `'a` doesn't match explicit `'static`: suggest `'_`
+ type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>); //~ incompatible lifetime on type
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr b/tests/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
new file mode 100644
index 000000000..86e0f5745
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
@@ -0,0 +1,87 @@
+error: incompatible lifetime on type
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:15:18
+ |
+LL | type T<'a> = Box<dyn A + 'a>;
+ | ^^^^^^^^^^^^^^^
+ |
+note: because this has an unmet lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:10:17
+ |
+LL | type T<'a>: A;
+ | ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined here...
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:15:12
+ |
+LL | type T<'a> = Box<dyn A + 'a>;
+ | ^^
+ = note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+note: this has an implicit `'static` lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:7:20
+ |
+LL | impl A for Box<dyn A> {}
+ | ^
+help: consider relaxing the implicit `'static` requirement
+ |
+LL | impl A for Box<dyn A + '_> {}
+ | ++++
+
+error: incompatible lifetime on type
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:25:18
+ |
+LL | type T<'a> = Box<dyn A + 'a>;
+ | ^^^^^^^^^^^^^^^
+ |
+note: because this has an unmet lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:21:17
+ |
+LL | type T<'a>: C;
+ | ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined here...
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:25:12
+ |
+LL | type T<'a> = Box<dyn A + 'a>;
+ | ^^
+note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:19:1
+ |
+LL | impl C for Box<dyn A + 'static> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incompatible lifetime on type
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:35:18
+ |
+LL | type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: because this has an unmet lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:17
+ |
+LL | type T<'a>: E;
+ | ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined here...
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:35:12
+ |
+LL | type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
+ | ^^
+ = note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+note: this has an implicit `'static` lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:29:21
+ |
+LL | impl E for (Box<dyn A>, Box<dyn A>) {}
+ | ^
+note: this has an implicit `'static` lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:29:33
+ |
+LL | impl E for (Box<dyn A>, Box<dyn A>) {}
+ | ^
+help: consider relaxing the implicit `'static` requirement
+ |
+LL | impl E for (Box<dyn A + '_>, Box<dyn A>) {}
+ | ++++
+help: consider relaxing the implicit `'static` requirement
+ |
+LL | impl E for (Box<dyn A>, Box<dyn A + '_>) {}
+ | ++++
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/generic-associated-types/issue-78671.base.stderr b/tests/ui/generic-associated-types/issue-78671.base.stderr
new file mode 100644
index 000000000..bad8c1c9d
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-78671.base.stderr
@@ -0,0 +1,35 @@
+error[E0107]: missing generics for associated type `CollectionFamily::Member`
+ --> $DIR/issue-78671.rs:10:47
+ |
+LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
+ | ^^^^^^ expected 1 generic argument
+ |
+note: associated type defined here, with 1 generic parameter: `T`
+ --> $DIR/issue-78671.rs:7:10
+ |
+LL | type Member<T>;
+ | ^^^^^^ -
+help: add missing generic argument
+ |
+LL | Box::new(Family) as &dyn CollectionFamily<Member<T>=usize>
+ | +++
+
+error[E0038]: the trait `CollectionFamily` cannot be made into an object
+ --> $DIR/issue-78671.rs:10:25
+ |
+LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-78671.rs:7:10
+ |
+LL | trait CollectionFamily {
+ | ---------------- this trait cannot be made into an object...
+LL | type Member<T>;
+ | ^^^^^^ ...because it contains the generic associated type `Member`
+ = help: consider moving `Member` to another trait
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0038, E0107.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/generic-associated-types/issue-78671.extended.stderr b/tests/ui/generic-associated-types/issue-78671.extended.stderr
new file mode 100644
index 000000000..1d8a3d410
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-78671.extended.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `CollectionFamily::Member`
+ --> $DIR/issue-78671.rs:10:47
+ |
+LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
+ | ^^^^^^ expected 1 generic argument
+ |
+note: associated type defined here, with 1 generic parameter: `T`
+ --> $DIR/issue-78671.rs:7:10
+ |
+LL | type Member<T>;
+ | ^^^^^^ -
+help: add missing generic argument
+ |
+LL | Box::new(Family) as &dyn CollectionFamily<Member<T>=usize>
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-78671.rs b/tests/ui/generic-associated-types/issue-78671.rs
new file mode 100644
index 000000000..327b0c14a
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-78671.rs
@@ -0,0 +1,17 @@
+// revisions: base extended
+
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+trait CollectionFamily {
+ type Member<T>;
+}
+fn floatify() {
+ Box::new(Family) as &dyn CollectionFamily<Member=usize>
+ //~^ ERROR: missing generics for associated type
+ //[base]~^^ ERROR: the trait `CollectionFamily` cannot be made into an object
+}
+
+struct Family;
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-79422.base.stderr b/tests/ui/generic-associated-types/issue-79422.base.stderr
new file mode 100644
index 000000000..f1de77bc3
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-79422.base.stderr
@@ -0,0 +1,52 @@
+error[E0107]: missing generics for associated type `MapLike::VRefCont`
+ --> $DIR/issue-79422.rs:47:36
+ |
+LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
+ | ^^^^^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/issue-79422.rs:23:10
+ |
+LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
+ | ^^^^^^^^ --
+help: add missing lifetime argument
+ |
+LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
+ | ++++
+
+error[E0038]: the trait `MapLike` cannot be made into an object
+ --> $DIR/issue-79422.rs:47:12
+ |
+LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-79422.rs:23:10
+ |
+LL | trait MapLike<K, V> {
+ | ------- this trait cannot be made into an object...
+LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
+ | ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
+ = help: consider moving `VRefCont` to another trait
+
+error[E0038]: the trait `MapLike` cannot be made into an object
+ --> $DIR/issue-79422.rs:44:13
+ |
+LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-79422.rs:23:10
+ |
+LL | trait MapLike<K, V> {
+ | ------- this trait cannot be made into an object...
+LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
+ | ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
+ = help: consider moving `VRefCont` to another trait
+ = note: required for `Box<BTreeMap<u8, u8>>` to implement `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>`
+ = note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0038, E0107.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/generic-associated-types/issue-79422.extended.stderr b/tests/ui/generic-associated-types/issue-79422.extended.stderr
new file mode 100644
index 000000000..d79de0ca6
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-79422.extended.stderr
@@ -0,0 +1,35 @@
+error[E0107]: missing generics for associated type `MapLike::VRefCont`
+ --> $DIR/issue-79422.rs:47:36
+ |
+LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
+ | ^^^^^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/issue-79422.rs:23:10
+ |
+LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
+ | ^^^^^^^^ --
+help: add missing lifetime argument
+ |
+LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
+ | ++++
+
+error[E0271]: type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)`
+ --> $DIR/issue-79422.rs:44:13
+ |
+LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'_> == (dyn RefCont<'_, u8> + 'static)`
+ |
+note: expected this to be `(dyn RefCont<'_, u8> + 'static)`
+ --> $DIR/issue-79422.rs:28:25
+ |
+LL | type VRefCont<'a> = &'a V where Self: 'a;
+ | ^^^^^
+ = note: expected trait object `(dyn RefCont<'_, u8> + 'static)`
+ found reference `&u8`
+ = note: required for the cast from `BTreeMap<u8, u8>` to the object type `dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0107, E0271.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-79422.rs b/tests/ui/generic-associated-types/issue-79422.rs
new file mode 100644
index 000000000..a52dd792d
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-79422.rs
@@ -0,0 +1,50 @@
+// revisions: base extended
+
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+trait RefCont<'a, T> {
+ fn t(&'a self) -> &'a T;
+}
+
+impl<'a, T> RefCont<'a, T> for &'a T {
+ fn t(&'a self) -> &'a T {
+ self
+ }
+}
+
+impl<'a, T> RefCont<'a, T> for Box<T> {
+ fn t(&'a self) -> &'a T {
+ self.as_ref()
+ }
+}
+
+trait MapLike<K, V> {
+ type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
+ fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>;
+}
+
+impl<K: Ord, V: 'static> MapLike<K, V> for std::collections::BTreeMap<K, V> {
+ type VRefCont<'a> = &'a V where Self: 'a;
+ fn get<'a>(&'a self, key: &K) -> Option<&'a V> {
+ std::collections::BTreeMap::get(self, key)
+ }
+}
+
+struct Source;
+
+impl<K, V: Default> MapLike<K, V> for Source {
+ type VRefCont<'a> = Box<V>;
+ fn get<'a>(&self, _: &K) -> Option<Box<V>> {
+ Some(Box::new(V::default()))
+ }
+}
+
+fn main() {
+ let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
+ //[base]~^ ERROR the trait
+ //[extended]~^^ type mismatch
+ as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
+ //~^ ERROR missing generics for associated type
+ //[base]~^^ ERROR the trait
+}
diff --git a/tests/ui/generic-associated-types/issue-79636-1.rs b/tests/ui/generic-associated-types/issue-79636-1.rs
new file mode 100644
index 000000000..a89039b5c
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-79636-1.rs
@@ -0,0 +1,21 @@
+trait Monad {
+ type Unwrapped;
+ type Wrapped<B>;
+
+ fn bind<B, F>(self, f: F) -> Self::Wrapped<B> {
+ todo!()
+ }
+}
+
+fn join<MOuter, MInner, A>(outer: MOuter) -> MOuter::Wrapped<A>
+where
+ MOuter: Monad<Unwrapped = MInner>,
+ MInner: Monad<Unwrapped = A, Wrapped = MOuter::Wrapped<A>>,
+ //~^ ERROR: missing generics for associated type `Monad::Wrapped`
+{
+ outer.bind(|inner| inner)
+}
+
+fn main() {
+ assert_eq!(join(Some(Some(true))), Some(true));
+}
diff --git a/tests/ui/generic-associated-types/issue-79636-1.stderr b/tests/ui/generic-associated-types/issue-79636-1.stderr
new file mode 100644
index 000000000..6e0d2ff4d
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-79636-1.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `Monad::Wrapped`
+ --> $DIR/issue-79636-1.rs:13:34
+ |
+LL | MInner: Monad<Unwrapped = A, Wrapped = MOuter::Wrapped<A>>,
+ | ^^^^^^^ expected 1 generic argument
+ |
+note: associated type defined here, with 1 generic parameter: `B`
+ --> $DIR/issue-79636-1.rs:3:10
+ |
+LL | type Wrapped<B>;
+ | ^^^^^^^ -
+help: add missing generic argument
+ |
+LL | MInner: Monad<Unwrapped = A, Wrapped<B> = MOuter::Wrapped<A>>,
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-79636-2.rs b/tests/ui/generic-associated-types/issue-79636-2.rs
new file mode 100644
index 000000000..ff5ff38c9
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-79636-2.rs
@@ -0,0 +1,15 @@
+trait SomeTrait {
+ type Wrapped<A>: SomeTrait;
+
+ fn f() -> ();
+}
+
+fn program<W>() -> ()
+where
+ W: SomeTrait<Wrapped = W>,
+ //~^ ERROR: missing generics for associated type `SomeTrait::Wrapped`
+{
+ return W::f();
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-79636-2.stderr b/tests/ui/generic-associated-types/issue-79636-2.stderr
new file mode 100644
index 000000000..162873239
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-79636-2.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `SomeTrait::Wrapped`
+ --> $DIR/issue-79636-2.rs:9:18
+ |
+LL | W: SomeTrait<Wrapped = W>,
+ | ^^^^^^^ expected 1 generic argument
+ |
+note: associated type defined here, with 1 generic parameter: `A`
+ --> $DIR/issue-79636-2.rs:2:10
+ |
+LL | type Wrapped<A>: SomeTrait;
+ | ^^^^^^^ -
+help: add missing generic argument
+ |
+LL | W: SomeTrait<Wrapped<A> = W>,
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-80433-reduced.rs b/tests/ui/generic-associated-types/issue-80433-reduced.rs
new file mode 100644
index 000000000..44831a995
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-80433-reduced.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+struct E {}
+
+trait TestMut {
+ type Output<'a>;
+ fn test_mut(&mut self) -> Self::Output<'static>;
+}
+
+impl TestMut for E {
+ type Output<'a> = usize;
+ fn test_mut(&mut self) -> Self::Output<'static> {
+ todo!()
+ }
+}
+
+fn test_simpler<'a>(_: impl TestMut<Output<'a> = usize>) {}
+
+fn main() {
+ test_simpler(E {});
+}
diff --git a/tests/ui/generic-associated-types/issue-80433.rs b/tests/ui/generic-associated-types/issue-80433.rs
new file mode 100644
index 000000000..05ff82fa7
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-80433.rs
@@ -0,0 +1,32 @@
+#[derive(Default)]
+struct E<T> {
+ data: T,
+}
+
+trait TestMut {
+ type Output<'a>;
+ fn test_mut<'a>(&'a mut self) -> Self::Output<'a>;
+}
+
+impl<T> TestMut for E<T>
+where
+ T: 'static,
+{
+ type Output<'a> = &'a mut T;
+ fn test_mut<'a>(&'a mut self) -> Self::Output<'a> {
+ &mut self.data
+ }
+}
+
+fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
+ //~^ ERROR missing generics for associated type
+{
+ for n in 0i16..100 {
+ *dst.test_mut() = n.into();
+ }
+}
+
+fn main() {
+ let mut t1: E<f32> = Default::default();
+ test_simpler(&mut t1);
+}
diff --git a/tests/ui/generic-associated-types/issue-80433.stderr b/tests/ui/generic-associated-types/issue-80433.stderr
new file mode 100644
index 000000000..4f4f96a4b
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-80433.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `TestMut::Output`
+ --> $DIR/issue-80433.rs:21:47
+ |
+LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
+ | ^^^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/issue-80433.rs:7:10
+ |
+LL | type Output<'a>;
+ | ^^^^^^ --
+help: add missing lifetime argument
+ |
+LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output<'a> = &'a mut f32>)
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-81487.rs b/tests/ui/generic-associated-types/issue-81487.rs
new file mode 100644
index 000000000..0d19a75bb
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-81487.rs
@@ -0,0 +1,17 @@
+// build-pass
+
+trait Trait {
+ type Ref<'a>;
+}
+
+impl Trait for () {
+ type Ref<'a> = &'a i8;
+}
+
+struct RefRef<'a, T: Trait>(&'a <T as Trait>::Ref<'a>);
+
+fn wrap<'a, T: Trait>(reff: &'a <T as Trait>::Ref<'a>) -> RefRef<'a, T> {
+ RefRef(reff)
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-81712-cyclic-traits.rs b/tests/ui/generic-associated-types/issue-81712-cyclic-traits.rs
new file mode 100644
index 000000000..a7cc9a605
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-81712-cyclic-traits.rs
@@ -0,0 +1,18 @@
+// Regression test for #81712.
+
+trait A {
+ type BType: B<AType = Self>;
+}
+
+trait B {
+ type AType: A<BType = Self>;
+}
+trait C {
+ type DType<T>: D<T, CType = Self>;
+}
+trait D<T> {
+ type CType: C<DType = Self>;
+ //~^ ERROR missing generics for associated type
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-81712-cyclic-traits.stderr b/tests/ui/generic-associated-types/issue-81712-cyclic-traits.stderr
new file mode 100644
index 000000000..e0fc225f4
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-81712-cyclic-traits.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `C::DType`
+ --> $DIR/issue-81712-cyclic-traits.rs:14:19
+ |
+LL | type CType: C<DType = Self>;
+ | ^^^^^ expected 1 generic argument
+ |
+note: associated type defined here, with 1 generic parameter: `T`
+ --> $DIR/issue-81712-cyclic-traits.rs:11:10
+ |
+LL | type DType<T>: D<T, CType = Self>;
+ | ^^^^^ -
+help: add missing generic argument
+ |
+LL | type CType: C<DType<T> = Self>;
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-81862.rs b/tests/ui/generic-associated-types/issue-81862.rs
new file mode 100644
index 000000000..bde828b77
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-81862.rs
@@ -0,0 +1,10 @@
+trait StreamingIterator {
+ type Item<'a>;
+ fn next(&mut self) -> Option<Self::Item>;
+ //~^ ERROR missing generics for associated type
+}
+
+fn main() {}
+
+// call stack from back to front:
+// create_substs_for_assoc_ty -> qpath_to_ty -> res_to_ty -> ast_ty_to_ty -> ty_of_fn
diff --git a/tests/ui/generic-associated-types/issue-81862.stderr b/tests/ui/generic-associated-types/issue-81862.stderr
new file mode 100644
index 000000000..df30be65e
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-81862.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `StreamingIterator::Item`
+ --> $DIR/issue-81862.rs:3:40
+ |
+LL | fn next(&mut self) -> Option<Self::Item>;
+ | ^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/issue-81862.rs:2:10
+ |
+LL | type Item<'a>;
+ | ^^^^ --
+help: add missing lifetime argument
+ |
+LL | fn next(&mut self) -> Option<Self::Item<'_>>;
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-84931.rs b/tests/ui/generic-associated-types/issue-84931.rs
new file mode 100644
index 000000000..4123ce9d4
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-84931.rs
@@ -0,0 +1,21 @@
+// check-fail
+
+trait StreamingIter {
+ type Item<'a> where Self: 'a;
+ fn next<'a>(&'a mut self) -> Option<Self::Item::<'a>>;
+}
+
+struct StreamingSliceIter<'a, T> {
+ idx: usize,
+ data: &'a mut [T],
+}
+
+impl<'b, T: 'b> StreamingIter for StreamingSliceIter<'b, T> {
+ type Item<'a> = &'a mut T;
+ //~^ the parameter type
+ fn next(&mut self) -> Option<&mut T> {
+ loop {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-84931.stderr b/tests/ui/generic-associated-types/issue-84931.stderr
new file mode 100644
index 000000000..fffea98a4
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-84931.stderr
@@ -0,0 +1,11 @@
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/issue-84931.rs:14:21
+ |
+LL | type Item<'a> = &'a mut T;
+ | ^^^^^^^^^- help: consider adding a where clause: `where T: 'a`
+ | |
+ | ...so that the reference type `&'a mut T` does not outlive the data it points at
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0309`.
diff --git a/tests/ui/generic-associated-types/issue-85921.rs b/tests/ui/generic-associated-types/issue-85921.rs
new file mode 100644
index 000000000..d281ed9ee
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-85921.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+trait Trait {
+ type Assoc<'a>;
+
+ fn with_assoc(f: impl FnOnce(Self::Assoc<'_>));
+}
+
+impl Trait for () {
+ type Assoc<'a> = i32;
+
+ fn with_assoc(f: impl FnOnce(Self::Assoc<'_>)) {
+ f(5i32)
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-86218-2.rs b/tests/ui/generic-associated-types/issue-86218-2.rs
new file mode 100644
index 000000000..63c839ea8
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-86218-2.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+pub trait Stream {
+ type Item;
+}
+
+impl Stream for () {
+ type Item = i32;
+}
+
+trait Yay<AdditionalValue> {
+ type InnerStream<'s>: Stream<Item = i32> + 's;
+ fn foo<'s>() -> Self::InnerStream<'s>;
+}
+
+impl<T> Yay<T> for () {
+ type InnerStream<'s> = impl Stream<Item = i32> + 's;
+ fn foo<'s>() -> Self::InnerStream<'s> { () }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-86218.rs b/tests/ui/generic-associated-types/issue-86218.rs
new file mode 100644
index 000000000..b2c3071f0
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-86218.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+pub trait Stream {
+ type Item;
+}
+
+impl Stream for () {
+ type Item = i32;
+}
+
+trait Yay<AdditionalValue> {
+ type InnerStream<'s>: Stream<Item = i32> + 's;
+ fn foo<'s>() -> Self::InnerStream<'s>;
+}
+
+impl<'a> Yay<&'a ()> for () {
+ type InnerStream<'s> = impl Stream<Item = i32> + 's;
+ //^ ERROR does not fulfill the required lifetime
+ fn foo<'s>() -> Self::InnerStream<'s> { () }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-86483.rs b/tests/ui/generic-associated-types/issue-86483.rs
new file mode 100644
index 000000000..70267637a
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-86483.rs
@@ -0,0 +1,14 @@
+// Regression test of #86483.
+//
+// Made to pass as part of fixing #98095.
+//
+// check-pass
+
+pub trait IceIce<T>
+where
+ for<'a> T: 'a,
+{
+ type Ice<'v>: IntoIterator<Item = &'v T>;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-86787.rs b/tests/ui/generic-associated-types/issue-86787.rs
new file mode 100644
index 000000000..96075ca50
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-86787.rs
@@ -0,0 +1,37 @@
+// check-fail
+
+enum Either<L, R> {
+ Left(L),
+ Right(R),
+}
+
+pub trait HasChildrenOf {
+ type T;
+ type TRef<'a>;
+ //~^ missing required
+
+ fn ref_children<'a>(&'a self) -> Vec<Self::TRef<'a>>;
+ fn take_children(self) -> Vec<Self::T>;
+}
+
+impl<Left, Right> HasChildrenOf for Either<Left, Right>
+where
+ Left: HasChildrenOf,
+ Right: HasChildrenOf,
+{
+ type T = Either<Left::T, Right::T>;
+ type TRef<'a> = Either<&'a Left::T, &'a Right::T>
+ where
+ <Left as HasChildrenOf>::T: 'a,
+ <Right as HasChildrenOf>::T: 'a;
+
+ fn ref_children<'a>(&'a self) -> Vec<Self::TRef<'a>> {
+ todo!()
+ }
+
+ fn take_children(self) -> Vec<Self::T> {
+ todo!()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-86787.stderr b/tests/ui/generic-associated-types/issue-86787.stderr
new file mode 100644
index 000000000..f34c63cf7
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-86787.stderr
@@ -0,0 +1,13 @@
+error: missing required bound on `TRef`
+ --> $DIR/issue-86787.rs:10:5
+ |
+LL | type TRef<'a>;
+ | ^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'a`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-associated-types/issue-87258_a.rs b/tests/ui/generic-associated-types/issue-87258_a.rs
new file mode 100644
index 000000000..9ab683d3d
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87258_a.rs
@@ -0,0 +1,24 @@
+#![feature(type_alias_impl_trait)]
+
+// See https://github.com/rust-lang/rust/issues/87258#issuecomment-883293367
+
+trait Trait1 {}
+
+struct Struct<'b>(&'b ());
+
+impl<'d> Trait1 for Struct<'d> {}
+
+pub trait Trait2 {
+ type FooFuture<'a>: Trait1;
+ fn foo<'a>() -> Self::FooFuture<'a>;
+}
+
+impl<'c, S: Trait2> Trait2 for &'c mut S {
+ type FooFuture<'a> = impl Trait1;
+ //~^ ERROR unconstrained opaque type
+ fn foo<'a>() -> Self::FooFuture<'a> {
+ Struct(unimplemented!())
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-87258_a.stderr b/tests/ui/generic-associated-types/issue-87258_a.stderr
new file mode 100644
index 000000000..eae9bd9b1
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87258_a.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/issue-87258_a.rs:17:26
+ |
+LL | type FooFuture<'a> = impl Trait1;
+ | ^^^^^^^^^^^
+ |
+ = note: `FooFuture` must be used in combination with a concrete type within the same impl
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-associated-types/issue-87258_b.rs b/tests/ui/generic-associated-types/issue-87258_b.rs
new file mode 100644
index 000000000..7b7610b21
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87258_b.rs
@@ -0,0 +1,26 @@
+#![feature(type_alias_impl_trait)]
+
+// See https://github.com/rust-lang/rust/issues/87258#issuecomment-883293367
+
+trait Trait1 {}
+
+struct Struct<'b>(&'b ());
+
+impl<'d> Trait1 for Struct<'d> {}
+
+pub trait Trait2 {
+ type FooFuture<'a>: Trait1;
+ fn foo<'a>() -> Self::FooFuture<'a>;
+}
+
+type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1;
+//~^ ERROR unconstrained opaque type
+
+impl<'c, S: Trait2> Trait2 for &'c mut S {
+ type FooFuture<'a> = Helper<'c, 'a, S>;
+ fn foo<'a>() -> Self::FooFuture<'a> {
+ Struct(unimplemented!())
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-87258_b.stderr b/tests/ui/generic-associated-types/issue-87258_b.stderr
new file mode 100644
index 000000000..0ee665f38
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87258_b.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/issue-87258_b.rs:16:49
+ |
+LL | type Helper<'xenon, 'yttrium, KABOOM: Trait2> = impl Trait1;
+ | ^^^^^^^^^^^
+ |
+ = note: `Helper` must be used in combination with a concrete type within the same module
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-associated-types/issue-87429-2.rs b/tests/ui/generic-associated-types/issue-87429-2.rs
new file mode 100644
index 000000000..feb43ee5a
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87429-2.rs
@@ -0,0 +1,18 @@
+// Derived from `issue-87429`. A test that ensures that using bound vars in the
+// predicates in the param env when checking that an associated type satisfies
+// its bounds does not cause us to not be able to use the bounds on the parameters.
+
+// check-pass
+
+trait Family {
+ type Member<'a, C: Eq>: for<'b> MyBound<'b, C>;
+}
+
+trait MyBound<'a, C> { }
+impl<'a, C: Eq> MyBound<'a, C> for i32 { }
+
+impl Family for () {
+ type Member<'a, C: Eq> = i32;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-87429-associated-type-default.rs b/tests/ui/generic-associated-types/issue-87429-associated-type-default.rs
new file mode 100644
index 000000000..2006f9bc7
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87429-associated-type-default.rs
@@ -0,0 +1,17 @@
+// check-fail
+
+#![feature(associated_type_defaults)]
+
+trait Family {
+ // Fine, i32: PartialEq<i32>
+ type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = i32;
+}
+
+struct Foo;
+trait Family2 {
+ // Not fine, not Foo: PartialEq<Foo>
+ type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo;
+ //~^ ERROR can't compare
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-87429-associated-type-default.stderr b/tests/ui/generic-associated-types/issue-87429-associated-type-default.stderr
new file mode 100644
index 000000000..b1abe012b
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87429-associated-type-default.stderr
@@ -0,0 +1,20 @@
+error[E0277]: can't compare `Foo` with `Foo`
+ --> $DIR/issue-87429-associated-type-default.rs:13:60
+ |
+LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo;
+ | ^^^ no implementation for `Foo == Foo`
+ |
+ = help: the trait `PartialEq` is not implemented for `Foo`
+note: required by a bound in `Family2::Member`
+ --> $DIR/issue-87429-associated-type-default.rs:13:22
+ |
+LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family2::Member`
+help: consider annotating `Foo` with `#[derive(PartialEq)]`
+ |
+LL | #[derive(PartialEq)]
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-87429-specialization.rs b/tests/ui/generic-associated-types/issue-87429-specialization.rs
new file mode 100644
index 000000000..6e31f1b21
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87429-specialization.rs
@@ -0,0 +1,24 @@
+// check-fail
+
+#![feature(specialization)]
+//~^ WARN incomplete
+
+trait Family {
+ type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
+}
+
+struct I32Family;
+
+impl Family for I32Family {
+ default type Member<'a> = i32;
+}
+
+struct Foo;
+struct FooFamily;
+
+impl Family for FooFamily {
+ default type Member<'a> = Foo;
+ //~^ ERROR can't compare
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-87429-specialization.stderr b/tests/ui/generic-associated-types/issue-87429-specialization.stderr
new file mode 100644
index 000000000..11c4ebf60
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87429-specialization.stderr
@@ -0,0 +1,30 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/issue-87429-specialization.rs:3:12
+ |
+LL | #![feature(specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: can't compare `Foo` with `Foo`
+ --> $DIR/issue-87429-specialization.rs:20:31
+ |
+LL | default type Member<'a> = Foo;
+ | ^^^ no implementation for `Foo == Foo`
+ |
+ = help: the trait `PartialEq` is not implemented for `Foo`
+note: required by a bound in `Family::Member`
+ --> $DIR/issue-87429-specialization.rs:7:22
+ |
+LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family::Member`
+help: consider annotating `Foo` with `#[derive(PartialEq)]`
+ |
+LL | #[derive(PartialEq)]
+ |
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-87429.rs b/tests/ui/generic-associated-types/issue-87429.rs
new file mode 100644
index 000000000..56394823c
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87429.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+trait Family {
+ type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
+}
+
+struct I32;
+
+impl Family for I32 {
+ type Member<'a> = i32;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-87748.rs b/tests/ui/generic-associated-types/issue-87748.rs
new file mode 100644
index 000000000..6cbe3d902
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87748.rs
@@ -0,0 +1,21 @@
+// Checks that we properly add implied bounds from unnormalized projections in
+// inputs when typechecking functions.
+
+// check-pass
+
+trait MyTrait {
+ type Assoc<'a, 'b> where 'b: 'a;
+ fn do_sth(arg: Self::Assoc<'_, '_>);
+ fn do_sth2(arg: Self::Assoc<'_, '_>) {}
+}
+
+struct Foo;
+
+impl MyTrait for Foo {
+ type Assoc<'a, 'b> = u32 where 'b: 'a;
+
+ fn do_sth(_: u32) {}
+ fn do_sth2(_: Self::Assoc<'static, 'static>) {}
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-87750.rs b/tests/ui/generic-associated-types/issue-87750.rs
new file mode 100644
index 000000000..b35657989
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-87750.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+trait PointerFamily {
+ type Pointer<T>;
+}
+
+struct Rc<T>(Box<T>);
+struct RcFamily;
+
+impl PointerFamily for RcFamily {
+ type Pointer<T> = Rc<T>;
+}
+
+#[allow(dead_code)]
+enum Node<T, P: PointerFamily>
+where
+ P::Pointer<Node<T, P>>: Sized,
+{
+ Cons(P::Pointer<Node<T, P>>),
+}
+
+fn main() {
+ let _list: <RcFamily as PointerFamily>::Pointer<Node<i32, RcFamily>>;
+}
diff --git a/tests/ui/generic-associated-types/issue-88287.rs b/tests/ui/generic-associated-types/issue-88287.rs
new file mode 100644
index 000000000..82188493d
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-88287.rs
@@ -0,0 +1,39 @@
+// edition:2018
+
+#![feature(type_alias_impl_trait)]
+
+use std::future::Future;
+
+trait SearchableResource<Criteria> {
+ type SearchResult;
+}
+
+trait SearchableResourceExt<Criteria>: SearchableResource<Criteria> {
+ type Future<'f, A: 'f + ?Sized, B: 'f>: Future<Output = Result<Vec<A::SearchResult>, ()>> + 'f
+ where
+ A: SearchableResource<B>,
+ Self: 'f;
+
+ fn search<'c>(&'c self, client: &'c ()) -> Self::Future<'c, Self, Criteria>;
+}
+
+type SearchFutureTy<'f, A, B: 'f>
+where
+ A: SearchableResource<B> + ?Sized + 'f,
+= impl Future<Output = Result<Vec<A::SearchResult>, ()>> + 'f;
+impl<T, Criteria> SearchableResourceExt<Criteria> for T
+where
+ T: SearchableResource<Criteria>,
+{
+ type Future<'f, A, B: 'f> = SearchFutureTy<'f, A, B>
+ where
+ A: SearchableResource<B> + ?Sized + 'f,
+ Self: 'f;
+
+ fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> {
+ async move { todo!() }
+ //~^ ERROR: the size for values of type `A` cannot be known at compilation time
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-88287.stderr b/tests/ui/generic-associated-types/issue-88287.stderr
new file mode 100644
index 000000000..1b84cce62
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-88287.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+ --> $DIR/issue-88287.rs:34:9
+ |
+LL | type SearchFutureTy<'f, A, B: 'f>
+ | - this type parameter needs to be `std::marker::Sized`
+...
+LL | async move { todo!() }
+ | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+note: required by a bound in `<T as SearchableResourceExt<Criteria>>`
+ --> $DIR/issue-88287.rs:24:6
+ |
+LL | impl<T, Criteria> SearchableResourceExt<Criteria> for T
+ | ^ required by this bound in `<T as SearchableResourceExt<Criteria>>`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+ |
+LL - A: SearchableResource<B> + ?Sized + 'f,
+LL + A: SearchableResource<B> + 'f,
+ |
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | T: SearchableResource<Criteria> + ?Sized,
+ | ++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/issue-88360.rs b/tests/ui/generic-associated-types/issue-88360.rs
new file mode 100644
index 000000000..c02690618
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-88360.rs
@@ -0,0 +1,18 @@
+trait GatTrait {
+ type Gat<'a> where Self: 'a;
+
+ fn test(&self) -> Self::Gat<'_>;
+}
+
+trait SuperTrait<T>
+where
+ Self: 'static,
+ for<'a> Self: GatTrait<Gat<'a> = &'a T>,
+{
+ fn copy(&self) -> Self::Gat<'_> where T: Copy {
+ *self.test()
+ //~^ mismatched types
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-88360.stderr b/tests/ui/generic-associated-types/issue-88360.stderr
new file mode 100644
index 000000000..cd3750344
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-88360.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-88360.rs:13:9
+ |
+LL | trait SuperTrait<T>
+ | - this type parameter
+...
+LL | fn copy(&self) -> Self::Gat<'_> where T: Copy {
+ | ------------- expected `&T` because of return type
+LL | *self.test()
+ | ^^^^^^^^^^^^
+ | |
+ | expected `&T`, found type parameter `T`
+ | help: consider borrowing here: `&*self.test()`
+ |
+ = note: expected reference `&T`
+ found type parameter `T`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/generic-associated-types/issue-88405.rs b/tests/ui/generic-associated-types/issue-88405.rs
new file mode 100644
index 000000000..8dad6a89f
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-88405.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+trait SomeTrait {}
+trait OtherTrait {
+ type Item;
+}
+
+trait ErrorSimpleExample {
+ type AssociatedType: SomeTrait;
+ type GatBounded<T: SomeTrait>;
+ type ErrorMinimal: OtherTrait<Item = Self::GatBounded<Self::AssociatedType>>;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-88459.rs b/tests/ui/generic-associated-types/issue-88459.rs
new file mode 100644
index 000000000..07d7bc06d
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-88459.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+trait Trait {
+ type Assoc<'a>;
+}
+
+fn f<T: Trait>(_: T, _: impl Fn(T::Assoc<'_>)) {}
+
+struct Type;
+
+impl Trait for Type {
+ type Assoc<'a> = ();
+}
+
+fn main() {
+ f(Type, |_|());
+}
diff --git a/tests/ui/generic-associated-types/issue-88595.rs b/tests/ui/generic-associated-types/issue-88595.rs
new file mode 100644
index 000000000..24641ee1f
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-88595.rs
@@ -0,0 +1,21 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+trait A<'a> {
+ type B<'b>: Clone
+ // FIXME(generic_associated_types): Remove one of the below bounds
+ // https://github.com/rust-lang/rust/pull/90678#discussion_r744976085
+ where
+ Self: 'a, Self: 'b;
+
+ fn a(&'a self) -> Self::B<'a>;
+}
+
+struct C;
+
+impl<'a> A<'a> for C {
+ type B<'b> = impl Clone;
+
+ fn a(&'a self) -> Self::B<'a> {} //~ ERROR: non-defining opaque type use in defining scope
+}
diff --git a/tests/ui/generic-associated-types/issue-88595.stderr b/tests/ui/generic-associated-types/issue-88595.stderr
new file mode 100644
index 000000000..bcefc8066
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-88595.stderr
@@ -0,0 +1,16 @@
+error: non-defining opaque type use in defining scope
+ --> $DIR/issue-88595.rs:20:35
+ |
+LL | fn a(&'a self) -> Self::B<'a> {}
+ | ^^
+ |
+note: lifetime used multiple times
+ --> $DIR/issue-88595.rs:17:6
+ |
+LL | impl<'a> A<'a> for C {
+ | ^^
+LL | type B<'b> = impl Clone;
+ | ^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-associated-types/issue-89008.rs b/tests/ui/generic-associated-types/issue-89008.rs
new file mode 100644
index 000000000..669dbafb5
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-89008.rs
@@ -0,0 +1,37 @@
+// check-pass
+// edition:2021
+
+#![feature(type_alias_impl_trait)]
+
+use std::future::Future;
+use std::marker::PhantomData;
+
+trait Stream {
+ type Item;
+}
+
+struct Empty<T> {
+ _phantom: PhantomData<T>,
+}
+
+impl<T> Stream for Empty<T> {
+ type Item = T;
+}
+
+trait X {
+ type LineStream<'a, Repr>: Stream<Item = Repr> where Self: 'a;
+ type LineStreamFut<'a, Repr>: Future<Output = Self::LineStream<'a, Repr>> where Self: 'a;
+ fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr>;
+}
+
+struct Y;
+
+impl X for Y {
+ type LineStream<'a, Repr> = impl Stream<Item = Repr>;
+ type LineStreamFut<'a, Repr> = impl Future<Output = Self::LineStream<'a, Repr>>;
+ fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
+ async { Empty { _phantom: PhantomData } }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-89352.rs b/tests/ui/generic-associated-types/issue-89352.rs
new file mode 100644
index 000000000..1896d0c87
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-89352.rs
@@ -0,0 +1,30 @@
+// check-pass
+
+use std::marker::PhantomData;
+
+pub trait GenAssoc<T> {
+ type Iter<'at>;
+ fn iter(&self) -> Self::Iter<'_>;
+ fn reborrow<'longt: 'shortt, 'shortt>(iter: Self::Iter<'longt>) -> Self::Iter<'shortt>;
+}
+
+pub struct Wrapper<'a, T: 'a, A: GenAssoc<T>> {
+ a: A::Iter<'a>,
+ _p: PhantomData<T>,
+}
+
+impl<'ai, T: 'ai, A: GenAssoc<T>> GenAssoc<T> for Wrapper<'ai, T, A>
+where
+ A::Iter<'ai>: Clone,
+{
+ type Iter<'b> = ();
+ fn iter<'s>(&'s self) -> Self::Iter<'s> {
+ let a = A::reborrow::<'ai, 's>(self.a.clone());
+ }
+
+ fn reborrow<'long: 'short, 'short>(iter: Self::Iter<'long>) -> Self::Iter<'short> {
+ ()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-90014.rs b/tests/ui/generic-associated-types/issue-90014.rs
new file mode 100644
index 000000000..55db95a6d
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-90014.rs
@@ -0,0 +1,21 @@
+// edition:2018
+
+#![feature(type_alias_impl_trait)]
+
+use std::future::Future;
+
+trait MakeFut {
+ type Fut<'a> where Self: 'a;
+ fn make_fut<'a>(&'a self) -> Self::Fut<'a>;
+}
+
+impl MakeFut for &'_ mut () {
+ type Fut<'a> = impl Future<Output = ()>;
+ //~^ ERROR: the type `&mut ()` does not fulfill the required lifetime
+
+ fn make_fut<'a>(&'a self) -> Self::Fut<'a> {
+ async { () }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-90014.stderr b/tests/ui/generic-associated-types/issue-90014.stderr
new file mode 100644
index 000000000..b4b1bc7da
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-90014.stderr
@@ -0,0 +1,22 @@
+error[E0477]: the type `&mut ()` does not fulfill the required lifetime
+ --> $DIR/issue-90014.rs:13:20
+ |
+LL | type Fut<'a> where Self: 'a;
+ | ------------ definition of `Fut` from trait
+...
+LL | type Fut<'a> = impl Future<Output = ()>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: type must outlive the lifetime `'a` as defined here
+ --> $DIR/issue-90014.rs:13:14
+ |
+LL | type Fut<'a> = impl Future<Output = ()>;
+ | ^^
+help: copy the `where` clause predicates from the trait
+ |
+LL | type Fut<'a> = impl Future<Output = ()> where Self: 'a;
+ | ++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/tests/ui/generic-associated-types/issue-90729.rs b/tests/ui/generic-associated-types/issue-90729.rs
new file mode 100644
index 000000000..bcec2e321
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-90729.rs
@@ -0,0 +1,36 @@
+// check-pass
+
+use std::marker::PhantomData;
+
+pub trait Type {
+ type Ref<'a>;
+}
+
+pub trait AsBytes {}
+
+impl AsBytes for &str {}
+
+pub struct Utf8;
+
+impl Type for Utf8 {
+ type Ref<'a> = &'a str;
+}
+
+pub struct Bytes<T: Type> {
+ _marker: PhantomData<T>,
+}
+
+impl<T: Type> Bytes<T>
+where
+ for<'a> T::Ref<'a>: AsBytes,
+{
+ pub fn new() -> Self {
+ Self {
+ _marker: PhantomData,
+ }
+ }
+}
+
+fn main() {
+ let _b = Bytes::<Utf8>::new();
+}
diff --git a/tests/ui/generic-associated-types/issue-91139.migrate.stderr b/tests/ui/generic-associated-types/issue-91139.migrate.stderr
new file mode 100644
index 000000000..690160577
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-91139.migrate.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `<<`
+ --> $DIR/issue-91139.rs:1:1
+ |
+LL | <<<<<<< HEAD
+ | ^^ expected identifier
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-associated-types/issue-91139.rs b/tests/ui/generic-associated-types/issue-91139.rs
new file mode 100644
index 000000000..adc0cb4e0
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-91139.rs
@@ -0,0 +1,27 @@
+trait Foo<T> {
+ type Type<'a>
+ where
+ T: 'a;
+}
+
+impl<T> Foo<T> for () {
+ type Type<'a> = ()
+ where
+ T: 'a;
+}
+
+fn foo<T>() {
+ let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ //~^ ERROR `T` does not live long enough
+ //~| ERROR `T` does not live long enough
+ //
+ // FIXME: This error is bogus, but it arises because we try to validate
+ // that `<() as Foo<T>>::Type<'a>` is valid, which requires proving
+ // that `T: 'a`. Since `'a` is higher-ranked, this becomes
+ // `for<'a> T: 'a`, which is not true. Of course, the error is bogus
+ // because there *ought* to be an implied bound stating that `'a` is
+ // not any lifetime but specifically
+ // "some `'a` such that `<() as Foo<T>>::Type<'a>" is valid".
+}
+
+pub fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-91139.stderr b/tests/ui/generic-associated-types/issue-91139.stderr
new file mode 100644
index 000000000..d9d76adfb
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-91139.stderr
@@ -0,0 +1,14 @@
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:14:12
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:14:12
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/generic-associated-types/issue-91883.rs b/tests/ui/generic-associated-types/issue-91883.rs
new file mode 100644
index 000000000..e870e08a3
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-91883.rs
@@ -0,0 +1,40 @@
+use std::fmt::Debug;
+use std::marker::PhantomData;
+
+#[derive(Debug)]
+pub struct TransactionImpl<'db> {
+ _marker: PhantomData<&'db ()>,
+}
+
+#[derive(Debug)]
+pub struct CursorImpl<'txn> {
+ _marker: PhantomData<&'txn ()>,
+}
+
+pub trait Cursor<'txn> {}
+
+pub trait Transaction<'db>: Send + Sync + Debug + Sized {
+ type Cursor<'tx>: Cursor<'tx>
+ where
+ 'db: 'tx,
+ Self: 'tx;
+
+ fn cursor<'tx>(&'tx self) -> Result<Self::Cursor<'tx>, ()>
+ where
+ 'db: 'tx;
+}
+
+impl<'tx> Cursor<'tx> for CursorImpl<'tx> {}
+
+impl<'db> Transaction<'db> for TransactionImpl<'db> {
+ type Cursor<'tx> = CursorImpl<'tx>; //~ ERROR lifetime bound not satisfied
+
+ fn cursor<'tx>(&'tx self) -> Result<Self::Cursor<'tx>, ()>
+ where
+ 'db: 'tx,
+ {
+ loop {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-91883.stderr b/tests/ui/generic-associated-types/issue-91883.stderr
new file mode 100644
index 000000000..d5db96209
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-91883.stderr
@@ -0,0 +1,27 @@
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/issue-91883.rs:30:24
+ |
+LL | type Cursor<'tx>: Cursor<'tx>
+ | ----------------------------- definition of `Cursor` from trait
+...
+LL | type Cursor<'tx> = CursorImpl<'tx>;
+ | ^^^^^^^^^^^^^^^
+ |
+note: lifetime parameter instantiated with the lifetime `'db` as defined here
+ --> $DIR/issue-91883.rs:29:6
+ |
+LL | impl<'db> Transaction<'db> for TransactionImpl<'db> {
+ | ^^^
+note: but lifetime parameter must outlive the lifetime `'tx` as defined here
+ --> $DIR/issue-91883.rs:30:17
+ |
+LL | type Cursor<'tx> = CursorImpl<'tx>;
+ | ^^^
+help: copy the `where` clause predicates from the trait
+ |
+LL | type Cursor<'tx> = CursorImpl<'tx> where 'db: 'tx, Self: 'tx;
+ | +++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0478`.
diff --git a/tests/ui/generic-associated-types/issue-92033.rs b/tests/ui/generic-associated-types/issue-92033.rs
new file mode 100644
index 000000000..d111580b8
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-92033.rs
@@ -0,0 +1,37 @@
+struct Texture;
+
+trait Surface {
+ type TextureIter<'a>: Iterator<Item = &'a Texture>
+ where
+ Self: 'a;
+
+ fn get_texture(&self) -> Self::TextureIter<'_>;
+}
+
+trait Swapchain {
+ type Surface<'a>: Surface
+ where
+ Self: 'a;
+
+ fn get_surface(&self) -> Self::Surface<'_>;
+}
+
+impl<'s> Surface for &'s Texture {
+ type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+ //~^ ERROR the type
+
+ fn get_texture(&self) -> Self::TextureIter<'_> {
+ let option: Option<&Texture> = Some(self);
+ option.into_iter()
+ }
+}
+
+impl Swapchain for Texture {
+ type Surface<'a> = &'a Texture;
+
+ fn get_surface(&self) -> Self::Surface<'_> {
+ self
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-92033.stderr b/tests/ui/generic-associated-types/issue-92033.stderr
new file mode 100644
index 000000000..ddc420a7b
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-92033.stderr
@@ -0,0 +1,22 @@
+error[E0477]: the type `&'s Texture` does not fulfill the required lifetime
+ --> $DIR/issue-92033.rs:20:28
+ |
+LL | type TextureIter<'a>: Iterator<Item = &'a Texture>
+ | -------------------------------------------------- definition of `TextureIter` from trait
+...
+LL | type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: type must outlive the lifetime `'a` as defined here
+ --> $DIR/issue-92033.rs:20:22
+ |
+LL | type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+ | ^^
+help: copy the `where` clause predicates from the trait
+ |
+LL | type TextureIter<'a> = std::option::IntoIter<&'a Texture> where Self: 'a;
+ | ++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/tests/ui/generic-associated-types/issue-92096.migrate.stderr b/tests/ui/generic-associated-types/issue-92096.migrate.stderr
new file mode 100644
index 000000000..ce1fd6dd9
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-92096.migrate.stderr
@@ -0,0 +1,24 @@
+error[E0311]: the parameter type `C` may not live long enough
+ --> $DIR/issue-92096.rs:19:33
+ |
+LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
+ | ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | C: Client + Send + Sync + 'a,
+ | ++++
+
+error[E0311]: the parameter type `C` may not live long enough
+ --> $DIR/issue-92096.rs:19:33
+ |
+LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
+ | ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | C: Client + Send + Sync + 'a,
+ | ++++
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/generic-associated-types/issue-92096.rs b/tests/ui/generic-associated-types/issue-92096.rs
new file mode 100644
index 000000000..e285af666
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-92096.rs
@@ -0,0 +1,28 @@
+// edition:2018
+
+use std::future::Future;
+
+trait Client {
+ type Connecting<'a>: Future + Send
+ where
+ Self: 'a;
+
+ fn connect(&'_ self) -> Self::Connecting<'_>;
+}
+
+fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
+where
+ C: Client + Send + Sync,
+{
+ async move { c.connect().await }
+ //~^ ERROR `C` does not live long enough
+ //
+ // FIXME(#71723). This is because we infer at some point a value of
+ //
+ // impl Future<Output = <C as Client>::Connection<'_>>
+ //
+ // and then we somehow fail the WF check because `where C: 'a` is not known,
+ // but I'm not entirely sure how that comes about.
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-92096.stderr b/tests/ui/generic-associated-types/issue-92096.stderr
new file mode 100644
index 000000000..91a06d5ac
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-92096.stderr
@@ -0,0 +1,8 @@
+error: `C` does not live long enough
+ --> $DIR/issue-92096.rs:17:5
+ |
+LL | async move { c.connect().await }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-associated-types/issue-92280.rs b/tests/ui/generic-associated-types/issue-92280.rs
new file mode 100644
index 000000000..9284beea3
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-92280.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+#![allow(non_camel_case_types)]
+
+trait HasAssoc {
+ type Assoc;
+}
+
+trait Iterate<S: HasAssoc> {
+ type Iter<'a>
+ where
+ Self: 'a;
+}
+
+struct KeySegment_Broken<T> {
+ key: T,
+}
+impl<S: HasAssoc> Iterate<S> for KeySegment_Broken<S::Assoc> {
+ type Iter<'a> = ()
+ where
+ Self: 'a;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-92954.rs b/tests/ui/generic-associated-types/issue-92954.rs
new file mode 100644
index 000000000..22ce8f9fe
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-92954.rs
@@ -0,0 +1,8 @@
+// check-pass
+
+pub trait Foo {
+ type Assoc<'c>;
+ fn function() -> for<'x> fn(Self::Assoc<'x>);
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-93141.rs b/tests/ui/generic-associated-types/issue-93141.rs
new file mode 100644
index 000000000..48c78b9c0
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-93141.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+pub trait Fooey: Sized {
+ type Context<'c> where Self: 'c;
+}
+
+pub struct Handle<E: Fooey>(Option<Box<dyn for<'c> Fn(&mut E::Context<'c>)>>);
+
+fn tuple<T>() -> (Option<T>,) { (Option::None,) }
+
+pub struct FooImpl {}
+impl Fooey for FooImpl {
+ type Context<'c> = &'c ();
+}
+
+impl FooImpl {
+ pub fn fail1() -> Handle<Self> {
+ let (tx,) = tuple();
+ Handle(tx)
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-93262.rs b/tests/ui/generic-associated-types/issue-93262.rs
new file mode 100644
index 000000000..a7bcd111d
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-93262.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+pub trait Trait {
+ type Assoc<'a> where Self: 'a;
+}
+
+pub trait Foo<T: Trait>
+where
+ for<'a> T::Assoc<'a>: Clone
+{}
+
+pub struct Type;
+
+impl<T: Trait> Foo<T> for Type
+where
+ for<'a> T::Assoc<'a>: Clone
+{}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-93340.rs b/tests/ui/generic-associated-types/issue-93340.rs
new file mode 100644
index 000000000..4662fda53
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-93340.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+pub trait Scalar: 'static {
+ type RefType<'a>: ScalarRef<'a>;
+}
+
+pub trait ScalarRef<'a>: 'a {}
+
+fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O {
+ todo!()
+}
+
+fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
+) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
+ cmp_eq
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-93341.rs b/tests/ui/generic-associated-types/issue-93341.rs
new file mode 100644
index 000000000..737b2bbdb
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-93341.rs
@@ -0,0 +1,54 @@
+// check-pass
+
+use std::marker::PhantomData;
+
+pub struct Id<'id>(PhantomData<fn(&'id ()) -> &'id ()>);
+
+fn new_id() -> Id<'static> {
+ Id(PhantomData)
+}
+
+pub trait HasLifetime where {
+ type AtLifetime<'a>;
+}
+
+pub struct ExistentialLifetime<S: HasLifetime>(S::AtLifetime<'static>);
+
+impl<S: HasLifetime> ExistentialLifetime<S> {
+ pub fn new<F>(f: F) -> ExistentialLifetime<S>
+ where for<'id> F: FnOnce(Id<'id>) -> S::AtLifetime<'id> {
+ ExistentialLifetime(f(new_id()))
+ }
+}
+
+
+struct ExampleS<'id>(Id<'id>);
+
+struct ExampleMarker;
+
+impl HasLifetime for ExampleMarker {
+ type AtLifetime<'id> = ExampleS<'id>;
+}
+
+
+fn broken0() -> ExistentialLifetime<ExampleMarker> {
+ fn new_helper<'id>(id: Id<'id>) -> ExampleS<'id> {
+ ExampleS(id)
+ }
+
+ ExistentialLifetime::<ExampleMarker>::new(new_helper)
+}
+
+fn broken1() -> ExistentialLifetime<ExampleMarker> {
+ fn new_helper<'id>(id: Id<'id>) -> <ExampleMarker as HasLifetime>::AtLifetime<'id> {
+ ExampleS(id)
+ }
+
+ ExistentialLifetime::<ExampleMarker>::new(new_helper)
+}
+
+fn broken2() -> ExistentialLifetime<ExampleMarker> {
+ ExistentialLifetime::<ExampleMarker>::new(|id| ExampleS(id))
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-93342.rs b/tests/ui/generic-associated-types/issue-93342.rs
new file mode 100644
index 000000000..d4422d5d1
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-93342.rs
@@ -0,0 +1,55 @@
+// check-pass
+
+use std::marker::PhantomData;
+
+pub trait Scalar: 'static {
+ type RefType<'a>: ScalarRef<'a>;
+}
+
+pub trait ScalarRef<'a>: 'a {}
+
+impl Scalar for i32 {
+ type RefType<'a> = i32;
+}
+
+impl Scalar for String {
+ type RefType<'a> = &'a str;
+}
+
+impl Scalar for bool {
+ type RefType<'a> = i32;
+}
+
+impl<'a> ScalarRef<'a> for bool {}
+
+impl<'a> ScalarRef<'a> for i32 {}
+
+impl<'a> ScalarRef<'a> for &'a str {}
+
+fn str_contains(a: &str, b: &str) -> bool {
+ a.contains(b)
+}
+
+pub struct BinaryExpression<A: Scalar, B: Scalar, O: Scalar, F>
+where
+ F: Fn(A::RefType<'_>, B::RefType<'_>) -> O,
+{
+ f: F,
+ _phantom: PhantomData<(A, B, O)>,
+}
+
+impl<A: Scalar, B: Scalar, O: Scalar, F> BinaryExpression<A, B, O, F>
+where
+ F: Fn(A::RefType<'_>, B::RefType<'_>) -> O,
+{
+ pub fn new(f: F) -> Self {
+ Self {
+ f,
+ _phantom: PhantomData,
+ }
+ }
+}
+
+fn main() {
+ BinaryExpression::<String, String, bool, _>::new(str_contains);
+}
diff --git a/tests/ui/generic-associated-types/issue-93874.rs b/tests/ui/generic-associated-types/issue-93874.rs
new file mode 100644
index 000000000..30956655a
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-93874.rs
@@ -0,0 +1,33 @@
+// check-pass
+
+pub trait Build {
+ type Output<O>;
+ fn build<O>(self, input: O) -> Self::Output<O>;
+}
+
+pub struct IdentityBuild;
+impl Build for IdentityBuild {
+ type Output<O> = O;
+ fn build<O>(self, input: O) -> Self::Output<O> {
+ input
+ }
+}
+
+fn a() {
+ let _x: u8 = IdentityBuild.build(10);
+}
+
+fn b() {
+ let _x: Vec<u8> = IdentityBuild.build(Vec::new());
+}
+
+fn c() {
+ let mut f = IdentityBuild.build(|| ());
+ (f)();
+}
+
+pub fn main() {
+ a();
+ b();
+ c();
+}
diff --git a/tests/ui/generic-associated-types/issue-95305.rs b/tests/ui/generic-associated-types/issue-95305.rs
new file mode 100644
index 000000000..6c3ec20e7
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-95305.rs
@@ -0,0 +1,19 @@
+// It's not yet clear how '_ and GATs should interact.
+// Forbid it for now but proper support might be added
+// at some point in the future.
+
+#![feature(anonymous_lifetime_in_impl_trait)]
+trait Foo {
+ type Item<'a>;
+}
+
+fn foo(x: &impl Foo<Item<'_> = u32>) { }
+ //~^ ERROR `'_` cannot be used here [E0637]
+
+// Ok: the anonymous lifetime is bound to the function.
+fn bar(x: &impl for<'a> Foo<Item<'a> = &'_ u32>) { }
+
+// Ok: the anonymous lifetime is bound to the function.
+fn baz(x: &impl for<'a> Foo<Item<'a> = &u32>) { }
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-95305.stderr b/tests/ui/generic-associated-types/issue-95305.stderr
new file mode 100644
index 000000000..eb15cbc62
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-95305.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/issue-95305.rs:10:26
+ |
+LL | fn foo(x: &impl Foo<Item<'_> = u32>) { }
+ | ^^ `'_` is a reserved lifetime name
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0637`.
diff --git a/tests/ui/generic-associated-types/iterable.rs b/tests/ui/generic-associated-types/iterable.rs
new file mode 100644
index 000000000..8ad351bd3
--- /dev/null
+++ b/tests/ui/generic-associated-types/iterable.rs
@@ -0,0 +1,44 @@
+// run-pass
+
+trait Iterable {
+ type Item<'a> where Self: 'a;
+ type Iter<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
+
+ fn iter<'a>(&'a self) -> Self::Iter<'a>;
+}
+
+// Impl for struct type
+impl<T> Iterable for Vec<T> {
+ type Item<'a> = <std::slice::Iter<'a, T> as Iterator>::Item where T: 'a;
+ type Iter<'a> = std::slice::Iter<'a, T> where T: 'a;
+
+ fn iter<'a>(&'a self) -> Self::Iter<'a> {
+ self[..].iter()
+ }
+}
+
+// Impl for a primitive type
+impl<T> Iterable for [T] {
+ type Item<'a> = <std::slice::Iter<'a, T> as Iterator>::Item where T: 'a;
+ type Iter<'a> = std::slice::Iter<'a, T> where T: 'a;
+
+ fn iter<'a>(&'a self) -> Self::Iter<'a> {
+ self.iter()
+ }
+}
+
+fn make_iter<'a, I: Iterable + ?Sized>(it: &'a I) -> I::Iter<'a> {
+ it.iter()
+}
+
+fn get_first<'a, I: Iterable + ?Sized>(it: &'a I) -> Option<I::Item<'a>> {
+ it.iter().next()
+}
+
+fn main() {
+ let v = vec![1, 2, 3];
+ assert_eq!(v, make_iter(&v).copied().collect::<Vec<_>>());
+ assert_eq!(v, make_iter(&*v).copied().collect::<Vec<_>>());
+ assert_eq!(Some(&1), get_first(&v));
+ assert_eq!(Some(&1), get_first(&*v));
+}
diff --git a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs b/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs
new file mode 100644
index 000000000..83655341d
--- /dev/null
+++ b/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs
@@ -0,0 +1,33 @@
+// Test that the predicate printed in an unresolved method error prints the
+// generics for a generic associated type.
+
+trait X {
+ type Y<T>;
+}
+
+trait M {
+ fn f(&self) {}
+}
+
+impl<T: X<Y<i32> = i32>> M for T {}
+//~^ NOTE trait bound `<S as X>::Y<i32> = i32` was not satisfied
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+struct S;
+//~^ NOTE method `f` not found for this
+//~| NOTE doesn't satisfy `<S as X>::Y<i32> = i32`
+//~| NOTE doesn't satisfy `S: M`
+
+impl X for S {
+ type Y<T> = bool;
+}
+
+fn f(a: S) {
+ a.f();
+ //~^ ERROR the method `f` exists for struct `S`, but its trait bounds were not satisfied
+ //~| NOTE method cannot be called on `S` due to unsatisfied trait bounds
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr b/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr
new file mode 100644
index 000000000..baef38f6b
--- /dev/null
+++ b/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr
@@ -0,0 +1,24 @@
+error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
+ --> $DIR/method-unsatified-assoc-type-predicate.rs:28:7
+ |
+LL | struct S;
+ | --------
+ | |
+ | method `f` not found for this struct
+ | doesn't satisfy `<S as X>::Y<i32> = i32`
+ | doesn't satisfy `S: M`
+...
+LL | a.f();
+ | ^ method cannot be called on `S` due to unsatisfied trait bounds
+ |
+note: trait bound `<S as X>::Y<i32> = i32` was not satisfied
+ --> $DIR/method-unsatified-assoc-type-predicate.rs:12:11
+ |
+LL | impl<T: X<Y<i32> = i32>> M for T {}
+ | ^^^^^^^^^^^^ - -
+ | |
+ | unsatisfied trait bound introduced here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/generic-associated-types/mismatched-where-clause-regions.rs b/tests/ui/generic-associated-types/mismatched-where-clause-regions.rs
new file mode 100644
index 000000000..8caf53176
--- /dev/null
+++ b/tests/ui/generic-associated-types/mismatched-where-clause-regions.rs
@@ -0,0 +1,12 @@
+trait Foo {
+ type T<'a1, 'b1>
+ where
+ 'a1: 'b1;
+}
+
+impl Foo for () {
+ type T<'a2, 'b2> = () where 'b2: 'a2;
+ //~^ ERROR impl has stricter requirements than trait
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/mismatched-where-clause-regions.stderr b/tests/ui/generic-associated-types/mismatched-where-clause-regions.stderr
new file mode 100644
index 000000000..91a030076
--- /dev/null
+++ b/tests/ui/generic-associated-types/mismatched-where-clause-regions.stderr
@@ -0,0 +1,17 @@
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/mismatched-where-clause-regions.rs:8:38
+ |
+LL | type T<'a1, 'b1>
+ | ---------------- definition of `T` from trait
+...
+LL | type T<'a2, 'b2> = () where 'b2: 'a2;
+ | ^^^ impl has extra requirement `'b2: 'a2`
+ |
+help: copy the `where` clause predicates from the trait
+ |
+LL | type T<'a2, 'b2> = () where 'a2: 'b2;
+ | ~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/tests/ui/generic-associated-types/missing-bounds.fixed b/tests/ui/generic-associated-types/missing-bounds.fixed
new file mode 100644
index 000000000..ee758f19e
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing-bounds.fixed
@@ -0,0 +1,46 @@
+// run-rustfix
+
+use std::ops::Add;
+
+struct A<B>(B);
+
+impl<B> Add for A<B> where B: Add + Add<Output = B> {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ A(self.0 + rhs.0) //~ ERROR mismatched types
+ }
+}
+
+struct C<B>(B);
+
+impl<B: Add + Add<Output = B>> Add for C<B> {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ Self(self.0 + rhs.0) //~ ERROR mismatched types
+ }
+}
+
+struct D<B>(B);
+
+impl<B: std::ops::Add<Output = B>> Add for D<B> {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ Self(self.0 + rhs.0) //~ ERROR cannot add `B` to `B`
+ }
+}
+
+struct E<B>(B);
+
+impl<B: Add + Add<Output = B>> Add for E<B> where B: Add<Output = B> {
+ //~^ ERROR equality constraints are not yet supported in `where` clauses
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ Self(self.0 + rhs.0) //~ ERROR mismatched types
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/missing-bounds.rs b/tests/ui/generic-associated-types/missing-bounds.rs
new file mode 100644
index 000000000..ffafff5e9
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing-bounds.rs
@@ -0,0 +1,46 @@
+// run-rustfix
+
+use std::ops::Add;
+
+struct A<B>(B);
+
+impl<B> Add for A<B> where B: Add {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ A(self.0 + rhs.0) //~ ERROR mismatched types
+ }
+}
+
+struct C<B>(B);
+
+impl<B: Add> Add for C<B> {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ Self(self.0 + rhs.0) //~ ERROR mismatched types
+ }
+}
+
+struct D<B>(B);
+
+impl<B> Add for D<B> {
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ Self(self.0 + rhs.0) //~ ERROR cannot add `B` to `B`
+ }
+}
+
+struct E<B>(B);
+
+impl<B: Add> Add for E<B> where <B as Add>::Output = B {
+ //~^ ERROR equality constraints are not yet supported in `where` clauses
+ type Output = Self;
+
+ fn add(self, rhs: Self) -> Self {
+ Self(self.0 + rhs.0) //~ ERROR mismatched types
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/missing-bounds.stderr b/tests/ui/generic-associated-types/missing-bounds.stderr
new file mode 100644
index 000000000..9f669b9a5
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing-bounds.stderr
@@ -0,0 +1,105 @@
+error: equality constraints are not yet supported in `where` clauses
+ --> $DIR/missing-bounds.rs:37:33
+ |
+LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
+ | ^^^^^^^^^^^^^^^^^^^^^^ not supported
+ |
+ = note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
+help: if `Output` is an associated type you're trying to set, use the associated type binding syntax
+ |
+LL | impl<B: Add> Add for E<B> where B: Add<Output = B> {
+ | ~~~~~~~~~~~~~~~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/missing-bounds.rs:11:11
+ |
+LL | impl<B> Add for A<B> where B: Add {
+ | - this type parameter
+...
+LL | A(self.0 + rhs.0)
+ | - ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
+ | |
+ | arguments to this struct are incorrect
+ |
+ = note: expected type parameter `B`
+ found associated type `<B as Add>::Output`
+help: the type constructed contains `<B as Add>::Output` due to the type of the argument passed
+ --> $DIR/missing-bounds.rs:11:9
+ |
+LL | A(self.0 + rhs.0)
+ | ^^--------------^
+ | |
+ | this argument influences the type of `A`
+note: tuple struct defined here
+ --> $DIR/missing-bounds.rs:5:8
+ |
+LL | struct A<B>(B);
+ | ^
+help: consider further restricting this bound
+ |
+LL | impl<B> Add for A<B> where B: Add + Add<Output = B> {
+ | +++++++++++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/missing-bounds.rs:21:14
+ |
+LL | impl<B: Add> Add for C<B> {
+ | - this type parameter
+...
+LL | Self(self.0 + rhs.0)
+ | ---- ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected type parameter `B`
+ found associated type `<B as Add>::Output`
+note: tuple struct defined here
+ --> $DIR/missing-bounds.rs:15:8
+ |
+LL | struct C<B>(B);
+ | ^
+help: consider further restricting this bound
+ |
+LL | impl<B: Add + Add<Output = B>> Add for C<B> {
+ | +++++++++++++++++
+
+error[E0369]: cannot add `B` to `B`
+ --> $DIR/missing-bounds.rs:31:21
+ |
+LL | Self(self.0 + rhs.0)
+ | ------ ^ ----- B
+ | |
+ | B
+ |
+help: consider restricting type parameter `B`
+ |
+LL | impl<B: std::ops::Add<Output = B>> Add for D<B> {
+ | +++++++++++++++++++++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/missing-bounds.rs:42:14
+ |
+LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
+ | - this type parameter
+...
+LL | Self(self.0 + rhs.0)
+ | ---- ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
+ | |
+ | arguments to this function are incorrect
+ |
+ = note: expected type parameter `B`
+ found associated type `<B as Add>::Output`
+note: tuple struct defined here
+ --> $DIR/missing-bounds.rs:35:8
+ |
+LL | struct E<B>(B);
+ | ^
+help: consider further restricting this bound
+ |
+LL | impl<B: Add + Add<Output = B>> Add for E<B> where <B as Add>::Output = B {
+ | +++++++++++++++++
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0308, E0369.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/generic-associated-types/missing-where-clause-on-trait.rs b/tests/ui/generic-associated-types/missing-where-clause-on-trait.rs
new file mode 100644
index 000000000..de9cad308
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing-where-clause-on-trait.rs
@@ -0,0 +1,11 @@
+// check-fail
+
+trait Foo {
+ type Assoc<'a, 'b>;
+}
+impl Foo for () {
+ type Assoc<'a, 'b> = () where 'a: 'b;
+ //~^ impl has stricter requirements than trait
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/missing-where-clause-on-trait.stderr b/tests/ui/generic-associated-types/missing-where-clause-on-trait.stderr
new file mode 100644
index 000000000..8a71fc73a
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing-where-clause-on-trait.stderr
@@ -0,0 +1,18 @@
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/missing-where-clause-on-trait.rs:7:39
+ |
+LL | type Assoc<'a, 'b>;
+ | ------------------ definition of `Assoc` from trait
+...
+LL | type Assoc<'a, 'b> = () where 'a: 'b;
+ | ^^ impl has extra requirement `'a: 'b`
+ |
+help: remove the `where` clause
+ |
+LL - type Assoc<'a, 'b> = () where 'a: 'b;
+LL + type Assoc<'a, 'b> = () ;
+ |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.rs b/tests/ui/generic-associated-types/missing_lifetime_args.rs
new file mode 100644
index 000000000..78def8092
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing_lifetime_args.rs
@@ -0,0 +1,20 @@
+trait X {
+ type Y<'a, 'b>;
+}
+
+struct Foo<'a, 'b, 'c> {
+ a: &'a u32,
+ b: &'b str,
+ c: &'c str,
+}
+
+fn foo<'c, 'd>(_arg: Box<dyn X<Y = (&'c u32, &'d u32)>>) {}
+//~^ ERROR missing generics for associated type
+
+fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
+//~^ ERROR this struct takes 3 lifetime arguments but 2 lifetime
+
+fn f<'a>(_arg: Foo<'a>) {}
+//~^ ERROR this struct takes 3 lifetime arguments but 1 lifetime
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
new file mode 100644
index 000000000..8f74b12c0
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr
@@ -0,0 +1,55 @@
+error[E0107]: missing generics for associated type `X::Y`
+ --> $DIR/missing_lifetime_args.rs:11:32
+ |
+LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y = (&'c u32, &'d u32)>>) {}
+ | ^ expected 2 lifetime arguments
+ |
+note: associated type defined here, with 2 lifetime parameters: `'a`, `'b`
+ --> $DIR/missing_lifetime_args.rs:2:10
+ |
+LL | type Y<'a, 'b>;
+ | ^ -- --
+help: add missing lifetime arguments
+ |
+LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'_, '_> = (&'c u32, &'d u32)>>) {}
+ | ++++++++
+
+error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
+ --> $DIR/missing_lifetime_args.rs:14:26
+ |
+LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {}
+ | ^^^ -- -- supplied 2 lifetime arguments
+ | |
+ | expected 3 lifetime arguments
+ |
+note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
+ --> $DIR/missing_lifetime_args.rs:5:8
+ |
+LL | struct Foo<'a, 'b, 'c> {
+ | ^^^ -- -- --
+help: add missing lifetime argument
+ |
+LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {}
+ | ++++
+
+error[E0107]: this struct takes 3 lifetime arguments but 1 lifetime argument was supplied
+ --> $DIR/missing_lifetime_args.rs:17:16
+ |
+LL | fn f<'a>(_arg: Foo<'a>) {}
+ | ^^^ -- supplied 1 lifetime argument
+ | |
+ | expected 3 lifetime arguments
+ |
+note: struct defined here, with 3 lifetime parameters: `'a`, `'b`, `'c`
+ --> $DIR/missing_lifetime_args.rs:5:8
+ |
+LL | struct Foo<'a, 'b, 'c> {
+ | ^^^ -- -- --
+help: add missing lifetime arguments
+ |
+LL | fn f<'a>(_arg: Foo<'a, 'a, 'a>) {}
+ | ++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/missing_lifetime_const.rs b/tests/ui/generic-associated-types/missing_lifetime_const.rs
new file mode 100644
index 000000000..8b174b9e9
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing_lifetime_const.rs
@@ -0,0 +1,10 @@
+trait Foo {
+ type Assoc<'a, const N: usize>;
+}
+
+fn foo<T: Foo>() {
+ let _: <T as Foo>::Assoc<3>;
+ //~^ ERROR this associated type
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/missing_lifetime_const.stderr b/tests/ui/generic-associated-types/missing_lifetime_const.stderr
new file mode 100644
index 000000000..62d2e9f49
--- /dev/null
+++ b/tests/ui/generic-associated-types/missing_lifetime_const.stderr
@@ -0,0 +1,19 @@
+error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+ --> $DIR/missing_lifetime_const.rs:6:24
+ |
+LL | let _: <T as Foo>::Assoc<3>;
+ | ^^^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/missing_lifetime_const.rs:2:10
+ |
+LL | type Assoc<'a, const N: usize>;
+ | ^^^^^ --
+help: add missing lifetime argument
+ |
+LL | let _: <T as Foo>::Assoc<'a, 3>;
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/own-bound-span.rs b/tests/ui/generic-associated-types/own-bound-span.rs
new file mode 100644
index 000000000..3699f7296
--- /dev/null
+++ b/tests/ui/generic-associated-types/own-bound-span.rs
@@ -0,0 +1,17 @@
+struct S;
+
+trait D {
+ type P<T: Copy>;
+ //~^ NOTE required by this bound in `D::P`
+ //~| NOTE required by a bound in `D::P`
+}
+
+impl D for S {
+ type P<T: Copy> = ();
+}
+
+fn main() {
+ let _: <S as D>::P<String>;
+ //~^ ERROR the trait bound `String: Copy` is not satisfied
+ //~| NOTE the trait `Copy` is not implemented for `String`
+}
diff --git a/tests/ui/generic-associated-types/own-bound-span.stderr b/tests/ui/generic-associated-types/own-bound-span.stderr
new file mode 100644
index 000000000..8ab8ea623
--- /dev/null
+++ b/tests/ui/generic-associated-types/own-bound-span.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+ --> $DIR/own-bound-span.rs:14:12
+ |
+LL | let _: <S as D>::P<String>;
+ | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by a bound in `D::P`
+ --> $DIR/own-bound-span.rs:4:15
+ |
+LL | type P<T: Copy>;
+ | ^^^^ required by this bound in `D::P`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind.rs b/tests/ui/generic-associated-types/parameter_number_and_kind.rs
new file mode 100644
index 000000000..8428e7763
--- /dev/null
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind.rs
@@ -0,0 +1,18 @@
+#![feature(associated_type_defaults)]
+
+trait Foo {
+ type A<'a>;
+ type B<'a, 'b>;
+ type C;
+ type D<T>;
+ type E<'a, T>;
+ // Test parameters in default values
+ type FOk<T> = Self::E<'static, T>;
+ type FErr1 = Self::E<'static, 'static>;
+ //~^ ERROR this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
+ //~| ERROR this associated type takes 1
+ type FErr2<T> = Self::E<'static, T, u32>;
+ //~^ ERROR this associated type takes 1
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind.stderr b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr
new file mode 100644
index 000000000..c20b9669e
--- /dev/null
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr
@@ -0,0 +1,47 @@
+error[E0107]: this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied
+ --> $DIR/parameter_number_and_kind.rs:11:24
+ |
+LL | type FErr1 = Self::E<'static, 'static>;
+ | ^ ------- help: remove this lifetime argument
+ | |
+ | expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/parameter_number_and_kind.rs:8:10
+ |
+LL | type E<'a, T>;
+ | ^ --
+
+error[E0107]: this associated type takes 1 generic argument but 0 generic arguments were supplied
+ --> $DIR/parameter_number_and_kind.rs:11:24
+ |
+LL | type FErr1 = Self::E<'static, 'static>;
+ | ^ expected 1 generic argument
+ |
+note: associated type defined here, with 1 generic parameter: `T`
+ --> $DIR/parameter_number_and_kind.rs:8:10
+ |
+LL | type E<'a, T>;
+ | ^ -
+help: add missing generic argument
+ |
+LL | type FErr1 = Self::E<'static, 'static, T>;
+ | +++
+
+error[E0107]: this associated type takes 1 generic argument but 2 generic arguments were supplied
+ --> $DIR/parameter_number_and_kind.rs:14:27
+ |
+LL | type FErr2<T> = Self::E<'static, T, u32>;
+ | ^ --- help: remove this generic argument
+ | |
+ | expected 1 generic argument
+ |
+note: associated type defined here, with 1 generic parameter: `T`
+ --> $DIR/parameter_number_and_kind.rs:8:10
+ |
+LL | type E<'a, T>;
+ | ^ -
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind_impl.rs b/tests/ui/generic-associated-types/parameter_number_and_kind_impl.rs
new file mode 100644
index 000000000..c1381025a
--- /dev/null
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind_impl.rs
@@ -0,0 +1,33 @@
+#![feature(associated_type_defaults)]
+
+// FIXME(#44265) add tests for type-generic and const-genertic associated types.
+
+trait Foo {
+ type A<'a>;
+ type B<'a, 'b>;
+ type C;
+}
+
+struct Fooy;
+
+impl Foo for Fooy {
+ type A = u32;
+ //~^ ERROR lifetime parameters or bounds on type `A` do not match the trait declaration
+ type B<'a, T> = Vec<T>;
+ //~^ ERROR type `B` has 1 type parameter but its trait declaration has 0 type parameters
+ type C<'a> = u32;
+ //~^ ERROR lifetime parameters or bounds on type `C` do not match the trait declaration
+}
+
+struct Fooer;
+
+impl Foo for Fooer {
+ type A<T> = u32;
+ //~^ ERROR type `A` has 1 type parameter but its trait declaration has 0 type parameters
+ type B<'a> = u32;
+ //~^ ERROR lifetime parameters or bounds on type `B` do not match the trait declaration
+ type C<T> = T;
+ //~^ ERROR type `C` has 1 type parameter but its trait declaration has 0 type parameters
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind_impl.stderr b/tests/ui/generic-associated-types/parameter_number_and_kind_impl.stderr
new file mode 100644
index 000000000..fdd6d305a
--- /dev/null
+++ b/tests/ui/generic-associated-types/parameter_number_and_kind_impl.stderr
@@ -0,0 +1,62 @@
+error[E0195]: lifetime parameters or bounds on type `A` do not match the trait declaration
+ --> $DIR/parameter_number_and_kind_impl.rs:14:11
+ |
+LL | type A<'a>;
+ | ---- lifetimes in impl do not match this type in trait
+...
+LL | type A = u32;
+ | ^ lifetimes do not match type in trait
+
+error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
+ --> $DIR/parameter_number_and_kind_impl.rs:16:12
+ |
+LL | type B<'a, 'b>;
+ | -- --
+ | |
+ | expected 0 type parameters
+...
+LL | type B<'a, T> = Vec<T>;
+ | ^^ ^
+ | |
+ | found 1 type parameter
+
+error[E0195]: lifetime parameters or bounds on type `C` do not match the trait declaration
+ --> $DIR/parameter_number_and_kind_impl.rs:18:11
+ |
+LL | type C;
+ | - lifetimes in impl do not match this type in trait
+...
+LL | type C<'a> = u32;
+ | ^^^^ lifetimes do not match type in trait
+
+error[E0049]: type `A` has 1 type parameter but its trait declaration has 0 type parameters
+ --> $DIR/parameter_number_and_kind_impl.rs:25:12
+ |
+LL | type A<'a>;
+ | -- expected 0 type parameters
+...
+LL | type A<T> = u32;
+ | ^ found 1 type parameter
+
+error[E0195]: lifetime parameters or bounds on type `B` do not match the trait declaration
+ --> $DIR/parameter_number_and_kind_impl.rs:27:11
+ |
+LL | type B<'a, 'b>;
+ | -------- lifetimes in impl do not match this type in trait
+...
+LL | type B<'a> = u32;
+ | ^^^^ lifetimes do not match type in trait
+
+error[E0049]: type `C` has 1 type parameter but its trait declaration has 0 type parameters
+ --> $DIR/parameter_number_and_kind_impl.rs:29:12
+ |
+LL | type C;
+ | - expected 0 type parameters
+...
+LL | type C<T> = T;
+ | ^ found 1 type parameter
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0049, E0195.
+For more information about an error, try `rustc --explain E0049`.
diff --git a/tests/ui/generic-associated-types/parse/in-trait-impl.rs b/tests/ui/generic-associated-types/parse/in-trait-impl.rs
new file mode 100644
index 000000000..767098835
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/in-trait-impl.rs
@@ -0,0 +1,8 @@
+// check-pass
+// compile-flags: -Z parse-only
+
+impl<T> Baz for T where T: Foo {
+ type Quux<'a> = <T as Foo>::Bar<'a, 'static>;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/in-trait.rs b/tests/ui/generic-associated-types/parse/in-trait.rs
new file mode 100644
index 000000000..6628aac37
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/in-trait.rs
@@ -0,0 +1,22 @@
+// check-pass
+// compile-flags: -Z parse-only
+
+use std::ops::Deref;
+use std::fmt::Debug;
+
+trait Foo {
+ type Bar<'a>;
+ type Bar<'a, 'b>;
+ type Bar<'a, 'b,>;
+ type Bar<'a, 'b, T>;
+ type Bar<'a, 'b, T, U>;
+ type Bar<'a, 'b, T, U,>;
+ type Bar<'a, 'b, T: Debug, U,>;
+ type Bar<'a, 'b, T: Debug, U,>: Debug;
+ type Bar<'a, 'b, T: Debug, U,>: Deref<Target = T> + Into<U>;
+ type Bar<'a, 'b, T: Debug, U,> where T: Deref<Target = U>, U: Into<T>;
+ type Bar<'a, 'b, T: Debug, U,>: Deref<Target = T> + Into<U>
+ where T: Deref<Target = U>, U: Into<T>;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/trait-path-expected-token.rs b/tests/ui/generic-associated-types/parse/trait-path-expected-token.rs
new file mode 100644
index 000000000..cbb051892
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-expected-token.rs
@@ -0,0 +1,8 @@
+trait X {
+ type Y<'a>;
+}
+
+fn f1<'a>(arg : Box<dyn X<Y = B = &'a ()>>) {}
+ //~^ ERROR: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=`
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/trait-path-expected-token.stderr b/tests/ui/generic-associated-types/parse/trait-path-expected-token.stderr
new file mode 100644
index 000000000..53d5f9de6
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-expected-token.stderr
@@ -0,0 +1,10 @@
+error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `=`
+ --> $DIR/trait-path-expected-token.rs:5:33
+ |
+LL | fn f1<'a>(arg : Box<dyn X<Y = B = &'a ()>>) {}
+ | - ^ expected one of 7 possible tokens
+ | |
+ | maybe try to close unmatched angle bracket
+
+error: aborting due to previous error
+
diff --git a/tests/ui/generic-associated-types/parse/trait-path-expressions.rs b/tests/ui/generic-associated-types/parse/trait-path-expressions.rs
new file mode 100644
index 000000000..9183ec497
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-expressions.rs
@@ -0,0 +1,20 @@
+mod error1 {
+ trait X {
+ type Y<'a>;
+ }
+
+ fn f1<'a>(arg : Box<dyn X< 1 = 32 >>) {}
+ //~^ ERROR: expected expression, found `)`
+}
+
+mod error2 {
+
+ trait X {
+ type Y<'a>;
+ }
+
+ fn f2<'a>(arg : Box<dyn X< { 1 } = 32 >>) {}
+ //~^ ERROR: expected one of
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/trait-path-expressions.stderr b/tests/ui/generic-associated-types/parse/trait-path-expressions.stderr
new file mode 100644
index 000000000..cf2b1763f
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-expressions.stderr
@@ -0,0 +1,23 @@
+error: expected expression, found `)`
+ --> $DIR/trait-path-expressions.rs:6:39
+ |
+LL | fn f1<'a>(arg : Box<dyn X< 1 = 32 >>) {}
+ | - ^ expected expression
+ | |
+ | while parsing a const generic argument starting here
+
+error: expected one of `,`, `:`, or `>`, found `=`
+ --> $DIR/trait-path-expressions.rs:16:36
+ |
+LL | fn f2<'a>(arg : Box<dyn X< { 1 } = 32 >>) {}
+ | - ^ expected one of `,`, `:`, or `>`
+ | |
+ | maybe try to close unmatched angle bracket
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | fn f2<'a>(arg : Box<dyn X< { 1 }> = 32 >>) {}
+ | +
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs
new file mode 100644
index 000000000..ecabf8943
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs
@@ -0,0 +1,18 @@
+trait X {
+ type Y<'a>;
+}
+
+const _: () = {
+ fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
+ //~^ ERROR: expected one of `>`, a const expression, lifetime, or type, found `:`
+ //~| ERROR: expected parameter name, found `>`
+ //~| ERROR: expected one of `!`, `)`, `+`, `,`, or `::`, found `>`
+ //~| ERROR: constant provided when a type was expected
+};
+
+const _: () = {
+ fn f1<'a>(arg : Box<dyn X< = 32 >>) {}
+ //~^ ERROR: expected one of `>`, a const expression, lifetime, or type, found `=`
+};
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr
new file mode 100644
index 000000000..10ceccedc
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr
@@ -0,0 +1,43 @@
+error: expected one of `>`, a const expression, lifetime, or type, found `:`
+ --> $DIR/trait-path-missing-gen_arg.rs:6:30
+ |
+LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
+ | ^ expected one of `>`, a const expression, lifetime, or type
+ |
+help: expressions must be enclosed in braces to be used as const generic arguments
+ |
+LL | fn f1<'a>(arg : Box<{ dyn X< : 32 } >>) {}
+ | + +
+
+error: expected parameter name, found `>`
+ --> $DIR/trait-path-missing-gen_arg.rs:6:36
+ |
+LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
+ | ^ expected parameter name
+
+error: expected one of `!`, `)`, `+`, `,`, or `::`, found `>`
+ --> $DIR/trait-path-missing-gen_arg.rs:6:36
+ |
+LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
+ | ^
+ | |
+ | expected one of `!`, `)`, `+`, `,`, or `::`
+ | help: missing `,`
+
+error: expected one of `>`, a const expression, lifetime, or type, found `=`
+ --> $DIR/trait-path-missing-gen_arg.rs:14:30
+ |
+LL | fn f1<'a>(arg : Box<dyn X< = 32 >>) {}
+ | - ^ expected one of `>`, a const expression, lifetime, or type
+ | |
+ | maybe try to close unmatched angle bracket
+
+error[E0747]: constant provided when a type was expected
+ --> $DIR/trait-path-missing-gen_arg.rs:6:23
+ |
+LL | fn f1<'a>(arg : Box<dyn X< : 32 >>) {}
+ | ^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0747`.
diff --git a/tests/ui/generic-associated-types/parse/trait-path-segments.rs b/tests/ui/generic-associated-types/parse/trait-path-segments.rs
new file mode 100644
index 000000000..458e203eb
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-segments.rs
@@ -0,0 +1,32 @@
+const _: () = {
+ trait X {
+ type Y<'a>;
+ }
+
+ fn f1<'a>(arg : Box<dyn X<X::Y = u32>>) {}
+ //~^ ERROR: expected one of
+ };
+
+const _: () = {
+ trait X {
+ type Y<'a>;
+ }
+
+ trait Z {}
+
+ impl<T : X<<Self as X>::Y<'a> = &'a u32>> Z for T {}
+ //~^ ERROR: expected one of
+};
+
+const _: () = {
+ trait X {
+ type Y<'a>;
+ }
+
+ trait Z {}
+
+ impl<T : X<X::Y<'a> = &'a u32>> Z for T {}
+ //~^ ERROR: expected one of
+};
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/trait-path-segments.stderr b/tests/ui/generic-associated-types/parse/trait-path-segments.stderr
new file mode 100644
index 000000000..8bc737d67
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-segments.stderr
@@ -0,0 +1,41 @@
+error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, or `>`, found `=`
+ --> $DIR/trait-path-segments.rs:6:36
+ |
+LL | fn f1<'a>(arg : Box<dyn X<X::Y = u32>>) {}
+ | - ^ expected one of 8 possible tokens
+ | |
+ | maybe try to close unmatched angle bracket
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | fn f1<'a>(arg : Box<dyn X<X::Y> = u32>>) {}
+ | +
+
+error: expected one of `,`, `::`, `:`, or `>`, found `=`
+ --> $DIR/trait-path-segments.rs:17:35
+ |
+LL | impl<T : X<<Self as X>::Y<'a> = &'a u32>> Z for T {}
+ | - ^ expected one of `,`, `::`, `:`, or `>`
+ | |
+ | maybe try to close unmatched angle bracket
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | impl<T : X<<Self as X>::Y<'a>> = &'a u32>> Z for T {}
+ | +
+
+error: expected one of `!`, `+`, `,`, `::`, `:`, or `>`, found `=`
+ --> $DIR/trait-path-segments.rs:28:25
+ |
+LL | impl<T : X<X::Y<'a> = &'a u32>> Z for T {}
+ | - ^ expected one of `!`, `+`, `,`, `::`, `:`, or `>`
+ | |
+ | maybe try to close unmatched angle bracket
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | impl<T : X<X::Y<'a>> = &'a u32>> Z for T {}
+ | +
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
new file mode 100644
index 000000000..1622b92aa
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
@@ -0,0 +1,11 @@
+trait X {
+ type Y<'a>;
+}
+
+const _: () = {
+ fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+ //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments
+ //~| ERROR this associated type takes 0 generic arguments but 1 generic argument
+};
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
new file mode 100644
index 000000000..0a09ec5dc
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
@@ -0,0 +1,33 @@
+error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
+ --> $DIR/trait-path-type-error-once-implemented.rs:6:29
+ |
+LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+ | ^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'a`
+ --> $DIR/trait-path-type-error-once-implemented.rs:2:10
+ |
+LL | type Y<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | fn f2<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {}
+ | +++
+
+error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/trait-path-type-error-once-implemented.rs:6:29
+ |
+LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {}
+ | ^--- help: remove these generics
+ | |
+ | expected 0 generic arguments
+ |
+note: associated type defined here, with 0 generic parameters
+ --> $DIR/trait-path-type-error-once-implemented.rs:2:10
+ |
+LL | type Y<'a>;
+ | ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/parse/trait-path-types.rs b/tests/ui/generic-associated-types/parse/trait-path-types.rs
new file mode 100644
index 000000000..74a00342f
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-types.rs
@@ -0,0 +1,20 @@
+trait X {
+ type Y<'a>;
+}
+
+const _: () = {
+ fn f<'a>(arg : Box<dyn X< [u8; 1] = u32>>) {}
+ //~^ ERROR: expected one of
+};
+
+const _: () = {
+ fn f1<'a>(arg : Box<dyn X<(Y<'a>) = &'a ()>>) {}
+ //~^ ERROR: expected one of
+};
+
+const _: () = {
+ fn f1<'a>(arg : Box<dyn X< 'a = u32 >>) {}
+ //~^ ERROR: expected one of
+};
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/parse/trait-path-types.stderr b/tests/ui/generic-associated-types/parse/trait-path-types.stderr
new file mode 100644
index 000000000..8f7a73c95
--- /dev/null
+++ b/tests/ui/generic-associated-types/parse/trait-path-types.stderr
@@ -0,0 +1,41 @@
+error: expected one of `,`, `:`, or `>`, found `=`
+ --> $DIR/trait-path-types.rs:6:37
+ |
+LL | fn f<'a>(arg : Box<dyn X< [u8; 1] = u32>>) {}
+ | - ^ expected one of `,`, `:`, or `>`
+ | |
+ | maybe try to close unmatched angle bracket
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | fn f<'a>(arg : Box<dyn X< [u8; 1]> = u32>>) {}
+ | +
+
+error: expected one of `,`, `:`, or `>`, found `=`
+ --> $DIR/trait-path-types.rs:11:37
+ |
+LL | fn f1<'a>(arg : Box<dyn X<(Y<'a>) = &'a ()>>) {}
+ | - ^ expected one of `,`, `:`, or `>`
+ | |
+ | maybe try to close unmatched angle bracket
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | fn f1<'a>(arg : Box<dyn X<(Y<'a>)> = &'a ()>>) {}
+ | +
+
+error: expected one of `,`, `:`, or `>`, found `=`
+ --> $DIR/trait-path-types.rs:16:33
+ |
+LL | fn f1<'a>(arg : Box<dyn X< 'a = u32 >>) {}
+ | -- ^ expected one of `,`, `:`, or `>`
+ | |
+ | maybe try to close unmatched angle bracket
+ |
+help: you might have meant to end the type parameters here
+ |
+LL | fn f1<'a>(arg : Box<dyn X< 'a> = u32 >>) {}
+ | +
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/generic-associated-types/pointer_family.rs b/tests/ui/generic-associated-types/pointer_family.rs
new file mode 100644
index 000000000..80827cd56
--- /dev/null
+++ b/tests/ui/generic-associated-types/pointer_family.rs
@@ -0,0 +1,34 @@
+// check-pass
+
+use std::rc::Rc;
+use std::sync::Arc;
+use std::ops::Deref;
+
+trait PointerFamily {
+ type Pointer<T>: Deref<Target = T>;
+ fn new<T>(value: T) -> Self::Pointer<T>;
+}
+
+struct ArcFamily;
+
+impl PointerFamily for ArcFamily {
+ type Pointer<T> = Arc<T>;
+ fn new<T>(value: T) -> Self::Pointer<T> {
+ Arc::new(value)
+ }
+}
+
+struct RcFamily;
+
+impl PointerFamily for RcFamily {
+ type Pointer<T> = Rc<T>;
+ fn new<T>(value: T) -> Self::Pointer<T> {
+ Rc::new(value)
+ }
+}
+
+struct Foo<P: PointerFamily> {
+ bar: P::Pointer<String>,
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/projection-bound-cycle-generic.rs b/tests/ui/generic-associated-types/projection-bound-cycle-generic.rs
new file mode 100644
index 000000000..ecf6f69c9
--- /dev/null
+++ b/tests/ui/generic-associated-types/projection-bound-cycle-generic.rs
@@ -0,0 +1,59 @@
+// Like `projection-bound-cycle.rs` but this avoids using
+// `feature(trivial_bounds)`.
+
+trait Print {
+ fn print();
+}
+
+trait Foo {
+ type Item: Sized where <Self as Foo>::Item: Sized;
+}
+
+struct Number<T> { t: T }
+
+impl<T> Foo for Number<T> {
+ // Well-formedness checks require that the following
+ // goal is true:
+ // ```
+ // if ([T]: Sized) { # if the where clauses hold
+ // [T]: Sized # then the bound on the associated type hold
+ // }
+ // ```
+ // which it is :)
+ type Item = [T] where [T]: Sized;
+ //~^ ERROR overflow evaluating the requirement `<Number<T> as Foo>::Item == _`
+}
+
+struct OnlySized<T> where T: Sized { f: T }
+impl<T> Print for OnlySized<T> {
+ fn print() {
+ println!("{}", std::mem::size_of::<T>());
+ }
+}
+
+trait Bar {
+ type Assoc: Print;
+}
+
+impl<T> Bar for T where T: Foo {
+ // This is not ok, we need to prove `wf(<T as Foo>::Item)`, which requires
+ // knowing that `<T as Foo>::Item: Sized` to satisfy the where clause. We
+ // can use the bound on `Foo::Item` for this, but that requires
+ // `wf(<T as Foo>::Item)`, which is an invalid cycle.
+ type Assoc = OnlySized<<T as Foo>::Item>;
+}
+
+fn foo<T: Print>() {
+ T::print() // oops, in fact `T = OnlySized<str>` which is ill-formed
+}
+
+fn bar<T: Bar>() {
+ // we have `FromEnv(T: Bar)` hence
+ // `<T as Bar>::Assoc` is well-formed and
+ // `Implemented(<T as Bar>::Assoc: Print)` hold
+ foo::<<T as Bar>::Assoc>()
+}
+
+fn main() {
+ bar::<Number<u8>>()
+}
diff --git a/tests/ui/generic-associated-types/projection-bound-cycle-generic.stderr b/tests/ui/generic-associated-types/projection-bound-cycle-generic.stderr
new file mode 100644
index 000000000..aae9a56bb
--- /dev/null
+++ b/tests/ui/generic-associated-types/projection-bound-cycle-generic.stderr
@@ -0,0 +1,9 @@
+error[E0275]: overflow evaluating the requirement `<Number<T> as Foo>::Item == _`
+ --> $DIR/projection-bound-cycle-generic.rs:23:5
+ |
+LL | type Item = [T] where [T]: Sized;
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/generic-associated-types/projection-bound-cycle.rs b/tests/ui/generic-associated-types/projection-bound-cycle.rs
new file mode 100644
index 000000000..b51ae7ef2
--- /dev/null
+++ b/tests/ui/generic-associated-types/projection-bound-cycle.rs
@@ -0,0 +1,62 @@
+// Test case from Chalk.
+// Make sure that we make sure that we don't allow arbitrary bounds to be
+// proven when a bound and a where clause of an associated type are the same.
+
+#![feature(trivial_bounds)]
+
+trait Print {
+ fn print();
+}
+
+trait Foo {
+ type Item: Sized where <Self as Foo>::Item: Sized;
+}
+
+struct Number { }
+
+impl Foo for Number {
+ // Well-formedness checks require that the following
+ // goal is true:
+ // ```
+ // if (str: Sized) { # if the where clauses hold
+ // str: Sized # then the bound on the associated type hold
+ // }
+ // ```
+ // which it is :)
+ type Item = str where str: Sized;
+ //~^ ERROR overflow evaluating the requirement `<Number as Foo>::Item == _`
+}
+
+struct OnlySized<T> where T: Sized { f: T }
+impl<T> Print for OnlySized<T> {
+ fn print() {
+ println!("{}", std::mem::size_of::<T>());
+ }
+}
+
+trait Bar {
+ type Assoc: Print;
+}
+
+impl<T> Bar for T where T: Foo {
+ // This is not ok, we need to prove `wf(<T as Foo>::Item)`, which requires
+ // knowing that `<T as Foo>::Item: Sized` to satisfy the where clause. We
+ // can use the bound on `Foo::Item` for this, but that requires
+ // `wf(<T as Foo>::Item)`, which is an invalid cycle.
+ type Assoc = OnlySized<<T as Foo>::Item>;
+}
+
+fn foo<T: Print>() {
+ T::print() // oops, in fact `T = OnlySized<str>` which is ill-formed
+}
+
+fn bar<T: Bar>() {
+ // we have `FromEnv(T: Bar)` hence
+ // `<T as Bar>::Assoc` is well-formed and
+ // `Implemented(<T as Bar>::Assoc: Print)` hold
+ foo::<<T as Bar>::Assoc>()
+}
+
+fn main() {
+ bar::<Number>()
+}
diff --git a/tests/ui/generic-associated-types/projection-bound-cycle.stderr b/tests/ui/generic-associated-types/projection-bound-cycle.stderr
new file mode 100644
index 000000000..b1b8afeec
--- /dev/null
+++ b/tests/ui/generic-associated-types/projection-bound-cycle.stderr
@@ -0,0 +1,9 @@
+error[E0275]: overflow evaluating the requirement `<Number as Foo>::Item == _`
+ --> $DIR/projection-bound-cycle.rs:26:5
+ |
+LL | type Item = str where str: Sized;
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/generic-associated-types/projection-type-lifetime-mismatch.rs b/tests/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
new file mode 100644
index 000000000..8e4d5ca5e
--- /dev/null
+++ b/tests/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
@@ -0,0 +1,33 @@
+pub trait X {
+ type Y<'a> where Self: 'a;
+ fn m(&self) -> Self::Y<'_>;
+}
+
+impl X for () {
+ type Y<'a> = &'a ();
+
+ fn m(&self) -> Self::Y<'_> {
+ self
+ }
+}
+
+fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () {
+ x.m()
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () {
+ x.m()
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn h(x: &()) -> &'static () {
+ x.m()
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {
+ f(&());
+ g(&());
+ h(&());
+}
diff --git a/tests/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr b/tests/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr
new file mode 100644
index 000000000..753ead48b
--- /dev/null
+++ b/tests/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr
@@ -0,0 +1,26 @@
+error: lifetime may not live long enough
+ --> $DIR/projection-type-lifetime-mismatch.rs:15:5
+ |
+LL | fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () {
+ | - let's call the lifetime of this reference `'1`
+LL | x.m()
+ | ^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/projection-type-lifetime-mismatch.rs:20:5
+ |
+LL | fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () {
+ | - let's call the lifetime of this reference `'1`
+LL | x.m()
+ | ^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/projection-type-lifetime-mismatch.rs:25:5
+ |
+LL | fn h(x: &()) -> &'static () {
+ | - let's call the lifetime of this reference `'1`
+LL | x.m()
+ | ^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/generic-associated-types/self-outlives-lint.rs b/tests/ui/generic-associated-types/self-outlives-lint.rs
new file mode 100644
index 000000000..673891fc3
--- /dev/null
+++ b/tests/ui/generic-associated-types/self-outlives-lint.rs
@@ -0,0 +1,224 @@
+// check-fail
+
+use std::fmt::Debug;
+
+// We have a `&'a self`, so we need a `Self: 'a`
+trait Iterable {
+ type Item<'x>;
+ //~^ missing required
+ fn iter<'a>(&'a self) -> Self::Item<'a>;
+}
+
+/*
+impl<T> Iterable for T {
+ type Item<'a> = &'a T;
+ fn iter<'a>(&'a self) -> Self::Item<'a> {
+ self
+ }
+}
+*/
+
+// We have a `&'a T`, so we need a `T: 'x`
+trait Deserializer<T> {
+ type Out<'x>;
+ //~^ missing required
+ fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a>;
+}
+
+/*
+impl<T> Deserializer<T> for () {
+ type Out<'a> = &'a T;
+ fn deserialize<'a>(&self, input: &'a T) -> Self::Out<'a> { input }
+}
+*/
+
+// We have a `&'b T` and a `'b: 'a`, so it is implied that `T: 'a`. Therefore, we need a `T: 'x`
+trait Deserializer2<T> {
+ type Out<'x>;
+ //~^ missing required
+ fn deserialize2<'a, 'b: 'a>(&self, input1: &'b T) -> Self::Out<'a>;
+}
+
+// We have a `&'a T` and a `&'b U`, so we need a `T: 'x` and a `U: 'y`
+trait Deserializer3<T, U> {
+ type Out<'x, 'y>;
+ //~^ missing required
+ fn deserialize2<'a, 'b>(&self, input: &'a T, input2: &'b U) -> Self::Out<'a, 'b>;
+}
+
+// `T` is a param on the function, so it can't be named by the associated type
+trait Deserializer4 {
+ type Out<'x>;
+ fn deserialize<'a, T>(&self, input: &'a T) -> Self::Out<'a>;
+}
+
+struct Wrap<T>(T);
+
+// We pass `Wrap<T>` and we see `&'z Wrap<T>`, so we require `D: 'x`
+trait Des {
+ type Out<'x, D>;
+ //~^ missing required
+ fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, Wrap<T>>;
+}
+/*
+impl Des for () {
+ type Out<'x, D> = &'x D; // Not okay
+ fn des<'a, T>(&self, data: &'a Wrap<T>) -> Self::Out<'a, Wrap<T>> {
+ data
+ }
+}
+*/
+
+// We have `T` and `'z` as GAT substs. Because of `&'z Wrap<T>`, there is an
+// implied bound that `T: 'z`, so we require `D: 'x`
+trait Des2 {
+ type Out<'x, D>;
+ //~^ missing required
+ fn des<'z, T>(&self, data: &'z Wrap<T>) -> Self::Out<'z, T>;
+}
+/*
+impl Des2 for () {
+ type Out<'x, D> = &'x D;
+ fn des<'a, T>(&self, data: &'a Wrap<T>) -> Self::Out<'a, T> {
+ &data.0
+ }
+}
+*/
+
+// We see `&'z T`, so we require `D: 'x`
+trait Des3 {
+ type Out<'x, D>;
+ //~^ missing required
+ fn des<'z, T>(&self, data: &'z T) -> Self::Out<'z, T>;
+}
+/*
+impl Des3 for () {
+ type Out<'x, D> = &'x D;
+ fn des<'a, T>(&self, data: &'a T) -> Self::Out<'a, T> {
+ data
+ }
+}
+*/
+
+// Similar case to before, except with GAT.
+trait NoGat<'a> {
+ type Bar;
+ fn method(&'a self) -> Self::Bar;
+}
+
+// Lifetime is not on function; except `Self: 'a`
+// FIXME: we require two bounds (`where Self: 'a, Self: 'b`) when we should only require one
+trait TraitLifetime<'a> {
+ type Bar<'b>;
+ //~^ missing required
+ fn method(&'a self) -> Self::Bar<'a>;
+}
+
+// Like above, but we have a where clause that can prove what we want
+// FIXME: we require two bounds (`where Self: 'a, Self: 'b`) when we should only require one
+trait TraitLifetimeWhere<'a> where Self: 'a {
+ type Bar<'b>;
+ //~^ missing required
+ fn method(&'a self) -> Self::Bar<'a>;
+}
+
+// Explicit bound instead of implicit; we want to still error
+trait ExplicitBound {
+ type Bar<'b>;
+ //~^ missing required
+ fn method<'b>(&self, token: &'b ()) -> Self::Bar<'b> where Self: 'b;
+}
+
+// The use of the GAT here is not in the return, we don't want to error
+trait NotInReturn {
+ type Bar<'b>;
+ fn method<'b>(&'b self) where Self::Bar<'b>: Debug;
+}
+
+// We obviously error for `Iterator`, but we should also error for `Item`
+trait IterableTwo {
+ type Item<'a>;
+ //~^ missing required
+ type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
+ //~^ missing required
+ fn iter<'a>(&'a self) -> Self::Iterator<'a>;
+}
+
+trait IterableTwoWhere {
+ type Item<'a>;
+ //~^ missing required
+ type Iterator<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
+ fn iter<'a>(&'a self) -> Self::Iterator<'a>;
+}
+
+// We also should report region outlives clauses. Here, we know that `'y: 'x`,
+// because of `&'x &'y`, so we require that `'b: 'a`.
+trait RegionOutlives {
+ type Bar<'a, 'b>;
+ //~^ missing required
+ fn foo<'x, 'y>(&self, input: &'x &'y ()) -> Self::Bar<'x, 'y>;
+}
+
+/*
+impl Foo for () {
+ type Bar<'a, 'b> = &'a &'b ();
+ fn foo<'x, 'y>(&self, input: &'x &'y ()) -> Self::Bar<'x, 'y> {
+ input
+ }
+}
+*/
+
+// Similar to the above, except with explicit bounds
+trait ExplicitRegionOutlives<'ctx> {
+ type Fut<'out>;
+ //~^ missing required
+
+ fn test<'out>(ctx: &'ctx i32) -> Self::Fut<'out>
+ where
+ 'ctx: 'out;
+}
+
+
+// If there are multiple methods that return the GAT, require a set of clauses
+// that can be satisfied by *all* methods
+trait MultipleMethods {
+ type Bar<'me>;
+
+ fn gimme<'a>(&'a self) -> Self::Bar<'a>;
+ fn gimme_default(&self) -> Self::Bar<'static>;
+}
+
+// We would normally require `Self: 'a`, but we can prove that `Self: 'static`
+// because of the the bounds on the trait, so the bound is proven
+trait Trait: 'static {
+ type Assoc<'a>;
+ fn make_assoc(_: &u32) -> Self::Assoc<'_>;
+}
+
+// We ignore `'static` lifetimes for any lints
+trait StaticReturn<'a> {
+ type Y<'b>;
+ fn foo(&self) -> Self::Y<'static>;
+}
+
+// Same as above, but with extra method that takes GAT - just make sure this works
+trait StaticReturnAndTakes<'a> {
+ type Y<'b>;
+ fn foo(&self) -> Self::Y<'static>;
+ fn bar<'b>(&self, arg: Self::Y<'b>);
+}
+
+// We require bounds when the GAT appears in the inputs
+trait Input {
+ type Item<'a>;
+ //~^ missing required
+ fn takes_item<'a>(&'a self, item: Self::Item<'a>);
+}
+
+// We don't require bounds when the GAT appears in the where clauses
+trait WhereClause {
+ type Item<'a>;
+ fn takes_item<'a>(&'a self) where Self::Item<'a>: ;
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/self-outlives-lint.stderr b/tests/ui/generic-associated-types/self-outlives-lint.stderr
new file mode 100644
index 000000000..9e9b2e18a
--- /dev/null
+++ b/tests/ui/generic-associated-types/self-outlives-lint.stderr
@@ -0,0 +1,178 @@
+error: missing required bound on `Item`
+ --> $DIR/self-outlives-lint.rs:7:5
+ |
+LL | type Item<'x>;
+ | ^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'x`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Out`
+ --> $DIR/self-outlives-lint.rs:23:5
+ |
+LL | type Out<'x>;
+ | ^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where T: 'x`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Out`
+ --> $DIR/self-outlives-lint.rs:37:5
+ |
+LL | type Out<'x>;
+ | ^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where T: 'x`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bounds on `Out`
+ --> $DIR/self-outlives-lint.rs:44:5
+ |
+LL | type Out<'x, 'y>;
+ | ^^^^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clauses: `where T: 'x, U: 'y`
+ |
+ = note: these bounds are currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Out`
+ --> $DIR/self-outlives-lint.rs:59:5
+ |
+LL | type Out<'x, D>;
+ | ^^^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where D: 'x`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Out`
+ --> $DIR/self-outlives-lint.rs:75:5
+ |
+LL | type Out<'x, D>;
+ | ^^^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where D: 'x`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Out`
+ --> $DIR/self-outlives-lint.rs:90:5
+ |
+LL | type Out<'x, D>;
+ | ^^^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where D: 'x`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bounds on `Bar`
+ --> $DIR/self-outlives-lint.rs:112:5
+ |
+LL | type Bar<'b>;
+ | ^^^^^^^^^^^^-
+ | |
+ | help: add the required where clauses: `where Self: 'a, Self: 'b`
+ |
+ = note: these bounds are currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Bar`
+ --> $DIR/self-outlives-lint.rs:120:5
+ |
+LL | type Bar<'b>;
+ | ^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'b`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Bar`
+ --> $DIR/self-outlives-lint.rs:127:5
+ |
+LL | type Bar<'b>;
+ | ^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'b`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Iterator`
+ --> $DIR/self-outlives-lint.rs:142:5
+ |
+LL | type Iterator<'a>: Iterator<Item = Self::Item<'a>>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'a`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Item`
+ --> $DIR/self-outlives-lint.rs:140:5
+ |
+LL | type Item<'a>;
+ | ^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'a`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Item`
+ --> $DIR/self-outlives-lint.rs:148:5
+ |
+LL | type Item<'a>;
+ | ^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'a`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Bar`
+ --> $DIR/self-outlives-lint.rs:157:5
+ |
+LL | type Bar<'a, 'b>;
+ | ^^^^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where 'b: 'a`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Fut`
+ --> $DIR/self-outlives-lint.rs:173:5
+ |
+LL | type Fut<'out>;
+ | ^^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where 'ctx: 'out`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: missing required bound on `Item`
+ --> $DIR/self-outlives-lint.rs:213:5
+ |
+LL | type Item<'a>;
+ | ^^^^^^^^^^^^^-
+ | |
+ | help: add the required where clause: `where Self: 'a`
+ |
+ = note: this bound is currently required to ensure that impls have maximum flexibility
+ = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
+
+error: aborting due to 16 previous errors
+
diff --git a/tests/ui/generic-associated-types/shadowing.rs b/tests/ui/generic-associated-types/shadowing.rs
new file mode 100644
index 000000000..a05d6e143
--- /dev/null
+++ b/tests/ui/generic-associated-types/shadowing.rs
@@ -0,0 +1,29 @@
+trait Shadow<'a> {
+ type Bar<'a>;
+ //~^ ERROR lifetime name `'a` shadows a lifetime name that is already in scope
+}
+
+trait NoShadow<'a> {
+ type Bar<'b>; // OK
+}
+
+impl<'a> NoShadow<'a> for &'a u32 {
+ type Bar<'a> = i32;
+ //~^ ERROR lifetime name `'a` shadows a lifetime name that is already in scope
+}
+
+trait ShadowT<T> {
+ type Bar<T>;
+ //~^ ERROR the name `T` is already used
+}
+
+trait NoShadowT<T> {
+ type Bar<U>; // OK
+}
+
+impl<T> NoShadowT<T> for Option<T> {
+ type Bar<T> = i32;
+ //~^ ERROR the name `T` is already used
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/shadowing.stderr b/tests/ui/generic-associated-types/shadowing.stderr
new file mode 100644
index 000000000..bb32684bc
--- /dev/null
+++ b/tests/ui/generic-associated-types/shadowing.stderr
@@ -0,0 +1,36 @@
+error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
+ --> $DIR/shadowing.rs:2:14
+ |
+LL | trait Shadow<'a> {
+ | -- first declared here
+LL | type Bar<'a>;
+ | ^^ lifetime `'a` already in scope
+
+error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
+ --> $DIR/shadowing.rs:11:14
+ |
+LL | impl<'a> NoShadow<'a> for &'a u32 {
+ | -- first declared here
+LL | type Bar<'a> = i32;
+ | ^^ lifetime `'a` already in scope
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+ --> $DIR/shadowing.rs:16:14
+ |
+LL | trait ShadowT<T> {
+ | - first use of `T`
+LL | type Bar<T>;
+ | ^ already used
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+ --> $DIR/shadowing.rs:25:14
+ |
+LL | impl<T> NoShadowT<T> for Option<T> {
+ | - first use of `T`
+LL | type Bar<T> = i32;
+ | ^ already used
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0403, E0496.
+For more information about an error, try `rustc --explain E0403`.
diff --git a/tests/ui/generic-associated-types/streaming_iterator.rs b/tests/ui/generic-associated-types/streaming_iterator.rs
new file mode 100644
index 000000000..408b8dc99
--- /dev/null
+++ b/tests/ui/generic-associated-types/streaming_iterator.rs
@@ -0,0 +1,74 @@
+// run-pass
+
+use std::fmt::Display;
+
+trait StreamingIterator {
+ type Item<'a> where Self: 'a;
+ // Applying the lifetime parameter `'a` to `Self::Item` inside the trait.
+ fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
+}
+
+struct Foo<T: StreamingIterator + 'static> {
+ // Applying a concrete lifetime to the constructor outside the trait.
+ bar: <T as StreamingIterator>::Item<'static>,
+}
+
+// Users can bound parameters by the type constructed by that trait's associated type constructor
+// of a trait using HRTB. Both type equality bounds and trait bounds of this kind are valid:
+//FIXME(#44265): This next line should parse and be valid
+//fn foo<T: for<'a> StreamingIterator<Item<'a>=&'a [i32]>>(_iter: T) { /* ... */ }
+fn _foo<T>(_iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ }
+
+// Full example of enumerate iterator
+
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+struct StreamEnumerate<I> {
+ iter: I,
+ count: usize,
+}
+
+impl<I: StreamingIterator> StreamingIterator for StreamEnumerate<I> {
+ type Item<'a> = (usize, I::Item<'a>) where Self: 'a;
+ fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
+ match self.iter.next() {
+ None => None,
+ Some(val) => {
+ let r = Some((self.count, val));
+ self.count += 1;
+ r
+ }
+ }
+ }
+}
+
+impl<I: Iterator> StreamingIterator for I {
+ type Item<'a> = <I as Iterator>::Item where Self: 'a;
+ fn next(&mut self) -> Option<<I as StreamingIterator>::Item<'_>> {
+ Iterator::next(self)
+ }
+}
+
+impl<I> StreamEnumerate<I> {
+ pub fn new(iter: I) -> Self {
+ StreamEnumerate {
+ count: 0,
+ iter,
+ }
+ }
+}
+
+fn test_stream_enumerate() {
+ let v = vec!["a", "b", "c"];
+ let mut se = StreamEnumerate::new(v.iter());
+ while let Some(item) = se.next() {
+ assert_eq!(v[item.0], *item.1);
+ }
+ let x = Foo::<std::slice::Iter<'static, u32>> {
+ bar: &0u32,
+ };
+ assert_eq!(*x.bar, 0u32);
+}
+
+fn main() {
+ test_stream_enumerate();
+}
diff --git a/tests/ui/generic-associated-types/trait-objects.base.stderr b/tests/ui/generic-associated-types/trait-objects.base.stderr
new file mode 100644
index 000000000..556422c27
--- /dev/null
+++ b/tests/ui/generic-associated-types/trait-objects.base.stderr
@@ -0,0 +1,18 @@
+error[E0038]: the trait `StreamingIterator` cannot be made into an object
+ --> $DIR/trait-objects.rs:13:21
+ |
+LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/trait-objects.rs:7:10
+ |
+LL | trait StreamingIterator {
+ | ----------------- this trait cannot be made into an object...
+LL | type Item<'a> where Self: 'a;
+ | ^^^^ ...because it contains the generic associated type `Item`
+ = help: consider moving `Item` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/generic-associated-types/trait-objects.extended.stderr b/tests/ui/generic-associated-types/trait-objects.extended.stderr
new file mode 100644
index 000000000..45b64d2b0
--- /dev/null
+++ b/tests/ui/generic-associated-types/trait-objects.extended.stderr
@@ -0,0 +1,19 @@
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/trait-objects.rs:15:5
+ |
+LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | `x` is a reference that is only valid in the function body
+LL |
+LL | x.size_hint().0
+ | ^^^^^^^^^^^^^
+ | |
+ | `x` escapes the function body here
+ | argument requires that `'1` must outlive `'static`
+ |
+ = note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0521`.
diff --git a/tests/ui/generic-associated-types/trait-objects.rs b/tests/ui/generic-associated-types/trait-objects.rs
new file mode 100644
index 000000000..17fed11ba
--- /dev/null
+++ b/tests/ui/generic-associated-types/trait-objects.rs
@@ -0,0 +1,19 @@
+// revisions: base extended
+
+#![cfg_attr(extended, feature(generic_associated_types_extended))]
+#![cfg_attr(extended, allow(incomplete_features))]
+
+trait StreamingIterator {
+ type Item<'a> where Self: 'a;
+ fn size_hint(&self) -> (usize, Option<usize>);
+ // Uncommenting makes `StreamingIterator` not object safe
+// fn next(&mut self) -> Self::Item<'_>;
+}
+
+fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
+ //[base]~^ the trait `StreamingIterator` cannot be made into an object
+ x.size_hint().0
+ //[extended]~^ borrowed data escapes
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/type-param-defaults.rs b/tests/ui/generic-associated-types/type-param-defaults.rs
new file mode 100644
index 000000000..f034076b0
--- /dev/null
+++ b/tests/ui/generic-associated-types/type-param-defaults.rs
@@ -0,0 +1,34 @@
+// Check that we disallow GAT param defaults, even with `invalid_type_param_default` allowed
+
+#![allow(invalid_type_param_default)]
+
+trait Trait {
+ type Assoc<T = u32>;
+ //~^ defaults for type parameters are only allowed
+}
+
+impl Trait for () {
+ type Assoc<T = u32> = u64;
+ //~^ defaults for type parameters are only allowed
+}
+
+impl Trait for u32 {
+ type Assoc<T = u32> = T;
+ //~^ defaults for type parameters are only allowed
+}
+
+trait Other {}
+impl Other for u32 {}
+
+fn foo<T>()
+where
+ T: Trait<Assoc = u32>,
+ T::Assoc: Other {
+ }
+
+fn main() {
+ // errors
+ foo::<()>();
+ // works
+ foo::<u32>();
+}
diff --git a/tests/ui/generic-associated-types/type-param-defaults.stderr b/tests/ui/generic-associated-types/type-param-defaults.stderr
new file mode 100644
index 000000000..85ccaba0e
--- /dev/null
+++ b/tests/ui/generic-associated-types/type-param-defaults.stderr
@@ -0,0 +1,20 @@
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/type-param-defaults.rs:6:16
+ |
+LL | type Assoc<T = u32>;
+ | ^^^^^^^
+
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/type-param-defaults.rs:11:16
+ |
+LL | type Assoc<T = u32> = u64;
+ | ^^^^^^^
+
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/type-param-defaults.rs:16:16
+ |
+LL | type Assoc<T = u32> = T;
+ | ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.rs b/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
new file mode 100644
index 000000000..1cc09aa6d
--- /dev/null
+++ b/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
@@ -0,0 +1,25 @@
+pub trait X {
+ type Y<'a: 'static>;
+ //~^ WARNING unnecessary lifetime parameter
+}
+
+impl X for () {
+ type Y<'a> = &'a ();
+}
+
+struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> {
+ f: <T as X>::Y<'a>,
+ //~^ ERROR lifetime bound not satisfied
+}
+
+struct C<'a, T: X> {
+ f: <T as X>::Y<'a>,
+ //~^ ERROR lifetime bound not satisfied
+}
+
+struct D<'a> {
+ f: <() as X>::Y<'a>,
+ //~^ ERROR lifetime bound not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr b/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
new file mode 100644
index 000000000..fbd79879d
--- /dev/null
+++ b/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
@@ -0,0 +1,50 @@
+warning: unnecessary lifetime parameter `'a`
+ --> $DIR/unsatified-item-lifetime-bound.rs:2:12
+ |
+LL | type Y<'a: 'static>;
+ | ^^
+ |
+ = help: you can use the `'static` lifetime directly, in place of `'a`
+
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/unsatified-item-lifetime-bound.rs:11:8
+ |
+LL | f: <T as X>::Y<'a>,
+ | ^^^^^^^^^^^^^^^
+ |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+ --> $DIR/unsatified-item-lifetime-bound.rs:10:10
+ |
+LL | struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> {
+ | ^^
+ = note: but lifetime parameter must outlive the static lifetime
+
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/unsatified-item-lifetime-bound.rs:16:8
+ |
+LL | f: <T as X>::Y<'a>,
+ | ^^^^^^^^^^^^^^^
+ |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+ --> $DIR/unsatified-item-lifetime-bound.rs:15:10
+ |
+LL | struct C<'a, T: X> {
+ | ^^
+ = note: but lifetime parameter must outlive the static lifetime
+
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/unsatified-item-lifetime-bound.rs:21:8
+ |
+LL | f: <() as X>::Y<'a>,
+ | ^^^^^^^^^^^^^^^^
+ |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+ --> $DIR/unsatified-item-lifetime-bound.rs:20:10
+ |
+LL | struct D<'a> {
+ | ^^
+ = note: but lifetime parameter must outlive the static lifetime
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0478`.
diff --git a/tests/ui/generic-associated-types/unsatisfied-outlives-bound.rs b/tests/ui/generic-associated-types/unsatisfied-outlives-bound.rs
new file mode 100644
index 000000000..7137d9237
--- /dev/null
+++ b/tests/ui/generic-associated-types/unsatisfied-outlives-bound.rs
@@ -0,0 +1,19 @@
+trait ATy {
+ type Item<'a>: 'a;
+}
+
+impl<'b> ATy for &'b () {
+ type Item<'a> = &'b ();
+ //~^ ERROR the type `&'b ()` does not fulfill the required lifetime
+}
+
+trait StaticTy {
+ type Item<'a>: 'static;
+}
+
+impl StaticTy for () {
+ type Item<'a> = &'a ();
+ //~^ ERROR the type `&'a ()` does not fulfill the required lifetime
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/unsatisfied-outlives-bound.stderr b/tests/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
new file mode 100644
index 000000000..1c9ac01ec
--- /dev/null
+++ b/tests/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
@@ -0,0 +1,27 @@
+error[E0477]: the type `&'b ()` does not fulfill the required lifetime
+ --> $DIR/unsatisfied-outlives-bound.rs:6:21
+ |
+LL | type Item<'a> = &'b ();
+ | ^^^^^^
+ |
+note: type must outlive the lifetime `'a` as defined here as required by this binding
+ --> $DIR/unsatisfied-outlives-bound.rs:6:15
+ |
+LL | type Item<'a> = &'b ();
+ | ^^
+
+error[E0477]: the type `&'a ()` does not fulfill the required lifetime
+ --> $DIR/unsatisfied-outlives-bound.rs:15:21
+ |
+LL | type Item<'a> = &'a ();
+ | ^^^^^^
+ |
+note: type must satisfy the static lifetime as required by this binding
+ --> $DIR/unsatisfied-outlives-bound.rs:11:20
+ |
+LL | type Item<'a>: 'static;
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/tests/ui/generic-associated-types/variance_constraints.rs b/tests/ui/generic-associated-types/variance_constraints.rs
new file mode 100644
index 000000000..0e9dbb8b1
--- /dev/null
+++ b/tests/ui/generic-associated-types/variance_constraints.rs
@@ -0,0 +1,22 @@
+// check-pass
+// issue #69184
+
+trait A {
+ type B<'a> where Self: 'a;
+
+ fn make_b<'a>(&'a self) -> Self::B<'a>;
+}
+
+struct S {}
+impl A for S {
+ type B<'a> = &'a S;
+ fn make_b<'a>(&'a self) -> &'a Self {
+ self
+ }
+}
+
+enum E<'a> {
+ S(<S as A>::B<'a>),
+}
+
+fn main() {}