summaryrefslogtreecommitdiffstats
path: root/src/test/ui/type-alias-impl-trait
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/type-alias-impl-trait
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/type-alias-impl-trait')
-rw-r--r--src/test/ui/type-alias-impl-trait/argument-types.rs26
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs24
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-type-const.rs32
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs26
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs26
-rw-r--r--src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs26
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr26
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs21
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr22
-rw-r--r--src/test/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs21
-rw-r--r--src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs10
-rw-r--r--src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs20
-rw-r--r--src/test/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs2
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/bound_reduction2.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/bounds-are-checked-2.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/bounds-are-checked-2.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/bounds-are-checked.rs24
-rw-r--r--src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/closures_in_branches.rs31
-rw-r--r--src/test/ui/type-alias-impl-trait/closures_in_branches.stderr25
-rw-r--r--src/test/ui/type-alias-impl-trait/coherence.rs17
-rw-r--r--src/test/ui/type-alias-impl-trait/coherence.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/collect_hidden_types.rs22
-rw-r--r--src/test/ui/type-alias-impl-trait/constrain_inputs.rs17
-rw-r--r--src/test/ui/type-alias-impl-trait/cross_crate_ice.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs11
-rw-r--r--src/test/ui/type-alias-impl-trait/cross_inference.rs10
-rw-r--r--src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs8
-rw-r--r--src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr10
-rw-r--r--src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.stderr10
-rw-r--r--src/test/ui/type-alias-impl-trait/cross_inference_rpit.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs6
-rw-r--r--src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr10
-rw-r--r--src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr25
-rw-r--r--src/test/ui/type-alias-impl-trait/defining-use-submodule.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/different_defining_uses.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/different_defining_uses.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs44
-rw-r--r--src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/fallback.rs28
-rw-r--r--src/test/ui/type-alias-impl-trait/fallback.stderr17
-rw-r--r--src/test/ui/type-alias-impl-trait/field-types.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/future.rs22
-rw-r--r--src/test/ui/type-alias-impl-trait/future.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs11
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs28
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr38
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs12
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr25
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs20
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr51
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr39
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs24
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs17
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr27
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr62
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs11
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs29
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr35
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_not_used.rs11
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_not_used.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr32
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_underconstrained.rs12
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr35
-rw-r--r--src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs17
-rw-r--r--src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr12
-rw-r--r--src/test/ui/type-alias-impl-trait/incomplete-inference.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/incomplete-inference.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/inference-cycle.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/inference-cycle.stderr22
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-52843.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-52843.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53092-2.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53092-2.stderr55
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53092.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53092.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53096.rs11
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53096.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs10
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53598.rs27
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53598.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs26
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs24
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs27
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr26
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57700.rs21
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57700.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs31
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57961.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-57961.stderr20
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs39
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-58887.rs22
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-58951-2.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-58951.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60371.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60371.stderr21
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60407.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60407.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60564-working.rs24
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60564.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60564.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60662.rs10
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-60662.stdout14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs38
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-63279.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-63279.stderr48
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-63355.rs46
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs21
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65384.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65384.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-65918.rs51
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs21
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs33
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr31
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-69323.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-70121.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-72793.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74244.rs20
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74244.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74280.rs12
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74280.stderr12
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74761-2.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74761-2.stderr15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74761.rs15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74761.stderr15
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs24
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-77179.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-77179.stderr12
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-78450.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs41
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs73
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-89686.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-89686.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-89952.rs31
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-90400-1.rs30
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-90400-1.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-90400-2.rs38
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-90400-2.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-93411.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-94429.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-94429.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-98604.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-98604.stderr18
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-98608.rs9
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-98608.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs9
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs21
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr15
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr18
-rw-r--r--src/test/ui/type-alias-impl-trait/multiple_definitions.rs30
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr16
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs17
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/nested.rs17
-rw-r--r--src/test/ui/type-alias-impl-trait/nested.stderr12
-rw-r--r--src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs20
-rw-r--r--src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr20
-rw-r--r--src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs24
-rw-r--r--src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr31
-rw-r--r--src/test/ui/type-alias-impl-trait/not_a_defining_use.rs36
-rw-r--r--src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr38
-rw-r--r--src/test/ui/type-alias-impl-trait/not_well_formed.rs17
-rw-r--r--src/test/ui/type-alias-impl-trait/not_well_formed.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/reveal_local.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/reveal_local.stderr28
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential-2.rs10
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential-2.stderr23
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential-3.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential-4.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential-4.stderr63
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential.rs28
-rw-r--r--src/test/ui/type-alias-impl-trait/self-referential.stderr66
-rw-r--r--src/test/ui/type-alias-impl-trait/static-const-types.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs20
-rw-r--r--src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/structural-match.rs21
-rw-r--r--src/test/ui/type-alias-impl-trait/structural-match.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs12
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs11
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs26
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs25
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs12
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs30
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr9
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs12
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr10
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr10
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs79
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs84
-rw-r--r--src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/type_of_a_let.rs22
-rw-r--r--src/test/ui/type-alias-impl-trait/type_of_a_let.stderr23
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_generic.rs28
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs34
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr20
-rw-r--r--src/test/ui/type-alias-impl-trait/unused_generic_param.rs22
-rw-r--r--src/test/ui/type-alias-impl-trait/weird-return-types.rs16
-rw-r--r--src/test/ui/type-alias-impl-trait/wf-check-fn-def.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/wf-check-fn-def.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs23
-rw-r--r--src/test/ui/type-alias-impl-trait/wf_check_closures.rs17
-rw-r--r--src/test/ui/type-alias-impl-trait/wf_check_closures.stderr19
264 files changed, 5366 insertions, 0 deletions
diff --git a/src/test/ui/type-alias-impl-trait/argument-types.rs b/src/test/ui/type-alias-impl-trait/argument-types.rs
new file mode 100644
index 000000000..185207b98
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/argument-types.rs
@@ -0,0 +1,26 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+// check-pass
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+
+fn foo1(mut x: Foo) {
+ x = 22_u32;
+}
+
+fn foo2(mut x: Foo) {
+ // no constraint on x
+}
+
+fn foo3(x: Foo) {
+ println!("{:?}", x);
+}
+
+fn foo_value() -> Foo {
+ 11_u32
+}
+
+fn main() {
+ foo3(foo_value());
+}
diff --git a/src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs b/src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs
new file mode 100644
index 000000000..703e3e869
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs
@@ -0,0 +1,24 @@
+#![feature(type_alias_impl_trait)]
+
+// build-pass
+
+trait T { type Item; }
+
+type Alias<'a> = impl T<Item = &'a ()>;
+
+struct S;
+impl<'a> T for &'a S {
+ type Item = &'a ();
+}
+
+fn filter_positive<'a>() -> Alias<'a> {
+ &S
+}
+
+fn with_positive(fun: impl Fn(Alias<'_>)) {
+ fun(filter_positive());
+}
+
+fn main() {
+ with_positive(|_| ());
+}
diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-const.rs b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs
new file mode 100644
index 000000000..0ade36daf
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/assoc-type-const.rs
@@ -0,0 +1,32 @@
+// Tests that we properly detect defining usages when using
+// const generics in an associated opaque type
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait UnwrapItemsExt<'a, const C: usize> {
+ type Iter;
+ fn unwrap_items(self) -> Self::Iter;
+}
+
+struct MyStruct<const C: usize> {}
+
+trait MyTrait<'a, const C: usize> {
+ type MyItem;
+ const MY_CONST: usize;
+}
+
+impl<'a, const C: usize> MyTrait<'a, C> for MyStruct<C> {
+ type MyItem = u8;
+ const MY_CONST: usize = C;
+}
+
+impl<'a, I, const C: usize> UnwrapItemsExt<'a, C> for I {
+ type Iter = impl MyTrait<'a, C>;
+
+ fn unwrap_items(self) -> Self::Iter {
+ MyStruct::<C> {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs
new file mode 100644
index 000000000..3f34b00ec
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs
@@ -0,0 +1,26 @@
+// Tests that we don't allow unconstrained lifetime parameters in impls when
+// the lifetime is used in an associated opaque type.
+
+#![feature(type_alias_impl_trait)]
+
+trait UnwrapItemsExt {
+ type Iter;
+ fn unwrap_items(self) -> Self::Iter;
+}
+
+struct MyStruct {}
+
+trait MyTrait<'a> {}
+
+impl<'a> MyTrait<'a> for MyStruct {}
+
+impl<'a, I> UnwrapItemsExt for I {
+ //~^ ERROR the lifetime parameter `'a` is not constrained
+ type Iter = impl MyTrait<'a>;
+
+ fn unwrap_items(self) -> Self::Iter {
+ MyStruct {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr
new file mode 100644
index 000000000..e594dc577
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr
@@ -0,0 +1,9 @@
+error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/assoc-type-lifetime-unconstrained.rs:17:6
+ |
+LL | impl<'a, I> UnwrapItemsExt for I {
+ | ^^ unconstrained lifetime parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs
new file mode 100644
index 000000000..39f785d8c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/assoc-type-lifetime.rs
@@ -0,0 +1,26 @@
+// Tests that we still detect defining usages when
+// lifetimes are used in an associated opaque type
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait UnwrapItemsExt<'a> {
+ type Iter;
+ fn unwrap_items(self) -> Self::Iter;
+}
+
+struct MyStruct {}
+
+trait MyTrait<'a> {}
+
+impl<'a> MyTrait<'a> for MyStruct {}
+
+impl<'a, I> UnwrapItemsExt<'a> for I {
+ type Iter = impl MyTrait<'a>;
+
+ fn unwrap_items(self) -> Self::Iter {
+ MyStruct {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs b/src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs
new file mode 100644
index 000000000..42f07d49f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs
@@ -0,0 +1,26 @@
+#![feature(type_alias_impl_trait)]
+// build-pass (FIXME(62277): could be check-pass?)
+
+trait Bar {}
+struct Dummy;
+impl Bar for Dummy {}
+
+trait Foo {
+ type Assoc: Bar;
+ fn foo() -> Self::Assoc;
+ fn bar() -> Self::Assoc;
+}
+
+type Helper = impl Bar;
+
+impl Foo for i32 {
+ type Assoc = Helper;
+ fn foo() -> Helper {
+ Dummy
+ }
+ fn bar() -> Helper {
+ Dummy
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs
new file mode 100644
index 000000000..a1584581e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+mod m {
+ type Foo = impl std::fmt::Debug;
+
+ pub fn foo() -> Foo {
+ 22_u32
+ }
+}
+
+fn is_send<T: Send>(_: T) {}
+
+fn main() {
+ is_send(m::foo());
+}
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs
new file mode 100644
index 000000000..fc89b0e87
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs
@@ -0,0 +1,25 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+mod m {
+ use std::rc::Rc;
+
+ type Foo = impl std::fmt::Debug; //~ NOTE appears within the type
+ //~^ within this `Foo`
+ //~| expansion of desugaring
+
+ pub fn foo() -> Foo {
+ Rc::new(22_u32)
+ }
+}
+
+fn is_send<T: Send>(_: T) {}
+//~^ required by this bound
+//~| required by a bound
+
+fn main() {
+ is_send(m::foo());
+ //~^ ERROR: `Rc<u32>` cannot be sent between threads safely [E0277]
+ //~| NOTE cannot be sent
+ //~| NOTE required by a bound
+}
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
new file mode 100644
index 000000000..d7247302d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
@@ -0,0 +1,26 @@
+error[E0277]: `Rc<u32>` cannot be sent between threads safely
+ --> $DIR/auto-trait-leakage2.rs:21:13
+ |
+LL | type Foo = impl std::fmt::Debug;
+ | -------------------- within this `Foo`
+...
+LL | is_send(m::foo());
+ | ------- ^^^^^^^^ `Rc<u32>` cannot be sent between threads safely
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: within `Foo`, the trait `Send` is not implemented for `Rc<u32>`
+note: required because it appears within the type `Foo`
+ --> $DIR/auto-trait-leakage2.rs:7:16
+ |
+LL | type Foo = impl std::fmt::Debug;
+ | ^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `is_send`
+ --> $DIR/auto-trait-leakage2.rs:16:15
+ |
+LL | fn is_send<T: Send>(_: T) {}
+ | ^^^^ required by this bound in `is_send`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs
new file mode 100644
index 000000000..5fb7a9473
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs
@@ -0,0 +1,21 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// FIXME This should compile, but it currently doesn't
+
+mod m {
+ type Foo = impl std::fmt::Debug;
+ //~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391]
+
+ pub fn foo() -> Foo {
+ 22_u32
+ }
+
+ pub fn bar() {
+ is_send(foo());
+ }
+
+ fn is_send<T: Send>(_: T) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr
new file mode 100644
index 000000000..1e9a45aac
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr
@@ -0,0 +1,22 @@
+error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
+ --> $DIR/auto-trait-leakage3.rs:7:16
+ |
+LL | type Foo = impl std::fmt::Debug;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: ...which requires type-checking `m::bar`...
+ --> $DIR/auto-trait-leakage3.rs:15:9
+ |
+LL | is_send(foo());
+ | ^^^^^^^
+ = note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`...
+ = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in module `m`
+ --> $DIR/auto-trait-leakage3.rs:6:1
+ |
+LL | mod m {
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs b/src/test/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs
new file mode 100644
index 000000000..75d20a6fe
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs
@@ -0,0 +1,21 @@
+#![feature(type_alias_impl_trait)]
+
+// edition:2018
+
+use std::future::Future;
+
+pub trait Service<Request> {
+ type Future: Future<Output = ()>;
+ fn call(&mut self, req: Request) -> Self::Future;
+}
+
+// NOTE: the pub(crate) here is critical
+pub(crate) fn new() -> () {}
+
+pub struct A;
+impl Service<()> for A {
+ type Future = impl Future<Output = ()>;
+ fn call(&mut self, _: ()) -> Self::Future {
+ async { new() }
+ }
+}
diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
new file mode 100644
index 000000000..e7bca2231
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
@@ -0,0 +1,10 @@
+// Crate that exports an opaque `impl Trait` type. Used for testing cross-crate.
+
+#![crate_type = "rlib"]
+#![feature(type_alias_impl_trait)]
+
+pub type Foo = impl std::fmt::Debug;
+
+pub fn foo() -> Foo {
+ 5
+}
diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs
new file mode 100644
index 000000000..119f7df1f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs
@@ -0,0 +1,20 @@
+// Crate that exports an opaque `impl Trait` type. Used for testing cross-crate.
+
+#![crate_type = "rlib"]
+#![feature(type_alias_impl_trait)]
+
+pub trait View {
+ type Tmp: Iterator<Item = u32>;
+
+ fn test(&self) -> Self::Tmp;
+}
+
+pub struct X;
+
+impl View for X {
+ type Tmp = impl Iterator<Item = u32>;
+
+ fn test(&self) -> Self::Tmp {
+ vec![1, 2, 3].into_iter()
+ }
+}
diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs b/src/test/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs
new file mode 100644
index 000000000..52802dd8f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs
@@ -0,0 +1,2 @@
+pub trait ForeignTrait {}
+pub struct ForeignType<T>(pub T);
diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction.rs b/src/test/ui/type-alias-impl-trait/bound_reduction.rs
new file mode 100644
index 000000000..b9b50f0b7
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction.rs
@@ -0,0 +1,19 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![allow(warnings)]
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+}
+
+type Foo<V> = impl std::fmt::Debug;
+
+trait Trait<U> {}
+
+fn foo_desugared<T: Trait<[u32; {
+ #[no_mangle]
+ static FOO: usize = 42;
+ 3
+}]>>(_: T) -> Foo<T> {
+ (42, std::marker::PhantomData::<T>)
+}
diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.rs b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
new file mode 100644
index 000000000..4d2890b5d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+trait TraitWithAssoc {
+ type Assoc;
+}
+
+type Foo<V> = impl Trait<V>;
+
+trait Trait<U> {}
+
+impl<W> Trait<W> for () {}
+
+fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
+ ()
+ //~^ ERROR non-defining opaque type use
+}
diff --git a/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
new file mode 100644
index 000000000..c405b1f6a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/bound_reduction2.stderr
@@ -0,0 +1,14 @@
+error: non-defining opaque type use in defining scope
+ --> $DIR/bound_reduction2.rs:16:5
+ |
+LL | ()
+ | ^^
+ |
+note: used non-generic type `<T as TraitWithAssoc>::Assoc` for generic parameter
+ --> $DIR/bound_reduction2.rs:9:10
+ |
+LL | type Foo<V> = impl Trait<V>;
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.rs b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.rs
new file mode 100644
index 000000000..55b4dc8dc
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.rs
@@ -0,0 +1,19 @@
+// Make sure that we check that impl trait types implement the traits that they
+// claim to.
+
+#![feature(type_alias_impl_trait)]
+
+type X<T> = impl Clone;
+
+fn f<T: Clone>(t: T) -> X<T> {
+ t
+ //~^ ERROR the trait bound `T: Clone` is not satisfied
+}
+
+fn g<T>(o: Option<X<T>>) -> Option<X<T>> {
+ o.clone()
+}
+
+fn main() {
+ g(None::<X<&mut ()>>);
+}
diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.stderr b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.stderr
new file mode 100644
index 000000000..8678e9b33
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked-2.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `T: Clone` is not satisfied
+ --> $DIR/bounds-are-checked-2.rs:9:5
+ |
+LL | t
+ | ^ the trait `Clone` is not implemented for `T`
+ |
+help: consider restricting type parameter `T`
+ |
+LL | type X<T: std::clone::Clone> = impl Clone;
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs b/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs
new file mode 100644
index 000000000..83d22161e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked.rs
@@ -0,0 +1,24 @@
+// Make sure that we check that impl trait types implement the traits that they
+// claim to.
+
+#![feature(type_alias_impl_trait)]
+
+type X<'a> = impl Into<&'static str> + From<&'a str>;
+
+fn f<'a: 'static>(t: &'a str) -> X<'a> {
+ //~^ WARNING unnecessary lifetime parameter
+ t
+ //~^ ERROR non-defining opaque type use
+}
+
+fn extend_lt<'a>(o: &'a str) -> &'static str {
+ X::<'_>::from(o).into()
+}
+
+fn main() {
+ let r = {
+ let s = "abcdef".to_string();
+ extend_lt(&s)
+ };
+ println!("{}", r);
+}
diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr b/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr
new file mode 100644
index 000000000..920eef11d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr
@@ -0,0 +1,19 @@
+warning: unnecessary lifetime parameter `'a`
+ --> $DIR/bounds-are-checked.rs:8:6
+ |
+LL | fn f<'a: 'static>(t: &'a str) -> X<'a> {
+ | ^^
+ |
+ = help: you can use the `'static` lifetime directly, in place of `'a`
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/bounds-are-checked.rs:10:5
+ |
+LL | type X<'a> = impl Into<&'static str> + From<&'a str>;
+ | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
+...
+LL | t
+ | ^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/src/test/ui/type-alias-impl-trait/closures_in_branches.rs b/src/test/ui/type-alias-impl-trait/closures_in_branches.rs
new file mode 100644
index 000000000..7bb490bbe
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closures_in_branches.rs
@@ -0,0 +1,31 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl std::ops::FnOnce(String) -> usize;
+
+fn foo(b: bool) -> Foo {
+ if b {
+ |x| x.len() //~ ERROR type annotations needed
+ } else {
+ panic!()
+ }
+}
+
+
+type Foo1 = impl std::ops::FnOnce(String) -> usize;
+fn foo1(b: bool) -> Foo1 {
+ |x| x.len()
+}
+
+fn bar(b: bool) -> impl std::ops::FnOnce(String) -> usize {
+ if b {
+ |x| x.len() //~ ERROR type annotations needed
+ } else {
+ panic!()
+ }
+}
+
+fn bar1(b: bool) -> impl std::ops::FnOnce(String) -> usize {
+ |x| x.len()
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr
new file mode 100644
index 000000000..48b7946ea
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closures_in_branches.stderr
@@ -0,0 +1,25 @@
+error[E0282]: type annotations needed
+ --> $DIR/closures_in_branches.rs:7:10
+ |
+LL | |x| x.len()
+ | ^ - type must be known at this point
+ |
+help: consider giving this closure parameter an explicit type
+ |
+LL | |x: _| x.len()
+ | +++
+
+error[E0282]: type annotations needed
+ --> $DIR/closures_in_branches.rs:21:10
+ |
+LL | |x| x.len()
+ | ^ - type must be known at this point
+ |
+help: consider giving this closure parameter an explicit type
+ |
+LL | |x: _| x.len()
+ | +++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/type-alias-impl-trait/coherence.rs b/src/test/ui/type-alias-impl-trait/coherence.rs
new file mode 100644
index 000000000..98ac215ad
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/coherence.rs
@@ -0,0 +1,17 @@
+// aux-build:foreign-crate.rs
+#![feature(type_alias_impl_trait)]
+
+extern crate foreign_crate;
+
+trait LocalTrait {}
+impl<T> LocalTrait for foreign_crate::ForeignType<T> {}
+
+type AliasOfForeignType<T> = impl LocalTrait;
+fn use_alias<T>(val: T) -> AliasOfForeignType<T> {
+ foreign_crate::ForeignType(val)
+}
+
+impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
+//~^ ERROR cannot implement trait on type alias impl trait
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/coherence.stderr b/src/test/ui/type-alias-impl-trait/coherence.stderr
new file mode 100644
index 000000000..3ce25d94f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/coherence.stderr
@@ -0,0 +1,14 @@
+error: cannot implement trait on type alias impl trait
+ --> $DIR/coherence.rs:14:41
+ |
+LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+note: type alias impl trait defined here
+ --> $DIR/coherence.rs:9:30
+ |
+LL | type AliasOfForeignType<T> = impl LocalTrait;
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/collect_hidden_types.rs b/src/test/ui/type-alias-impl-trait/collect_hidden_types.rs
new file mode 100644
index 000000000..e78f178e4
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/collect_hidden_types.rs
@@ -0,0 +1,22 @@
+// aux-build:collect_hidden_types.rs
+use collect_hidden_types::Service;
+use std::future::Future;
+use std::pin::Pin;
+use std::task::Context;
+
+// build-pass
+
+// edition:2018
+
+extern crate collect_hidden_types;
+
+fn broken(mut a: collect_hidden_types::A, cx: &mut Context<'_>) {
+ let mut fut = a.call(());
+ let _ = unsafe { Pin::new_unchecked(&mut fut) }.poll(cx);
+}
+
+pub async fn meeb(cx: &mut Context<'_>) {
+ broken(collect_hidden_types::A, cx);
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs.rs b/src/test/ui/type-alias-impl-trait/constrain_inputs.rs
new file mode 100644
index 000000000..c32174288
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/constrain_inputs.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+mod foo {
+ type Ty<'a> = impl Sized;
+ fn defining(s: &str) -> Ty<'_> { s }
+ fn execute(ty: Ty<'_>) -> &str { todo!() }
+}
+
+mod bar {
+ type Ty<'a> = impl FnOnce() -> &'a str;
+ fn defining(s: &str) -> Ty<'_> { move || s }
+ fn execute(ty: Ty<'_>) -> &str { ty() }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs b/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs
new file mode 100644
index 000000000..c30608176
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/cross_crate_ice.rs
@@ -0,0 +1,16 @@
+// aux-build:cross_crate_ice.rs
+// build-pass (FIXME(62277): could be check-pass?)
+
+extern crate cross_crate_ice;
+
+struct Bar(cross_crate_ice::Foo);
+
+impl Bar {
+ fn zero(&self) -> &cross_crate_ice::Foo {
+ &self.0
+ }
+}
+
+fn main() {
+ let _ = cross_crate_ice::foo();
+}
diff --git a/src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs b/src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs
new file mode 100644
index 000000000..3a7e49026
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/cross_crate_ice2.rs
@@ -0,0 +1,11 @@
+// aux-build:cross_crate_ice2.rs
+// build-pass (FIXME(62277): could be check-pass?)
+
+extern crate cross_crate_ice2;
+
+use cross_crate_ice2::View;
+
+fn main() {
+ let v = cross_crate_ice2::X;
+ v.test();
+}
diff --git a/src/test/ui/type-alias-impl-trait/cross_inference.rs b/src/test/ui/type-alias-impl-trait/cross_inference.rs
new file mode 100644
index 000000000..dafaf40a6
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/cross_inference.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+ type T = impl Copy;
+ let foo: T = (1u32, 2u32);
+ let x: (_, _) = foo;
+ println!("{:?}", x);
+}
diff --git a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
new file mode 100644
index 000000000..811832848
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
@@ -0,0 +1,8 @@
+// compile-flags: --edition=2021
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+ type T = impl Copy; //~ ERROR unconstrained opaque type
+ let foo: T = (1u32, 2u32);
+ let (a, b): (u32, u32) = foo;
+}
diff --git a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr
new file mode 100644
index 000000000..03b172e6d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/cross_inference_pattern_bug.rs:5:14
+ |
+LL | type T = impl Copy;
+ | ^^^^^^^^^
+ |
+ = note: `T` 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/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
new file mode 100644
index 000000000..328096d44
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
@@ -0,0 +1,13 @@
+// known-bug: #96572
+// compile-flags: --edition=2021 --crate-type=lib
+// rustc-env:RUST_BACKTRACE=0
+
+// tracked in https://github.com/rust-lang/rust/issues/96572
+
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+ type T = impl Copy; // error: unconstrained opaque type
+ let foo: T = (1u32, 2u32);
+ let (a, b) = foo; // removing this line makes the code compile
+}
diff --git a/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.stderr b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.stderr
new file mode 100644
index 000000000..8aa1f4956
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/cross_inference_pattern_bug_no_type.rs:10:14
+ |
+LL | type T = impl Copy; // error: unconstrained opaque type
+ | ^^^^^^^^^
+ |
+ = note: `T` 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/type-alias-impl-trait/cross_inference_rpit.rs b/src/test/ui/type-alias-impl-trait/cross_inference_rpit.rs
new file mode 100644
index 000000000..f6affbf17
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/cross_inference_rpit.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+fn foo(b: bool) -> impl Copy {
+ if b {
+ return (5,6)
+ }
+ let x: (_, _) = foo(true);
+ println!("{:?}", x);
+ (1u32, 2u32)
+}
+
+fn main() {
+ foo(false);
+}
diff --git a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs
new file mode 100644
index 000000000..6febd0715
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.rs
@@ -0,0 +1,6 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+// declared but never defined
+type Bar = impl std::fmt::Debug; //~ ERROR unconstrained opaque type
diff --git a/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr
new file mode 100644
index 000000000..60bc24320
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/declared_but_never_defined.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/declared_but_never_defined.rs:6:12
+ |
+LL | type Bar = impl std::fmt::Debug;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `Bar` 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/type-alias-impl-trait/declared_but_not_defined_in_scope.rs b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs
new file mode 100644
index 000000000..5bda5f0fc
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs
@@ -0,0 +1,13 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+mod boo {
+ // declared in module but not defined inside of it
+ pub type Boo = impl ::std::fmt::Debug; //~ ERROR unconstrained opaque type
+}
+
+fn bomp() -> boo::Boo {
+ ""
+ //~^ mismatched types
+}
diff --git a/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr
new file mode 100644
index 000000000..fbfa0ccf1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr
@@ -0,0 +1,25 @@
+error: unconstrained opaque type
+ --> $DIR/declared_but_not_defined_in_scope.rs:7:20
+ |
+LL | pub type Boo = impl ::std::fmt::Debug;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `Boo` must be used in combination with a concrete type within the same module
+
+error[E0308]: mismatched types
+ --> $DIR/declared_but_not_defined_in_scope.rs:11:5
+ |
+LL | pub type Boo = impl ::std::fmt::Debug;
+ | ---------------------- the expected opaque type
+...
+LL | fn bomp() -> boo::Boo {
+ | -------- expected `Boo` because of return type
+LL | ""
+ | ^^ expected opaque type, found `&str`
+ |
+ = note: expected opaque type `Boo`
+ found reference `&'static str`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/defining-use-submodule.rs b/src/test/ui/type-alias-impl-trait/defining-use-submodule.rs
new file mode 100644
index 000000000..8b51f5571
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/defining-use-submodule.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// test that the type alias impl trait defining use is in a submodule
+
+fn main() {}
+
+type Foo = impl std::fmt::Display;
+type Bar = impl std::fmt::Display;
+
+mod foo {
+ pub fn foo() -> super::Foo {
+ "foo"
+ }
+
+ pub mod bar {
+ pub fn bar() -> crate::Bar {
+ 1
+ }
+ }
+}
diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses.rs
new file mode 100644
index 000000000..4505c4d95
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/different_defining_uses.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+// two definitions with different types
+type Foo = impl std::fmt::Debug;
+
+fn foo() -> Foo {
+ ""
+}
+
+fn bar() -> Foo {
+ 42i32
+ //~^ ERROR concrete type differs from previous
+}
diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses.stderr b/src/test/ui/type-alias-impl-trait/different_defining_uses.stderr
new file mode 100644
index 000000000..a8b4cd7af
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/different_defining_uses.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/different_defining_uses.rs:13:5
+ |
+LL | 42i32
+ | ^^^^^ expected `&'static str`, got `i32`
+ |
+note: previous use here
+ --> $DIR/different_defining_uses.rs:9:5
+ |
+LL | ""
+ | ^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs
new file mode 100644
index 000000000..7740f774e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+// check-pass
+fn main() {}
+
+// two definitions with different types
+type Foo = impl std::fmt::Debug;
+
+fn foo() -> Foo {
+ ""
+}
+
+fn bar() -> Foo {
+ panic!()
+}
+
+fn boo() -> Foo {
+ loop {}
+}
diff --git a/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs
new file mode 100644
index 000000000..8549687ea
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs
@@ -0,0 +1,44 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+// two definitions with different types
+type Foo = impl std::fmt::Debug;
+
+fn foo() -> Foo {
+ ""
+}
+
+fn bar(arg: bool) -> Foo {
+ if arg {
+ panic!()
+ } else {
+ "bar"
+ }
+}
+
+fn boo(arg: bool) -> Foo {
+ if arg {
+ loop {}
+ } else {
+ "boo"
+ }
+}
+
+fn bar2(arg: bool) -> Foo {
+ if arg {
+ "bar2"
+ } else {
+ panic!()
+ }
+}
+
+fn boo2(arg: bool) -> Foo {
+ if arg {
+ "boo2"
+ } else {
+ loop {}
+ }
+}
diff --git a/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs
new file mode 100644
index 000000000..4f424b8c6
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+type OneLifetime<'a, 'b> = impl std::fmt::Debug;
+
+fn foo<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> {
+ a
+}
+
+fn bar<'a, 'b>(a: &'a u32, b: &'b u32) -> OneLifetime<'a, 'b> {
+ b
+ //~^ ERROR: concrete type differs from previous defining opaque type use
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr
new file mode 100644
index 000000000..0c50a84e8
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/different_lifetimes_defining_uses.rs:11:5
+ |
+LL | b
+ | ^ expected `&'a u32`, got `&'b u32`
+ |
+note: previous use here
+ --> $DIR/different_lifetimes_defining_uses.rs:7:5
+ |
+LL | a
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/fallback.rs b/src/test/ui/type-alias-impl-trait/fallback.rs
new file mode 100644
index 000000000..d8cf7d71f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/fallback.rs
@@ -0,0 +1,28 @@
+// Tests that we correctly handle opaque types being used opaquely,
+// even within their defining scope.
+//
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Copy;
+
+enum Wrapper<T> {
+ First(T),
+ Second
+}
+
+// This method constrains `Foo` to be `bool`
+fn constrained_foo() -> Foo {
+ true
+}
+
+
+// This method does not constrain `Foo`.
+// Per RFC 2071, function bodies may either
+// fully constrain an opaque type, or place no
+// constraints on it.
+fn unconstrained_foo() -> Wrapper<Foo> {
+ Wrapper::Second
+ //~^ ERROR: type annotations needed
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/fallback.stderr b/src/test/ui/type-alias-impl-trait/fallback.stderr
new file mode 100644
index 000000000..e767bfdb0
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/fallback.stderr
@@ -0,0 +1,17 @@
+error[E0283]: type annotations needed
+ --> $DIR/fallback.rs:24:5
+ |
+LL | fn unconstrained_foo() -> Wrapper<Foo> {
+ | ------------ type must be known at this point
+LL | Wrapper::Second
+ | ^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the enum `Wrapper`
+ |
+ = note: cannot satisfy `_: Copy`
+help: consider specifying the generic argument
+ |
+LL | Wrapper::<T>::Second
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/src/test/ui/type-alias-impl-trait/field-types.rs b/src/test/ui/type-alias-impl-trait/field-types.rs
new file mode 100644
index 000000000..d99ed5812
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/field-types.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// check-pass
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+
+struct Bar {
+ foo: Foo,
+}
+
+fn bar() -> Bar {
+ Bar { foo: "foo" }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/future.rs b/src/test/ui/type-alias-impl-trait/future.rs
new file mode 100644
index 000000000..56323216e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/future.rs
@@ -0,0 +1,22 @@
+#![feature(type_alias_impl_trait)]
+
+// edition:2021
+// compile-flags: --crate-type=lib
+
+use std::future::Future;
+
+trait Bar {
+ fn bar(&self);
+}
+
+type FooFuture<B> = impl Future<Output = ()>;
+
+fn foo<B: Bar>(bar: B) -> FooFuture<B> {
+ async move { bar.bar() }
+ //~^ ERROR: the trait bound `B: Bar` is not satisfied
+}
+
+pub fn mainish(ctx: &mut std::task::Context) {
+ let boom: FooFuture<u32> = unsafe { core::mem::zeroed() };
+ Box::pin(boom).as_mut().poll(ctx);
+}
diff --git a/src/test/ui/type-alias-impl-trait/future.stderr b/src/test/ui/type-alias-impl-trait/future.stderr
new file mode 100644
index 000000000..7e76c120a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/future.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `B: Bar` is not satisfied
+ --> $DIR/future.rs:15:5
+ |
+LL | async move { bar.bar() }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B`
+ |
+note: required by a bound in `foo`
+ --> $DIR/future.rs:14:11
+ |
+LL | fn foo<B: Bar>(bar: B) -> FooFuture<B> {
+ | ^^^ required by this bound in `foo`
+help: consider restricting type parameter `B`
+ |
+LL | type FooFuture<B: Bar> = impl Future<Output = ()>;
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs
new file mode 100644
index 000000000..8b683ad28
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.rs
@@ -0,0 +1,14 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+type MyIter<T> = impl Iterator<Item = T>;
+
+fn my_iter<T>(t: T) -> MyIter<T> {
+ std::iter::once(t)
+}
+
+fn my_iter2<T>(t: T) -> MyIter<T> {
+ Some(t).into_iter()
+ //~^ ERROR concrete type differs from previous
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr
new file mode 100644
index 000000000..47ac33462
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_different_defining_uses.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/generic_different_defining_uses.rs:12:5
+ |
+LL | Some(t).into_iter()
+ | ^^^^^^^^^^^^^^^^^^^ expected `std::iter::Once<T>`, got `std::option::IntoIter<T>`
+ |
+note: previous use here
+ --> $DIR/generic_different_defining_uses.rs:8:5
+ |
+LL | std::iter::once(t)
+ | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs
new file mode 100644
index 000000000..c9b9e128f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs
@@ -0,0 +1,11 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+type Two<'a, 'b> = impl std::fmt::Debug;
+
+
+fn one<'a>(t: &'a ()) -> Two<'a, 'a> {
+ t
+ //~^ ERROR non-defining opaque type use
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr
new file mode 100644
index 000000000..222aaea78
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr
@@ -0,0 +1,14 @@
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_duplicate_lifetime_param.rs:9:5
+ |
+LL | t
+ | ^
+ |
+note: lifetime used multiple times
+ --> $DIR/generic_duplicate_lifetime_param.rs:5:10
+ |
+LL | type Two<'a, 'b> = impl std::fmt::Debug;
+ | ^^ ^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
new file mode 100644
index 000000000..093c1c231
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
@@ -0,0 +1,28 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+// test that unused generic parameters are ok
+type TwoTys<T, U> = impl Debug;
+
+type TwoLifetimes<'a, 'b> = impl Debug;
+
+type TwoConsts<const X: usize, const Y: usize> = impl Debug;
+
+
+fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
+ t
+ //~^ ERROR non-defining opaque type use in defining scope
+}
+
+fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
+ t
+ //~^ ERROR non-defining opaque type use in defining scope
+}
+
+fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
+ t
+ //~^ ERROR non-defining opaque type use in defining scope
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
new file mode 100644
index 000000000..b2edcc552
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
@@ -0,0 +1,38 @@
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_duplicate_param_use.rs:16:5
+ |
+LL | t
+ | ^
+ |
+note: type used multiple times
+ --> $DIR/generic_duplicate_param_use.rs:8:13
+ |
+LL | type TwoTys<T, U> = impl Debug;
+ | ^ ^
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_duplicate_param_use.rs:21:5
+ |
+LL | t
+ | ^
+ |
+note: lifetime used multiple times
+ --> $DIR/generic_duplicate_param_use.rs:10:19
+ |
+LL | type TwoLifetimes<'a, 'b> = impl Debug;
+ | ^^ ^^
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_duplicate_param_use.rs:26:5
+ |
+LL | t
+ | ^
+ |
+note: constant used multiple times
+ --> $DIR/generic_duplicate_param_use.rs:12:16
+ |
+LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
+ | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs
new file mode 100644
index 000000000..c17d595db
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs
@@ -0,0 +1,12 @@
+// check-pass
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+type Two<T: Debug, U> = impl Debug;
+
+fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
+ (t, 4u32)
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
new file mode 100644
index 000000000..201535efe
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
@@ -0,0 +1,13 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+// test that unused generic parameters are ok
+type Two<T, U> = impl Debug;
+
+fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+ t
+ //~^ ERROR `T` doesn't implement `Debug`
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
new file mode 100644
index 000000000..3dbfff745
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
@@ -0,0 +1,14 @@
+error[E0277]: `T` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use2.rs:11:5
+ |
+LL | t
+ | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+help: consider restricting type parameter `T`
+ |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+ | +++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
new file mode 100644
index 000000000..e7a25fc72
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+// test that unused generic parameters are ok
+type Two<T, U> = impl Debug;
+
+fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
+ t
+ //~^ ERROR `T` doesn't implement `Debug`
+}
+
+fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
+ u
+ //~^ ERROR `U` doesn't implement `Debug`
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
new file mode 100644
index 000000000..7bec38220
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
@@ -0,0 +1,25 @@
+error[E0277]: `T` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use3.rs:11:5
+ |
+LL | t
+ | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+help: consider restricting type parameter `T`
+ |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `U` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use3.rs:16:5
+ |
+LL | u
+ | ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+help: consider restricting type parameter `U`
+ |
+LL | type Two<T, U: std::fmt::Debug> = impl Debug;
+ | +++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
new file mode 100644
index 000000000..d1e5a0f01
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
@@ -0,0 +1,13 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+// test that unused generic parameters are ok
+type Two<T, U> = impl Debug;
+
+fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
+ u
+ //~^ ERROR `U` doesn't implement `Debug`
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
new file mode 100644
index 000000000..21a5369d9
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
@@ -0,0 +1,14 @@
+error[E0277]: `U` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use4.rs:11:5
+ |
+LL | u
+ | ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+help: consider restricting type parameter `U`
+ |
+LL | type Two<T, U: std::fmt::Debug> = impl Debug;
+ | +++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs
new file mode 100644
index 000000000..3bd1dda63
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs
@@ -0,0 +1,20 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+// test that unused generic parameters are ok
+type Two<T, U> = impl Debug;
+
+fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+ (t, u)
+ //~^ ERROR `T` doesn't implement `Debug`
+ //~| ERROR `U` doesn't implement `Debug`
+}
+
+fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+ (u, t)
+ //~^ ERROR `T` doesn't implement `Debug`
+ //~| ERROR `U` doesn't implement `Debug`
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
new file mode 100644
index 000000000..2768f0c3a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
@@ -0,0 +1,51 @@
+error[E0277]: `T` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use5.rs:11:5
+ |
+LL | (t, u)
+ | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(T, U)`
+help: consider restricting type parameter `T`
+ |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `U` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use5.rs:11:5
+ |
+LL | (t, u)
+ | ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(T, U)`
+help: consider restricting type parameter `U`
+ |
+LL | type Two<T, U: std::fmt::Debug> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `U` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use5.rs:17:5
+ |
+LL | (u, t)
+ | ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+help: consider restricting type parameter `U`
+ |
+LL | type Two<T, U: std::fmt::Debug> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `T` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use5.rs:17:5
+ |
+LL | (u, t)
+ | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+help: consider restricting type parameter `T`
+ |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+ | +++++++++++++++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs
new file mode 100644
index 000000000..5120925e5
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+// test that unused generic parameters are ok
+type Two<T, U> = impl Debug;
+
+fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+ (t, t)
+ //~^ ERROR `T` doesn't implement `Debug`
+}
+
+fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+ (u, t)
+ //~^ ERROR `T` doesn't implement `Debug`
+ //~| ERROR `U` doesn't implement `Debug`
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
new file mode 100644
index 000000000..c1712ca2e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
@@ -0,0 +1,39 @@
+error[E0277]: `T` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use6.rs:11:5
+ |
+LL | (t, t)
+ | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(T, T)`
+help: consider restricting type parameter `T`
+ |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `U` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use6.rs:16:5
+ |
+LL | (u, t)
+ | ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+help: consider restricting type parameter `U`
+ |
+LL | type Two<T, U: std::fmt::Debug> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `T` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use6.rs:16:5
+ |
+LL | (u, t)
+ | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(U, T)`
+help: consider restricting type parameter `T`
+ |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+ | +++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs
new file mode 100644
index 000000000..feebf81ee
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs
@@ -0,0 +1,24 @@
+// check-pass
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+type Two<A: Debug, B> = impl Debug;
+
+fn two<T: Debug + Copy, U>(t: T, u: U) -> Two<T, U> {
+ (t, t)
+}
+
+fn three<T: Debug, U>(t: T, t2: T, u: U) -> Two<T, U> {
+ (t, t2)
+}
+
+fn four<T: Debug, U, V>(t: T, t2: T, u: U, v: V) -> Two<T, U> {
+ (t, t2)
+}
+
+fn five<X, Y: Debug>(x: X, y: Y, y2: Y) -> Two<Y, X> {
+ (y, y2)
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs
new file mode 100644
index 000000000..3a4b5047b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs
@@ -0,0 +1,17 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+type Two<T, U> = impl Debug;
+
+fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
+ (t, 4u32)
+ //~^ ERROR `T` doesn't implement `Debug`
+}
+
+fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> {
+ (u, 4u32)
+ //~^ ERROR `U` doesn't implement `Debug`
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
new file mode 100644
index 000000000..b83105c45
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
@@ -0,0 +1,27 @@
+error[E0277]: `T` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use8.rs:10:5
+ |
+LL | (t, 4u32)
+ | ^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(T, u32)`
+help: consider restricting type parameter `T`
+ |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `U` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use8.rs:15:5
+ |
+LL | (u, 4u32)
+ | ^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(U, u32)`
+help: consider restricting type parameter `U`
+ |
+LL | type Two<T, U: std::fmt::Debug> = impl Debug;
+ | +++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
new file mode 100644
index 000000000..6afcdfe4d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
@@ -0,0 +1,25 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+type Two<A, B> = impl Debug;
+
+trait Foo {
+ type Bar: Debug;
+ const BAR: Self::Bar;
+}
+
+fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
+ (t, u, T::BAR)
+ //~^ ERROR the trait bound `A: Foo` is not satisfied
+ //~| ERROR `A` doesn't implement `Debug`
+ //~| ERROR `B` doesn't implement `Debug`
+}
+
+fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
+ (t, u, 42)
+ //~^ ERROR `A` doesn't implement `Debug`
+ //~| ERROR `B` doesn't implement `Debug`
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
new file mode 100644
index 000000000..50cf98273
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
@@ -0,0 +1,62 @@
+error[E0277]: the trait bound `A: Foo` is not satisfied
+ --> $DIR/generic_duplicate_param_use9.rs:15:5
+ |
+LL | (t, u, T::BAR)
+ | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
+ |
+help: consider restricting type parameter `A`
+ |
+LL | type Two<A: Foo, B> = impl Debug;
+ | +++++
+
+error[E0277]: `A` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use9.rs:15:5
+ |
+LL | (t, u, T::BAR)
+ | ^^^^^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
+help: consider restricting type parameter `A`
+ |
+LL | type Two<A: std::fmt::Debug, B> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `B` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use9.rs:15:5
+ |
+LL | (t, u, T::BAR)
+ | ^^^^^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
+help: consider restricting type parameter `B`
+ |
+LL | type Two<A, B: std::fmt::Debug> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `A` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use9.rs:22:5
+ |
+LL | (t, u, 42)
+ | ^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(A, B, i32)`
+help: consider restricting type parameter `A`
+ |
+LL | type Two<A: std::fmt::Debug, B> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: `B` doesn't implement `Debug`
+ --> $DIR/generic_duplicate_param_use9.rs:22:5
+ |
+LL | (t, u, 42)
+ | ^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(A, B, i32)`
+help: consider restricting type parameter `B`
+ |
+LL | type Two<A, B: std::fmt::Debug> = impl Debug;
+ | +++++++++++++++++
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs b/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs
new file mode 100644
index 000000000..e109c38c9
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_lifetime_param.rs
@@ -0,0 +1,11 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+type Region<'a> = impl std::fmt::Debug;
+
+fn region<'b>(a: &'b ()) -> Region<'b> {
+ a
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs
new file mode 100644
index 000000000..f39741a6a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.rs
@@ -0,0 +1,29 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+type OneTy<T> = impl Debug;
+
+type OneLifetime<'a> = impl Debug;
+
+type OneConst<const X: usize> = impl Debug;
+
+
+// Not defining uses, because they doesn't define *all* possible generics.
+
+fn concrete_ty() -> OneTy<u32> {
+ 5u32
+ //~^ ERROR non-defining opaque type use in defining scope
+}
+
+fn concrete_lifetime() -> OneLifetime<'static> {
+ 6u32
+ //~^ ERROR non-defining opaque type use in defining scope
+}
+
+fn concrete_const() -> OneConst<{ 123 }> {
+ 7u32
+ //~^ ERROR non-defining opaque type use in defining scope
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr
new file mode 100644
index 000000000..e7565525a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr
@@ -0,0 +1,35 @@
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_nondefining_use.rs:17:5
+ |
+LL | 5u32
+ | ^^^^
+ |
+note: used non-generic type `u32` for generic parameter
+ --> $DIR/generic_nondefining_use.rs:7:12
+ |
+LL | type OneTy<T> = impl Debug;
+ | ^
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_nondefining_use.rs:22:5
+ |
+LL | type OneLifetime<'a> = impl Debug;
+ | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
+...
+LL | 6u32
+ | ^^^^
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_nondefining_use.rs:27:5
+ |
+LL | 7u32
+ | ^^^^
+ |
+note: used non-generic constant `123` for generic parameter
+ --> $DIR/generic_nondefining_use.rs:11:15
+ |
+LL | type OneConst<const X: usize> = impl Debug;
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/type-alias-impl-trait/generic_not_used.rs b/src/test/ui/type-alias-impl-trait/generic_not_used.rs
new file mode 100644
index 000000000..c70f473cf
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_not_used.rs
@@ -0,0 +1,11 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+type WrongGeneric<T: 'static> = impl 'static;
+//~^ ERROR: at least one trait must be specified
+
+fn wrong_generic<U: 'static, V: 'static>(_: U, v: V) -> WrongGeneric<U> {
+ v
+ //~^ ERROR type parameter `V` is part of concrete type but not used in parameter list
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_not_used.stderr b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr
new file mode 100644
index 000000000..fd720239a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_not_used.stderr
@@ -0,0 +1,14 @@
+error: at least one trait must be specified
+ --> $DIR/generic_not_used.rs:5:33
+ |
+LL | type WrongGeneric<T: 'static> = impl 'static;
+ | ^^^^^^^^^^^^
+
+error: type parameter `V` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+ --> $DIR/generic_not_used.rs:9:5
+ |
+LL | v
+ | ^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
new file mode 100644
index 000000000..cb9077647
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
@@ -0,0 +1,16 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+ let y = 42;
+ let x = wrong_generic(&y);
+ let z: i32 = x;
+ //~^ ERROR non-defining opaque type use
+}
+
+type WrongGeneric<T> = impl 'static;
+//~^ ERROR: at least one trait must be specified
+
+fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
+ t
+ //~^ ERROR the parameter type `T` may not live long enough
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
new file mode 100644
index 000000000..ba583241a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
@@ -0,0 +1,32 @@
+error: at least one trait must be specified
+ --> $DIR/generic_type_does_not_live_long_enough.rs:10:24
+ |
+LL | type WrongGeneric<T> = impl 'static;
+ | ^^^^^^^^^^^^
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_type_does_not_live_long_enough.rs:6:18
+ |
+LL | let z: i32 = x;
+ | ^
+ |
+note: used non-generic type `&'static i32` for generic parameter
+ --> $DIR/generic_type_does_not_live_long_enough.rs:10:19
+ |
+LL | type WrongGeneric<T> = impl 'static;
+ | ^
+
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/generic_type_does_not_live_long_enough.rs:14:5
+ |
+LL | t
+ | ^ ...so that the type `T` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn wrong_generic<T: 'static>(t: T) -> WrongGeneric<T> {
+ | +++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs b/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs
new file mode 100644
index 000000000..d87a25aad
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs
@@ -0,0 +1,12 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+trait Trait {}
+type Underconstrained<T: Trait> = impl Send;
+
+// no `Trait` bound
+fn underconstrain<T>(_: T) -> Underconstrained<T> {
+ //~^ ERROR the trait bound `T: Trait`
+ unimplemented!()
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr
new file mode 100644
index 000000000..c73288329
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Trait` is not satisfied
+ --> $DIR/generic_underconstrained.rs:9:31
+ |
+LL | fn underconstrain<T>(_: T) -> Underconstrained<T> {
+ | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
+ |
+note: required by a bound in `Underconstrained`
+ --> $DIR/generic_underconstrained.rs:6:26
+ |
+LL | type Underconstrained<T: Trait> = impl Send;
+ | ^^^^^ required by this bound in `Underconstrained`
+help: consider restricting type parameter `T`
+ |
+LL | fn underconstrain<T: Trait>(_: T) -> Underconstrained<T> {
+ | +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs
new file mode 100644
index 000000000..8adc0bf32
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+type Underconstrained<T: std::fmt::Debug> = impl Send;
+
+// not a defining use, because it doesn't define *all* possible generics
+fn underconstrained<U>(_: U) -> Underconstrained<U> {
+ //~^ ERROR `U` doesn't implement `Debug`
+ 5u32
+}
+
+type Underconstrained2<T: std::fmt::Debug> = impl Send;
+
+// not a defining use, because it doesn't define *all* possible generics
+fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
+ //~^ ERROR `V` doesn't implement `Debug`
+ 5u32
+}
diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr
new file mode 100644
index 000000000..d77d978aa
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr
@@ -0,0 +1,35 @@
+error[E0277]: `U` doesn't implement `Debug`
+ --> $DIR/generic_underconstrained2.rs:8:33
+ |
+LL | fn underconstrained<U>(_: U) -> Underconstrained<U> {
+ | ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+note: required by a bound in `Underconstrained`
+ --> $DIR/generic_underconstrained2.rs:5:26
+ |
+LL | type Underconstrained<T: std::fmt::Debug> = impl Send;
+ | ^^^^^^^^^^^^^^^ required by this bound in `Underconstrained`
+help: consider restricting type parameter `U`
+ |
+LL | fn underconstrained<U: std::fmt::Debug>(_: U) -> Underconstrained<U> {
+ | +++++++++++++++++
+
+error[E0277]: `V` doesn't implement `Debug`
+ --> $DIR/generic_underconstrained2.rs:16:43
+ |
+LL | fn underconstrained2<U, V>(_: U, _: V) -> Underconstrained2<V> {
+ | ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+note: required by a bound in `Underconstrained2`
+ --> $DIR/generic_underconstrained2.rs:13:27
+ |
+LL | type Underconstrained2<T: std::fmt::Debug> = impl Send;
+ | ^^^^^^^^^^^^^^^ required by this bound in `Underconstrained2`
+help: consider restricting type parameter `V`
+ |
+LL | fn underconstrained2<U, V: std::fmt::Debug>(_: U, _: V) -> Underconstrained2<V> {
+ | +++++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs
new file mode 100644
index 000000000..851c2f66c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs
@@ -0,0 +1,17 @@
+// Ensure that we don't ICE if associated type impl trait is used in an impl
+// with an unconstrained type parameter.
+
+#![feature(type_alias_impl_trait)]
+
+trait X {
+ type I;
+ fn f() -> Self::I;
+}
+
+impl<T> X for () {
+ //~^ ERROR the type parameter `T` is not constrained
+ type I = impl Sized;
+ fn f() -> Self::I {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr
new file mode 100644
index 000000000..8cf8fb1d1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr
@@ -0,0 +1,9 @@
+error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/impl-with-unconstrained-param.rs:11:6
+ |
+LL | impl<T> X for () {
+ | ^ 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/type-alias-impl-trait/incoherent-assoc-imp-trait.rs b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs
new file mode 100644
index 000000000..685d76ee3
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs
@@ -0,0 +1,15 @@
+// Regression test for issue 67856
+
+#![feature(unboxed_closures)]
+#![feature(type_alias_impl_trait)]
+#![feature(fn_traits)]
+
+trait MyTrait {}
+impl MyTrait for () {}
+
+impl<F> FnOnce<()> for &F {
+ //~^ ERROR type parameter `F` must be used
+ type Output = impl MyTrait;
+ extern "rust-call" fn call_once(self, _: ()) -> Self::Output {}
+}
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr
new file mode 100644
index 000000000..b93ea955c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr
@@ -0,0 +1,12 @@
+error[E0210]: type parameter `F` must be used as the type parameter for some local type (e.g., `MyStruct<F>`)
+ --> $DIR/incoherent-assoc-imp-trait.rs:10:6
+ |
+LL | impl<F> FnOnce<()> for &F {
+ | ^ type parameter `F` must be used as the type parameter for some local type
+ |
+ = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
+ = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/type-alias-impl-trait/incomplete-inference.rs b/src/test/ui/type-alias-impl-trait/incomplete-inference.rs
new file mode 100644
index 000000000..4c8bf2cfc
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/incomplete-inference.rs
@@ -0,0 +1,14 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Sized;
+
+fn bar() -> Foo {
+ None
+ //~^ ERROR: type annotations needed [E0282]
+}
+
+fn baz() -> Foo {
+ Some(())
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr b/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr
new file mode 100644
index 000000000..9a0e71b4e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/incomplete-inference.rs:6:5
+ |
+LL | None
+ | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
+ |
+help: consider specifying the generic argument
+ |
+LL | None::<T>
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.rs b/src/test/ui/type-alias-impl-trait/inference-cycle.rs
new file mode 100644
index 000000000..79caddf79
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/inference-cycle.rs
@@ -0,0 +1,25 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+mod m {
+ type Foo = impl std::fmt::Debug;
+ //~^ ERROR cycle detected
+
+ // Cycle: error today, but it'd be nice if it eventually worked
+
+ pub fn foo() -> Foo {
+ is_send(bar())
+ }
+
+ pub fn bar() {
+ is_send(foo()); // Today: error
+ }
+
+ fn baz() {
+ let f: Foo = 22_u32;
+ }
+
+ fn is_send<T: Send>(_: T) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.stderr b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr
new file mode 100644
index 000000000..b9d646b92
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr
@@ -0,0 +1,22 @@
+error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
+ --> $DIR/inference-cycle.rs:5:16
+ |
+LL | type Foo = impl std::fmt::Debug;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: ...which requires type-checking `m::bar`...
+ --> $DIR/inference-cycle.rs:15:9
+ |
+LL | is_send(foo()); // Today: error
+ | ^^^^^^^
+ = note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`...
+ = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in module `m`
+ --> $DIR/inference-cycle.rs:4:1
+ |
+LL | mod m {
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs
new file mode 100644
index 000000000..50eeff0b1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs
@@ -0,0 +1,13 @@
+// Checks to ensure that we properly detect when a closure constrains an opaque type
+
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {
+ type Opaque = impl Debug;
+ fn _unused() -> Opaque { String::new() }
+ let null = || -> Opaque { 0 };
+ //~^ ERROR: concrete type differs from previous defining opaque type use
+ println!("{:?}", null());
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr
new file mode 100644
index 000000000..4c5fd2255
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/issue-52843-closure-constrain.rs:10:31
+ |
+LL | let null = || -> Opaque { 0 };
+ | ^ expected `String`, got `i32`
+ |
+note: previous use here
+ --> $DIR/issue-52843-closure-constrain.rs:9:30
+ |
+LL | fn _unused() -> Opaque { String::new() }
+ | ^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-52843.rs b/src/test/ui/type-alias-impl-trait/issue-52843.rs
new file mode 100644
index 000000000..159d3ccd2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-52843.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo<T> = impl Default;
+
+#[allow(unused)]
+fn foo<T: Default>(t: T) -> Foo<T> {
+ t
+ //~^ ERROR: the trait bound `T: Default` is not satisfied
+}
+
+struct NotDefault;
+
+fn main() {
+ let _ = Foo::<NotDefault>::default();
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-52843.stderr b/src/test/ui/type-alias-impl-trait/issue-52843.stderr
new file mode 100644
index 000000000..acd40f980
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-52843.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `T: Default` is not satisfied
+ --> $DIR/issue-52843.rs:7:5
+ |
+LL | t
+ | ^ the trait `Default` is not implemented for `T`
+ |
+help: consider restricting type parameter `T`
+ |
+LL | type Foo<T: std::default::Default> = impl Default;
+ | +++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.rs b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs
new file mode 100644
index 000000000..438ac35fd
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+type Bug<T, U> = impl Fn(T) -> U + Copy; //~ ERROR cycle detected
+
+const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
+//~^ ERROR: cannot transmute
+
+fn make_bug<T, U: From<T>>() -> Bug<T, U> {
+ |x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied
+}
+
+fn main() {
+ CONST_BUG(0);
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr
new file mode 100644
index 000000000..1b89d5571
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr
@@ -0,0 +1,55 @@
+error[E0391]: cycle detected when computing type of `Bug::{opaque#0}`
+ --> $DIR/issue-53092-2.rs:4:18
+ |
+LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: ...which requires type-checking `CONST_BUG`...
+ --> $DIR/issue-53092-2.rs:6:1
+ |
+LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: ...which requires computing layout of `Bug<u8, ()>`...
+ = note: ...which requires normalizing `Bug<u8, ()>`...
+ = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in top-level module
+ --> $DIR/issue-53092-2.rs:1:1
+ |
+LL | / #![feature(type_alias_impl_trait)]
+LL | | #![allow(dead_code)]
+LL | |
+LL | | type Bug<T, U> = impl Fn(T) -> U + Copy;
+... |
+LL | | CONST_BUG(0);
+LL | | }
+ | |_^
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/issue-53092-2.rs:6:41
+ |
+LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: source type: `[closure@$DIR/issue-53092-2.rs:6:61: 6:68]` (0 bits)
+ = note: target type: `Bug<u8, ()>` (size can vary because of [type error])
+
+error[E0277]: the trait bound `U: From<T>` is not satisfied
+ --> $DIR/issue-53092-2.rs:10:5
+ |
+LL | |x| x.into()
+ | ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
+ |
+note: required by a bound in `make_bug`
+ --> $DIR/issue-53092-2.rs:9:19
+ |
+LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
+ | ^^^^^^^ required by this bound in `make_bug`
+help: consider restricting type parameter `U`
+ |
+LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
+ | +++++++++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0391, E0512.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-53092.rs b/src/test/ui/type-alias-impl-trait/issue-53092.rs
new file mode 100644
index 000000000..1be5b46d6
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53092.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+type Bug<T, U> = impl Fn(T) -> U + Copy;
+
+union Moo {
+ x: Bug<u8, ()>,
+ y: (),
+}
+
+const CONST_BUG: Bug<u8, ()> = unsafe { Moo { y: () }.x };
+
+fn make_bug<T, U: From<T>>() -> Bug<T, U> {
+ |x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied
+}
+
+fn main() {
+ CONST_BUG(0);
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-53092.stderr b/src/test/ui/type-alias-impl-trait/issue-53092.stderr
new file mode 100644
index 000000000..2109cf8a7
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53092.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `U: From<T>` is not satisfied
+ --> $DIR/issue-53092.rs:14:5
+ |
+LL | |x| x.into()
+ | ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
+ |
+note: required by a bound in `make_bug`
+ --> $DIR/issue-53092.rs:13:19
+ |
+LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
+ | ^^^^^^^ required by this bound in `make_bug`
+help: consider restricting type parameter `U`
+ |
+LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
+ | +++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-53096.rs b/src/test/ui/type-alias-impl-trait/issue-53096.rs
new file mode 100644
index 000000000..007dcf3bc
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53096.rs
@@ -0,0 +1,11 @@
+#![feature(rustc_attrs)]
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Fn() -> usize;
+const fn bar() -> Foo {
+ || 0usize
+}
+const BAZR: Foo = bar();
+
+#[rustc_error]
+fn main() {} //~ ERROR
diff --git a/src/test/ui/type-alias-impl-trait/issue-53096.stderr b/src/test/ui/type-alias-impl-trait/issue-53096.stderr
new file mode 100644
index 000000000..0af3a75f8
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53096.stderr
@@ -0,0 +1,8 @@
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/issue-53096.rs:11:1
+ |
+LL | fn main() {}
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
new file mode 100644
index 000000000..4a11bb502
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
@@ -0,0 +1,10 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Fn() -> Foo;
+
+fn foo() -> Foo {
+//~^ ERROR: overflow evaluating the requirement
+ foo
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr
new file mode 100644
index 000000000..d20b1cc6d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr
@@ -0,0 +1,11 @@
+error[E0275]: overflow evaluating the requirement `fn() -> Foo {foo}: Sized`
+ --> $DIR/issue-53398-cyclic-types.rs:5:13
+ |
+LL | fn foo() -> Foo {
+ | ^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_53398_cyclic_types`)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.rs b/src/test/ui/type-alias-impl-trait/issue-53598.rs
new file mode 100644
index 000000000..9c1cbf926
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53598.rs
@@ -0,0 +1,27 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+pub trait Foo {
+ type Item: Debug;
+
+ fn foo<T: Debug>(_: T) -> Self::Item;
+}
+
+#[derive(Debug)]
+pub struct S<T>(std::marker::PhantomData<T>);
+
+pub struct S2;
+
+impl Foo for S2 {
+ type Item = impl Debug;
+
+ fn foo<T: Debug>(_: T) -> Self::Item {
+ S::<T>(Default::default())
+ //~^ Error type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+ }
+}
+
+fn main() {
+ S2::foo(123);
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-53598.stderr b/src/test/ui/type-alias-impl-trait/issue-53598.stderr
new file mode 100644
index 000000000..f8b8201e2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53598.stderr
@@ -0,0 +1,8 @@
+error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+ --> $DIR/issue-53598.rs:20:9
+ |
+LL | S::<T>(Default::default())
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs
new file mode 100644
index 000000000..a3f126d56
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs
@@ -0,0 +1,19 @@
+#![feature(generators, generator_trait, rustc_attrs)]
+#![feature(type_alias_impl_trait)]
+
+use std::ops::Generator;
+
+type GenOnce<Y, R> = impl Generator<Yield = Y, Return = R>;
+
+const fn const_generator<Y, R>(yielding: Y, returning: R) -> GenOnce<Y, R> {
+ move || {
+ yield yielding;
+
+ return returning;
+ }
+}
+
+const FOO: GenOnce<usize, usize> = const_generator(10, 100);
+
+#[rustc_error]
+fn main() {} //~ ERROR
diff --git a/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr
new file mode 100644
index 000000000..eb1c9603a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr
@@ -0,0 +1,8 @@
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/issue-53678-generator-and-const-fn.rs:19:1
+ |
+LL | fn main() {}
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs b/src/test/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs
new file mode 100644
index 000000000..af0780ab0
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs
@@ -0,0 +1,26 @@
+// check-pass
+// Regression test for issue #55099
+// Tests that we don't incorrectly consider a lifetime to part
+// of the concrete type
+
+#![feature(type_alias_impl_trait)]
+
+trait Future {}
+
+struct AndThen<F>(F);
+
+impl<F> Future for AndThen<F> {}
+
+struct Foo<'a> {
+ x: &'a mut (),
+}
+
+type F = impl Future;
+
+impl<'a> Foo<'a> {
+ fn reply(&mut self) -> F {
+ AndThen(|| ())
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs b/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs
new file mode 100644
index 000000000..3a7a5da07
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs
@@ -0,0 +1,24 @@
+// Regression test for #57188
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+struct Baz<'a> {
+ source: &'a str,
+}
+
+trait Foo<'a> {
+ type T: Iterator<Item = Baz<'a>> + 'a;
+ fn foo(source: &'a str) -> Self::T;
+}
+
+struct Bar;
+impl<'a> Foo<'a> for Bar {
+ type T = impl Iterator<Item = Baz<'a>> + 'a;
+ fn foo(source: &'a str) -> Self::T {
+ std::iter::once(Baz { source })
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
new file mode 100644
index 000000000..067ed7ea1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
@@ -0,0 +1,27 @@
+// Regression test for issue #57611
+// Ensures that we don't ICE
+// FIXME: This should compile, but it currently doesn't
+// known-bug: unknown
+
+#![feature(trait_alias)]
+#![feature(type_alias_impl_trait)]
+
+trait Foo {
+ type Bar: Baz<Self, Self>;
+
+ fn bar(&self) -> Self::Bar;
+}
+
+struct X;
+
+impl Foo for X {
+ type Bar = impl Baz<Self, Self>;
+
+ fn bar(&self) -> Self::Bar {
+ |x| x
+ }
+}
+
+trait Baz<A: ?Sized, B: ?Sized> = Fn(&A) -> &B;
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
new file mode 100644
index 000000000..f14bf6b0f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr
@@ -0,0 +1,26 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-57611-trait-alias.rs:21:9
+ |
+LL | |x| x
+ | ^^^^^ one type is more general than the other
+ |
+ = note: expected trait `for<'r> Fn<(&'r X,)>`
+ found trait `Fn<(&X,)>`
+note: this closure does not fulfill the lifetime requirements
+ --> $DIR/issue-57611-trait-alias.rs:21:9
+ |
+LL | |x| x
+ | ^^^
+
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/issue-57611-trait-alias.rs:21:9
+ |
+LL | |x| x
+ | ^^^^^ implementation of `FnOnce` is not general enough
+ |
+ = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
+ = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.rs b/src/test/ui/type-alias-impl-trait/issue-57700.rs
new file mode 100644
index 000000000..484589387
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-57700.rs
@@ -0,0 +1,21 @@
+#![feature(arbitrary_self_types)]
+#![feature(type_alias_impl_trait)]
+
+use std::ops::Deref;
+
+trait Foo {
+ type Bar: Foo;
+
+ fn foo(self: impl Deref<Target = Self>) -> Self::Bar;
+}
+
+impl<C> Foo for C {
+ type Bar = impl Foo;
+
+ fn foo(self: impl Deref<Target = Self>) -> Self::Bar {
+ self
+ //~^ Error type parameter `impl Deref<Target = Self>` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-57700.stderr b/src/test/ui/type-alias-impl-trait/issue-57700.stderr
new file mode 100644
index 000000000..31b6df5d4
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-57700.stderr
@@ -0,0 +1,8 @@
+error: type parameter `impl Deref<Target = Self>` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+ --> $DIR/issue-57700.rs:16:9
+ |
+LL | self
+ | ^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs b/src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs
new file mode 100644
index 000000000..fcab2c7db
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-57807-associated-type.rs
@@ -0,0 +1,31 @@
+// Regression test for issue #57807 - ensure
+// that we properly unify associated types within
+// a type alias impl trait
+// check-pass
+#![feature(type_alias_impl_trait)]
+
+trait Bar {
+ type A;
+}
+
+impl Bar for () {
+ type A = ();
+}
+
+trait Foo {
+ type A;
+ type B: Bar<A = Self::A>;
+
+ fn foo() -> Self::B;
+}
+
+impl Foo for () {
+ type A = ();
+ type B = impl Bar<A = Self::A>;
+
+ fn foo() -> Self::B {
+ ()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-57961.rs b/src/test/ui/type-alias-impl-trait/issue-57961.rs
new file mode 100644
index 000000000..472886c9c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-57961.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+
+type X = impl Sized;
+
+trait Foo {
+ type Bar: Iterator<Item = X>;
+}
+
+impl Foo for () {
+ type Bar = std::vec::IntoIter<u32>;
+ //~^ ERROR type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X
+}
+
+fn incoherent() {
+ let f: X = 22_i32;
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-57961.stderr b/src/test/ui/type-alias-impl-trait/issue-57961.stderr
new file mode 100644
index 000000000..ed4caf6ce
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-57961.stderr
@@ -0,0 +1,20 @@
+error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X`
+ --> $DIR/issue-57961.rs:10:16
+ |
+LL | type X = impl Sized;
+ | ---------- the expected opaque type
+...
+LL | type Bar = std::vec::IntoIter<u32>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `u32`
+ |
+ = note: expected opaque type `X`
+ found type `u32`
+note: required by a bound in `Foo::Bar`
+ --> $DIR/issue-57961.rs:6:24
+ |
+LL | type Bar: Iterator<Item = X>;
+ | ^^^^^^^^ required by this bound in `Foo::Bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs b/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs
new file mode 100644
index 000000000..f20ddf020
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs
@@ -0,0 +1,39 @@
+// check-pass
+
+#![feature(generators, generator_trait)]
+#![feature(type_alias_impl_trait)]
+
+use std::ops::{Generator, GeneratorState};
+use std::pin::Pin;
+
+type RandGenerator<'a> = impl Generator<Return = (), Yield = u64> + 'a;
+fn rand_generator<'a>(rng: &'a ()) -> RandGenerator<'a> {
+ move || {
+ let _rng = rng;
+ loop {
+ yield 0;
+ }
+ }
+}
+
+pub type RandGeneratorWithIndirection<'a> = impl Generator<Return = (), Yield = u64> + 'a;
+pub fn rand_generator_with_indirection<'a>(rng: &'a ()) -> RandGeneratorWithIndirection<'a> {
+ fn helper<'b>(rng: &'b ()) -> impl 'b + Generator<Return = (), Yield = u64> {
+ move || {
+ let _rng = rng;
+ loop {
+ yield 0;
+ }
+ }
+ }
+
+ helper(rng)
+}
+
+fn main() {
+ let mut gen = rand_generator(&());
+ match unsafe { Pin::new_unchecked(&mut gen) }.resume(()) {
+ GeneratorState::Yielded(_) => {}
+ GeneratorState::Complete(_) => {}
+ };
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-58887.rs b/src/test/ui/type-alias-impl-trait/issue-58887.rs
new file mode 100644
index 000000000..96ac78602
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-58887.rs
@@ -0,0 +1,22 @@
+// run-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait UnwrapItemsExt {
+ type Iter;
+ fn unwrap_items(self) -> Self::Iter;
+}
+
+impl<I, T, E> UnwrapItemsExt for I
+where
+ I: Iterator<Item = Result<T, E>>,
+ E: std::fmt::Debug,
+{
+ type Iter = impl Iterator<Item = T>;
+
+ fn unwrap_items(self) -> Self::Iter {
+ self.map(|x| x.unwrap())
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-58951-2.rs b/src/test/ui/type-alias-impl-trait/issue-58951-2.rs
new file mode 100644
index 000000000..e4ba7f8e2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-58951-2.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+mod defining_use_scope {
+ pub type A = impl Iterator;
+
+ pub fn def_a() -> A {
+ 0..1
+ }
+}
+use defining_use_scope::*;
+
+pub fn use_a() {
+ def_a().map(|x| x);
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-58951.rs b/src/test/ui/type-alias-impl-trait/issue-58951.rs
new file mode 100644
index 000000000..7303cbab4
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-58951.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+type A = impl Iterator;
+
+fn def_a() -> A {
+ 0..1
+}
+
+pub fn use_a() {
+ def_a().map(|x| x);
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs
new file mode 100644
index 000000000..9a40f3d9b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs
@@ -0,0 +1,14 @@
+trait Bug {
+ type Item: Bug;
+
+ const FUN: fn() -> Self::Item;
+}
+
+impl Bug for &() {
+ type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable
+
+ const FUN: fn() -> Self::Item = || ();
+ //~^ ERROR the trait bound `(): Bug` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
new file mode 100644
index 000000000..082b0f0c3
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr
@@ -0,0 +1,21 @@
+error[E0658]: `impl Trait` in type aliases is unstable
+ --> $DIR/issue-60371.rs:8:17
+ |
+LL | type Item = impl Bug;
+ | ^^^^^^^^
+ |
+ = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+ = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
+
+error[E0277]: the trait bound `(): Bug` is not satisfied
+ --> $DIR/issue-60371.rs:10:40
+ |
+LL | const FUN: fn() -> Self::Item = || ();
+ | ^ the trait `Bug` is not implemented for `()`
+ |
+ = help: the trait `Bug` is implemented for `&()`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-60407.rs b/src/test/ui/type-alias-impl-trait/issue-60407.rs
new file mode 100644
index 000000000..b833429c7
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-60407.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait, rustc_attrs)]
+
+type Debuggable = impl core::fmt::Debug;
+
+static mut TEST: Option<Debuggable> = None;
+
+#[rustc_error]
+fn main() {
+ //~^ ERROR
+ unsafe { TEST = Some(foo()) }
+}
+
+fn foo() -> Debuggable {
+ 0u32
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-60407.stderr b/src/test/ui/type-alias-impl-trait/issue-60407.stderr
new file mode 100644
index 000000000..fecee2779
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-60407.stderr
@@ -0,0 +1,8 @@
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/issue-60407.rs:8:1
+ |
+LL | fn main() {
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-60564-working.rs b/src/test/ui/type-alias-impl-trait/issue-60564-working.rs
new file mode 100644
index 000000000..38accc824
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-60564-working.rs
@@ -0,0 +1,24 @@
+#![feature(type_alias_impl_trait)]
+
+// check-pass
+
+trait IterBits {
+ type BitsIter: Iterator<Item = u8>;
+ fn iter_bits(self, n: u8) -> Self::BitsIter;
+}
+
+impl<T: Copy, E> IterBits for T
+where
+ T: std::ops::Shr<Output = T>
+ + std::ops::BitAnd<T, Output = T>
+ + std::convert::From<u8>
+ + std::convert::TryInto<u8, Error = E>,
+ E: std::fmt::Debug,
+{
+ type BitsIter = impl std::iter::Iterator<Item = u8>;
+ fn iter_bits(self, n: u8) -> Self::BitsIter {
+ (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs
new file mode 100644
index 000000000..4fc767931
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs
@@ -0,0 +1,25 @@
+#![feature(type_alias_impl_trait)]
+
+trait IterBits {
+ type BitsIter: Iterator<Item = u8>;
+ fn iter_bits(self, n: u8) -> Self::BitsIter;
+}
+
+type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+
+impl<T: Copy, E> IterBits for T
+where
+ T: std::ops::Shr<Output = T>
+ + std::ops::BitAnd<T, Output = T>
+ + std::convert::From<u8>
+ + std::convert::TryInto<u8, Error = E>,
+ E: std::fmt::Debug,
+{
+ type BitsIter = IterBitsIter<T, E, u8>;
+ fn iter_bits(self, n: u8) -> Self::BitsIter {
+ (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
+ //~^ ERROR non-defining opaque type use in defining scope
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr
new file mode 100644
index 000000000..bbc93657b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr
@@ -0,0 +1,14 @@
+error: non-defining opaque type use in defining scope
+ --> $DIR/issue-60564.rs:20:9
+ |
+LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: used non-generic type `u8` for generic parameter
+ --> $DIR/issue-60564.rs:8:25
+ |
+LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-60662.rs b/src/test/ui/type-alias-impl-trait/issue-60662.rs
new file mode 100644
index 000000000..b9faa668b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-60662.rs
@@ -0,0 +1,10 @@
+// check-pass
+// compile-flags: -Z unpretty=hir
+
+#![feature(type_alias_impl_trait)]
+
+trait Animal {}
+
+fn main() {
+ pub type ServeFut = impl Animal;
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-60662.stdout b/src/test/ui/type-alias-impl-trait/issue-60662.stdout
new file mode 100644
index 000000000..5b3d7375d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-60662.stdout
@@ -0,0 +1,14 @@
+// check-pass
+// compile-flags: -Z unpretty=hir
+
+#![feature(type_alias_impl_trait)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+trait Animal { }
+
+fn main() {
+ type ServeFut = /*impl Trait*/;
+ }
diff --git a/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs b/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs
new file mode 100644
index 000000000..36779a0ce
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs
@@ -0,0 +1,38 @@
+// Regression test for #62988
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait MyTrait {
+ type AssocType: Send;
+ fn ret(&self) -> Self::AssocType;
+}
+
+impl MyTrait for () {
+ type AssocType = impl Send;
+ fn ret(&self) -> Self::AssocType {
+ ()
+ }
+}
+
+impl<'a> MyTrait for &'a () {
+ type AssocType = impl Send;
+ fn ret(&self) -> Self::AssocType {
+ ()
+ }
+}
+
+trait MyLifetimeTrait<'a> {
+ type AssocType: Send + 'a;
+ fn ret(&self) -> Self::AssocType;
+}
+
+impl<'a> MyLifetimeTrait<'a> for &'a () {
+ type AssocType = impl Send + 'a;
+ fn ret(&self) -> Self::AssocType {
+ *self
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs b/src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs
new file mode 100644
index 000000000..7414611a7
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs
@@ -0,0 +1,13 @@
+// Regression test for issue #63263.
+// Tests that we properly handle closures with an explicit return type
+// that return an opaque type.
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+pub type Closure = impl FnOnce();
+
+fn main() {
+ || -> Closure { || () };
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.rs b/src/test/ui/type-alias-impl-trait/issue-63279.rs
new file mode 100644
index 000000000..97332e16d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-63279.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Zsave-analysis
+
+#![feature(type_alias_impl_trait)]
+
+type Closure = impl FnOnce();
+
+fn c() -> Closure {
+ //~^ ERROR: expected a `FnOnce<()>` closure, found `()`
+ || -> Closure { || () }
+ //~^ ERROR: mismatched types
+ //~| ERROR: mismatched types
+ //~| ERROR: expected a `FnOnce<()>` closure, found `()`
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.stderr
new file mode 100644
index 000000000..110b8d1ee
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-63279.stderr
@@ -0,0 +1,48 @@
+error[E0277]: expected a `FnOnce<()>` closure, found `()`
+ --> $DIR/issue-63279.rs:7:11
+ |
+LL | fn c() -> Closure {
+ | ^^^^^^^ expected an `FnOnce<()>` closure, found `()`
+ |
+ = help: the trait `FnOnce<()>` is not implemented for `()`
+ = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
+
+error[E0277]: expected a `FnOnce<()>` closure, found `()`
+ --> $DIR/issue-63279.rs:9:11
+ |
+LL | || -> Closure { || () }
+ | ^^^^^^^ expected an `FnOnce<()>` closure, found `()`
+ |
+ = help: the trait `FnOnce<()>` is not implemented for `()`
+ = note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-63279.rs:9:21
+ |
+LL | || -> Closure { || () }
+ | ^^^^^ expected `()`, found closure
+ |
+ = note: expected unit type `()`
+ found closure `[closure@$DIR/issue-63279.rs:9:21: 9:23]`
+help: use parentheses to call this closure
+ |
+LL | || -> Closure { (|| ())() }
+ | + +++
+
+error[E0308]: mismatched types
+ --> $DIR/issue-63279.rs:9:5
+ |
+LL | || -> Closure { || () }
+ | ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure
+ |
+ = note: expected unit type `()`
+ found closure `[closure@$DIR/issue-63279.rs:9:5: 9:18]`
+help: use parentheses to call this closure
+ |
+LL | (|| -> Closure { || () })()
+ | + +++
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-63355.rs b/src/test/ui/type-alias-impl-trait/issue-63355.rs
new file mode 100644
index 000000000..7066a0535
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-63355.rs
@@ -0,0 +1,46 @@
+#![feature(type_alias_impl_trait)]
+// check-pass
+
+pub trait Foo {}
+
+pub trait Bar {
+ type Foo: Foo;
+
+ fn foo() -> Self::Foo;
+}
+
+pub trait Baz {
+ type Foo: Foo;
+ type Bar: Bar<Foo = Self::Foo>;
+
+ fn foo() -> Self::Foo;
+ fn bar() -> Self::Bar;
+}
+
+impl Foo for () {}
+
+impl Bar for () {
+ type Foo = FooImpl;
+
+ fn foo() -> Self::Foo {
+ ()
+ }
+}
+
+pub type FooImpl = impl Foo;
+pub type BarImpl = impl Bar<Foo = FooImpl>;
+
+impl Baz for () {
+ type Foo = FooImpl;
+ type Bar = BarImpl;
+
+ fn foo() -> Self::Foo {
+ ()
+ }
+
+ fn bar() -> Self::Bar {
+ ()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs b/src/test/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs
new file mode 100644
index 000000000..28f4a85c9
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs
@@ -0,0 +1,21 @@
+// check-pass
+// Regression test for issue #63677 - ensure that
+// coherence checking can properly handle 'impl trait'
+// in type aliases
+#![feature(type_alias_impl_trait)]
+
+pub trait Trait {}
+pub struct S1<T>(T);
+pub struct S2<T>(T);
+
+pub type T1 = impl Trait;
+pub type T2 = S1<T1>;
+pub type T3 = S2<T2>;
+
+impl<T> Trait for S1<T> {}
+impl<T: Trait> S2<T> {}
+impl T3 {}
+
+pub fn use_t1() -> T1 { S1(()) }
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.rs b/src/test/ui/type-alias-impl-trait/issue-65384.rs
new file mode 100644
index 000000000..9a119c4d2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-65384.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+#![allow(incomplete_features)]
+
+trait MyTrait {}
+
+impl MyTrait for () {}
+
+type Bar = impl MyTrait;
+
+impl MyTrait for Bar {}
+//~^ ERROR: cannot implement trait on type alias impl trait
+
+fn bazr() -> Bar { }
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-65384.stderr b/src/test/ui/type-alias-impl-trait/issue-65384.stderr
new file mode 100644
index 000000000..41bcea27e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-65384.stderr
@@ -0,0 +1,14 @@
+error: cannot implement trait on type alias impl trait
+ --> $DIR/issue-65384.rs:10:18
+ |
+LL | impl MyTrait for Bar {}
+ | ^^^
+ |
+note: type alias impl trait defined here
+ --> $DIR/issue-65384.rs:8:12
+ |
+LL | type Bar = impl MyTrait;
+ | ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
new file mode 100644
index 000000000..72c22827f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Zsave-analysis
+// check-pass
+
+#![feature(type_alias_impl_trait, rustc_attrs)]
+
+type T = impl Sized;
+// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed
+// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive;
+// so difference assertion should not be declared on impl-trait-type-alias's instances.
+// for details, check RFC-2515:
+// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md
+
+fn take(_: fn() -> T) {}
+
+fn main() {
+ take(|| {});
+ take(|| {});
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-65918.rs b/src/test/ui/type-alias-impl-trait/issue-65918.rs
new file mode 100644
index 000000000..af6d50109
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-65918.rs
@@ -0,0 +1,51 @@
+// ignore-test: This now ICEs again.
+
+// build-pass
+
+#![feature(type_alias_impl_trait)]
+
+use std::marker::PhantomData;
+
+/* copied Index and TryFrom for convenience (and simplicity) */
+trait MyIndex<T> {
+ type O;
+ fn my_index(self) -> Self::O;
+}
+trait MyFrom<T>: Sized {
+ type Error;
+ fn my_from(value: T) -> Result<Self, Self::Error>;
+}
+
+/* MCVE starts here */
+trait F {}
+impl F for () {}
+type DummyT<T> = impl F;
+fn _dummy_t<T>() -> DummyT<T> {}
+
+struct Phantom1<T>(PhantomData<T>);
+struct Phantom2<T>(PhantomData<T>);
+struct Scope<T>(Phantom2<DummyT<T>>);
+
+impl<T> Scope<T> {
+ fn new() -> Self {
+ unimplemented!()
+ }
+}
+
+impl<T> MyFrom<Phantom2<T>> for Phantom1<T> {
+ type Error = ();
+ fn my_from(_: Phantom2<T>) -> Result<Self, Self::Error> {
+ unimplemented!()
+ }
+}
+
+impl<T: MyFrom<Phantom2<DummyT<U>>>, U> MyIndex<Phantom1<T>> for Scope<U> {
+ type O = T;
+ fn my_index(self) -> Self::O {
+ MyFrom::my_from(self.0).ok().unwrap()
+ }
+}
+
+fn main() {
+ let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs b/src/test/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs
new file mode 100644
index 000000000..d97270c31
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs
@@ -0,0 +1,21 @@
+// Regression test for issue #66580
+// Ensures that we don't try to determine whether a closure
+// is foreign when it's the underlying type of an opaque type
+// check-pass
+#![feature(type_alias_impl_trait)]
+
+type Closure = impl FnOnce();
+
+fn closure() -> Closure {
+ || {}
+}
+
+struct Wrap<T> {
+ f: T,
+}
+
+impl Wrap<Closure> {}
+
+impl<T> Wrap<T> {}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs b/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs
new file mode 100644
index 000000000..cd219328a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs
@@ -0,0 +1,33 @@
+// check-pass
+// Regression test for issue #67844
+// Ensures that we properly handle nested TAIT occurrences
+// with generic parameters
+
+#![feature(type_alias_impl_trait)]
+
+trait WithAssoc {
+ type AssocType;
+}
+
+trait WithParam<A> {}
+
+type Return<A> = impl WithAssoc<AssocType = impl WithParam<A>>;
+
+struct MyParam;
+impl<A> WithParam<A> for MyParam {}
+
+struct MyStruct;
+
+impl WithAssoc for MyStruct {
+ type AssocType = MyParam;
+}
+
+fn my_fun<A>() -> Return<A> {
+ MyStruct
+}
+
+fn my_other_fn<A>() -> impl WithAssoc<AssocType = impl WithParam<A>> {
+ MyStruct
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs
new file mode 100644
index 000000000..5223fb1c7
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs
@@ -0,0 +1,14 @@
+// Regression test for issue #68368
+// Ensures that we don't ICE when emitting an error
+// for a non-defining use when lifetimes are involved
+
+#![feature(type_alias_impl_trait)]
+trait Trait<T> {}
+type Alias<'a, U> = impl Trait<U>;
+
+fn f<'a>() -> Alias<'a, ()> {}
+//~^ ERROR non-defining opaque type use in defining scope
+
+fn main() {}
+
+impl<X> Trait<X> for () {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
new file mode 100644
index 000000000..7fb9a0c41
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
@@ -0,0 +1,14 @@
+error: non-defining opaque type use in defining scope
+ --> $DIR/issue-68368-non-defining-use-2.rs:9:29
+ |
+LL | fn f<'a>() -> Alias<'a, ()> {}
+ | ^^
+ |
+note: used non-generic type `()` for generic parameter
+ --> $DIR/issue-68368-non-defining-use-2.rs:7:16
+ |
+LL | type Alias<'a, U> = impl Trait<U>;
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
new file mode 100644
index 000000000..b50462bf2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
@@ -0,0 +1,14 @@
+// Regression test for issue #68368
+// Ensures that we don't ICE when emitting an error
+// for a non-defining use when lifetimes are involved
+
+#![feature(type_alias_impl_trait)]
+trait Trait<T> {}
+type Alias<'a, U> = impl Trait<U>;
+
+fn f<'a>() -> Alias<'a, ()> {}
+//~^ ERROR non-defining opaque type use in defining scope
+
+fn main() {}
+
+impl Trait<()> for () {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
new file mode 100644
index 000000000..8059621b6
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
@@ -0,0 +1,14 @@
+error: non-defining opaque type use in defining scope
+ --> $DIR/issue-68368-non-defining-use.rs:9:29
+ |
+LL | fn f<'a>() -> Alias<'a, ()> {}
+ | ^^
+ |
+note: used non-generic type `()` for generic parameter
+ --> $DIR/issue-68368-non-defining-use.rs:7:16
+ |
+LL | type Alias<'a, U> = impl Trait<U>;
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs
new file mode 100644
index 000000000..428454bc0
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs
@@ -0,0 +1,23 @@
+// Regression test for #69136
+
+#![feature(type_alias_impl_trait)]
+
+trait SomeTrait {}
+
+impl SomeTrait for () {}
+
+trait WithAssoc<A> {
+ type AssocType;
+}
+
+impl<T> WithAssoc<T> for () {
+ type AssocType = ();
+}
+
+type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
+//~^ ERROR use of undeclared lifetime name `'a`
+
+fn my_fun() -> Return<()> {}
+//~^ ERROR non-defining opaque type use in defining scope
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr
new file mode 100644
index 000000000..7b50c8af2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr
@@ -0,0 +1,31 @@
+error[E0261]: use of undeclared lifetime name `'a`
+ --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:65
+ |
+LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + '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 | type Return<A> = impl for<'a> WithAssoc<A, AssocType = impl SomeTrait + 'a>;
+ | +++++++
+help: consider introducing lifetime `'a` here
+ |
+LL | type Return<'a, A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
+ | +++
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:20:27
+ |
+LL | fn my_fun() -> Return<()> {}
+ | ^^
+ |
+note: used non-generic type `()` for generic parameter
+ --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:17:13
+ |
+LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
+ | ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0261`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs
new file mode 100644
index 000000000..a6916eda8
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs
@@ -0,0 +1,23 @@
+// Test-pass variant of #69136
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait SomeTrait {}
+
+impl SomeTrait for () {}
+
+trait WithAssoc {
+ type AssocType;
+}
+
+impl WithAssoc for () {
+ type AssocType = ();
+}
+
+type Return<'a> = impl WithAssoc<AssocType = impl Sized + 'a>;
+
+fn my_fun<'a>() -> Return<'a> {}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-69323.rs b/src/test/ui/type-alias-impl-trait/issue-69323.rs
new file mode 100644
index 000000000..a9bd6daf2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-69323.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+use std::iter::{once, Chain};
+
+fn test1<A: Iterator<Item = &'static str>>(x: A) -> Chain<A, impl Iterator<Item = &'static str>> {
+ x.chain(once(","))
+}
+
+type I<A> = Chain<A, impl Iterator<Item = &'static str>>;
+fn test2<A: Iterator<Item = &'static str>>(x: A) -> I<A> {
+ x.chain(once(","))
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-70121.rs b/src/test/ui/type-alias-impl-trait/issue-70121.rs
new file mode 100644
index 000000000..dff0d89d4
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-70121.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+pub type Successors<'a> = impl Iterator<Item = &'a ()>;
+
+pub fn f<'a>() -> Successors<'a> {
+ None.into_iter()
+}
+
+pub trait Tr {
+ type Item;
+}
+
+impl<'a> Tr for &'a () {
+ type Item = Successors<'a>;
+}
+
+pub fn kazusa<'a>() -> <&'a () as Tr>::Item {
+ None.into_iter()
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-72793.rs b/src/test/ui/type-alias-impl-trait/issue-72793.rs
new file mode 100644
index 000000000..828c87114
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-72793.rs
@@ -0,0 +1,25 @@
+// check-pass
+// compile-flags: -Zmir-opt-level=3
+
+#![feature(type_alias_impl_trait)]
+
+trait T { type Item; }
+
+type Alias<'a> = impl T<Item = &'a ()>;
+
+struct S;
+impl<'a> T for &'a S {
+ type Item = &'a ();
+}
+
+fn filter_positive<'a>() -> Alias<'a> {
+ &S
+}
+
+fn with_positive(fun: impl Fn(Alias<'_>)) {
+ fun(filter_positive());
+}
+
+fn main() {
+ with_positive(|_| ());
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-74244.rs b/src/test/ui/type-alias-impl-trait/issue-74244.rs
new file mode 100644
index 000000000..bb4104b3d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74244.rs
@@ -0,0 +1,20 @@
+#![feature(type_alias_impl_trait)]
+
+trait Allocator {
+ type Buffer;
+}
+
+struct DefaultAllocator;
+
+impl<T> Allocator for DefaultAllocator {
+ //~^ ERROR: the type parameter `T` is not constrained
+ type Buffer = ();
+}
+
+type A = impl Fn(<DefaultAllocator as Allocator>::Buffer);
+
+fn foo() -> A {
+ |_| ()
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-74244.stderr b/src/test/ui/type-alias-impl-trait/issue-74244.stderr
new file mode 100644
index 000000000..ff6bacd27
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74244.stderr
@@ -0,0 +1,9 @@
+error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-74244.rs:9:6
+ |
+LL | impl<T> Allocator for DefaultAllocator {
+ | ^ 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/type-alias-impl-trait/issue-74280.rs b/src/test/ui/type-alias-impl-trait/issue-74280.rs
new file mode 100644
index 000000000..ad641eaa0
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74280.rs
@@ -0,0 +1,12 @@
+// Regression test for #74280.
+
+#![feature(type_alias_impl_trait)]
+
+type Test = impl Copy;
+
+fn test() -> Test {
+ let y = || -> Test { () };
+ 7 //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.stderr b/src/test/ui/type-alias-impl-trait/issue-74280.stderr
new file mode 100644
index 000000000..5ed29e0ac
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74280.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-74280.rs:9:5
+ |
+LL | fn test() -> Test {
+ | ---- expected `_` because of return type
+LL | let y = || -> Test { () };
+LL | 7
+ | ^ expected `()`, found integer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.rs b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs
new file mode 100644
index 000000000..d26ca5c3e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+
+pub trait A {
+ type B;
+ fn f(&self) -> Self::B;
+}
+impl<'a, 'b> A for () {
+ //~^ ERROR the lifetime parameter `'a` is not constrained
+ //~| ERROR the lifetime parameter `'b` is not constrained
+ type B = impl core::fmt::Debug;
+
+ fn f(&self) -> Self::B {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
new file mode 100644
index 000000000..f15d0a069
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr
@@ -0,0 +1,15 @@
+error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-74761-2.rs:7:6
+ |
+LL | impl<'a, 'b> A for () {
+ | ^^ unconstrained lifetime parameter
+
+error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-74761-2.rs:7:10
+ |
+LL | impl<'a, 'b> A for () {
+ | ^^ unconstrained lifetime parameter
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.rs b/src/test/ui/type-alias-impl-trait/issue-74761.rs
new file mode 100644
index 000000000..d26ca5c3e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761.rs
@@ -0,0 +1,15 @@
+#![feature(type_alias_impl_trait)]
+
+pub trait A {
+ type B;
+ fn f(&self) -> Self::B;
+}
+impl<'a, 'b> A for () {
+ //~^ ERROR the lifetime parameter `'a` is not constrained
+ //~| ERROR the lifetime parameter `'b` is not constrained
+ type B = impl core::fmt::Debug;
+
+ fn f(&self) -> Self::B {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.stderr b/src/test/ui/type-alias-impl-trait/issue-74761.stderr
new file mode 100644
index 000000000..1d016fe07
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74761.stderr
@@ -0,0 +1,15 @@
+error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-74761.rs:7:6
+ |
+LL | impl<'a, 'b> A for () {
+ | ^^ unconstrained lifetime parameter
+
+error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/issue-74761.rs:7:10
+ |
+LL | impl<'a, 'b> A for () {
+ | ^^ unconstrained lifetime parameter
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
new file mode 100644
index 000000000..fb56cc54d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
@@ -0,0 +1,24 @@
+// Regression test for issue #76202
+// Tests that we don't ICE when we have a trait impl on a TAIT.
+
+#![feature(type_alias_impl_trait)]
+
+trait Dummy {}
+impl Dummy for () {}
+
+type F = impl Dummy;
+fn f() -> F {}
+
+trait Test {
+ fn test(self);
+}
+
+impl Test for F {
+ //~^ ERROR cannot implement trait
+ fn test(self) {}
+}
+
+fn main() {
+ let x: F = f();
+ x.test();
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr
new file mode 100644
index 000000000..2d4a6854a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.stderr
@@ -0,0 +1,14 @@
+error: cannot implement trait on type alias impl trait
+ --> $DIR/issue-76202-trait-impl-for-tait.rs:16:15
+ |
+LL | impl Test for F {
+ | ^
+ |
+note: type alias impl trait defined here
+ --> $DIR/issue-76202-trait-impl-for-tait.rs:9:10
+ |
+LL | type F = impl Dummy;
+ | ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.rs b/src/test/ui/type-alias-impl-trait/issue-77179.rs
new file mode 100644
index 000000000..8d818d4a3
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-77179.rs
@@ -0,0 +1,14 @@
+// Regression test for #77179.
+
+#![feature(type_alias_impl_trait)]
+
+type Pointer<T> = impl std::ops::Deref<Target=T>;
+
+fn test() -> Pointer<_> {
+ //~^ ERROR: the placeholder `_` is not allowed within types
+ Box::new(1)
+}
+
+fn main() {
+ test();
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.stderr b/src/test/ui/type-alias-impl-trait/issue-77179.stderr
new file mode 100644
index 000000000..053546e4b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-77179.stderr
@@ -0,0 +1,12 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+ --> $DIR/issue-77179.rs:7:22
+ |
+LL | fn test() -> Pointer<_> {
+ | --------^-
+ | | |
+ | | not allowed in type signatures
+ | help: replace with the correct return type: `Pointer<i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-78450.rs b/src/test/ui/type-alias-impl-trait/issue-78450.rs
new file mode 100644
index 000000000..fccbfb74f
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-78450.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+pub trait AssociatedImpl {
+ type ImplTrait;
+
+ fn f() -> Self::ImplTrait;
+}
+
+struct S<T>(T);
+
+trait Associated {
+ type A;
+}
+
+impl<'a, T: Associated<A = &'a ()>> AssociatedImpl for S<T> {
+ type ImplTrait = impl core::fmt::Debug;
+
+ fn f() -> Self::ImplTrait {
+ ()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
new file mode 100644
index 000000000..fa25d8f76
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
@@ -0,0 +1,23 @@
+// Regression test for issues #84660 and #86411: both are variations on #76202.
+// Tests that we don't ICE when we have an opaque type appearing anywhere in an impl header.
+
+#![feature(type_alias_impl_trait)]
+
+trait Foo {}
+impl Foo for () {}
+type Bar = impl Foo;
+fn _defining_use() -> Bar {}
+
+trait TraitArg<T> {
+ fn f();
+}
+
+impl TraitArg<Bar> for () { //~ ERROR cannot implement trait
+ fn f() {
+ println!("ho");
+ }
+}
+
+fn main() {
+ <() as TraitArg<Bar>>::f();
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr
new file mode 100644
index 000000000..bb70d07be
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.stderr
@@ -0,0 +1,14 @@
+error: cannot implement trait on type alias impl trait
+ --> $DIR/issue-84660-trait-impl-for-tait.rs:15:15
+ |
+LL | impl TraitArg<Bar> for () {
+ | ^^^
+ |
+note: type alias impl trait defined here
+ --> $DIR/issue-84660-trait-impl-for-tait.rs:8:12
+ |
+LL | type Bar = impl Foo;
+ | ^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
new file mode 100644
index 000000000..f12d1b6d9
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
@@ -0,0 +1,41 @@
+// Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an
+// impl header being accepted was used to create unsoundness.
+
+#![feature(type_alias_impl_trait)]
+
+trait Foo {}
+impl Foo for () {}
+type Bar = impl Foo;
+fn _defining_use() -> Bar {}
+
+trait Trait<T, In> {
+ type Out;
+ fn convert(i: In) -> Self::Out;
+}
+
+impl<In, Out> Trait<Bar, In> for Out { //~ ERROR cannot implement trait
+ type Out = Out;
+ fn convert(_i: In) -> Self::Out {
+ unreachable!();
+ }
+}
+
+impl<In, Out> Trait<(), In> for Out {
+ type Out = In;
+ fn convert(i: In) -> Self::Out {
+ i
+ }
+}
+
+fn transmute<In, Out>(i: In) -> Out {
+ <Out as Trait<Bar, In>>::convert(i)
+}
+
+fn main() {
+ let d;
+ {
+ let x = "Hello World".to_string();
+ d = transmute::<&String, &String>(&x);
+ }
+ println!("{}", d);
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr
new file mode 100644
index 000000000..f2d600fb4
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr
@@ -0,0 +1,14 @@
+error: cannot implement trait on type alias impl trait
+ --> $DIR/issue-84660-unsoundness.rs:16:21
+ |
+LL | impl<In, Out> Trait<Bar, In> for Out {
+ | ^^^
+ |
+note: type alias impl trait defined here
+ --> $DIR/issue-84660-unsoundness.rs:8:12
+ |
+LL | type Bar = impl Foo;
+ | ^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs b/src/test/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs
new file mode 100644
index 000000000..80a74eb63
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs
@@ -0,0 +1,73 @@
+// check-pass
+
+use std::error::Error as StdError;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+pub trait Stream {
+ type Item;
+ fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, None)
+ }
+}
+
+pub trait TryStream: Stream {
+ type Ok;
+ type Error;
+
+ fn try_poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Ok, Self::Error>>>;
+}
+
+impl<S, T, E> TryStream for S
+where
+ S: ?Sized + Stream<Item = Result<T, E>>,
+{
+ type Ok = T;
+ type Error = E;
+
+ fn try_poll_next(
+ self: Pin<&mut Self>,
+ cx: &mut Context<'_>,
+ ) -> Poll<Option<Result<Self::Ok, Self::Error>>> {
+ self.poll_next(cx)
+ }
+}
+
+pub trait ServerSentEvent: Sized + Send + Sync + 'static {}
+
+impl<T: Send + Sync + 'static> ServerSentEvent for T {}
+
+struct SseKeepAlive<S> {
+ event_stream: S,
+}
+
+struct SseComment<T>(T);
+
+impl<S> Stream for SseKeepAlive<S>
+where
+ S: TryStream + Send + 'static,
+ S::Ok: ServerSentEvent,
+ S::Error: StdError + Send + Sync + 'static,
+{
+ type Item = Result<SseComment<&'static str>, ()>;
+ fn poll_next(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Option<Self::Item>> {
+ unimplemented!()
+ }
+}
+
+pub fn keep<S>(
+ event_stream: S,
+) -> impl TryStream<Ok = impl ServerSentEvent + Send + 'static, Error = ()> + Send + 'static
+where
+ S: TryStream + Send + 'static,
+ S::Ok: ServerSentEvent + Send,
+ S::Error: StdError + Send + Sync + 'static,
+{
+ SseKeepAlive { event_stream }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.rs b/src/test/ui/type-alias-impl-trait/issue-89686.rs
new file mode 100644
index 000000000..de070fc9d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-89686.rs
@@ -0,0 +1,23 @@
+// edition:2018
+
+#![feature(type_alias_impl_trait)]
+
+use std::future::Future;
+
+type G<'a, T> = impl Future<Output = ()>;
+
+trait Trait {
+ type F: Future<Output = ()>;
+
+ fn f(&self) -> Self::F;
+
+ fn g<'a>(&'a self) -> G<'a, Self>
+ where
+ Self: Sized,
+ {
+ async move { self.f().await }
+ //~^ ERROR: the trait bound `T: Trait` is not satisfied
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.stderr b/src/test/ui/type-alias-impl-trait/issue-89686.stderr
new file mode 100644
index 000000000..b636ada8b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-89686.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `T: Trait` is not satisfied
+ --> $DIR/issue-89686.rs:18:9
+ |
+LL | async move { self.f().await }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
+ |
+help: consider restricting type parameter `T`
+ |
+LL | type G<'a, T: Trait> = impl Future<Output = ()>;
+ | +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-89952.rs b/src/test/ui/type-alias-impl-trait/issue-89952.rs
new file mode 100644
index 000000000..dc0f19c04
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-89952.rs
@@ -0,0 +1,31 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait SomeTrait {}
+impl SomeTrait for () {}
+
+trait MyFuture {
+ type Output;
+}
+impl<T> MyFuture for T {
+ type Output = T;
+}
+
+trait ReturnsFuture {
+ type Output: SomeTrait;
+ type Future: MyFuture<Output = Result<Self::Output, ()>>;
+ fn func() -> Self::Future;
+}
+
+struct Foo;
+
+impl ReturnsFuture for Foo {
+ type Output = impl SomeTrait;
+ type Future = impl MyFuture<Output = Result<Self::Output, ()>>;
+ fn func() -> Self::Future {
+ Result::<(), ()>::Err(())
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-1.rs b/src/test/ui/type-alias-impl-trait/issue-90400-1.rs
new file mode 100644
index 000000000..8550a3e86
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-90400-1.rs
@@ -0,0 +1,30 @@
+// Regression test for #90400,
+// taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836
+
+#![feature(generic_associated_types)]
+#![feature(type_alias_impl_trait)]
+
+trait Bar {
+ fn bar(&self);
+}
+
+trait Foo {
+ type FooFn<B>: FnOnce();
+
+ fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B>;
+}
+
+struct MyFoo;
+
+impl Foo for MyFoo {
+ type FooFn<B> = impl FnOnce();
+
+ fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B> {
+ move || bar.bar() //~ ERROR: the trait bound `B: Bar` is not satisfied
+ }
+}
+
+fn main() {
+ let boom: <MyFoo as Foo>::FooFn<u32> = unsafe { core::mem::zeroed() };
+ boom();
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr b/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr
new file mode 100644
index 000000000..428a10740
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-90400-1.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `B: Bar` is not satisfied
+ --> $DIR/issue-90400-1.rs:23:9
+ |
+LL | move || bar.bar()
+ | ^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B`
+ |
+note: required by a bound in `<MyFoo as Foo>::foo`
+ --> $DIR/issue-90400-1.rs:22:15
+ |
+LL | fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B> {
+ | ^^^ required by this bound in `<MyFoo as Foo>::foo`
+help: consider restricting type parameter `B`
+ |
+LL | type FooFn<B: Bar> = impl FnOnce();
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-2.rs b/src/test/ui/type-alias-impl-trait/issue-90400-2.rs
new file mode 100644
index 000000000..2b369bb8a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-90400-2.rs
@@ -0,0 +1,38 @@
+// Regression test for #90400,
+// taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836
+
+#![feature(generic_associated_types)]
+#![feature(type_alias_impl_trait)]
+
+trait Bar {
+ fn bar(&self);
+}
+
+trait Baz {
+ fn baz(&self);
+}
+
+trait Foo {
+ type FooFn<B>: Baz;
+
+ fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B>;
+}
+
+struct MyFoo;
+impl Foo for MyFoo {
+ type FooFn<B> = impl Baz;
+
+ fn foo<B: Bar>(&self, bar: B) -> Self::FooFn<B> {
+ MyBaz(bar) //~ ERROR: the trait bound `B: Bar` is not satisfied
+ }
+}
+
+struct MyBaz<B: Bar>(B);
+impl<B: Bar> Baz for MyBaz<B> {
+ fn baz(&self) {}
+}
+
+fn main() {
+ let boom: <MyFoo as Foo>::FooFn<u32> = unsafe { core::mem::zeroed() };
+ boom.baz();
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr b/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr
new file mode 100644
index 000000000..5da05a439
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-90400-2.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `B: Bar` is not satisfied
+ --> $DIR/issue-90400-2.rs:26:9
+ |
+LL | MyBaz(bar)
+ | ^^^^^^^^^^ the trait `Bar` is not implemented for `B`
+ |
+note: required because of the requirements on the impl of `Baz` for `MyBaz<B>`
+ --> $DIR/issue-90400-2.rs:31:14
+ |
+LL | impl<B: Bar> Baz for MyBaz<B> {
+ | ^^^ ^^^^^^^^
+help: consider restricting type parameter `B`
+ |
+LL | type FooFn<B: Bar> = impl Baz;
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-93411.rs b/src/test/ui/type-alias-impl-trait/issue-93411.rs
new file mode 100644
index 000000000..1f8c78926
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-93411.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+
+// this test used to stack overflow due to infinite recursion.
+// check-pass
+// compile-flags: --edition=2018
+
+use std::future::Future;
+
+fn main() {
+ let _ = move || async move {
+ let value = 0u8;
+ blah(&value).await;
+ };
+}
+
+type BlahFut<'a> = impl Future<Output = ()> + Send + 'a;
+fn blah<'a>(_value: &'a u8) -> BlahFut<'a> {
+ async {}
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-94429.rs b/src/test/ui/type-alias-impl-trait/issue-94429.rs
new file mode 100644
index 000000000..2c965b875
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-94429.rs
@@ -0,0 +1,23 @@
+#![feature(type_alias_impl_trait, generator_trait, generators)]
+use std::ops::Generator;
+
+trait Runnable {
+ type Gen: Generator<Yield = (), Return = ()>;
+
+ fn run(&mut self) -> Self::Gen;
+}
+
+struct Implementor {}
+
+impl Runnable for Implementor {
+ type Gen = impl Generator<Yield = (), Return = ()>;
+
+ fn run(&mut self) -> Self::Gen {
+ //~^ ERROR: type mismatch resolving
+ move || {
+ yield 1;
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-94429.stderr b/src/test/ui/type-alias-impl-trait/issue-94429.stderr
new file mode 100644
index 000000000..8d7f7a07b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-94429.stderr
@@ -0,0 +1,9 @@
+error[E0271]: type mismatch resolving `<[generator@$DIR/issue-94429.rs:17:9: 17:16] as Generator>::Yield == ()`
+ --> $DIR/issue-94429.rs:15:26
+ |
+LL | fn run(&mut self) -> Self::Gen {
+ | ^^^^^^^^^ expected integer, found `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-98604.rs b/src/test/ui/type-alias-impl-trait/issue-98604.rs
new file mode 100644
index 000000000..a4fd8a82a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-98604.rs
@@ -0,0 +1,13 @@
+// edition:2018
+
+type AsyncFnPtr = Box<
+ dyn Fn() -> std::pin::Pin<Box<dyn std::future::Future<Output = ()>>>,
+>;
+
+async fn test() {}
+
+#[allow(unused_must_use)]
+fn main() {
+ Box::new(test) as AsyncFnPtr;
+ //~^ ERROR type mismatch
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-98604.stderr b/src/test/ui/type-alias-impl-trait/issue-98604.stderr
new file mode 100644
index 000000000..f04d1b4d7
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-98604.stderr
@@ -0,0 +1,18 @@
+error[E0271]: type mismatch resolving `<fn() -> impl Future<Output = ()> {test} as FnOnce<()>>::Output == Pin<Box<(dyn Future<Output = ()> + 'static)>>`
+ --> $DIR/issue-98604.rs:11:5
+ |
+LL | Box::new(test) as AsyncFnPtr;
+ | ^^^^^^^^^^^^^^ expected struct `Pin`, found opaque type
+ |
+note: while checking the return type of the `async fn`
+ --> $DIR/issue-98604.rs:7:17
+ |
+LL | async fn test() {}
+ | ^ checked the `Output` of this `async fn`, found opaque type
+ = note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
+ found opaque type `impl Future<Output = ()>`
+ = note: required for the cast from `fn() -> impl Future<Output = ()> {test}` to the object type `dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-98608.rs b/src/test/ui/type-alias-impl-trait/issue-98608.rs
new file mode 100644
index 000000000..d75762a8b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-98608.rs
@@ -0,0 +1,9 @@
+fn hi() -> impl Sized { std::ptr::null::<u8>() }
+
+fn main() {
+ let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
+ //~^ ERROR type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>`
+ let boxed = b();
+ let null = *boxed;
+ println!("{null:?}");
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-98608.stderr b/src/test/ui/type-alias-impl-trait/issue-98608.stderr
new file mode 100644
index 000000000..8f3ec7d9d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-98608.stderr
@@ -0,0 +1,16 @@
+error[E0271]: type mismatch resolving `<fn() -> impl Sized {hi} as FnOnce<()>>::Output == Box<u8>`
+ --> $DIR/issue-98608.rs:4:39
+ |
+LL | fn hi() -> impl Sized { std::ptr::null::<u8>() }
+ | ---------- the found opaque type
+...
+LL | let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
+ | ^^^^^^^^^^^^ expected struct `Box`, found opaque type
+ |
+ = note: expected struct `Box<u8>`
+ found opaque type `impl Sized`
+ = note: required for the cast from `fn() -> impl Sized {hi}` to the object type `dyn Fn() -> Box<u8>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs
new file mode 100644
index 000000000..b887fcf30
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs
@@ -0,0 +1,13 @@
+// https://github.com/rust-lang/rust/issues/73481
+// This test used to cause unsoundness, since one of the two possible
+// resolutions was chosen at random instead of erroring due to conflicts.
+
+#![feature(type_alias_impl_trait)]
+
+type Y<A, B> = impl std::fmt::Debug;
+
+fn g<A, B>() -> (Y<A, B>, Y<B, A>) {
+ (42_i64, 60) //~ ERROR concrete type differs from previous defining opaque type use
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr
new file mode 100644
index 000000000..278117009
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr
@@ -0,0 +1,11 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/multiple-def-uses-in-one-fn-infer.rs:10:5
+ |
+LL | (42_i64, 60)
+ | ^^^^^^^^^^^^
+ | |
+ | expected `i64`, got `i32`
+ | this expression supplies two conflicting concrete types for the same opaque type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs
new file mode 100644
index 000000000..3f122f106
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs
@@ -0,0 +1,9 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo<'a, 'b> = impl std::fmt::Debug;
+
+fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
+ (i, i) //~ ERROR concrete type differs from previous
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr
new file mode 100644
index 000000000..81e603e23
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr
@@ -0,0 +1,11 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/multiple-def-uses-in-one-fn-lifetimes.rs:6:5
+ |
+LL | (i, i)
+ | ^^^^^^
+ | |
+ | expected `&'a i32`, got `&'b i32`
+ | this expression supplies two conflicting concrete types for the same opaque type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs
new file mode 100644
index 000000000..83fd9a1da
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs
@@ -0,0 +1,21 @@
+// check-pass
+#![feature(type_alias_impl_trait)]
+
+type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
+
+fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
+ (a.clone(), a)
+}
+
+type Foo<'a, 'b> = impl std::fmt::Debug;
+
+fn foo<'x, 'y>(i: &'x i32, j: &'y i32) -> (Foo<'x, 'y>, Foo<'y, 'x>) {
+ (i, j)
+}
+
+fn main() {
+ println!("{}", <X<_, _> as ToString>::to_string(&f(42_i32, String::new()).1));
+ let meh = 42;
+ let muh = 69;
+ println!("{:?}", foo(&meh, &muh));
+}
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
new file mode 100644
index 000000000..da845e861
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
@@ -0,0 +1,16 @@
+// https://github.com/rust-lang/rust/issues/73481
+// This test used to cause unsoundness, since one of the two possible
+// resolutions was chosen at random instead of erroring due to conflicts.
+
+#![feature(type_alias_impl_trait)]
+
+type X<A, B> = impl Into<&'static A>;
+
+fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
+ //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied
+ (a, a)
+}
+
+fn main() {
+ println!("{}", <X<_, _> as Into<&String>>::into(f(&[1isize, 2, 3], String::new()).1));
+}
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
new file mode 100644
index 000000000..cdaae99e2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `&'static B: From<&A>` is not satisfied
+ --> $DIR/multiple-def-uses-in-one-fn.rs:9:45
+ |
+LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) {
+ | ^^^^^^^^^^^^^^^^^^ the trait `From<&A>` is not implemented for `&'static B`
+ |
+ = note: required because of the requirements on the impl of `Into<&'static B>` for `&A`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+ |
+LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> {
+ | ++++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
new file mode 100644
index 000000000..14510a529
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
@@ -0,0 +1,16 @@
+// https://github.com/rust-lang/rust/issues/73481
+// This test used to cause unsoundness, since one of the two possible
+// resolutions was chosen at random instead of erroring due to conflicts.
+
+#![feature(type_alias_impl_trait)]
+
+type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
+
+fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+ (a.clone(), a)
+ //~^ ERROR concrete type differs from previous defining opaque type
+}
+
+fn main() {
+ println!("{}", <X<_, _> as ToString>::to_string(&f(42_i32, String::new()).1));
+}
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
new file mode 100644
index 000000000..0f752212a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
@@ -0,0 +1,11 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/multiple-def-uses-in-one-fn2.rs:10:5
+ |
+LL | (a.clone(), a)
+ | ^^^^^^^^^^^^^^
+ | |
+ | expected `A`, got `B`
+ | this expression supplies two conflicting concrete types for the same opaque type
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
new file mode 100644
index 000000000..11a922443
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
@@ -0,0 +1,18 @@
+// https://github.com/rust-lang/rust/issues/73481
+// This test used to cause unsoundness, since one of the two possible
+// resolutions was chosen at random instead of erroring due to conflicts.
+
+#![feature(type_alias_impl_trait)]
+
+type X<A: ToString + Clone, B: ToString + Clone> = impl ToString;
+
+fn f<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<B, A>) {
+ (a, b)
+}
+
+fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
+ (a, b)
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
new file mode 100644
index 000000000..bbe709dcc
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+ --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9
+ |
+LL | fn g<A: ToString + Clone, B: ToString + Clone>(a: A, b: B) -> (X<A, B>, X<A, B>) {
+ | - - found type parameter
+ | |
+ | expected type parameter
+LL | (a, b)
+ | ^ expected type parameter `A`, found type parameter `B`
+ |
+ = note: expected type parameter `A`
+ found type parameter `B`
+ = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+ = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/multiple_definitions.rs b/src/test/ui/type-alias-impl-trait/multiple_definitions.rs
new file mode 100644
index 000000000..9e6268e63
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/multiple_definitions.rs
@@ -0,0 +1,30 @@
+// check-pass
+
+use std::marker::PhantomData;
+
+pub struct ConcreteError {}
+pub trait IoBase {}
+struct X {}
+impl IoBase for X {}
+
+pub struct ClusterIterator<B, E, S = B> {
+ pub fat: B,
+ phantom_s: PhantomData<S>,
+ phantom_e: PhantomData<E>,
+}
+
+pub struct FileSystem<IO: IoBase> {
+ pub disk: IO,
+}
+
+impl<IO: IoBase> FileSystem<IO> {
+ pub fn cluster_iter(&self) -> ClusterIterator<impl IoBase + '_, ConcreteError> {
+ ClusterIterator {
+ fat: X {},
+ phantom_s: PhantomData::default(),
+ phantom_e: PhantomData::default(),
+ }
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs
new file mode 100644
index 000000000..822489716
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+use std::fmt::Debug;
+
+type FooX = impl Debug;
+
+trait Foo<A> { }
+
+impl Foo<()> for () { }
+
+fn foo() -> impl Foo<FooX> {
+ //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
+ // FIXME(type-alias-impl-trait): We could probably make this work.
+ ()
+}
+
+fn main() { }
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr
new file mode 100644
index 000000000..62db019ed
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
+ --> $DIR/nested-tait-inference.rs:12:13
+ |
+LL | fn foo() -> impl Foo<FooX> {
+ | ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
+...
+LL | ()
+ | -- return type was inferred to be `()` here
+ |
+ = help: the trait `Foo<()>` is implemented for `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs
new file mode 100644
index 000000000..0d7f5bad2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+use std::fmt::Debug;
+
+type FooX = impl Debug;
+
+trait Foo<A> {}
+
+impl Foo<()> for () {}
+impl Foo<u32> for () {}
+
+fn foo() -> impl Foo<FooX> {
+ //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
+ ()
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
new file mode 100644
index 000000000..f4d96038d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
+ --> $DIR/nested-tait-inference2.rs:13:13
+ |
+LL | fn foo() -> impl Foo<FooX> {
+ | ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
+LL |
+LL | ()
+ | -- return type was inferred to be `()` here
+ |
+ = help: the following other types implement trait `Foo<A>`:
+ <() as Foo<()>>
+ <() as Foo<u32>>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs
new file mode 100644
index 000000000..ebf3a99bb
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.rs
@@ -0,0 +1,17 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+use std::fmt::Debug;
+
+type FooX = impl Debug;
+
+trait Foo<A> { }
+
+impl Foo<FooX> for () { }
+//~^ cannot implement trait on type alias impl trait
+
+fn foo() -> impl Foo<FooX> {
+ ()
+}
+
+fn main() { }
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr
new file mode 100644
index 000000000..4a3fb1673
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference3.stderr
@@ -0,0 +1,14 @@
+error: cannot implement trait on type alias impl trait
+ --> $DIR/nested-tait-inference3.rs:10:10
+ |
+LL | impl Foo<FooX> for () { }
+ | ^^^^
+ |
+note: type alias impl trait defined here
+ --> $DIR/nested-tait-inference3.rs:6:13
+ |
+LL | type FooX = impl Debug;
+ | ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/nested.rs b/src/test/ui/type-alias-impl-trait/nested.rs
new file mode 100644
index 000000000..6b866be7d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested.rs
@@ -0,0 +1,17 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl std::fmt::Debug;
+type Bar = impl Trait<Foo>;
+
+trait Trait<T> {}
+
+impl<T, U> Trait<T> for U {}
+
+fn bar() -> Bar {
+ 42
+}
+
+fn main() {
+ println!("{:?}", bar());
+ //~^ ERROR `Bar` doesn't implement `Debug`
+}
diff --git a/src/test/ui/type-alias-impl-trait/nested.stderr b/src/test/ui/type-alias-impl-trait/nested.stderr
new file mode 100644
index 000000000..732af5c0b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested.stderr
@@ -0,0 +1,12 @@
+error[E0277]: `Bar` doesn't implement `Debug`
+ --> $DIR/nested.rs:15:22
+ |
+LL | println!("{:?}", bar());
+ | ^^^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = help: the trait `Debug` is not implemented for `Bar`
+ = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs
new file mode 100644
index 000000000..60b6e1aac
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs
@@ -0,0 +1,20 @@
+#![feature(type_alias_impl_trait)]
+
+mod my_mod {
+ use std::fmt::Debug;
+
+ pub type Foo = impl Debug;
+ pub type Foot = impl Debug;
+
+ pub fn get_foo() -> Foo {
+ 5i32
+ }
+
+ pub fn get_foot() -> Foot {
+ get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type
+ }
+}
+
+fn main() {
+ let _: my_mod::Foot = my_mod::get_foot();
+}
diff --git a/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr
new file mode 100644
index 000000000..fa6ecf68d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr
@@ -0,0 +1,19 @@
+error: opaque type's hidden type cannot be another opaque type from the same scope
+ --> $DIR/nested_type_alias_impl_trait.rs:14:9
+ |
+LL | get_foo()
+ | ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
+ |
+note: opaque type whose hidden type is being assigned
+ --> $DIR/nested_type_alias_impl_trait.rs:7:21
+ |
+LL | pub type Foot = impl Debug;
+ | ^^^^^^^^^^
+note: opaque type being used as hidden type
+ --> $DIR/nested_type_alias_impl_trait.rs:6:20
+ |
+LL | pub type Foo = impl Debug;
+ | ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs
new file mode 100644
index 000000000..fed5ac07c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/never_reveal_concrete_type.rs
@@ -0,0 +1,14 @@
+#![feature(type_alias_impl_trait)]
+// check-pass
+fn main() {}
+
+type NoReveal = impl std::fmt::Debug;
+
+fn define_no_reveal() -> NoReveal {
+ ""
+}
+
+fn no_reveal(x: NoReveal) {
+ let _: &'static str = x;
+ let _ = x as &'static str;
+}
diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
new file mode 100644
index 000000000..46621362e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
@@ -0,0 +1,19 @@
+// Issue 52985: user code provides no use case that allows a type alias `impl Trait`
+// We now emit a 'unconstrained opaque type' error
+
+#![feature(type_alias_impl_trait)]
+
+mod foo {
+ pub type Foo = impl Copy;
+ //~^ ERROR unconstrained opaque type
+
+ // make compiler happy about using 'Foo'
+ pub fn bar(x: Foo) -> Foo {
+ x
+ }
+}
+
+fn main() {
+ let _: foo::Foo = std::mem::transmute(0u8);
+ //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
+}
diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr
new file mode 100644
index 000000000..337708b87
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr
@@ -0,0 +1,20 @@
+error: unconstrained opaque type
+ --> $DIR/no_inferrable_concrete_type.rs:7:20
+ |
+LL | pub type Foo = impl Copy;
+ | ^^^^^^^^^
+ |
+ = note: `Foo` must be used in combination with a concrete type within the same module
+
+error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
+ --> $DIR/no_inferrable_concrete_type.rs:17:23
+ |
+LL | let _: foo::Foo = std::mem::transmute(0u8);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: source type: `u8` (8 bits)
+ = note: target type: `Foo` (size can vary because of [type error])
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0512`.
diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs
new file mode 100644
index 000000000..61153b1e1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs
@@ -0,0 +1,24 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+mod boo {
+ pub type Boo = impl ::std::fmt::Debug;
+ fn bomp() -> Boo {
+ ""
+ }
+}
+
+// We don't actually know the type here.
+
+fn bomp2() {
+ let _: &str = bomp(); //~ ERROR mismatched types
+}
+
+fn bomp() -> boo::Boo {
+ "" //~ ERROR mismatched types
+}
+
+fn bomp_loop() -> boo::Boo {
+ loop {}
+}
diff --git a/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr
new file mode 100644
index 000000000..ae03a5b3e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr
@@ -0,0 +1,31 @@
+error[E0308]: mismatched types
+ --> $DIR/no_revealing_outside_defining_module.rs:15:19
+ |
+LL | pub type Boo = impl ::std::fmt::Debug;
+ | ---------------------- the found opaque type
+...
+LL | let _: &str = bomp();
+ | ---- ^^^^^^ expected `&str`, found opaque type
+ | |
+ | expected due to this
+ |
+ = note: expected reference `&str`
+ found opaque type `Boo`
+
+error[E0308]: mismatched types
+ --> $DIR/no_revealing_outside_defining_module.rs:19:5
+ |
+LL | pub type Boo = impl ::std::fmt::Debug;
+ | ---------------------- the expected opaque type
+...
+LL | fn bomp() -> boo::Boo {
+ | -------- expected `Boo` because of return type
+LL | ""
+ | ^^ expected opaque type, found `&str`
+ |
+ = note: expected opaque type `Boo`
+ found reference `&'static str`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
new file mode 100644
index 000000000..fa47d13f5
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.rs
@@ -0,0 +1,36 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+type Two<T, U> = impl Debug;
+
+fn three<T: Debug, U>(t: T) -> Two<T, U> {
+ (t, 5i8)
+ //~^ ERROR `T` doesn't implement `Debug`
+}
+
+trait Bar {
+ type Blub: Debug;
+ const FOO: Self::Blub;
+}
+
+impl Bar for u32 {
+ type Blub = i32;
+ const FOO: i32 = 42;
+}
+
+fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
+ (t, <U as Bar>::FOO)
+ //~^ ERROR `U: Bar` is not satisfied
+ //~| ERROR `T` doesn't implement `Debug`
+}
+
+fn is_sync<T: Sync>() {}
+
+fn asdfl() {
+ //FIXME(oli-obk): these currently cause cycle errors
+ //is_sync::<Two<i32, u32>>();
+ //is_sync::<Two<i32, *const i32>>();
+}
diff --git a/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
new file mode 100644
index 000000000..a5ac38c38
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/not_a_defining_use.stderr
@@ -0,0 +1,38 @@
+error[E0277]: `T` doesn't implement `Debug`
+ --> $DIR/not_a_defining_use.rs:10:5
+ |
+LL | (t, 5i8)
+ | ^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(T, i8)`
+help: consider restricting type parameter `T`
+ |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+ | +++++++++++++++++
+
+error[E0277]: the trait bound `U: Bar` is not satisfied
+ --> $DIR/not_a_defining_use.rs:25:5
+ |
+LL | (t, <U as Bar>::FOO)
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `U`
+ |
+help: consider restricting type parameter `U`
+ |
+LL | type Two<T, U: Bar> = impl Debug;
+ | +++++
+
+error[E0277]: `T` doesn't implement `Debug`
+ --> $DIR/not_a_defining_use.rs:25:5
+ |
+LL | (t, <U as Bar>::FOO)
+ | ^^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required because of the requirements on the impl of `Debug` for `(T, _)`
+help: consider restricting type parameter `T`
+ |
+LL | type Two<T: std::fmt::Debug, U> = impl Debug;
+ | +++++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/not_well_formed.rs b/src/test/ui/type-alias-impl-trait/not_well_formed.rs
new file mode 100644
index 000000000..fbb7a4d58
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/not_well_formed.rs
@@ -0,0 +1,17 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+trait TraitWithAssoc {
+ type Assoc;
+}
+
+type Foo<V> = impl Trait<V::Assoc>; //~ associated type `Assoc` not found for `V`
+
+trait Trait<U> {}
+
+impl<W> Trait<W> for () {}
+
+fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T> {
+ ()
+}
diff --git a/src/test/ui/type-alias-impl-trait/not_well_formed.stderr b/src/test/ui/type-alias-impl-trait/not_well_formed.stderr
new file mode 100644
index 000000000..c36b95f47
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/not_well_formed.stderr
@@ -0,0 +1,9 @@
+error[E0220]: associated type `Assoc` not found for `V`
+ --> $DIR/not_well_formed.rs:9:29
+ |
+LL | type Foo<V> = impl Trait<V::Assoc>;
+ | ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/src/test/ui/type-alias-impl-trait/reveal_local.rs b/src/test/ui/type-alias-impl-trait/reveal_local.rs
new file mode 100644
index 000000000..7ecb55353
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/reveal_local.rs
@@ -0,0 +1,25 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+//~^ ERROR cycle detected
+
+fn is_send<T: Send>() { }
+
+fn not_good() {
+ // Error: this function does not constrain `Foo` to any particular
+ // hidden type, so it cannot rely on `Send` being true.
+ is_send::<Foo>();
+}
+
+fn not_gooder() {
+ // Constrain `Foo = u32`
+ let x: Foo = 22_u32;
+
+ // while we could know this from the hidden type, it would
+ // need extra roundabout logic to support it.
+ is_send::<Foo>();
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/reveal_local.stderr b/src/test/ui/type-alias-impl-trait/reveal_local.stderr
new file mode 100644
index 000000000..27fded333
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/reveal_local.stderr
@@ -0,0 +1,28 @@
+error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
+ --> $DIR/reveal_local.rs:5:12
+ |
+LL | type Foo = impl Debug;
+ | ^^^^^^^^^^
+ |
+note: ...which requires type-checking `not_good`...
+ --> $DIR/reveal_local.rs:13:5
+ |
+LL | is_send::<Foo>();
+ | ^^^^^^^^^^^^^^
+ = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Send`...
+ = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in top-level module
+ --> $DIR/reveal_local.rs:1:1
+ |
+LL | / #![feature(type_alias_impl_trait)]
+LL | |
+LL | | use std::fmt::Debug;
+LL | |
+... |
+LL | |
+LL | | fn main() {}
+ | |____________^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/type-alias-impl-trait/self-referential-2.rs b/src/test/ui/type-alias-impl-trait/self-referential-2.rs
new file mode 100644
index 000000000..8781196c3
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/self-referential-2.rs
@@ -0,0 +1,10 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl std::fmt::Debug;
+type Bar = impl PartialEq<Foo>;
+
+fn bar() -> Bar {
+ 42_i32 //~^ ERROR can't compare `i32` with `Foo`
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/self-referential-2.stderr b/src/test/ui/type-alias-impl-trait/self-referential-2.stderr
new file mode 100644
index 000000000..2b505d307
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/self-referential-2.stderr
@@ -0,0 +1,23 @@
+error[E0277]: can't compare `i32` with `Foo`
+ --> $DIR/self-referential-2.rs:6:13
+ |
+LL | fn bar() -> Bar {
+ | ^^^ no implementation for `i32 == Foo`
+LL | 42_i32
+ | ------ return type was inferred to be `i32` here
+ |
+ = help: the trait `PartialEq<Foo>` is not implemented for `i32`
+ = help: the following other types implement trait `PartialEq<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/self-referential-3.rs b/src/test/ui/type-alias-impl-trait/self-referential-3.rs
new file mode 100644
index 000000000..d40715717
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/self-referential-3.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![feature(type_alias_impl_trait)]
+
+type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug;
+
+fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
+ i
+}
+
+fn main() {
+ let meh = 42;
+ let muh = 42;
+ assert_eq!(bar(&meh), bar(&muh));
+}
diff --git a/src/test/ui/type-alias-impl-trait/self-referential-4.rs b/src/test/ui/type-alias-impl-trait/self-referential-4.rs
new file mode 100644
index 000000000..36742c8ad
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/self-referential-4.rs
@@ -0,0 +1,25 @@
+#![feature(type_alias_impl_trait)]
+
+type Bar<'a, 'b> = impl PartialEq<Bar<'b, 'static>> + std::fmt::Debug;
+
+fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
+ i //~^ ERROR can't compare `&i32` with `Bar<'b, 'static>`
+}
+
+type Foo<'a, 'b> = impl PartialEq<Foo<'static, 'b>> + std::fmt::Debug;
+
+fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
+ i //~^ ERROR can't compare `&i32` with `Foo<'static, 'b>`
+}
+
+type Moo<'a, 'b> = impl PartialEq<Moo<'static, 'a>> + std::fmt::Debug;
+
+fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
+ i //~^ ERROR can't compare `&i32` with `Moo<'static, 'a>`
+}
+
+fn main() {
+ let meh = 42;
+ let muh = 69;
+ assert_eq!(bar(&meh), bar(&meh));
+}
diff --git a/src/test/ui/type-alias-impl-trait/self-referential-4.stderr b/src/test/ui/type-alias-impl-trait/self-referential-4.stderr
new file mode 100644
index 000000000..27880f792
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/self-referential-4.stderr
@@ -0,0 +1,63 @@
+error[E0277]: can't compare `&i32` with `Bar<'b, 'static>`
+ --> $DIR/self-referential-4.rs:5:31
+ |
+LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
+ | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'static>`
+LL | i
+ | - return type was inferred to be `&i32` here
+ |
+ = help: the trait `PartialEq<Bar<'b, 'static>>` is not implemented for `&i32`
+ = help: the following other types implement trait `PartialEq<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+
+error[E0277]: can't compare `&i32` with `Foo<'static, 'b>`
+ --> $DIR/self-referential-4.rs:11:31
+ |
+LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
+ | ^^^^^^^^^^^ no implementation for `&i32 == Foo<'static, 'b>`
+LL | i
+ | - return type was inferred to be `&i32` here
+ |
+ = help: the trait `PartialEq<Foo<'static, 'b>>` is not implemented for `&i32`
+ = help: the following other types implement trait `PartialEq<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+
+error[E0277]: can't compare `&i32` with `Moo<'static, 'a>`
+ --> $DIR/self-referential-4.rs:17:31
+ |
+LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
+ | ^^^^^^^^^^^ no implementation for `&i32 == Moo<'static, 'a>`
+LL | i
+ | - return type was inferred to be `&i32` here
+ |
+ = help: the trait `PartialEq<Moo<'static, 'a>>` is not implemented for `&i32`
+ = help: the following other types implement trait `PartialEq<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/self-referential.rs b/src/test/ui/type-alias-impl-trait/self-referential.rs
new file mode 100644
index 000000000..3ff5406a3
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/self-referential.rs
@@ -0,0 +1,28 @@
+#![feature(type_alias_impl_trait)]
+
+type Bar<'a, 'b> = impl PartialEq<Bar<'b, 'a>> + std::fmt::Debug;
+
+fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
+ //~^ ERROR can't compare `&i32` with `Bar<'b, 'a>`
+ i
+}
+
+type Foo<'a, 'b> = (i32, impl PartialEq<Foo<'a, 'b>> + std::fmt::Debug);
+
+fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
+ //~^ ERROR can't compare `&i32` with `(i32, &i32)`
+ (42, i)
+}
+
+type Moo<'a, 'b> = (i32, impl PartialEq<Moo<'b, 'a>> + std::fmt::Debug);
+
+fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
+ //~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
+ (42, i)
+}
+
+fn main() {
+ let meh = 42;
+ let muh = 69;
+ assert_eq!(bar(&meh), bar(&meh));
+}
diff --git a/src/test/ui/type-alias-impl-trait/self-referential.stderr b/src/test/ui/type-alias-impl-trait/self-referential.stderr
new file mode 100644
index 000000000..97d510f68
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/self-referential.stderr
@@ -0,0 +1,66 @@
+error[E0277]: can't compare `&i32` with `Bar<'b, 'a>`
+ --> $DIR/self-referential.rs:5:31
+ |
+LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
+ | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'b, 'a>`
+LL |
+LL | i
+ | - return type was inferred to be `&i32` here
+ |
+ = help: the trait `PartialEq<Bar<'b, 'a>>` is not implemented for `&i32`
+ = help: the following other types implement trait `PartialEq<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+
+error[E0277]: can't compare `&i32` with `(i32, &i32)`
+ --> $DIR/self-referential.rs:12:31
+ |
+LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
+ | ^^^^^^^^^^^ no implementation for `&i32 == (i32, &i32)`
+LL |
+LL | (42, i)
+ | ------- return type was inferred to be `(i32, &i32)` here
+ |
+ = help: the trait `PartialEq<(i32, &i32)>` is not implemented for `&i32`
+ = help: the following other types implement trait `PartialEq<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+
+error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
+ --> $DIR/self-referential.rs:19:31
+ |
+LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
+ | ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0})`
+LL |
+LL | (42, i)
+ | ------- return type was inferred to be `(i32, &i32)` here
+ |
+ = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0})>` is not implemented for `&i32`
+ = help: the following other types implement trait `PartialEq<Rhs>`:
+ f32
+ f64
+ i128
+ i16
+ i32
+ i64
+ i8
+ isize
+ and 6 others
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/static-const-types.rs b/src/test/ui/type-alias-impl-trait/static-const-types.rs
new file mode 100644
index 000000000..748a279e4
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/static-const-types.rs
@@ -0,0 +1,13 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// check-pass
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+
+static FOO1: Foo = 22_u32;
+const FOO2: Foo = 22_u32;
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs
new file mode 100644
index 000000000..c2ab6a9d1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.rs
@@ -0,0 +1,20 @@
+#![feature(type_alias_impl_trait)]
+
+type Bar = impl Send;
+
+// While i32 is structural-match, we do not want to leak this information.
+// (See https://github.com/rust-lang/rust/issues/72156)
+const fn leak_free() -> Bar {
+ 7i32
+}
+const LEAK_FREE: Bar = leak_free();
+
+fn leak_free_test() {
+ match LEAK_FREE {
+ LEAK_FREE => (),
+ //~^ `Bar` cannot be used in patterns
+ _ => (),
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr
new file mode 100644
index 000000000..dbc183f54
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/structural-match-no-leak.stderr
@@ -0,0 +1,8 @@
+error: `Bar` cannot be used in patterns
+ --> $DIR/structural-match-no-leak.rs:14:9
+ |
+LL | LEAK_FREE => (),
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/structural-match.rs b/src/test/ui/type-alias-impl-trait/structural-match.rs
new file mode 100644
index 000000000..7cc9ccaab
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/structural-match.rs
@@ -0,0 +1,21 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Send;
+
+// This is not structural-match
+struct A;
+
+const fn value() -> Foo {
+ A
+}
+const VALUE: Foo = value();
+
+fn test() {
+ match VALUE {
+ VALUE => (),
+ //~^ `Foo` cannot be used in patterns
+ _ => (),
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/structural-match.stderr b/src/test/ui/type-alias-impl-trait/structural-match.stderr
new file mode 100644
index 000000000..61287f268
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/structural-match.stderr
@@ -0,0 +1,8 @@
+error: `Foo` cannot be used in patterns
+ --> $DIR/structural-match.rs:15:9
+ |
+LL | VALUE => (),
+ | ^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs
new file mode 100644
index 000000000..f6a830296
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+type Foo = Box<dyn Iterator<Item = impl Send>>;
+
+fn make_foo() -> Foo {
+ Box::new(vec![1, 2, 3].into_iter())
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs
new file mode 100644
index 000000000..fddecfcac
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+type Foo = impl Iterator<Item = impl Send>;
+
+fn make_foo() -> Foo {
+ vec![1, 2].into_iter()
+}
+
+type Bar = impl Send;
+type Baz = impl Iterator<Item = Bar>;
+
+fn make_baz() -> Baz {
+ vec!["1", "2"].into_iter()
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
new file mode 100644
index 000000000..5630e036b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
@@ -0,0 +1,11 @@
+#![feature(type_alias_impl_trait)]
+// check-pass
+// Ensures that `const` items can constrain an opaque `impl Trait`.
+
+use std::fmt::Debug;
+
+pub type Foo = impl Debug;
+
+const _FOO: Foo = 5;
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs
new file mode 100644
index 000000000..857066c78
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs
@@ -0,0 +1,13 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// FIXME: this is ruled out for now but should work
+
+type Foo = fn() -> impl Send;
+//~^ ERROR: `impl Trait` only allowed in function and inherent method return types
+
+fn make_foo() -> Foo {
+ || 15
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr
new file mode 100644
index 000000000..a31cf1a51
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr
@@ -0,0 +1,9 @@
+error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
+ --> $DIR/type-alias-impl-trait-fn-type.rs:6:20
+ |
+LL | type Foo = fn() -> impl Send;
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0562`.
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs
new file mode 100644
index 000000000..07c891f06
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+// Regression test for issue #61863
+
+pub trait MyTrait {}
+
+#[derive(Debug)]
+pub struct MyStruct {
+ v: u64,
+}
+
+impl MyTrait for MyStruct {}
+
+pub fn bla() -> TE {
+ return MyStruct { v: 1 };
+}
+
+pub fn bla2() -> TE {
+ bla()
+}
+
+type TE = impl MyTrait;
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs
new file mode 100644
index 000000000..c5e8068e5
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+type A = impl Sized;
+fn f1() -> A {
+ 0
+}
+
+type B = impl ?Sized;
+fn f2() -> &'static B {
+ &[0]
+}
+
+type C = impl ?Sized + 'static;
+fn f3() -> &'static C {
+ &[0]
+}
+
+type D = impl ?Sized;
+fn f4() -> &'static D {
+ &1
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs
new file mode 100644
index 000000000..1a4064055
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+type Foo = Vec<impl Send>;
+
+fn make_foo() -> Foo {
+ vec![true, false]
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs
new file mode 100644
index 000000000..1f2d0e47e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs
@@ -0,0 +1,30 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+pub trait MyTrait {}
+
+impl MyTrait for bool {}
+
+type Foo = impl MyTrait;
+
+struct Blah {
+ my_foo: Foo,
+ my_u8: u8,
+}
+
+impl Blah {
+ fn new() -> Blah {
+ Blah { my_foo: make_foo(), my_u8: 12 }
+ }
+ fn into_inner(self) -> (Foo, u8, Foo) {
+ (self.my_foo, self.my_u8, make_foo())
+ }
+}
+
+fn make_foo() -> Foo {
+ true
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs
new file mode 100644
index 000000000..efbf4f1e3
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs
@@ -0,0 +1,18 @@
+// regression test for #74018
+
+#![feature(type_alias_impl_trait)]
+
+trait Trait {
+ type Associated;
+ fn into(self) -> Self::Associated;
+}
+
+impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) {
+ //~^ ERROR the lifetime parameter `'a` is not constrained
+ type Associated = (i32, impl Iterator<Item = i32>);
+ fn into(self) -> Self::Associated {
+ (0_i32, [0_i32].iter().copied())
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr
new file mode 100644
index 000000000..8cdce2f8e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr
@@ -0,0 +1,9 @@
+error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
+ --> $DIR/type-alias-impl-trait-unconstrained-lifetime.rs:10:6
+ |
+LL | impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) {
+ | ^^ unconstrained lifetime parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0207`.
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs
new file mode 100644
index 000000000..e5e7fb677
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs
@@ -0,0 +1,12 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Fn() -> Foo;
+//~^ ERROR: unconstrained opaque type
+
+fn crash(x: Foo) -> Foo {
+ x
+}
+
+fn main() {
+
+}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr
new file mode 100644
index 000000000..a770eeac3
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:12
+ |
+LL | type Foo = impl Fn() -> Foo;
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: `Foo` 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/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs
new file mode 100644
index 000000000..7c7a1b405
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs
@@ -0,0 +1,14 @@
+#![feature(type_alias_impl_trait)]
+
+pub trait Bar<T> {
+ type Item;
+}
+
+type Foo = impl Bar<Foo, Item = Foo>;
+//~^ ERROR: unconstrained opaque type
+
+fn crash(x: Foo) -> Foo {
+ x
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr
new file mode 100644
index 000000000..3f3699ce5
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:12
+ |
+LL | type Foo = impl Bar<Foo, Item = Foo>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `Foo` 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/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs
new file mode 100644
index 000000000..8ca279eec
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs
@@ -0,0 +1,14 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl 'static;
+//~^ ERROR: at least one trait must be specified
+
+fn foo() -> Foo {
+ "foo"
+}
+
+fn bar() -> impl 'static { //~ ERROR: at least one trait must be specified
+ "foo"
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr
new file mode 100644
index 000000000..3f7acd338
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr
@@ -0,0 +1,14 @@
+error: at least one trait must be specified
+ --> $DIR/type-alias-impl-trait-with-no-traits.rs:3:12
+ |
+LL | type Foo = impl 'static;
+ | ^^^^^^^^^^^^
+
+error: at least one trait must be specified
+ --> $DIR/type-alias-impl-trait-with-no-traits.rs:10:13
+ |
+LL | fn bar() -> impl 'static {
+ | ^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs
new file mode 100644
index 000000000..70c2ee427
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs
@@ -0,0 +1,79 @@
+// check-pass
+
+#![allow(dead_code)]
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+ assert_eq!(foo().to_string(), "foo");
+ assert_eq!(bar1().to_string(), "bar1");
+ assert_eq!(bar2().to_string(), "bar2");
+ let mut x = bar1();
+ x = bar2();
+ assert_eq!(my_iter(42u8).collect::<Vec<u8>>(), vec![42u8]);
+}
+
+// single definition
+type Foo = impl std::fmt::Display;
+
+fn foo() -> Foo {
+ "foo"
+}
+
+// two definitions
+type Bar = impl std::fmt::Display;
+
+fn bar1() -> Bar {
+ "bar1"
+}
+
+fn bar2() -> Bar {
+ "bar2"
+}
+
+type MyIter<T> = impl Iterator<Item = T>;
+
+fn my_iter<T>(t: T) -> MyIter<T> {
+ std::iter::once(t)
+}
+
+fn my_iter2<T>(t: T) -> MyIter<T> {
+ std::iter::once(t)
+}
+
+// param names should not have an effect!
+fn my_iter3<U>(u: U) -> MyIter<U> {
+ std::iter::once(u)
+}
+
+// param position should not have an effect!
+fn my_iter4<U, V>(_: U, v: V) -> MyIter<V> {
+ std::iter::once(v)
+}
+
+// param names should not have an effect!
+type MyOtherIter<T> = impl Iterator<Item = T>;
+
+fn my_other_iter<U>(u: U) -> MyOtherIter<U> {
+ std::iter::once(u)
+}
+
+trait Trait {}
+type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a;
+
+fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> {
+ t
+}
+
+mod pass_through {
+ pub type Passthrough<T: 'static> = impl Sized + 'static;
+
+ fn define_passthrough<T: 'static>(t: T) -> Passthrough<T> {
+ t
+ }
+}
+
+fn use_passthrough(x: pass_through::Passthrough<u32>) -> pass_through::Passthrough<u32> {
+ x
+}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs
new file mode 100644
index 000000000..67f56bcde
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait2.rs
@@ -0,0 +1,84 @@
+// check-pass
+
+#![allow(dead_code)]
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+ assert_eq!(foo().to_string(), "foo");
+ assert_eq!(bar1().to_string(), "bar1");
+ assert_eq!(bar2().to_string(), "bar2");
+ let mut x = bar1();
+ x = bar2();
+ assert_eq!(my_iter(42u8).collect::<Vec<u8>>(), vec![42u8]);
+}
+
+use defining_use_scope::*;
+
+mod defining_use_scope {
+ // single definition
+ pub type Foo = impl std::fmt::Display;
+
+ pub fn foo() -> Foo {
+ "foo"
+ }
+
+ // two definitions
+ pub type Bar = impl std::fmt::Display;
+
+ pub fn bar1() -> Bar {
+ "bar1"
+ }
+
+ pub fn bar2() -> Bar {
+ "bar2"
+ }
+
+ pub type MyIter<T> = impl Iterator<Item = T>;
+
+ pub fn my_iter<T>(t: T) -> MyIter<T> {
+ std::iter::once(t)
+ }
+
+ fn my_iter2<T>(t: T) -> MyIter<T> {
+ std::iter::once(t)
+ }
+
+ // param names should not have an effect!
+ fn my_iter3<U>(u: U) -> MyIter<U> {
+ std::iter::once(u)
+ }
+
+ // param position should not have an effect!
+ fn my_iter4<U, V>(_: U, v: V) -> MyIter<V> {
+ std::iter::once(v)
+ }
+
+ // param names should not have an effect!
+ type MyOtherIter<T> = impl Iterator<Item = T>;
+
+ fn my_other_iter<U>(u: U) -> MyOtherIter<U> {
+ std::iter::once(u)
+ }
+
+ trait Trait {}
+ type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a;
+
+ fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> {
+ t
+ }
+
+ mod pass_through {
+ pub type Passthrough<T: 'static> = impl Sized + 'static;
+
+ fn define_passthrough<T: 'static>(t: T) -> Passthrough<T> {
+ t
+ }
+ }
+
+ fn use_passthrough(x: pass_through::Passthrough<u32>) -> pass_through::Passthrough<u32> {
+ x
+ }
+
+}
diff --git a/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs
new file mode 100644
index 000000000..fd954801d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+#![feature(type_alias_impl_trait)]
+
+use std::iter::{once, Chain};
+
+type I<A> = Chain<A, impl Iterator<Item = &'static str>>;
+fn test2<A: Iterator<Item = &'static str>>(x: A) -> I<A> {
+ x.chain(once("5"))
+}
+
+fn main() {
+ assert_eq!(vec!["1", "3", "5"], test2(["1", "3"].iter().cloned()).collect::<Vec<_>>());
+}
diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let.rs b/src/test/ui/type-alias-impl-trait/type_of_a_let.rs
new file mode 100644
index 000000000..4e9d1788b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type_of_a_let.rs
@@ -0,0 +1,22 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+
+fn foo1() -> u32 {
+ let x: Foo = 22_u32;
+ x
+}
+
+fn foo2() -> u32 {
+ let x: Foo = 22_u32;
+ let y: Foo = x;
+ same_type((x, y)); //~ ERROR use of moved value
+ y //~ ERROR use of moved value
+}
+
+fn same_type<T>(x: (T, T)) {}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr b/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr
new file mode 100644
index 000000000..1dabe4586
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr
@@ -0,0 +1,23 @@
+error[E0382]: use of moved value: `x`
+ --> $DIR/type_of_a_let.rs:16:16
+ |
+LL | let x: Foo = 22_u32;
+ | - move occurs because `x` has type `Foo`, which does not implement the `Copy` trait
+LL | let y: Foo = x;
+ | - value moved here
+LL | same_type((x, y));
+ | ^ value used here after move
+
+error[E0382]: use of moved value: `y`
+ --> $DIR/type_of_a_let.rs:17:5
+ |
+LL | let y: Foo = x;
+ | - move occurs because `y` has type `Foo`, which does not implement the `Copy` trait
+LL | same_type((x, y));
+ | - value moved here
+LL | y
+ | ^ value used here after move
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_generic.rs b/src/test/ui/type-alias-impl-trait/underconstrained_generic.rs
new file mode 100644
index 000000000..aa537dfc9
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_generic.rs
@@ -0,0 +1,28 @@
+#![feature(type_alias_impl_trait)]
+
+use std::marker::PhantomData;
+
+trait Trait {
+ fn foo<T, U>(t: T) -> U;
+}
+
+trait ProofForConversion<X> {
+ fn convert<T, U>(_: PhantomData<Self>, r: T) -> U;
+}
+
+impl<X: Trait> ProofForConversion<X> for () {
+ fn convert<T, U>(_: PhantomData<Self>, r: T) -> U {
+ X::foo(r)
+ }
+}
+
+type Converter<T> = impl ProofForConversion<T>;
+
+fn _defining_use<T: Trait>() -> Converter<T> {
+ ()
+ //~^ ERROR the trait bound `T: Trait` is not satisfied
+}
+
+
+fn main() {
+}
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
new file mode 100644
index 000000000..e70916573
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Trait` is not satisfied
+ --> $DIR/underconstrained_generic.rs:22:5
+ |
+LL | ()
+ | ^^ the trait `Trait` is not implemented for `T`
+ |
+note: required because of the requirements on the impl of `ProofForConversion<T>` for `()`
+ --> $DIR/underconstrained_generic.rs:13:16
+ |
+LL | impl<X: Trait> ProofForConversion<X> for () {
+ | ^^^^^^^^^^^^^^^^^^^^^ ^^
+help: consider restricting type parameter `T`
+ |
+LL | type Converter<T: Trait> = impl ProofForConversion<T>;
+ | +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs
new file mode 100644
index 000000000..c5b2e8a1c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs
@@ -0,0 +1,34 @@
+#![feature(type_alias_impl_trait)]
+
+use std::marker::PhantomData;
+
+trait ProofForConversion<'a, 'b> {
+ fn convert<T: ?Sized>(_: PhantomData<Self>, r: &'a T) -> &'b T;
+}
+
+impl<'a, 'b> ProofForConversion<'a, 'b> for &'b &'a () {
+ fn convert<T: ?Sized>(_: PhantomData<Self>, r: &'a T) -> &'b T {
+ r
+ }
+}
+
+type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
+//~^ ERROR reference has a longer lifetime than the data it references
+
+// Even _defining_use with an explicit `'a: 'b` compiles fine, too.
+fn _defining_use<'a, 'b>(x: &'b &'a ()) -> Converter<'a, 'b> {
+ x
+}
+
+fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+ Converter::<'a, 'b>::convert(PhantomData, x)
+}
+
+fn main() {
+ let d;
+ {
+ let x = "Hello World".to_string();
+ d = extend_lifetime(&x);
+ }
+ println!("{}", d);
+}
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr
new file mode 100644
index 000000000..12d85a49d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr
@@ -0,0 +1,20 @@
+error[E0491]: in type `&'b &'a ()`, reference has a longer lifetime than the data it references
+ --> $DIR/underconstrained_lifetime.rs:15:26
+ |
+LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the pointer is valid for the lifetime `'b` as defined here
+ --> $DIR/underconstrained_lifetime.rs:15:20
+ |
+LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
+ | ^^
+note: but the referenced data is only valid for the lifetime `'a` as defined here
+ --> $DIR/underconstrained_lifetime.rs:15:16
+ |
+LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/src/test/ui/type-alias-impl-trait/unused_generic_param.rs b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs
new file mode 100644
index 000000000..ad5e4918c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/unused_generic_param.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+fn main() {}
+
+type PartiallyDefined<T> = impl Sized;
+
+fn partially_defined<T: std::fmt::Debug>(_: T) -> PartiallyDefined<T> {
+ 4u32
+}
+
+type PartiallyDefined2<T> = impl Sized;
+
+fn partially_defined2<T: std::fmt::Debug>(_: T) -> PartiallyDefined2<T> {
+ 4u32
+}
+
+fn partially_defined22<T>(_: T) -> PartiallyDefined2<T> {
+ 4u32
+}
diff --git a/src/test/ui/type-alias-impl-trait/weird-return-types.rs b/src/test/ui/type-alias-impl-trait/weird-return-types.rs
new file mode 100644
index 000000000..faad5ee95
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/weird-return-types.rs
@@ -0,0 +1,16 @@
+// edition:2018
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+use std::future::Future;
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+
+fn f() -> impl Future<Output = Foo> {
+ async move { 22_u32 }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/wf-check-fn-def.rs b/src/test/ui/type-alias-impl-trait/wf-check-fn-def.rs
new file mode 100644
index 000000000..449e9fbd0
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/wf-check-fn-def.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+
+trait Bar {
+ fn bar(&self);
+}
+
+type FooFn<B> = impl FnOnce(B);
+
+fn foo<B: Bar>() -> FooFn<B> {
+ fn mop<B: Bar>(bar: B) { bar.bar() }
+ mop // NOTE: no function pointer, but function zst item
+ //~^ ERROR the trait bound `B: Bar` is not satisfied
+}
+
+fn main() {
+ let boom: FooFn<u32> = unsafe { core::mem::zeroed() };
+ boom(42);
+}
diff --git a/src/test/ui/type-alias-impl-trait/wf-check-fn-def.stderr b/src/test/ui/type-alias-impl-trait/wf-check-fn-def.stderr
new file mode 100644
index 000000000..e0005489d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/wf-check-fn-def.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `B: Bar` is not satisfied
+ --> $DIR/wf-check-fn-def.rs:11:5
+ |
+LL | mop // NOTE: no function pointer, but function zst item
+ | ^^^ the trait `Bar` is not implemented for `B`
+ |
+note: required by a bound in `mop`
+ --> $DIR/wf-check-fn-def.rs:10:15
+ |
+LL | fn mop<B: Bar>(bar: B) { bar.bar() }
+ | ^^^ required by this bound in `mop`
+help: consider restricting type parameter `B`
+ |
+LL | type FooFn<B: Bar> = impl FnOnce(B);
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs b/src/test/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs
new file mode 100644
index 000000000..3b8470e4a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs
@@ -0,0 +1,23 @@
+#![feature(type_alias_impl_trait)]
+
+// build-pass
+
+trait Bar {
+ fn bar(&self);
+}
+
+type FooFn<B> = impl FnOnce(B);
+
+fn foo<B: Bar>() -> FooFn<B> {
+ fn mop<B: Bar>(bar: B) { bar.bar() }
+ mop as fn(B)
+ // function pointers don't have any obligations on them,
+ // thus the above compiles. It's obviously unsound to just
+ // procure a `FooFn` from the ether without making sure that
+ // the pointer is actually legal for all `B`
+}
+
+fn main() {
+ let boom: FooFn<u32> = unsafe { core::mem::zeroed() };
+ boom(42);
+}
diff --git a/src/test/ui/type-alias-impl-trait/wf_check_closures.rs b/src/test/ui/type-alias-impl-trait/wf_check_closures.rs
new file mode 100644
index 000000000..2c70696ff
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/wf_check_closures.rs
@@ -0,0 +1,17 @@
+#![feature(type_alias_impl_trait)]
+
+trait Bar {
+ fn bar(&self);
+}
+
+type FooFn<B> = impl FnOnce();
+
+fn foo<B: Bar>(bar: B) -> FooFn<B> {
+ move || { bar.bar() }
+ //~^ ERROR the trait bound `B: Bar` is not satisfied
+}
+
+fn main() {
+ let boom: FooFn<u32> = unsafe { core::mem::zeroed() };
+ boom();
+}
diff --git a/src/test/ui/type-alias-impl-trait/wf_check_closures.stderr b/src/test/ui/type-alias-impl-trait/wf_check_closures.stderr
new file mode 100644
index 000000000..58ae8617b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/wf_check_closures.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `B: Bar` is not satisfied
+ --> $DIR/wf_check_closures.rs:10:5
+ |
+LL | move || { bar.bar() }
+ | ^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B`
+ |
+note: required by a bound in `foo`
+ --> $DIR/wf_check_closures.rs:9:11
+ |
+LL | fn foo<B: Bar>(bar: B) -> FooFn<B> {
+ | ^^^ required by this bound in `foo`
+help: consider restricting type parameter `B`
+ |
+LL | type FooFn<B: Bar> = impl FnOnce();
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.