summaryrefslogtreecommitdiffstats
path: root/src/test/ui/generic-associated-types
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/generic-associated-types
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/generic-associated-types')
-rw-r--r--src/test/ui/generic-associated-types/anonymize-bound-vars.rs14
-rw-r--r--src/test/ui/generic-associated-types/auxiliary/foo_defn.rs8
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.rs17
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-80626.stderr15
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-86218.rs27
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-86218.stderr23
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87735.rs46
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87735.stderr9
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87748.rs23
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87748.stderr20
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87755.rs21
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87755.stderr9
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87803.rs27
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-87803.stderr12
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88382.rs31
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88382.stderr22
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88460.rs31
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88460.stderr19
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88526.rs35
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88526.stderr9
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-89008.rs44
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-89008.stderr19
-rw-r--r--src/test/ui/generic-associated-types/collections-project-default.rs71
-rw-r--r--src/test/ui/generic-associated-types/collections-project-default.stderr15
-rw-r--r--src/test/ui/generic-associated-types/collections.rs70
-rw-r--r--src/test/ui/generic-associated-types/collectivity-regression.rs24
-rw-r--r--src/test/ui/generic-associated-types/collectivity-regression.stderr14
-rw-r--r--src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs21
-rw-r--r--src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs21
-rw-r--r--src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs26
-rw-r--r--src/test/ui/generic-associated-types/const_params_have_right_type.rs12
-rw-r--r--src/test/ui/generic-associated-types/const_params_have_right_type.stderr16
-rw-r--r--src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs16
-rw-r--r--src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr18
-rw-r--r--src/test/ui/generic-associated-types/construct_with_other_type.rs24
-rw-r--r--src/test/ui/generic-associated-types/cross-crate-bounds.rs32
-rw-r--r--src/test/ui/generic-associated-types/cross-crate-bounds.stderr15
-rw-r--r--src/test/ui/generic-associated-types/elided-in-expr-position.rs38
-rw-r--r--src/test/ui/generic-associated-types/elided-in-expr-position.stderr35
-rw-r--r--src/test/ui/generic-associated-types/empty_generics.rs8
-rw-r--r--src/test/ui/generic-associated-types/empty_generics.stderr13
-rw-r--r--src/test/ui/generic-associated-types/equality-bound.rs15
-rw-r--r--src/test/ui/generic-associated-types/equality-bound.stderr43
-rw-r--r--src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr12
-rw-r--r--src/test/ui/generic-associated-types/extended/lending_iterator.rs39
-rw-r--r--src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr12
-rw-r--r--src/test/ui/generic-associated-types/extended/lending_iterator_2.rs31
-rw-r--r--src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs16
-rw-r--r--src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr21
-rw-r--r--src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs16
-rw-r--r--src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr19
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs11
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr26
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr18
-rw-r--r--src/test/ui/generic-associated-types/gat-in-trait-path.rs34
-rw-r--r--src/test/ui/generic-associated-types/gat-incomplete-warning.rs5
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs16
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr25
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs17
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr35
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs18
-rw-r--r--src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr74
-rw-r--r--src/test/ui/generic-associated-types/generic-associated-type-bounds.rs34
-rw-r--r--src/test/ui/generic-associated-types/generic-associated-types-where.rs28
-rw-r--r--src/test/ui/generic-associated-types/generic-associated-types-where.stderr25
-rw-r--r--src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs15
-rw-r--r--src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr38
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds.rs26
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds.stderr92
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds_ok.rs30
-rw-r--r--src/test/ui/generic-associated-types/issue-47206-where-clause.rs16
-rw-r--r--src/test/ui/generic-associated-types/issue-47206-where-clause.stderr12
-rw-r--r--src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs9
-rw-r--r--src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs13
-rw-r--r--src/test/ui/generic-associated-types/issue-67424.rs12
-rw-r--r--src/test/ui/generic-associated-types/issue-67424.stderr12
-rw-r--r--src/test/ui/generic-associated-types/issue-67510-pass.base.stderr18
-rw-r--r--src/test/ui/generic-associated-types/issue-67510-pass.rs16
-rw-r--r--src/test/ui/generic-associated-types/issue-67510.rs12
-rw-r--r--src/test/ui/generic-associated-types/issue-67510.stderr50
-rw-r--r--src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.rs31
-rw-r--r--src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr20
-rw-r--r--src/test/ui/generic-associated-types/issue-68643-broken-mir.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr20
-rw-r--r--src/test/ui/generic-associated-types/issue-68644-codegen-selection.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr20
-rw-r--r--src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr20
-rw-r--r--src/test/ui/generic-associated-types/issue-68648-1.rs25
-rw-r--r--src/test/ui/generic-associated-types/issue-68648-2.rs23
-rw-r--r--src/test/ui/generic-associated-types/issue-68648-2.stderr21
-rw-r--r--src/test/ui/generic-associated-types/issue-68649-pass.rs24
-rw-r--r--src/test/ui/generic-associated-types/issue-68653.rs15
-rw-r--r--src/test/ui/generic-associated-types/issue-68656-unsized-values.rs21
-rw-r--r--src/test/ui/generic-associated-types/issue-68656-unsized-values.stderr23
-rw-r--r--src/test/ui/generic-associated-types/issue-70303.rs59
-rw-r--r--src/test/ui/generic-associated-types/issue-70304.rs57
-rw-r--r--src/test/ui/generic-associated-types/issue-70304.stderr33
-rw-r--r--src/test/ui/generic-associated-types/issue-71176.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-71176.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-74684-1.rs25
-rw-r--r--src/test/ui/generic-associated-types/issue-74684-1.stderr18
-rw-r--r--src/test/ui/generic-associated-types/issue-74684-2.rs25
-rw-r--r--src/test/ui/generic-associated-types/issue-74684-2.stderr20
-rw-r--r--src/test/ui/generic-associated-types/issue-74816.rs22
-rw-r--r--src/test/ui/generic-associated-types/issue-74816.stderr35
-rw-r--r--src/test/ui/generic-associated-types/issue-74824.rs26
-rw-r--r--src/test/ui/generic-associated-types/issue-74824.stderr32
-rw-r--r--src/test/ui/generic-associated-types/issue-76407.rs27
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.base.stderr52
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.extended.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-76535.rs44
-rw-r--r--src/test/ui/generic-associated-types/issue-76826.rs44
-rw-r--r--src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs40
-rw-r--r--src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr87
-rw-r--r--src/test/ui/generic-associated-types/issue-78671.base.stderr35
-rw-r--r--src/test/ui/generic-associated-types/issue-78671.extended.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-78671.rs18
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.base.stderr52
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.extended.stderr35
-rw-r--r--src/test/ui/generic-associated-types/issue-79422.rs51
-rw-r--r--src/test/ui/generic-associated-types/issue-79636-1.rs23
-rw-r--r--src/test/ui/generic-associated-types/issue-79636-1.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-79636-2.rs17
-rw-r--r--src/test/ui/generic-associated-types/issue-79636-2.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-80433-reduced.rs23
-rw-r--r--src/test/ui/generic-associated-types/issue-80433.rs34
-rw-r--r--src/test/ui/generic-associated-types/issue-80433.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-81487.rs19
-rw-r--r--src/test/ui/generic-associated-types/issue-81712-cyclic-traits.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-81862.rs12
-rw-r--r--src/test/ui/generic-associated-types/issue-81862.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-84931.rs22
-rw-r--r--src/test/ui/generic-associated-types/issue-84931.stderr11
-rw-r--r--src/test/ui/generic-associated-types/issue-85921.rs19
-rw-r--r--src/test/ui/generic-associated-types/issue-86483.rs16
-rw-r--r--src/test/ui/generic-associated-types/issue-86787.rs38
-rw-r--r--src/test/ui/generic-associated-types/issue-86787.stderr13
-rw-r--r--src/test/ui/generic-associated-types/issue-87258_a.rs25
-rw-r--r--src/test/ui/generic-associated-types/issue-87258_a.stderr10
-rw-r--r--src/test/ui/generic-associated-types/issue-87258_b.rs27
-rw-r--r--src/test/ui/generic-associated-types/issue-87258_b.stderr10
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-2.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-associated-type-default.rs18
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr20
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-specialization.rs25
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-specialization.stderr30
-rw-r--r--src/test/ui/generic-associated-types/issue-87429.rs15
-rw-r--r--src/test/ui/generic-associated-types/issue-87750.rs22
-rw-r--r--src/test/ui/generic-associated-types/issue-87750.stderr9
-rw-r--r--src/test/ui/generic-associated-types/issue-88287.rs40
-rw-r--r--src/test/ui/generic-associated-types/issue-88287.stderr27
-rw-r--r--src/test/ui/generic-associated-types/issue-88360.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-88360.stderr20
-rw-r--r--src/test/ui/generic-associated-types/issue-88405.rs16
-rw-r--r--src/test/ui/generic-associated-types/issue-88459.rs19
-rw-r--r--src/test/ui/generic-associated-types/issue-88595.rs22
-rw-r--r--src/test/ui/generic-associated-types/issue-88595.stderr16
-rw-r--r--src/test/ui/generic-associated-types/issue-89352.rs32
-rw-r--r--src/test/ui/generic-associated-types/issue-90014.rs22
-rw-r--r--src/test/ui/generic-associated-types/issue-90014.stderr18
-rw-r--r--src/test/ui/generic-associated-types/issue-90729.rs38
-rw-r--r--src/test/ui/generic-associated-types/issue-91139.migrate.stderr13
-rw-r--r--src/test/ui/generic-associated-types/issue-91139.rs36
-rw-r--r--src/test/ui/generic-associated-types/issue-91139.stderr62
-rw-r--r--src/test/ui/generic-associated-types/issue-91762.rs30
-rw-r--r--src/test/ui/generic-associated-types/issue-91762.stderr14
-rw-r--r--src/test/ui/generic-associated-types/issue-91883.rs42
-rw-r--r--src/test/ui/generic-associated-types/issue-91883.stderr23
-rw-r--r--src/test/ui/generic-associated-types/issue-92033.rs39
-rw-r--r--src/test/ui/generic-associated-types/issue-92033.stderr18
-rw-r--r--src/test/ui/generic-associated-types/issue-92096.migrate.stderr24
-rw-r--r--src/test/ui/generic-associated-types/issue-92096.rs30
-rw-r--r--src/test/ui/generic-associated-types/issue-92096.stderr8
-rw-r--r--src/test/ui/generic-associated-types/issue-92280.rs25
-rw-r--r--src/test/ui/generic-associated-types/issue-92954.rs10
-rw-r--r--src/test/ui/generic-associated-types/issue-93141.rs25
-rw-r--r--src/test/ui/generic-associated-types/issue-93262.rs21
-rw-r--r--src/test/ui/generic-associated-types/issue-93340.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-93341.rs55
-rw-r--r--src/test/ui/generic-associated-types/issue-93342.rs57
-rw-r--r--src/test/ui/generic-associated-types/issue-93874.rs35
-rw-r--r--src/test/ui/generic-associated-types/issue-95305.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-95305.stderr9
-rw-r--r--src/test/ui/generic-associated-types/iterable.rs46
-rw-r--r--src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs35
-rw-r--r--src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr24
-rw-r--r--src/test/ui/generic-associated-types/missing-bounds.fixed46
-rw-r--r--src/test/ui/generic-associated-types/missing-bounds.rs46
-rw-r--r--src/test/ui/generic-associated-types/missing-bounds.stderr98
-rw-r--r--src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs13
-rw-r--r--src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr12
-rw-r--r--src/test/ui/generic-associated-types/missing_lifetime_args.rs22
-rw-r--r--src/test/ui/generic-associated-types/missing_lifetime_args.stderr55
-rw-r--r--src/test/ui/generic-associated-types/missing_lifetime_const.rs12
-rw-r--r--src/test/ui/generic-associated-types/missing_lifetime_const.stderr19
-rw-r--r--src/test/ui/generic-associated-types/parameter_number_and_kind.rs19
-rw-r--r--src/test/ui/generic-associated-types/parameter_number_and_kind.stderr47
-rw-r--r--src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs34
-rw-r--r--src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr62
-rw-r--r--src/test/ui/generic-associated-types/parse/in-trait-impl.rs10
-rw-r--r--src/test/ui/generic-associated-types/parse/in-trait.rs24
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-expected-token.rs10
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-expected-token.stderr10
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-expressions.rs22
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-expressions.stderr23
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs20
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr43
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-segments.rs34
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-segments.stderr41
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs13
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr33
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-types.rs22
-rw-r--r--src/test/ui/generic-associated-types/parse/trait-path-types.stderr41
-rw-r--r--src/test/ui/generic-associated-types/pointer_family.rs36
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs61
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr15
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle.rs63
-rw-r--r--src/test/ui/generic-associated-types/projection-bound-cycle.stderr15
-rw-r--r--src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs35
-rw-r--r--src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr26
-rw-r--r--src/test/ui/generic-associated-types/self-outlives-lint.rs213
-rw-r--r--src/test/ui/generic-associated-types/self-outlives-lint.stderr167
-rw-r--r--src/test/ui/generic-associated-types/shadowing.rs31
-rw-r--r--src/test/ui/generic-associated-types/shadowing.stderr36
-rw-r--r--src/test/ui/generic-associated-types/streaming_iterator.rs76
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.base.stderr18
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.extended.stderr17
-rw-r--r--src/test/ui/generic-associated-types/trait-objects.rs20
-rw-r--r--src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs27
-rw-r--r--src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr50
-rw-r--r--src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs21
-rw-r--r--src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr27
-rw-r--r--src/test/ui/generic-associated-types/variance_constraints.rs23
237 files changed, 6619 insertions, 0 deletions
diff --git a/src/test/ui/generic-associated-types/anonymize-bound-vars.rs b/src/test/ui/generic-associated-types/anonymize-bound-vars.rs
new file mode 100644
index 000000000..1ec9c6998
--- /dev/null
+++ b/src/test/ui/generic-associated-types/anonymize-bound-vars.rs
@@ -0,0 +1,14 @@
+// check-pass
+//
+// regression test for #98702
+#![feature(generic_associated_types)]
+
+trait Foo {
+ type Assoc<T>;
+}
+
+impl Foo for () {
+ type Assoc<T> = [T; 2*2];
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/auxiliary/foo_defn.rs b/src/test/ui/generic-associated-types/auxiliary/foo_defn.rs
new file mode 100644
index 000000000..0e8e14852
--- /dev/null
+++ b/src/test/ui/generic-associated-types/auxiliary/foo_defn.rs
@@ -0,0 +1,8 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/bugs/issue-80626.rs b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
new file mode 100644
index 000000000..14f27aff1
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.rs
@@ -0,0 +1,17 @@
+// check-fail
+// known-bug: #80626
+
+// This should pass, but it requires `Sized` to be coinductive.
+
+#![feature(generic_associated_types)]
+
+trait Allocator {
+ type Allocated<T>;
+}
+
+enum LinkedList<A: Allocator> {
+ Head,
+ Next(A::Allocated<Self>)
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
new file mode 100644
index 000000000..487b83dfa
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr
@@ -0,0 +1,15 @@
+error[E0275]: overflow evaluating the requirement `LinkedList<A>: Sized`
+ --> $DIR/issue-80626.rs:14:10
+ |
+LL | Next(A::Allocated<Self>)
+ | ^^^^^^^^^^^^^^^^^^
+ |
+note: required by a bound in `Allocator::Allocated`
+ --> $DIR/issue-80626.rs:9:20
+ |
+LL | type Allocated<T>;
+ | ^ required by this bound in `Allocator::Allocated`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.rs b/src/test/ui/generic-associated-types/bugs/issue-86218.rs
new file mode 100644
index 000000000..fb62c10a9
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-86218.rs
@@ -0,0 +1,27 @@
+// check-fail
+// known-bug: #86218
+
+// This should pass, but seems to run into a TAIT issue.
+
+#![feature(generic_associated_types)]
+#![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;
+ fn foo<'s>() -> Self::InnerStream<'s> { todo!() }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-86218.stderr b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr
new file mode 100644
index 000000000..fbf1c8f95
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-86218.stderr
@@ -0,0 +1,23 @@
+error[E0477]: the type `<() as Yay<&'a ()>>::InnerStream<'s>` does not fulfill the required lifetime
+ --> $DIR/issue-86218.rs:23:28
+ |
+LL | type InnerStream<'s> = impl Stream<Item = i32> + 's;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: type must outlive the lifetime `'s` as defined here as required by this binding
+ --> $DIR/issue-86218.rs:23:22
+ |
+LL | type InnerStream<'s> = impl Stream<Item = i32> + 's;
+ | ^^
+
+error: unconstrained opaque type
+ --> $DIR/issue-86218.rs:23:28
+ |
+LL | type InnerStream<'s> = impl Stream<Item = i32> + 's;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `InnerStream` must be used in combination with a concrete type within the same module
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87735.rs b/src/test/ui/generic-associated-types/bugs/issue-87735.rs
new file mode 100644
index 000000000..0844d84c3
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-87735.rs
@@ -0,0 +1,46 @@
+// check-fail
+// known-bug: #87735, #88526
+
+// This should pass, but we need an extension of implied bounds (probably).
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/bugs/issue-87735.stderr b/src/test/ui/generic-associated-types/bugs/issue-87735.stderr
new file mode 100644
index 000000000..0a18b5f0c
--- /dev/null
+++ b/src/test/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:27: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/src/test/ui/generic-associated-types/bugs/issue-87748.rs b/src/test/ui/generic-associated-types/bugs/issue-87748.rs
new file mode 100644
index 000000000..a3d00ee03
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-87748.rs
@@ -0,0 +1,23 @@
+// check-fail
+// known-bug: #87748
+
+// This should pass, but unnormalized input args aren't treated as implied.
+
+#![feature(generic_associated_types)]
+
+trait MyTrait {
+ type Assoc<'a, 'b> where 'b: 'a;
+ fn do_sth(arg: Self::Assoc<'_, '_>);
+}
+
+struct Foo;
+
+impl MyTrait for Foo {
+ type Assoc<'a, 'b> = u32 where 'b: 'a;
+
+ fn do_sth(_: u32) {}
+ // fn do_sth(_: Self::Assoc<'static, 'static>) {}
+ // fn do_sth(_: Self::Assoc<'_, '_>) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87748.stderr b/src/test/ui/generic-associated-types/bugs/issue-87748.stderr
new file mode 100644
index 000000000..ac197dfe6
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-87748.stderr
@@ -0,0 +1,20 @@
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/issue-87748.rs:18:5
+ |
+LL | fn do_sth(_: u32) {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+note: lifetime parameter instantiated with the anonymous lifetime as defined here
+ --> $DIR/issue-87748.rs:18:5
+ |
+LL | fn do_sth(_: u32) {}
+ | ^^^^^^^^^^^^^^^^^
+note: but lifetime parameter must outlive the anonymous lifetime as defined here
+ --> $DIR/issue-87748.rs:18:5
+ |
+LL | fn do_sth(_: u32) {}
+ | ^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0478`.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87755.rs b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
new file mode 100644
index 000000000..efa487d62
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-87755.rs
@@ -0,0 +1,21 @@
+// check-fail
+// known-bug: #87755
+
+// This should pass.
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/bugs/issue-87755.stderr b/src/test/ui/generic-associated-types/bugs/issue-87755.stderr
new file mode 100644
index 000000000..5d1aff011
--- /dev/null
+++ b/src/test/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:18:16
+ |
+LL | type Ass = Bar;
+ | ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/bugs/issue-87803.rs b/src/test/ui/generic-associated-types/bugs/issue-87803.rs
new file mode 100644
index 000000000..a8a111c99
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-87803.rs
@@ -0,0 +1,27 @@
+// check-fail
+// known-bug: #87803
+
+// This should pass, but using a type alias vs a reference directly
+// changes late-bound -> early-bound.
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/bugs/issue-87803.stderr b/src/test/ui/generic-associated-types/bugs/issue-87803.stderr
new file mode 100644
index 000000000..c81c051d3
--- /dev/null
+++ b/src/test/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:22: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/src/test/ui/generic-associated-types/bugs/issue-88382.rs b/src/test/ui/generic-associated-types/bugs/issue-88382.rs
new file mode 100644
index 000000000..5493b9b93
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-88382.rs
@@ -0,0 +1,31 @@
+// check-fail
+// known-bug: #88382
+
+// This should pass, but has a missed normalization due to HRTB.
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/bugs/issue-88382.stderr b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
new file mode 100644
index 000000000..7210895b7
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
@@ -0,0 +1,22 @@
+error[E0631]: type mismatch in function arguments
+ --> $DIR/issue-88382.rs:28: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<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
+ found function signature `for<'a, 'r> fn(&'r mut <_ as Iterable>::Iterator<'a>) -> _`
+note: required by a bound in `do_something`
+ --> $DIR/issue-88382.rs:22: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/src/test/ui/generic-associated-types/bugs/issue-88460.rs b/src/test/ui/generic-associated-types/bugs/issue-88460.rs
new file mode 100644
index 000000000..f1c3b2269
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-88460.rs
@@ -0,0 +1,31 @@
+// check-fail
+// known-bug: #88460
+
+// This should pass, but has a missed normalization due to HRTB.
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/bugs/issue-88460.stderr b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr
new file mode 100644
index 000000000..98c304cc9
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-88460.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
+ --> $DIR/issue-88460.rs:30:5
+ |
+LL | test(Foo);
+ | ^^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
+ |
+ = help: the trait `Marker` is implemented for `()`
+note: required by a bound in `test`
+ --> $DIR/issue-88460.rs:17: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/src/test/ui/generic-associated-types/bugs/issue-88526.rs b/src/test/ui/generic-associated-types/bugs/issue-88526.rs
new file mode 100644
index 000000000..15363ad04
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-88526.rs
@@ -0,0 +1,35 @@
+// check-fail
+// known-bug: #88526
+
+// This should pass, but requires more logic.
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/bugs/issue-88526.stderr b/src/test/ui/generic-associated-types/bugs/issue-88526.stderr
new file mode 100644
index 000000000..127c889bf
--- /dev/null
+++ b/src/test/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:27: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/src/test/ui/generic-associated-types/bugs/issue-89008.rs b/src/test/ui/generic-associated-types/bugs/issue-89008.rs
new file mode 100644
index 000000000..79c28b0d2
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-89008.rs
@@ -0,0 +1,44 @@
+// check-fail
+// edition:2021
+// known-bug: #88908
+
+// This should pass, but seems to run into a TAIT bug.
+
+#![feature(type_alias_impl_trait)]
+#![feature(generic_associated_types)]
+
+use std::future::Future;
+
+trait Stream {
+ type Item;
+}
+
+struct Empty<T>(T);
+impl<T> Stream for Empty<T> {
+ type Item = ();
+}
+fn empty<T>() -> Empty<T> {
+ todo!()
+}
+
+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()}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/bugs/issue-89008.stderr b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
new file mode 100644
index 000000000..50844fdc1
--- /dev/null
+++ b/src/test/ui/generic-associated-types/bugs/issue-89008.stderr
@@ -0,0 +1,19 @@
+error[E0271]: type mismatch resolving `<Empty<_> as Stream>::Item == Repr`
+ --> $DIR/issue-89008.rs:39:43
+ |
+LL | fn line_stream<'a, Repr>(&'a self) -> Self::LineStreamFut<'a, Repr> {
+ | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Empty<_> as Stream>::Item == Repr`
+ | |
+ | this type parameter
+ |
+note: expected this to be `()`
+ --> $DIR/issue-89008.rs:18:17
+ |
+LL | type Item = ();
+ | ^^
+ = note: expected unit type `()`
+ found type parameter `Repr`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/generic-associated-types/collections-project-default.rs b/src/test/ui/generic-associated-types/collections-project-default.rs
new file mode 100644
index 000000000..157e1b1d2
--- /dev/null
+++ b/src/test/ui/generic-associated-types/collections-project-default.rs
@@ -0,0 +1,71 @@
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/collections-project-default.stderr b/src/test/ui/generic-associated-types/collections-project-default.stderr
new file mode 100644
index 000000000..22fbc0271
--- /dev/null
+++ b/src/test/ui/generic-associated-types/collections-project-default.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+ --> $DIR/collections-project-default.rs:59: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/src/test/ui/generic-associated-types/collections.rs b/src/test/ui/generic-associated-types/collections.rs
new file mode 100644
index 000000000..1c00aa73f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/collections.rs
@@ -0,0 +1,70 @@
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/collectivity-regression.rs b/src/test/ui/generic-associated-types/collectivity-regression.rs
new file mode 100644
index 000000000..fb7368439
--- /dev/null
+++ b/src/test/ui/generic-associated-types/collectivity-regression.rs
@@ -0,0 +1,24 @@
+// Regression test from https://github.com/rust-lang/rust/pull/98109
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/collectivity-regression.stderr b/src/test/ui/generic-associated-types/collectivity-regression.stderr
new file mode 100644
index 000000000..a858dd7fd
--- /dev/null
+++ b/src/test/ui/generic-associated-types/collectivity-regression.stderr
@@ -0,0 +1,14 @@
+error: `T` does not live long enough
+ --> $DIR/collectivity-regression.rs:15:5
+ |
+LL | / || {
+LL | |
+LL | | //
+LL | | // FIXME(#98437). This regressed at some point and
+LL | | // probably should work.
+LL | | let _x = x;
+LL | | };
+ | |_____^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs
new file mode 100644
index 000000000..afde5f376
--- /dev/null
+++ b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-1.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![feature(generic_associated_types)]
+
+// 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/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs
new file mode 100644
index 000000000..51046be79
--- /dev/null
+++ b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-2.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![feature(generic_associated_types)]
+
+// 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/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs
new file mode 100644
index 000000000..457fe27b3
--- /dev/null
+++ b/src/test/ui/generic-associated-types/const-generics-gat-in-trait-return-type-3.rs
@@ -0,0 +1,26 @@
+// run-pass
+#![feature(generic_associated_types)]
+
+// 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/src/test/ui/generic-associated-types/const_params_have_right_type.rs b/src/test/ui/generic-associated-types/const_params_have_right_type.rs
new file mode 100644
index 000000000..6bed8e3af
--- /dev/null
+++ b/src/test/ui/generic-associated-types/const_params_have_right_type.rs
@@ -0,0 +1,12 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/const_params_have_right_type.stderr b/src/test/ui/generic-associated-types/const_params_have_right_type.stderr
new file mode 100644
index 000000000..89c993dee
--- /dev/null
+++ b/src/test/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:8: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/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs
new file mode 100644
index 000000000..e315ee842
--- /dev/null
+++ b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs
@@ -0,0 +1,16 @@
+// Test that correct syntax is used in suggestion to constrain associated type
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr
new file mode 100644
index 000000000..957ae5d29
--- /dev/null
+++ b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+ --> $DIR/constraint-assoc-type-suggestion.rs:12: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/src/test/ui/generic-associated-types/construct_with_other_type.rs b/src/test/ui/generic-associated-types/construct_with_other_type.rs
new file mode 100644
index 000000000..060804269
--- /dev/null
+++ b/src/test/ui/generic-associated-types/construct_with_other_type.rs
@@ -0,0 +1,24 @@
+#![feature(generic_associated_types)]
+
+// 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/src/test/ui/generic-associated-types/cross-crate-bounds.rs b/src/test/ui/generic-associated-types/cross-crate-bounds.rs
new file mode 100644
index 000000000..8934a07fd
--- /dev/null
+++ b/src/test/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/src/test/ui/generic-associated-types/cross-crate-bounds.stderr b/src/test/ui/generic-associated-types/cross-crate-bounds.stderr
new file mode 100644
index 000000000..c4009dd96
--- /dev/null
+++ b/src/test/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:6:15
+ |
+LL | type Bar: AsRef<()>;
+ | ^^^^^^^^^ required by this bound in `foo_defn::Foo::Bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/generic-associated-types/elided-in-expr-position.rs b/src/test/ui/generic-associated-types/elided-in-expr-position.rs
new file mode 100644
index 000000000..482d0d5c0
--- /dev/null
+++ b/src/test/ui/generic-associated-types/elided-in-expr-position.rs
@@ -0,0 +1,38 @@
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/elided-in-expr-position.stderr b/src/test/ui/generic-associated-types/elided-in-expr-position.stderr
new file mode 100644
index 000000000..b395a1cfd
--- /dev/null
+++ b/src/test/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:10: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:5:10
+ |
+LL | type Assoc<'a> where Self: 'a;
+ | ^^^^^ --
+help: add missing lifetime argument
+ |
+LL | fn g(&self) -> Self::Assoc<'a>;
+ | ~~~~~~~~~
+
+error[E0107]: missing generics for associated type `Trait::Assoc`
+ --> $DIR/elided-in-expr-position.rs:32: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:5:10
+ |
+LL | type Assoc<'a> where Self: 'a;
+ | ^^^^^ --
+help: add missing lifetime argument
+ |
+LL | fn g(&self) -> Self::Assoc<'a> {
+ | ~~~~~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/generic-associated-types/empty_generics.rs b/src/test/ui/generic-associated-types/empty_generics.rs
new file mode 100644
index 000000000..772b7f2b4
--- /dev/null
+++ b/src/test/ui/generic-associated-types/empty_generics.rs
@@ -0,0 +1,8 @@
+#![feature(generic_associated_types)]
+
+trait Foo {
+ type Bar<,>;
+ //~^ ERROR expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/empty_generics.stderr b/src/test/ui/generic-associated-types/empty_generics.stderr
new file mode 100644
index 000000000..ac22bfc08
--- /dev/null
+++ b/src/test/ui/generic-associated-types/empty_generics.stderr
@@ -0,0 +1,13 @@
+error: expected one of `#`, `>`, `const`, identifier, or lifetime, found `,`
+ --> $DIR/empty_generics.rs:4: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/src/test/ui/generic-associated-types/equality-bound.rs b/src/test/ui/generic-associated-types/equality-bound.rs
new file mode 100644
index 000000000..fcc2da801
--- /dev/null
+++ b/src/test/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/src/test/ui/generic-associated-types/equality-bound.stderr b/src/test/ui/generic-associated-types/equality-bound.stderr
new file mode 100644
index 000000000..d78f7a7fb
--- /dev/null
+++ b/src/test/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/src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr b/src/test/ui/generic-associated-types/extended/lending_iterator.base.stderr
new file mode 100644
index 000000000..3da7794b3
--- /dev/null
+++ b/src/test/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:14: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/src/test/ui/generic-associated-types/extended/lending_iterator.rs b/src/test/ui/generic-associated-types/extended/lending_iterator.rs
new file mode 100644
index 000000000..ede164766
--- /dev/null
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator.rs
@@ -0,0 +1,39 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr b/src/test/ui/generic-associated-types/extended/lending_iterator_2.base.stderr
new file mode 100644
index 000000000..6c2a624ca
--- /dev/null
+++ b/src/test/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:14: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/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs b/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
new file mode 100644
index 000000000..3c4a2184d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/extended/lending_iterator_2.rs
@@ -0,0 +1,31 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs
new file mode 100644
index 000000000..c1d68812e
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs
@@ -0,0 +1,16 @@
+// rust-lang/rust#60654: Do not ICE on an attempt to use GATs that is
+// missing the feature gate.
+
+struct Foo;
+
+trait MyTrait {
+ type Item<T>;
+ //~^ ERROR generic associated types are unstable [E0658]
+}
+
+impl MyTrait for Foo {
+ type Item<T> = T;
+ //~^ ERROR generic associated types are unstable [E0658]
+}
+
+fn main() { }
diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr
new file mode 100644
index 000000000..34f536dbe
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr
@@ -0,0 +1,21 @@
+error[E0658]: generic associated types are unstable
+ --> $DIR/gat-dont-ice-on-absent-feature-2.rs:7:5
+ |
+LL | type Item<T>;
+ | ^^^^^^^^^^^^^
+ |
+ = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
+ = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
+
+error[E0658]: generic associated types are unstable
+ --> $DIR/gat-dont-ice-on-absent-feature-2.rs:12:5
+ |
+LL | type Item<T> = T;
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
+ = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs
new file mode 100644
index 000000000..e8fc47d2a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs
@@ -0,0 +1,16 @@
+// rust-lang/rust#60654: Do not ICE on an attempt to use GATs that is
+// missing the feature gate.
+
+struct Foo;
+
+impl Iterator for Foo {
+ type Item<'b> = &'b Foo;
+ //~^ ERROR generic associated types are unstable [E0658]
+ //~| ERROR lifetime parameters or bounds on type `Item` do not match the trait declaration
+
+ fn next(&mut self) -> Option<Self::Item> {
+ None
+ }
+}
+
+fn main() { }
diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr
new file mode 100644
index 000000000..ec36886f7
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr
@@ -0,0 +1,19 @@
+error[E0658]: generic associated types are unstable
+ --> $DIR/gat-dont-ice-on-absent-feature.rs:7:5
+ |
+LL | type Item<'b> = &'b Foo;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
+ = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
+
+error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration
+ --> $DIR/gat-dont-ice-on-absent-feature.rs:7:14
+ |
+LL | type Item<'b> = &'b Foo;
+ | ^^^^ lifetimes do not match type in trait
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0195, E0658.
+For more information about an error, try `rustc --explain E0195`.
diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs
new file mode 100644
index 000000000..f542a7f54
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.rs
@@ -0,0 +1,11 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path-undeclared-lifetime.stderr
new file mode 100644
index 000000000..1792d8db2
--- /dev/null
+++ b/src/test/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:8: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:8: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/src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path.base.stderr
new file mode 100644
index 000000000..c2054f64e
--- /dev/null
+++ b/src/test/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:27: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:11: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/src/test/ui/generic-associated-types/gat-in-trait-path.rs b/src/test/ui/generic-associated-types/gat-in-trait-path.rs
new file mode 100644
index 000000000..c82450ccf
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-in-trait-path.rs
@@ -0,0 +1,34 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/gat-incomplete-warning.rs b/src/test/ui/generic-associated-types/gat-incomplete-warning.rs
new file mode 100644
index 000000000..607ea1759
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-incomplete-warning.rs
@@ -0,0 +1,5 @@
+// run-pass
+
+#![feature(generic_associated_types)]
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs
new file mode 100644
index 000000000..dbf7e02ae
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.rs
@@ -0,0 +1,16 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr b/src/test/ui/generic-associated-types/gat-trait-path-generic-type-arg.stderr
new file mode 100644
index 000000000..dad0dae6a
--- /dev/null
+++ b/src/test/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:11: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:11: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:9: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/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
new file mode 100644
index 000000000..9864787f0
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs
@@ -0,0 +1,17 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/src/test/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr
new file mode 100644
index 000000000..aeb9238de
--- /dev/null
+++ b/src/test/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:10: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:4: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:10: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:4: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/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
new file mode 100644
index 000000000..c55b0530c
--- /dev/null
+++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs
@@ -0,0 +1,18 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr
new file mode 100644
index 000000000..162214063
--- /dev/null
+++ b/src/test/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:7: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:7: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:14: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:7: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:4:8
+ |
+LL | type Y<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | fn foo<'a>(arg: Box<dyn X<Y('a, 'a) = &'a ()>>) {}
+ | +++
+
+error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
+ --> $DIR/gat-trait-path-parenthesised-args.rs:7: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:4: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:14: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:4:8
+ |
+LL | type Y<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | fn bar<'a>(arg: Box<dyn X<Y('a) = ()>>) {}
+ | ++
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs b/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs
new file mode 100644
index 000000000..d7c4dbda2
--- /dev/null
+++ b/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/generic-associated-types-where.rs b/src/test/ui/generic-associated-types/generic-associated-types-where.rs
new file mode 100644
index 000000000..2ecbc8c59
--- /dev/null
+++ b/src/test/ui/generic-associated-types/generic-associated-types-where.rs
@@ -0,0 +1,28 @@
+#![feature(generic_associated_types)]
+
+// 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/src/test/ui/generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/generic-associated-types/generic-associated-types-where.stderr
new file mode 100644
index 000000000..e866b3bab
--- /dev/null
+++ b/src/test/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:20: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:22: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/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
new file mode 100644
index 000000000..43058f7eb
--- /dev/null
+++ b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
@@ -0,0 +1,15 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
new file mode 100644
index 000000000..a4bb36190
--- /dev/null
+++ b/src/test/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:8: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:11: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/src/test/ui/generic-associated-types/impl_bounds.rs b/src/test/ui/generic-associated-types/impl_bounds.rs
new file mode 100644
index 000000000..ec1d171c0
--- /dev/null
+++ b/src/test/ui/generic-associated-types/impl_bounds.rs
@@ -0,0 +1,26 @@
+#![feature(generic_associated_types)]
+#![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
+ //~| ERROR lifetime bound not satisfied
+ 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/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr
new file mode 100644
index 000000000..ce79c635a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/impl_bounds.stderr
@@ -0,0 +1,92 @@
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/impl_bounds.rs:15: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:17: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`
+
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/impl_bounds.rs:17:22
+ |
+LL | type B<'a, 'b> where 'a: 'b;
+ | -------------- definition of `B` from trait
+...
+LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
+ | ^^^^^^^^^^^^^^^ - help: try copying this clause from the trait: `, 'a: 'b`
+ |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+ --> $DIR/impl_bounds.rs:17:12
+ |
+LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
+ | ^^
+note: but lifetime parameter must outlive the lifetime `'b` as defined here
+ --> $DIR/impl_bounds.rs:17:16
+ |
+LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
+ | ^^
+
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/impl_bounds.rs:20:33
+ |
+LL | type C = String where Self: Copy;
+ | ^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+ --> $DIR/impl_bounds.rs:11:10
+ |
+LL | #[derive(Copy, Clone)]
+ | ^^^^
+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:7: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:22:24
+ |
+LL | fn d() where Self: Copy {}
+ | ^^^^ the trait `Copy` is not implemented for `T`
+ |
+note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+ --> $DIR/impl_bounds.rs:11:10
+ |
+LL | #[derive(Copy, Clone)]
+ | ^^^^
+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:8: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 5 previous errors
+
+Some errors have detailed explanations: E0276, E0277, E0478.
+For more information about an error, try `rustc --explain E0276`.
diff --git a/src/test/ui/generic-associated-types/impl_bounds_ok.rs b/src/test/ui/generic-associated-types/impl_bounds_ok.rs
new file mode 100644
index 000000000..4df8235d9
--- /dev/null
+++ b/src/test/ui/generic-associated-types/impl_bounds_ok.rs
@@ -0,0 +1,30 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-47206-where-clause.rs b/src/test/ui/generic-associated-types/issue-47206-where-clause.rs
new file mode 100644
index 000000000..d352c1948
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-47206-where-clause.rs
@@ -0,0 +1,16 @@
+// Check that this program doesn't cause the compiler to error without output.
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-47206-where-clause.stderr b/src/test/ui/generic-associated-types/issue-47206-where-clause.stderr
new file mode 100644
index 000000000..31948a878
--- /dev/null
+++ b/src/test/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:12: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/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs b/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs
new file mode 100644
index 000000000..e87a76825
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+trait Cert {
+ type PublicKey<'a>: From<&'a [u8]>;
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs
new file mode 100644
index 000000000..d74d6d056
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs
@@ -0,0 +1,13 @@
+#![feature(generic_associated_types)]
+
+// check-pass
+
+trait Iterator {
+ type Item<'a>: 'a;
+}
+
+impl Iterator for () {
+ type Item<'a> = &'a ();
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-67424.rs b/src/test/ui/generic-associated-types/issue-67424.rs
new file mode 100644
index 000000000..fa35a3e8b
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-67424.rs
@@ -0,0 +1,12 @@
+// Fixed by #67160
+
+trait Trait1 {
+ type A;
+}
+
+trait Trait2 {
+ type Type1<B>: Trait1<A=B>;
+ //~^ ERROR: generic associated types are unstable
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-67424.stderr b/src/test/ui/generic-associated-types/issue-67424.stderr
new file mode 100644
index 000000000..bbb7d56f5
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-67424.stderr
@@ -0,0 +1,12 @@
+error[E0658]: generic associated types are unstable
+ --> $DIR/issue-67424.rs:8:5
+ |
+LL | type Type1<B>: Trait1<A=B>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
+ = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.base.stderr b/src/test/ui/generic-associated-types/issue-67510-pass.base.stderr
new file mode 100644
index 000000000..74a616aaa
--- /dev/null
+++ b/src/test/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:13: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:10: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/src/test/ui/generic-associated-types/issue-67510-pass.rs b/src/test/ui/generic-associated-types/issue-67510-pass.rs
new file mode 100644
index 000000000..c5b02ff9a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-67510-pass.rs
@@ -0,0 +1,16 @@
+// revisions: base extended
+//[base] check-fail
+//[extended] check-pass
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-67510.rs b/src/test/ui/generic-associated-types/issue-67510.rs
new file mode 100644
index 000000000..5725b660a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-67510.rs
@@ -0,0 +1,12 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-67510.stderr b/src/test/ui/generic-associated-types/issue-67510.stderr
new file mode 100644
index 000000000..8aeda22ba
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-67510.stderr
@@ -0,0 +1,50 @@
+error[E0261]: use of undeclared lifetime name `'a`
+ --> $DIR/issue-67510.rs:7: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:7: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:7: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:4: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/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.rs b/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.rs
new file mode 100644
index 000000000..617d985dc
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.rs
@@ -0,0 +1,31 @@
+// Regression test for #68641
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr b/src/test/ui/generic-associated-types/issue-68641-check-gat-bounds.stderr
new file mode 100644
index 000000000..2e21b38cb
--- /dev/null
+++ b/src/test/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:14: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:6: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/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs b/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs
new file mode 100644
index 000000000..def0ad18f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs
@@ -0,0 +1,20 @@
+// Regression test for #68642
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr b/src/test/ui/generic-associated-types/issue-68642-broken-llvm-ir.stderr
new file mode 100644
index 000000000..713cc744f
--- /dev/null
+++ b/src/test/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:14: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:6: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/src/test/ui/generic-associated-types/issue-68643-broken-mir.rs b/src/test/ui/generic-associated-types/issue-68643-broken-mir.rs
new file mode 100644
index 000000000..9af065b5d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68643-broken-mir.rs
@@ -0,0 +1,20 @@
+// Regression test for #68643
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr b/src/test/ui/generic-associated-types/issue-68643-broken-mir.stderr
new file mode 100644
index 000000000..a7b7f64cd
--- /dev/null
+++ b/src/test/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:14: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:6: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/src/test/ui/generic-associated-types/issue-68644-codegen-selection.rs b/src/test/ui/generic-associated-types/issue-68644-codegen-selection.rs
new file mode 100644
index 000000000..1d2636c26
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68644-codegen-selection.rs
@@ -0,0 +1,20 @@
+// Regression test for #68644
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr b/src/test/ui/generic-associated-types/issue-68644-codegen-selection.stderr
new file mode 100644
index 000000000..5e921e053
--- /dev/null
+++ b/src/test/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:14: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:6: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/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs b/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs
new file mode 100644
index 000000000..aa505064f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs
@@ -0,0 +1,20 @@
+// Regression test for #68645
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr b/src/test/ui/generic-associated-types/issue-68645-codegen-fulfillment.stderr
new file mode 100644
index 000000000..7edcdce62
--- /dev/null
+++ b/src/test/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:14: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:6: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/src/test/ui/generic-associated-types/issue-68648-1.rs b/src/test/ui/generic-associated-types/issue-68648-1.rs
new file mode 100644
index 000000000..17bc034b3
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68648-1.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+
+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/src/test/ui/generic-associated-types/issue-68648-2.rs b/src/test/ui/generic-associated-types/issue-68648-2.rs
new file mode 100644
index 000000000..6c9a0d126
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68648-2.rs
@@ -0,0 +1,23 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-68648-2.stderr b/src/test/ui/generic-associated-types/issue-68648-2.stderr
new file mode 100644
index 000000000..06c1efcd8
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68648-2.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-68648-2.rs:14: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:6: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/src/test/ui/generic-associated-types/issue-68649-pass.rs b/src/test/ui/generic-associated-types/issue-68649-pass.rs
new file mode 100644
index 000000000..33f08faff
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68649-pass.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-68653.rs b/src/test/ui/generic-associated-types/issue-68653.rs
new file mode 100644
index 000000000..1e84717e9
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68653.rs
@@ -0,0 +1,15 @@
+// A regression test for #68653, which was fixed by #68938.
+
+// check-pass
+
+#![feature(generic_associated_types)]
+
+trait Fun {
+ type F<'a: 'a>;
+}
+
+impl <T> Fun for T {
+ type F<'a> = Self;
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-68656-unsized-values.rs b/src/test/ui/generic-associated-types/issue-68656-unsized-values.rs
new file mode 100644
index 000000000..c0d933362
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-68656-unsized-values.rs
@@ -0,0 +1,21 @@
+// Regression test for #68656
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-68656-unsized-values.stderr b/src/test/ui/generic-associated-types/issue-68656-unsized-values.stderr
new file mode 100644
index 000000000..8e0f23716
--- /dev/null
+++ b/src/test/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:15: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:6: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/src/test/ui/generic-associated-types/issue-70303.rs b/src/test/ui/generic-associated-types/issue-70303.rs
new file mode 100644
index 000000000..568996e1a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-70303.rs
@@ -0,0 +1,59 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-70304.rs b/src/test/ui/generic-associated-types/issue-70304.rs
new file mode 100644
index 000000000..f778f985c
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-70304.rs
@@ -0,0 +1,57 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-70304.stderr b/src/test/ui/generic-associated-types/issue-70304.stderr
new file mode 100644
index 000000000..bba7cab70
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-70304.stderr
@@ -0,0 +1,33 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/issue-70304.rs:48:41
+ |
+LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
+ | ^^ `'_` is a reserved lifetime name
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/issue-70304.rs:48: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:4: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/src/test/ui/generic-associated-types/issue-71176.rs b/src/test/ui/generic-associated-types/issue-71176.rs
new file mode 100644
index 000000000..c2f0d59f4
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-71176.rs
@@ -0,0 +1,20 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-71176.stderr b/src/test/ui/generic-associated-types/issue-71176.stderr
new file mode 100644
index 000000000..08c8d4162
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-71176.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `Provider::A`
+ --> $DIR/issue-71176.rs:12: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:4: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/src/test/ui/generic-associated-types/issue-74684-1.rs b/src/test/ui/generic-associated-types/issue-74684-1.rs
new file mode 100644
index 000000000..0e3899a88
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74684-1.rs
@@ -0,0 +1,25 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-74684-1.stderr b/src/test/ui/generic-associated-types/issue-74684-1.stderr
new file mode 100644
index 000000000..2cd050ed8
--- /dev/null
+++ b/src/test/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:15: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/src/test/ui/generic-associated-types/issue-74684-2.rs b/src/test/ui/generic-associated-types/issue-74684-2.rs
new file mode 100644
index 000000000..fca55070b
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74684-2.rs
@@ -0,0 +1,25 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-74684-2.stderr b/src/test/ui/generic-associated-types/issue-74684-2.stderr
new file mode 100644
index 000000000..f0e03e73f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74684-2.stderr
@@ -0,0 +1,20 @@
+error[E0271]: type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+ --> $DIR/issue-74684-2.rs:23:5
+ |
+LL | bug(Box::new(x));
+ | ^^^ type mismatch resolving `<{integer} as Fun>::F<'_> == [u8]`
+ |
+note: expected this to be `[u8]`
+ --> $DIR/issue-74684-2.rs:10:18
+ |
+LL | type F<'a> = i32;
+ | ^^^
+note: required by a bound in `bug`
+ --> $DIR/issue-74684-2.rs:13: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/src/test/ui/generic-associated-types/issue-74816.rs b/src/test/ui/generic-associated-types/issue-74816.rs
new file mode 100644
index 000000000..c932025d1
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74816.rs
@@ -0,0 +1,22 @@
+#![feature(associated_type_defaults)]
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-74816.stderr b/src/test/ui/generic-associated-types/issue-74816.stderr
new file mode 100644
index 000000000..9eaa74e34
--- /dev/null
+++ b/src/test/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:9: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:9: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:9: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:9: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/src/test/ui/generic-associated-types/issue-74824.rs b/src/test/ui/generic-associated-types/issue-74824.rs
new file mode 100644
index 000000000..1bbf7aac5
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74824.rs
@@ -0,0 +1,26 @@
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-74824.stderr b/src/test/ui/generic-associated-types/issue-74824.stderr
new file mode 100644
index 000000000..8517eb9fa
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-74824.stderr
@@ -0,0 +1,32 @@
+error[E0277]: the trait bound `Box<T>: Copy` is not satisfied
+ --> $DIR/issue-74824.rs:7: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:7: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:7:26
+ |
+LL | type Copy<T>: Copy = Box<T>;
+ | ^^^^^^ the trait `Clone` is not implemented for `T`
+ |
+ = note: required because of the requirements on the impl of `Clone` for `Box<T>`
+note: required by a bound in `UnsafeCopy::Copy`
+ --> $DIR/issue-74824.rs:7: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/src/test/ui/generic-associated-types/issue-76407.rs b/src/test/ui/generic-associated-types/issue-76407.rs
new file mode 100644
index 000000000..a8141829b
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-76407.rs
@@ -0,0 +1,27 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-76535.base.stderr b/src/test/ui/generic-associated-types/issue-76535.base.stderr
new file mode 100644
index 000000000..5decd58bb
--- /dev/null
+++ b/src/test/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:40: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:10: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:40: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:10: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:40: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:10: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 because of the requirements on the impl of `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` for `Box<SuperStruct>`
+ = 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/src/test/ui/generic-associated-types/issue-76535.extended.stderr b/src/test/ui/generic-associated-types/issue-76535.extended.stderr
new file mode 100644
index 000000000..067d0489b
--- /dev/null
+++ b/src/test/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:40: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:10: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/src/test/ui/generic-associated-types/issue-76535.rs b/src/test/ui/generic-associated-types/issue-76535.rs
new file mode 100644
index 000000000..46f217ba0
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-76535.rs
@@ -0,0 +1,44 @@
+// revisions: base extended
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-76826.rs b/src/test/ui/generic-associated-types/issue-76826.rs
new file mode 100644
index 000000000..28eb3b0e7
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-76826.rs
@@ -0,0 +1,44 @@
+// run-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
new file mode 100644
index 000000000..850d83be6
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
@@ -0,0 +1,40 @@
+// Test for diagnostics when we have mismatched lifetime due to implict 'static lifetime in GATs
+
+// check-fail
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
new file mode 100644
index 000000000..d487f19ba
--- /dev/null
+++ b/src/test/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:17: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:12: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:17: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:9: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:27: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:23: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:27: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:21:1
+ |
+LL | impl C for Box<dyn A + 'static> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incompatible lifetime on type
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:37: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:33: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:37: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:31: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:31: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/src/test/ui/generic-associated-types/issue-78671.base.stderr b/src/test/ui/generic-associated-types/issue-78671.base.stderr
new file mode 100644
index 000000000..6bcd004b1
--- /dev/null
+++ b/src/test/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:11: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:8: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:11: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:8: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/src/test/ui/generic-associated-types/issue-78671.extended.stderr b/src/test/ui/generic-associated-types/issue-78671.extended.stderr
new file mode 100644
index 000000000..f1b489335
--- /dev/null
+++ b/src/test/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:11: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:8: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/src/test/ui/generic-associated-types/issue-78671.rs b/src/test/ui/generic-associated-types/issue-78671.rs
new file mode 100644
index 000000000..c09dac28b
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-78671.rs
@@ -0,0 +1,18 @@
+// revisions: base extended
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-79422.base.stderr b/src/test/ui/generic-associated-types/issue-79422.base.stderr
new file mode 100644
index 000000000..404c975d6
--- /dev/null
+++ b/src/test/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:48: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:24: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:48: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:24: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:45: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:24: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 because of the requirements on the impl of `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>` for `Box<BTreeMap<u8, u8>>`
+ = 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/src/test/ui/generic-associated-types/issue-79422.extended.stderr b/src/test/ui/generic-associated-types/issue-79422.extended.stderr
new file mode 100644
index 000000000..9bcbd7471
--- /dev/null
+++ b/src/test/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:48: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:24: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:45: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:29: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/src/test/ui/generic-associated-types/issue-79422.rs b/src/test/ui/generic-associated-types/issue-79422.rs
new file mode 100644
index 000000000..7749975e6
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-79422.rs
@@ -0,0 +1,51 @@
+// revisions: base extended
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-79636-1.rs b/src/test/ui/generic-associated-types/issue-79636-1.rs
new file mode 100644
index 000000000..6d73fd68d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-79636-1.rs
@@ -0,0 +1,23 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-79636-1.stderr b/src/test/ui/generic-associated-types/issue-79636-1.stderr
new file mode 100644
index 000000000..1ecb86282
--- /dev/null
+++ b/src/test/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:15: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:5: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/src/test/ui/generic-associated-types/issue-79636-2.rs b/src/test/ui/generic-associated-types/issue-79636-2.rs
new file mode 100644
index 000000000..cdaf2e483
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-79636-2.rs
@@ -0,0 +1,17 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-79636-2.stderr b/src/test/ui/generic-associated-types/issue-79636-2.stderr
new file mode 100644
index 000000000..ae61b7b10
--- /dev/null
+++ b/src/test/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:11: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:4: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/src/test/ui/generic-associated-types/issue-80433-reduced.rs b/src/test/ui/generic-associated-types/issue-80433-reduced.rs
new file mode 100644
index 000000000..f15d4d8b1
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-80433-reduced.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-80433.rs b/src/test/ui/generic-associated-types/issue-80433.rs
new file mode 100644
index 000000000..6a1fe7519
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-80433.rs
@@ -0,0 +1,34 @@
+#![feature(generic_associated_types)]
+
+#[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/src/test/ui/generic-associated-types/issue-80433.stderr b/src/test/ui/generic-associated-types/issue-80433.stderr
new file mode 100644
index 000000000..d8c210dcf
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-80433.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `TestMut::Output`
+ --> $DIR/issue-80433.rs:23: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:9: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/src/test/ui/generic-associated-types/issue-81487.rs b/src/test/ui/generic-associated-types/issue-81487.rs
new file mode 100644
index 000000000..7f399c4f9
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-81487.rs
@@ -0,0 +1,19 @@
+// build-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.rs b/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.rs
new file mode 100644
index 000000000..fa2f86242
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.rs
@@ -0,0 +1,20 @@
+// Regression test for #81712.
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr b/src/test/ui/generic-associated-types/issue-81712-cyclic-traits.stderr
new file mode 100644
index 000000000..86c99c32f
--- /dev/null
+++ b/src/test/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:16: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:13: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/src/test/ui/generic-associated-types/issue-81862.rs b/src/test/ui/generic-associated-types/issue-81862.rs
new file mode 100644
index 000000000..e457bca0c
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-81862.rs
@@ -0,0 +1,12 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-81862.stderr b/src/test/ui/generic-associated-types/issue-81862.stderr
new file mode 100644
index 000000000..c664b3ee6
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-81862.stderr
@@ -0,0 +1,19 @@
+error[E0107]: missing generics for associated type `StreamingIterator::Item`
+ --> $DIR/issue-81862.rs:5: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:4:10
+ |
+LL | type Item<'a>;
+ | ^^^^ --
+help: add missing lifetime argument
+ |
+LL | fn next(&mut self) -> Option<Self::Item<'a>>;
+ | ~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/generic-associated-types/issue-84931.rs b/src/test/ui/generic-associated-types/issue-84931.rs
new file mode 100644
index 000000000..9e247de16
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-84931.rs
@@ -0,0 +1,22 @@
+#![feature(generic_associated_types)]
+// 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/src/test/ui/generic-associated-types/issue-84931.stderr b/src/test/ui/generic-associated-types/issue-84931.stderr
new file mode 100644
index 000000000..11c3dffde
--- /dev/null
+++ b/src/test/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:15: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/src/test/ui/generic-associated-types/issue-85921.rs b/src/test/ui/generic-associated-types/issue-85921.rs
new file mode 100644
index 000000000..df59f497d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-85921.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-86483.rs b/src/test/ui/generic-associated-types/issue-86483.rs
new file mode 100644
index 000000000..07dd0bffd
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-86483.rs
@@ -0,0 +1,16 @@
+// Regression test of #86483.
+//
+// Made to pass as part of fixing #98095.
+//
+// check-pass
+
+#![feature(generic_associated_types)]
+
+pub trait IceIce<T>
+where
+ for<'a> T: 'a,
+{
+ type Ice<'v>: IntoIterator<Item = &'v T>;
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-86787.rs b/src/test/ui/generic-associated-types/issue-86787.rs
new file mode 100644
index 000000000..0f8096c8a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-86787.rs
@@ -0,0 +1,38 @@
+#![feature(generic_associated_types)]
+// 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/src/test/ui/generic-associated-types/issue-86787.stderr b/src/test/ui/generic-associated-types/issue-86787.stderr
new file mode 100644
index 000000000..d4b2267d3
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-86787.stderr
@@ -0,0 +1,13 @@
+error: missing required bound on `TRef`
+ --> $DIR/issue-86787.rs:11: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/src/test/ui/generic-associated-types/issue-87258_a.rs b/src/test/ui/generic-associated-types/issue-87258_a.rs
new file mode 100644
index 000000000..c65f3fb2a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87258_a.rs
@@ -0,0 +1,25 @@
+#![feature(type_alias_impl_trait)]
+#![feature(generic_associated_types)]
+
+// 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/src/test/ui/generic-associated-types/issue-87258_a.stderr b/src/test/ui/generic-associated-types/issue-87258_a.stderr
new file mode 100644
index 000000000..db3a5c819
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87258_a.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/issue-87258_a.rs:18:26
+ |
+LL | type FooFuture<'a> = impl Trait1;
+ | ^^^^^^^^^^^
+ |
+ = note: `FooFuture` must be used in combination with a concrete type within the same module
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/generic-associated-types/issue-87258_b.rs b/src/test/ui/generic-associated-types/issue-87258_b.rs
new file mode 100644
index 000000000..f59e0d766
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87258_b.rs
@@ -0,0 +1,27 @@
+#![feature(type_alias_impl_trait)]
+#![feature(generic_associated_types)]
+
+// 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/src/test/ui/generic-associated-types/issue-87258_b.stderr b/src/test/ui/generic-associated-types/issue-87258_b.stderr
new file mode 100644
index 000000000..9faccc961
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87258_b.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/issue-87258_b.rs:17: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/src/test/ui/generic-associated-types/issue-87429-2.rs b/src/test/ui/generic-associated-types/issue-87429-2.rs
new file mode 100644
index 000000000..d35bb098a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87429-2.rs
@@ -0,0 +1,20 @@
+// 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
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-87429-associated-type-default.rs b/src/test/ui/generic-associated-types/issue-87429-associated-type-default.rs
new file mode 100644
index 000000000..9ee07c2f1
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87429-associated-type-default.rs
@@ -0,0 +1,18 @@
+// check-fail
+
+#![feature(associated_type_defaults)]
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr b/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr
new file mode 100644
index 000000000..c6fa02cb9
--- /dev/null
+++ b/src/test/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:14: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:14: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/src/test/ui/generic-associated-types/issue-87429-specialization.rs b/src/test/ui/generic-associated-types/issue-87429-specialization.rs
new file mode 100644
index 000000000..b365e07fe
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87429-specialization.rs
@@ -0,0 +1,25 @@
+// check-fail
+
+#![feature(specialization)]
+//~^ WARN incomplete
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-87429-specialization.stderr b/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
new file mode 100644
index 000000000..015e0c779
--- /dev/null
+++ b/src/test/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: `#[warn(incomplete_features)]` on by default
+ = 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
+
+error[E0277]: can't compare `Foo` with `Foo`
+ --> $DIR/issue-87429-specialization.rs:21: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:8: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/src/test/ui/generic-associated-types/issue-87429.rs b/src/test/ui/generic-associated-types/issue-87429.rs
new file mode 100644
index 000000000..f905348ae
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87429.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-87750.rs b/src/test/ui/generic-associated-types/issue-87750.rs
new file mode 100644
index 000000000..89bd79ac2
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87750.rs
@@ -0,0 +1,22 @@
+#![feature(generic_associated_types)]
+
+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>>;
+ //~^ ERROR overflow evaluating the requirement `Node<i32, RcFamily>: Sized`
+}
diff --git a/src/test/ui/generic-associated-types/issue-87750.stderr b/src/test/ui/generic-associated-types/issue-87750.stderr
new file mode 100644
index 000000000..854541f3d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87750.stderr
@@ -0,0 +1,9 @@
+error[E0275]: overflow evaluating the requirement `Node<i32, RcFamily>: Sized`
+ --> $DIR/issue-87750.rs:20:16
+ |
+LL | let _list: <RcFamily as PointerFamily>::Pointer<Node<i32, RcFamily>>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/issue-88287.rs b/src/test/ui/generic-associated-types/issue-88287.rs
new file mode 100644
index 000000000..4952a0825
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-88287.rs
@@ -0,0 +1,40 @@
+// edition:2018
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-88287.stderr b/src/test/ui/generic-associated-types/issue-88287.stderr
new file mode 100644
index 000000000..5241d85a5
--- /dev/null
+++ b/src/test/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:35: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:25: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/src/test/ui/generic-associated-types/issue-88360.rs b/src/test/ui/generic-associated-types/issue-88360.rs
new file mode 100644
index 000000000..8ee98201a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-88360.rs
@@ -0,0 +1,20 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-88360.stderr b/src/test/ui/generic-associated-types/issue-88360.stderr
new file mode 100644
index 000000000..5f769d799
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-88360.stderr
@@ -0,0 +1,20 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-88360.rs:15: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/src/test/ui/generic-associated-types/issue-88405.rs b/src/test/ui/generic-associated-types/issue-88405.rs
new file mode 100644
index 000000000..4a405bd36
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-88405.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-88459.rs b/src/test/ui/generic-associated-types/issue-88459.rs
new file mode 100644
index 000000000..3b26a1801
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-88459.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-88595.rs b/src/test/ui/generic-associated-types/issue-88595.rs
new file mode 100644
index 000000000..e0796dfec
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-88595.rs
@@ -0,0 +1,22 @@
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-88595.stderr b/src/test/ui/generic-associated-types/issue-88595.stderr
new file mode 100644
index 000000000..79d3479af
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-88595.stderr
@@ -0,0 +1,16 @@
+error: non-defining opaque type use in defining scope
+ --> $DIR/issue-88595.rs:21:35
+ |
+LL | fn a(&'a self) -> Self::B<'a> {}
+ | ^^
+ |
+note: lifetime used multiple times
+ --> $DIR/issue-88595.rs:18:6
+ |
+LL | impl<'a> A<'a> for C {
+ | ^^
+LL | type B<'b> = impl Clone;
+ | ^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/generic-associated-types/issue-89352.rs b/src/test/ui/generic-associated-types/issue-89352.rs
new file mode 100644
index 000000000..d9c656d5f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-89352.rs
@@ -0,0 +1,32 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-90014.rs b/src/test/ui/generic-associated-types/issue-90014.rs
new file mode 100644
index 000000000..f110b0693
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-90014.rs
@@ -0,0 +1,22 @@
+// edition:2018
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-90014.stderr b/src/test/ui/generic-associated-types/issue-90014.stderr
new file mode 100644
index 000000000..457c582e8
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-90014.stderr
@@ -0,0 +1,18 @@
+error[E0477]: the type `&mut ()` does not fulfill the required lifetime
+ --> $DIR/issue-90014.rs:14:20
+ |
+LL | type Fut<'a> where Self: 'a;
+ | ------------ definition of `Fut` from trait
+...
+LL | type Fut<'a> = impl Future<Output = ()>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^- help: try copying this clause from the trait: `where Self: 'a`
+ |
+note: type must outlive the lifetime `'a` as defined here
+ --> $DIR/issue-90014.rs:14:14
+ |
+LL | type Fut<'a> = impl Future<Output = ()>;
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/src/test/ui/generic-associated-types/issue-90729.rs b/src/test/ui/generic-associated-types/issue-90729.rs
new file mode 100644
index 000000000..98295cce8
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-90729.rs
@@ -0,0 +1,38 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-91139.migrate.stderr b/src/test/ui/generic-associated-types/issue-91139.migrate.stderr
new file mode 100644
index 000000000..b424d9a2f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-91139.migrate.stderr
@@ -0,0 +1,13 @@
+error[E0311]: the parameter type `T` may not live long enough
+ --> $DIR/issue-91139.rs:27:12
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn foo<T: 'a>() {
+ | ++++
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/generic-associated-types/issue-91139.rs b/src/test/ui/generic-associated-types/issue-91139.rs
new file mode 100644
index 000000000..40eef11f0
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-91139.rs
@@ -0,0 +1,36 @@
+#![feature(generic_associated_types)]
+
+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
+ //~| ERROR `T` does not live long enough
+ //~| ERROR `T` does not live long enough
+ //~| ERROR `T` does not live long enough
+ //~| ERROR `T` does not live long enough
+ //~| ERROR `T` does not live long enough
+ //~| ERROR `T` does not live long enough
+ //~| ERROR `T` may 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/src/test/ui/generic-associated-types/issue-91139.stderr b/src/test/ui/generic-associated-types/issue-91139.stderr
new file mode 100644
index 000000000..b789b3a42
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-91139.stderr
@@ -0,0 +1,62 @@
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:16:12
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:16:12
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:16:12
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:16:12
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:16:58
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^
+
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:16:58
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^
+
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/issue-91139.rs:16:58
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn foo<T: 'static>() {
+ | +++++++++
+
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:16:58
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^
+
+error: `T` does not live long enough
+ --> $DIR/issue-91139.rs:16:58
+ |
+LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
+ | ^^^^^^^^^
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/generic-associated-types/issue-91762.rs b/src/test/ui/generic-associated-types/issue-91762.rs
new file mode 100644
index 000000000..b259a3c6e
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-91762.rs
@@ -0,0 +1,30 @@
+// check-fail
+
+// FIXME(generic_associated_types): We almost certaintly 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.
+
+#![feature(generic_associated_types)]
+
+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);
+ //~^ type annotations needed
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-91762.stderr b/src/test/ui/generic-associated-types/issue-91762.stderr
new file mode 100644
index 000000000..c2785fee3
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-91762.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/issue-91762.rs:25: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/src/test/ui/generic-associated-types/issue-91883.rs b/src/test/ui/generic-associated-types/issue-91883.rs
new file mode 100644
index 000000000..3d4585a44
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-91883.rs
@@ -0,0 +1,42 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-91883.stderr b/src/test/ui/generic-associated-types/issue-91883.stderr
new file mode 100644
index 000000000..baf4889cc
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-91883.stderr
@@ -0,0 +1,23 @@
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/issue-91883.rs:32:24
+ |
+LL | type Cursor<'tx>: Cursor<'tx>
+ | ----------------------------- definition of `Cursor` from trait
+...
+LL | type Cursor<'tx> = CursorImpl<'tx>;
+ | ^^^^^^^^^^^^^^^- help: try copying these clauses from the trait: `where 'db: 'tx, Self: 'tx`
+ |
+note: lifetime parameter instantiated with the lifetime `'db` as defined here
+ --> $DIR/issue-91883.rs:31: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:32:17
+ |
+LL | type Cursor<'tx> = CursorImpl<'tx>;
+ | ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0478`.
diff --git a/src/test/ui/generic-associated-types/issue-92033.rs b/src/test/ui/generic-associated-types/issue-92033.rs
new file mode 100644
index 000000000..1d5f7d5c0
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92033.rs
@@ -0,0 +1,39 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-92033.stderr b/src/test/ui/generic-associated-types/issue-92033.stderr
new file mode 100644
index 000000000..6dd901027
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92033.stderr
@@ -0,0 +1,18 @@
+error[E0477]: the type `&'s Texture` does not fulfill the required lifetime
+ --> $DIR/issue-92033.rs:22:28
+ |
+LL | type TextureIter<'a>: Iterator<Item = &'a Texture>
+ | -------------------------------------------------- definition of `TextureIter` from trait
+...
+LL | type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try copying this clause from the trait: `where Self: 'a`
+ |
+note: type must outlive the lifetime `'a` as defined here
+ --> $DIR/issue-92033.rs:22:22
+ |
+LL | type TextureIter<'a> = std::option::IntoIter<&'a Texture>;
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr
new file mode 100644
index 000000000..c74161cd3
--- /dev/null
+++ b/src/test/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:20: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:20: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/src/test/ui/generic-associated-types/issue-92096.rs b/src/test/ui/generic-associated-types/issue-92096.rs
new file mode 100644
index 000000000..377b8164a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92096.rs
@@ -0,0 +1,30 @@
+// edition:2018
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-92096.stderr b/src/test/ui/generic-associated-types/issue-92096.stderr
new file mode 100644
index 000000000..ca61a0f43
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92096.stderr
@@ -0,0 +1,8 @@
+error: `C` does not live long enough
+ --> $DIR/issue-92096.rs:19:5
+ |
+LL | async move { c.connect().await }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/generic-associated-types/issue-92280.rs b/src/test/ui/generic-associated-types/issue-92280.rs
new file mode 100644
index 000000000..81d000f10
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92280.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-92954.rs b/src/test/ui/generic-associated-types/issue-92954.rs
new file mode 100644
index 000000000..95c090ff4
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-92954.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+pub trait Foo {
+ type Assoc<'c>;
+ fn function() -> for<'x> fn(Self::Assoc<'x>);
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-93141.rs b/src/test/ui/generic-associated-types/issue-93141.rs
new file mode 100644
index 000000000..39ca77d13
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-93141.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-93262.rs b/src/test/ui/generic-associated-types/issue-93262.rs
new file mode 100644
index 000000000..adc6aa8fa
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-93262.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-93340.rs b/src/test/ui/generic-associated-types/issue-93340.rs
new file mode 100644
index 000000000..d065bde88
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-93340.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-93341.rs b/src/test/ui/generic-associated-types/issue-93341.rs
new file mode 100644
index 000000000..e96a768ec
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-93341.rs
@@ -0,0 +1,55 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+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/src/test/ui/generic-associated-types/issue-93342.rs b/src/test/ui/generic-associated-types/issue-93342.rs
new file mode 100644
index 000000000..d8d7adac9
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-93342.rs
@@ -0,0 +1,57 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-93874.rs b/src/test/ui/generic-associated-types/issue-93874.rs
new file mode 100644
index 000000000..f403d7516
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-93874.rs
@@ -0,0 +1,35 @@
+// check-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/issue-95305.rs b/src/test/ui/generic-associated-types/issue-95305.rs
new file mode 100644
index 000000000..e2f1710fa
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-95305.rs
@@ -0,0 +1,20 @@
+// 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(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/issue-95305.stderr b/src/test/ui/generic-associated-types/issue-95305.stderr
new file mode 100644
index 000000000..d8557525f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-95305.stderr
@@ -0,0 +1,9 @@
+error[E0637]: `'_` cannot be used here
+ --> $DIR/issue-95305.rs:11: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/src/test/ui/generic-associated-types/iterable.rs b/src/test/ui/generic-associated-types/iterable.rs
new file mode 100644
index 000000000..af0049891
--- /dev/null
+++ b/src/test/ui/generic-associated-types/iterable.rs
@@ -0,0 +1,46 @@
+#![feature(generic_associated_types)]
+
+// 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/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs
new file mode 100644
index 000000000..655abd18d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs
@@ -0,0 +1,35 @@
+// Test that the predicate printed in an unresolved method error prints the
+// generics for a generic associated type.
+
+#![feature(generic_associated_types)]
+
+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 unsatisfied trait bound introduced here
+//~| 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/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr
new file mode 100644
index 000000000..d9dc77ac8
--- /dev/null
+++ b/src/test/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:30: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:14: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/src/test/ui/generic-associated-types/missing-bounds.fixed b/src/test/ui/generic-associated-types/missing-bounds.fixed
new file mode 100644
index 000000000..2315810a4
--- /dev/null
+++ b/src/test/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/src/test/ui/generic-associated-types/missing-bounds.rs b/src/test/ui/generic-associated-types/missing-bounds.rs
new file mode 100644
index 000000000..ffafff5e9
--- /dev/null
+++ b/src/test/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/src/test/ui/generic-associated-types/missing-bounds.stderr b/src/test/ui/generic-associated-types/missing-bounds.stderr
new file mode 100644
index 000000000..138c642dd
--- /dev/null
+++ b/src/test/ui/generic-associated-types/missing-bounds.stderr
@@ -0,0 +1,98 @@
+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`
+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/src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs
new file mode 100644
index 000000000..8171dc0ae
--- /dev/null
+++ b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.rs
@@ -0,0 +1,13 @@
+// check-fail
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr
new file mode 100644
index 000000000..edd1f9367
--- /dev/null
+++ b/src/test/ui/generic-associated-types/missing-where-clause-on-trait.stderr
@@ -0,0 +1,12 @@
+error[E0276]: impl has stricter requirements than trait
+ --> $DIR/missing-where-clause-on-trait.rs:9: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`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0276`.
diff --git a/src/test/ui/generic-associated-types/missing_lifetime_args.rs b/src/test/ui/generic-associated-types/missing_lifetime_args.rs
new file mode 100644
index 000000000..cd918157f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/missing_lifetime_args.rs
@@ -0,0 +1,22 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/missing_lifetime_args.stderr b/src/test/ui/generic-associated-types/missing_lifetime_args.stderr
new file mode 100644
index 000000000..7cf3f4b73
--- /dev/null
+++ b/src/test/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:13: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:4:10
+ |
+LL | type Y<'a, 'b>;
+ | ^ -- --
+help: add missing lifetime arguments
+ |
+LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'c, 'd> = (&'c u32, &'d u32)>>) {}
+ | ~~~~~~~~~
+
+error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
+ --> $DIR/missing_lifetime_args.rs:16: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:7: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:19: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:7:8
+ |
+LL | struct Foo<'a, 'b, 'c> {
+ | ^^^ -- -- --
+help: add missing lifetime arguments
+ |
+LL | fn f<'a>(_arg: Foo<'a, 'b, 'c>) {}
+ | ++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/generic-associated-types/missing_lifetime_const.rs b/src/test/ui/generic-associated-types/missing_lifetime_const.rs
new file mode 100644
index 000000000..e3e78dd96
--- /dev/null
+++ b/src/test/ui/generic-associated-types/missing_lifetime_const.rs
@@ -0,0 +1,12 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/missing_lifetime_const.stderr b/src/test/ui/generic-associated-types/missing_lifetime_const.stderr
new file mode 100644
index 000000000..5d50637bd
--- /dev/null
+++ b/src/test/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:8: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:4: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/src/test/ui/generic-associated-types/parameter_number_and_kind.rs b/src/test/ui/generic-associated-types/parameter_number_and_kind.rs
new file mode 100644
index 000000000..0508cc2da
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parameter_number_and_kind.rs
@@ -0,0 +1,19 @@
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr b/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr
new file mode 100644
index 000000000..53d76fd22
--- /dev/null
+++ b/src/test/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:12: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:9: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:12: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:9: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:15: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:9: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/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs
new file mode 100644
index 000000000..6ca0bc6dd
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs
@@ -0,0 +1,34 @@
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr
new file mode 100644
index 000000000..1458bf0c4
--- /dev/null
+++ b/src/test/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:15: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:17: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:19: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:26: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:28: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:30: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/src/test/ui/generic-associated-types/parse/in-trait-impl.rs b/src/test/ui/generic-associated-types/parse/in-trait-impl.rs
new file mode 100644
index 000000000..7f4775ddb
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/in-trait-impl.rs
@@ -0,0 +1,10 @@
+// check-pass
+// compile-flags: -Z parse-only
+
+#![feature(generic_associated_types)]
+
+impl<T> Baz for T where T: Foo {
+ type Quux<'a> = <T as Foo>::Bar<'a, 'static>;
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/parse/in-trait.rs b/src/test/ui/generic-associated-types/parse/in-trait.rs
new file mode 100644
index 000000000..d438795eb
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/in-trait.rs
@@ -0,0 +1,24 @@
+// check-pass
+// compile-flags: -Z parse-only
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/parse/trait-path-expected-token.rs b/src/test/ui/generic-associated-types/parse/trait-path-expected-token.rs
new file mode 100644
index 000000000..be85598b7
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/trait-path-expected-token.rs
@@ -0,0 +1,10 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/parse/trait-path-expected-token.stderr b/src/test/ui/generic-associated-types/parse/trait-path-expected-token.stderr
new file mode 100644
index 000000000..2b265e921
--- /dev/null
+++ b/src/test/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:7: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/src/test/ui/generic-associated-types/parse/trait-path-expressions.rs b/src/test/ui/generic-associated-types/parse/trait-path-expressions.rs
new file mode 100644
index 000000000..d57c2813b
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/trait-path-expressions.rs
@@ -0,0 +1,22 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/parse/trait-path-expressions.stderr b/src/test/ui/generic-associated-types/parse/trait-path-expressions.stderr
new file mode 100644
index 000000000..272afc10b
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/trait-path-expressions.stderr
@@ -0,0 +1,23 @@
+error: expected expression, found `)`
+ --> $DIR/trait-path-expressions.rs:8: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:18: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/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs b/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs
new file mode 100644
index 000000000..791486480
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.rs
@@ -0,0 +1,20 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr b/src/test/ui/generic-associated-types/parse/trait-path-missing-gen_arg.stderr
new file mode 100644
index 000000000..3ace774a0
--- /dev/null
+++ b/src/test/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:8: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:8: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:8: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:16: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:8: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/src/test/ui/generic-associated-types/parse/trait-path-segments.rs b/src/test/ui/generic-associated-types/parse/trait-path-segments.rs
new file mode 100644
index 000000000..e943f075f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/trait-path-segments.rs
@@ -0,0 +1,34 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/parse/trait-path-segments.stderr b/src/test/ui/generic-associated-types/parse/trait-path-segments.stderr
new file mode 100644
index 000000000..7394393c0
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/trait-path-segments.stderr
@@ -0,0 +1,41 @@
+error: expected one of `!`, `(`, `+`, `,`, `::`, `:`, `<`, or `>`, found `=`
+ --> $DIR/trait-path-segments.rs:8: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:19: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:30: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/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
new file mode 100644
index 000000000..4846af96d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs
@@ -0,0 +1,13 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/src/test/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr
new file mode 100644
index 000000000..46ddcb635
--- /dev/null
+++ b/src/test/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:8: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:4:10
+ |
+LL | type Y<'a>;
+ | ^ --
+help: add missing lifetime argument
+ |
+LL | fn f2<'a>(arg : Box<dyn X<Y<'a, 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:8: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:4: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/src/test/ui/generic-associated-types/parse/trait-path-types.rs b/src/test/ui/generic-associated-types/parse/trait-path-types.rs
new file mode 100644
index 000000000..856253cc7
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/trait-path-types.rs
@@ -0,0 +1,22 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/parse/trait-path-types.stderr b/src/test/ui/generic-associated-types/parse/trait-path-types.stderr
new file mode 100644
index 000000000..fe9ed579e
--- /dev/null
+++ b/src/test/ui/generic-associated-types/parse/trait-path-types.stderr
@@ -0,0 +1,41 @@
+error: expected one of `,`, `:`, or `>`, found `=`
+ --> $DIR/trait-path-types.rs:8: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:13: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:18: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/src/test/ui/generic-associated-types/pointer_family.rs b/src/test/ui/generic-associated-types/pointer_family.rs
new file mode 100644
index 000000000..da86e7f27
--- /dev/null
+++ b/src/test/ui/generic-associated-types/pointer_family.rs
@@ -0,0 +1,36 @@
+#![feature(generic_associated_types)]
+
+// 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/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
new file mode 100644
index 000000000..794d677c8
--- /dev/null
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
@@ -0,0 +1,61 @@
+// Like `projection-bound-cycle.rs` but this avoids using
+// `feature(trivial_bounds)`.
+
+#![feature(generic_associated_types)]
+
+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;
+}
+
+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>;
+ //~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: Sized`
+}
+
+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/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
new file mode 100644
index 000000000..2b57c439f
--- /dev/null
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle-generic.stderr
@@ -0,0 +1,15 @@
+error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
+ --> $DIR/projection-bound-cycle-generic.rs:44:18
+ |
+LL | type Assoc = OnlySized<<T as Foo>::Item>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: required by a bound in `OnlySized`
+ --> $DIR/projection-bound-cycle-generic.rs:28:18
+ |
+LL | struct OnlySized<T> where T: Sized { f: T }
+ | ^ required by this bound in `OnlySized`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/projection-bound-cycle.rs b/src/test/ui/generic-associated-types/projection-bound-cycle.rs
new file mode 100644
index 000000000..6564a3608
--- /dev/null
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle.rs
@@ -0,0 +1,63 @@
+// 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(generic_associated_types)]
+#![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;
+}
+
+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>;
+ //~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: Sized`
+}
+
+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/src/test/ui/generic-associated-types/projection-bound-cycle.stderr b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
new file mode 100644
index 000000000..d9d0bf427
--- /dev/null
+++ b/src/test/ui/generic-associated-types/projection-bound-cycle.stderr
@@ -0,0 +1,15 @@
+error[E0275]: overflow evaluating the requirement `<T as Foo>::Item: Sized`
+ --> $DIR/projection-bound-cycle.rs:46:18
+ |
+LL | type Assoc = OnlySized<<T as Foo>::Item>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: required by a bound in `OnlySized`
+ --> $DIR/projection-bound-cycle.rs:30:18
+ |
+LL | struct OnlySized<T> where T: Sized { f: T }
+ | ^ required by this bound in `OnlySized`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
new file mode 100644
index 000000000..a40c0c2c4
--- /dev/null
+++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs
@@ -0,0 +1,35 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr
new file mode 100644
index 000000000..4620aa34e
--- /dev/null
+++ b/src/test/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:17: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:22: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:27: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/src/test/ui/generic-associated-types/self-outlives-lint.rs b/src/test/ui/generic-associated-types/self-outlives-lint.rs
new file mode 100644
index 000000000..300907adb
--- /dev/null
+++ b/src/test/ui/generic-associated-types/self-outlives-lint.rs
@@ -0,0 +1,213 @@
+#![feature(generic_associated_types)]
+
+// 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>);
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/self-outlives-lint.stderr b/src/test/ui/generic-associated-types/self-outlives-lint.stderr
new file mode 100644
index 000000000..fdb1f50a7
--- /dev/null
+++ b/src/test/ui/generic-associated-types/self-outlives-lint.stderr
@@ -0,0 +1,167 @@
+error: missing required bound on `Item`
+ --> $DIR/self-outlives-lint.rs:9: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:25: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:39: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:46: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:61: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:77: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:92: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:114: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:122: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:129: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 `Item`
+ --> $DIR/self-outlives-lint.rs:142: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 `Iterator`
+ --> $DIR/self-outlives-lint.rs:144: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:150: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:159: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:175: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: aborting due to 15 previous errors
+
diff --git a/src/test/ui/generic-associated-types/shadowing.rs b/src/test/ui/generic-associated-types/shadowing.rs
new file mode 100644
index 000000000..2a9763457
--- /dev/null
+++ b/src/test/ui/generic-associated-types/shadowing.rs
@@ -0,0 +1,31 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/shadowing.stderr b/src/test/ui/generic-associated-types/shadowing.stderr
new file mode 100644
index 000000000..be7659209
--- /dev/null
+++ b/src/test/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:4: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:13: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:18: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:27: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/src/test/ui/generic-associated-types/streaming_iterator.rs b/src/test/ui/generic-associated-types/streaming_iterator.rs
new file mode 100644
index 000000000..e71b6805a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/streaming_iterator.rs
@@ -0,0 +1,76 @@
+// run-pass
+
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/trait-objects.base.stderr b/src/test/ui/generic-associated-types/trait-objects.base.stderr
new file mode 100644
index 000000000..1df76a21b
--- /dev/null
+++ b/src/test/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:14: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:8: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/src/test/ui/generic-associated-types/trait-objects.extended.stderr b/src/test/ui/generic-associated-types/trait-objects.extended.stderr
new file mode 100644
index 000000000..52d48d578
--- /dev/null
+++ b/src/test/ui/generic-associated-types/trait-objects.extended.stderr
@@ -0,0 +1,17 @@
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/trait-objects.rs:16: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`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0521`.
diff --git a/src/test/ui/generic-associated-types/trait-objects.rs b/src/test/ui/generic-associated-types/trait-objects.rs
new file mode 100644
index 000000000..c1da1e0a3
--- /dev/null
+++ b/src/test/ui/generic-associated-types/trait-objects.rs
@@ -0,0 +1,20 @@
+// revisions: base extended
+
+#![feature(generic_associated_types)]
+#![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/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
new file mode 100644
index 000000000..8b40dac57
--- /dev/null
+++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs
@@ -0,0 +1,27 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
new file mode 100644
index 000000000..ae52010cc
--- /dev/null
+++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr
@@ -0,0 +1,50 @@
+warning: unnecessary lifetime parameter `'a`
+ --> $DIR/unsatified-item-lifetime-bound.rs:4: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:13: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:12: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:18: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:17: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:23:8
+ |
+LL | f: <() as X>::Y<'a>,
+ | ^^^^^^^^^^^^^^^^
+ |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+ --> $DIR/unsatified-item-lifetime-bound.rs:22: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/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs
new file mode 100644
index 000000000..6466bf98d
--- /dev/null
+++ b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs
@@ -0,0 +1,21 @@
+#![feature(generic_associated_types)]
+
+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/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
new file mode 100644
index 000000000..7ec9386ca
--- /dev/null
+++ b/src/test/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:8: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:8:15
+ |
+LL | type Item<'a> = &'b ();
+ | ^^
+
+error[E0477]: the type `&'a ()` does not fulfill the required lifetime
+ --> $DIR/unsatisfied-outlives-bound.rs:17:21
+ |
+LL | type Item<'a> = &'a ();
+ | ^^^^^^
+ |
+note: type must satisfy the static lifetime as required by this binding
+ --> $DIR/unsatisfied-outlives-bound.rs:13: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/src/test/ui/generic-associated-types/variance_constraints.rs b/src/test/ui/generic-associated-types/variance_constraints.rs
new file mode 100644
index 000000000..7d0f7638a
--- /dev/null
+++ b/src/test/ui/generic-associated-types/variance_constraints.rs
@@ -0,0 +1,23 @@
+// check-pass
+// issue #69184
+#![feature(generic_associated_types)]
+
+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() {}