summaryrefslogtreecommitdiffstats
path: root/tests/ui/type-alias-impl-trait
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/type-alias-impl-trait')
-rw-r--r--tests/ui/type-alias-impl-trait/argument-types.rs26
-rw-r--r--tests/ui/type-alias-impl-trait/assoc-projection-ice.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/assoc-type-const.rs32
-rw-r--r--tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs26
-rw-r--r--tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/assoc-type-lifetime.rs26
-rw-r--r--tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs26
-rw-r--r--tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr26
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/auxiliary/coherence_cross_crate_trait_decl.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/bound_reduction.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/bound_reduction2.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/bound_reduction2.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/bounds-are-checked.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/closure_args.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/closure_args2.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/closure_parent_substs.rs65
-rw-r--r--tests/ui/type-alias-impl-trait/closure_wf_outlives.rs65
-rw-r--r--tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr64
-rw-r--r--tests/ui/type-alias-impl-trait/closures_in_branches.rs31
-rw-r--r--tests/ui/type-alias-impl-trait/closures_in_branches.stderr25
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/coherence.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_cross_crate.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr13
-rw-r--r--tests/ui/type-alias-impl-trait/coherence_generalization.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/collect_hidden_types.rs22
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_inputs.rs33
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_inputs.stderr58
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs31
-rw-r--r--tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/cross_crate_ice.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/cross_crate_ice2.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/cross_inference.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/cross_inference_rpit.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/declared_but_never_defined.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr25
-rw-r--r--tests/ui/type-alias-impl-trait/defining-use-submodule.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/destructuring.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs44
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/fallback.rs28
-rw-r--r--tests/ui/type-alias-impl-trait/fallback.stderr17
-rw-r--r--tests/ui/type-alias-impl-trait/field-types.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/future.rs22
-rw-r--r--tests/ui/type-alias-impl-trait/future.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs33
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr38
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr25
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr51
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr39
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr27
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr62
-rw-r--r--tests/ui/type-alias-impl-trait/generic_lifetime_param.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_nondefining_use.rs28
-rw-r--r--tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr30
-rw-r--r--tests/ui/type-alias-impl-trait/generic_not_used.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/generic_not_used.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr30
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained2.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr35
-rw-r--r--tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs33
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr30
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds.rs51
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds2.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds3.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds_closure.rs31
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds_closure.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs51
-rw-r--r--tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs27
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs43
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr58
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs38
-rw-r--r--tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/incomplete-inference.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/incomplete-inference.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/inference-cycle.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/inference-cycle.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/issue-101750.rs37
-rw-r--r--tests/ui/type-alias-impl-trait/issue-104817.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/issue-104817.stock.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-52843.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-52843.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092-2.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092-2.stderr46
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53096.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53096.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53598.rs27
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53598.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs26
-rw-r--r--tests/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/issue-57611-trait-alias.rs26
-rw-r--r--tests/ui/type-alias-impl-trait/issue-57700.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/issue-57700.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/issue-57807-associated-type.rs31
-rw-r--r--tests/ui/type-alias-impl-trait/issue-57961.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/issue-57961.stderr20
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs39
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58662-simplified.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58887.rs22
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58951-2.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58951.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60371.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60371.stderr21
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60407.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60407.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60564-working.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60564.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60564.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60662.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/issue-60662.stdout14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs38
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63279.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63279.stderr48
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63355.rs46
-rw-r--r--tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/issue-65384.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-65384.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/issue-65918.rs51
-rw-r--r--tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs33
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr29
-rw-r--r--tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/issue-69323.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/issue-70121.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/issue-72793.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74244.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74244.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74280.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74280.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74761-2.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74761-2.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74761.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74761.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs31
-rw-r--r--tests/ui/type-alias-impl-trait/issue-77179.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-77179.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-78450.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs41
-rw-r--r--tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs73
-rw-r--r--tests/ui/type-alias-impl-trait/issue-89686.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/issue-89686.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-89952.rs31
-rw-r--r--tests/ui/type-alias-impl-trait/issue-90400-1.rs29
-rw-r--r--tests/ui/type-alias-impl-trait/issue-90400-1.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/issue-90400-2.rs37
-rw-r--r--tests/ui/type-alias-impl-trait/issue-90400-2.stderr21
-rw-r--r--tests/ui/type-alias-impl-trait/issue-93411.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/issue-94429.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/issue-94429.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs92
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98604.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98604.stderr18
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98608.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98608.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs7
-rw-r--r--tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr18
-rw-r--r--tests/ui/type-alias-impl-trait/multiple_definitions.rs30
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference2.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference3.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/nested.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/nested.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr31
-rw-r--r--tests/ui/type-alias-impl-trait/not_a_defining_use.rs36
-rw-r--r--tests/ui/type-alias-impl-trait/not_a_defining_use.stderr38
-rw-r--r--tests/ui/type-alias-impl-trait/not_well_formed.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/not_well_formed.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/outlives-bound-var.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/reveal_local.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/reveal_local.stderr28
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-2.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-2.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-3.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-4.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential-4.stderr36
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.rs28
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.stderr39
-rw-r--r--tests/ui/type-alias-impl-trait/self_implication.rs38
-rw-r--r--tests/ui/type-alias-impl-trait/static-const-types.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match-no-leak.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match.rs21
-rw-r--r--tests/ui/type-alias-impl-trait/structural-match.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs13
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs26
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs25
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs30
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs12
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr10
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs79
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs84
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/type_of_a_let.rs22
-rw-r--r--tests/ui/type-alias-impl-trait/type_of_a_let.stderr23
-rw-r--r--tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs14
-rw-r--r--tests/ui/type-alias-impl-trait/underconstrained_generic.rs28
-rw-r--r--tests/ui/type-alias-impl-trait/underconstrained_generic.stderr21
-rw-r--r--tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs34
-rw-r--r--tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr20
-rw-r--r--tests/ui/type-alias-impl-trait/unnameable_type.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/unnameable_type.stderr31
-rw-r--r--tests/ui/type-alias-impl-trait/unused_generic_param.rs22
-rw-r--r--tests/ui/type-alias-impl-trait/weird-return-types.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/wf-check-fn-def.rs18
-rw-r--r--tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/wf_check_closures.rs17
-rw-r--r--tests/ui/type-alias-impl-trait/wf_check_closures.stderr19
314 files changed, 6648 insertions, 0 deletions
diff --git a/tests/ui/type-alias-impl-trait/argument-types.rs b/tests/ui/type-alias-impl-trait/argument-types.rs
new file mode 100644
index 000000000..185207b98
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs b/tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
new file mode 100644
index 000000000..703e3e869
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/assoc-type-const.rs b/tests/ui/type-alias-impl-trait/assoc-type-const.rs
new file mode 100644
index 000000000..0ade36daf
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs
new file mode 100644
index 000000000..3f34b00ec
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr
new file mode 100644
index 000000000..e594dc577
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/assoc-type-lifetime.rs b/tests/ui/type-alias-impl-trait/assoc-type-lifetime.rs
new file mode 100644
index 000000000..39f785d8c
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs b/tests/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs
new file mode 100644
index 000000000..42f07d49f
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs
new file mode 100644
index 000000000..962606508
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs
@@ -0,0 +1,20 @@
+//check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait Trait {
+ type Opaque1;
+ type Opaque2;
+ fn constrain(self);
+}
+
+impl<'a> Trait for &'a () {
+ type Opaque1 = impl Sized;
+ type Opaque2 = impl Sized + 'a;
+ fn constrain(self) {
+ let _: Self::Opaque1 = ();
+ let _: Self::Opaque2 = self;
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage.rs
new file mode 100644
index 000000000..a1584581e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs
new file mode 100644
index 000000000..fc89b0e87
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
new file mode 100644
index 000000000..d7247302d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs
new file mode 100644
index 000000000..5fb7a9473
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr
new file mode 100644
index 000000000..1e9a45aac
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/auxiliary/coherence_cross_crate_trait_decl.rs b/tests/ui/type-alias-impl-trait/auxiliary/coherence_cross_crate_trait_decl.rs
new file mode 100644
index 000000000..712ed5543
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/auxiliary/coherence_cross_crate_trait_decl.rs
@@ -0,0 +1,9 @@
+pub trait SomeTrait {}
+
+impl SomeTrait for () {}
+
+// Adding this `impl` would cause errors in this crate's dependent,
+// so it would be a breaking change. We explicitly don't add this impl,
+// as the dependent crate already assumes this impl exists and thus already
+// does not compile.
+//impl SomeTrait for i32 {}
diff --git a/tests/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs b/tests/ui/type-alias-impl-trait/auxiliary/collect_hidden_types.rs
new file mode 100644
index 000000000..75d20a6fe
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs b/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
new file mode 100644
index 000000000..e7bca2231
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs b/tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs
new file mode 100644
index 000000000..119f7df1f
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs b/tests/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs
new file mode 100644
index 000000000..52802dd8f
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/bound_reduction.rs b/tests/ui/type-alias-impl-trait/bound_reduction.rs
new file mode 100644
index 000000000..b9b50f0b7
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/bound_reduction2.rs b/tests/ui/type-alias-impl-trait/bound_reduction2.rs
new file mode 100644
index 000000000..0bcc9e002
--- /dev/null
+++ b/tests/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 expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
+}
diff --git a/tests/ui/type-alias-impl-trait/bound_reduction2.stderr b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr
new file mode 100644
index 000000000..3c259bd9e
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/bound_reduction2.stderr
@@ -0,0 +1,12 @@
+error[E0792]: expected generic type parameter, found `<T as TraitWithAssoc>::Assoc`
+ --> $DIR/bound_reduction2.rs:16:5
+ |
+LL | type Foo<V> = impl Trait<V>;
+ | - this generic parameter must be used with a generic type parameter
+...
+LL | ()
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.rs
new file mode 100644
index 000000000..55b4dc8dc
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked-2.stderr
new file mode 100644
index 000000000..8678e9b33
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/bounds-are-checked.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked.rs
new file mode 100644
index 000000000..83d22161e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr
new file mode 100644
index 000000000..920eef11d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/closure_args.rs b/tests/ui/type-alias-impl-trait/closure_args.rs
new file mode 100644
index 000000000..c5e7af81d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/closure_args.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+// regression test for https://github.com/rust-lang/rust/issues/100800
+
+#![feature(type_alias_impl_trait)]
+
+trait Anything {}
+impl<T> Anything for T {}
+type Input = impl Anything;
+fn run<F: FnOnce(Input) -> ()>(f: F, i: Input) {
+ f(i);
+}
+
+fn main() {
+ run(|x: u32| {println!("{x}");}, 0);
+}
diff --git a/tests/ui/type-alias-impl-trait/closure_args2.rs b/tests/ui/type-alias-impl-trait/closure_args2.rs
new file mode 100644
index 000000000..82386c280
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/closure_args2.rs
@@ -0,0 +1,23 @@
+// run-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait Foo {
+ // This was reachable in https://github.com/rust-lang/rust/issues/100800
+ fn foo(&self) { unreachable!() }
+}
+impl<T> Foo for T {}
+
+struct B;
+impl B {
+ fn foo(&self) {}
+}
+
+type Input = impl Foo;
+fn run1<F: FnOnce(Input)>(f: F, i: Input) {f(i)}
+fn run2<F: FnOnce(B)>(f: F, i: B) {f(i)}
+
+fn main() {
+ run1(|x: B| {x.foo()}, B);
+ run2(|x: B| {x.foo()}, B);
+}
diff --git a/tests/ui/type-alias-impl-trait/closure_parent_substs.rs b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs
new file mode 100644
index 000000000..475f4724f
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs
@@ -0,0 +1,65 @@
+// When WF checking the hidden type in the ParamEnv of the opaque type,
+// one complication arises when the hidden type is a closure/generator:
+// the "parent_substs" of the type may reference lifetime parameters
+// not present in the opaque type.
+// These region parameters are not really useful in this check.
+// So here we ignore them and replace them with fresh region variables.
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// Basic test
+mod test1 {
+ // Hidden type = Closure['_#0r]
+ type Opaque = impl Sized;
+
+ fn define<'a: 'a>() -> Opaque {
+ || {}
+ }
+}
+
+// the region vars cannot both be equal to `'static` or `'empty`
+mod test2 {
+ trait Trait {}
+
+ // Hidden type = Closure['a, '_#0r, '_#1r]
+ // Constraints = [('_#0r: 'a), ('a: '_#1r)]
+ type Opaque<'a>
+ where
+ &'a (): Trait,
+ = impl Sized + 'a;
+
+ fn define<'a, 'x, 'y>() -> Opaque<'a>
+ where
+ &'a (): Trait,
+ 'x: 'a,
+ 'a: 'y,
+ {
+ || {}
+ }
+}
+
+// the region var cannot be equal to `'a` or `'b`
+mod test3 {
+ trait Trait {}
+
+ // Hidden type = Closure['a, 'b, '_#0r]
+ // Constraints = [('_#0r: 'a), ('_#0r: 'b)]
+ type Opaque<'a, 'b>
+ where
+ (&'a (), &'b ()): Trait,
+ = impl Sized + 'a + 'b;
+
+ fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+ where
+ (&'a (), &'b ()): Trait,
+ 'x: 'a,
+ 'x: 'b,
+ {
+ || {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs b/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs
new file mode 100644
index 000000000..53974dbb3
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/closure_wf_outlives.rs
@@ -0,0 +1,65 @@
+// If the hidden type is a closure, we require the "outlives" bounds that appear on the
+// defining site to also appear on the opaque type.
+//
+// It's not clear if this is the desired behavior but at least
+// it's consistent and has no back-compat risk.
+
+// check-fail
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// requires `'a: 'b` bound
+mod test1 {
+ type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ //~^ ERROR lifetime bound not satisfied
+
+ fn define<'a, 'b>() -> Opaque<'a, 'b>
+ where
+ 'a: 'b,
+ {
+ || {}
+ }
+}
+
+// Same as the above but through indirection `'x`
+mod test2 {
+ type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ //~^ ERROR cannot infer an appropriate lifetime
+
+ fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+ where
+ 'a: 'x,
+ 'x: 'b,
+ {
+ || {}
+ }
+}
+
+// fixed version of the above
+mod test2_fixed {
+ type Opaque<'a: 'b, 'b> = impl Sized + 'a + 'b;
+
+ fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+ where
+ 'a: 'x,
+ 'x: 'b,
+ {
+ || {}
+ }
+}
+
+// requires `T: 'static`
+mod test3 {
+ type Opaque<T> = impl Sized;
+ //~^ ERROR the parameter type `T` may not live long enough
+
+ fn define<T>() -> Opaque<T>
+ where
+ T: 'static,
+ {
+ || {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr b/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr
new file mode 100644
index 000000000..ae6462bb6
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/closure_wf_outlives.stderr
@@ -0,0 +1,64 @@
+error[E0478]: lifetime bound not satisfied
+ --> $DIR/closure_wf_outlives.rs:14:27
+ |
+LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+ --> $DIR/closure_wf_outlives.rs:14:17
+ |
+LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ | ^^
+note: but lifetime parameter must outlive the lifetime `'b` as defined here
+ --> $DIR/closure_wf_outlives.rs:14:21
+ |
+LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ | ^^
+
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+ --> $DIR/closure_wf_outlives.rs:27:27
+ |
+LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
+ --> $DIR/closure_wf_outlives.rs:27:17
+ |
+LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ | ^^
+note: ...so that the declared lifetime parameter bounds are satisfied
+ --> $DIR/closure_wf_outlives.rs:27:27
+ |
+LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ | ^^^^^^^^^^^^^^^^^^^^
+note: but, the lifetime must be valid for the lifetime `'b` as defined here...
+ --> $DIR/closure_wf_outlives.rs:27:21
+ |
+LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ | ^^
+note: ...so that the declared lifetime parameter bounds are satisfied
+ --> $DIR/closure_wf_outlives.rs:27:27
+ |
+LL | type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/closure_wf_outlives.rs:54:22
+ |
+LL | type Opaque<T> = impl Sized;
+ | ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+ |
+note: ...that is required by this bound
+ --> $DIR/closure_wf_outlives.rs:59:12
+ |
+LL | T: 'static,
+ | ^^^^^^^
+help: consider adding an explicit lifetime bound...
+ |
+LL | type Opaque<T: 'static> = impl Sized;
+ | +++++++++
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0310, E0478, E0495.
+For more information about an error, try `rustc --explain E0310`.
diff --git a/tests/ui/type-alias-impl-trait/closures_in_branches.rs b/tests/ui/type-alias-impl-trait/closures_in_branches.rs
new file mode 100644
index 000000000..7bb490bbe
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/closures_in_branches.stderr b/tests/ui/type-alias-impl-trait/closures_in_branches.stderr
new file mode 100644
index 000000000..9cc15f14a
--- /dev/null
+++ b/tests/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: /* Type */| 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: /* Type */| x.len()
+ | ++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/type-alias-impl-trait/coherence.rs b/tests/ui/type-alias-impl-trait/coherence.rs
new file mode 100644
index 000000000..077a31494
--- /dev/null
+++ b/tests/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 only traits defined in the current crate can be implemented for arbitrary types
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/coherence.stderr b/tests/ui/type-alias-impl-trait/coherence.stderr
new file mode 100644
index 000000000..00b0dbbb5
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/coherence.stderr
@@ -0,0 +1,14 @@
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+ --> $DIR/coherence.rs:14:1
+ |
+LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------
+ | | |
+ | | type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate
+ | impl doesn't use only types from inside the current crate
+ |
+ = note: define and implement a trait or new type instead
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0117`.
diff --git a/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs b/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs
new file mode 100644
index 000000000..a63e0a1ee
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/coherence_cross_crate.rs
@@ -0,0 +1,24 @@
+// aux-build: coherence_cross_crate_trait_decl.rs
+// This test ensures that adding an `impl SomeTrait for i32` within
+// `coherence_cross_crate_trait_decl` is not a breaking change, by
+// making sure that even without such an impl this test fails to compile.
+
+#![feature(type_alias_impl_trait)]
+
+extern crate coherence_cross_crate_trait_decl;
+
+use coherence_cross_crate_trait_decl::SomeTrait;
+
+trait OtherTrait {}
+
+type Alias = impl SomeTrait;
+
+fn constrain() -> Alias {
+ ()
+}
+
+impl OtherTrait for Alias {}
+impl OtherTrait for i32 {}
+//~^ ERROR: conflicting implementations of trait `OtherTrait` for type `Alias`
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr b/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr
new file mode 100644
index 000000000..63a3ce29c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/coherence_cross_crate.stderr
@@ -0,0 +1,13 @@
+error[E0119]: conflicting implementations of trait `OtherTrait` for type `Alias`
+ --> $DIR/coherence_cross_crate.rs:21:1
+ |
+LL | impl OtherTrait for Alias {}
+ | ------------------------- first implementation here
+LL | impl OtherTrait for i32 {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Alias`
+ |
+ = note: upstream crates may add a new impl of trait `coherence_cross_crate_trait_decl::SomeTrait` for type `i32` in future versions
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/type-alias-impl-trait/coherence_generalization.rs b/tests/ui/type-alias-impl-trait/coherence_generalization.rs
new file mode 100644
index 000000000..5c9ad9498
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/coherence_generalization.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+trait Trait {}
+type Opaque<T> = impl Sized;
+fn foo<T>() -> Opaque<T> {
+ ()
+}
+
+impl<T, V> Trait for (T, V, V, u32) {}
+impl<U, V> Trait for (Opaque<U>, V, i32, V) {}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/collect_hidden_types.rs b/tests/ui/type-alias-impl-trait/collect_hidden_types.rs
new file mode 100644
index 000000000..e78f178e4
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/constrain_inputs.rs b/tests/ui/type-alias-impl-trait/constrain_inputs.rs
new file mode 100644
index 000000000..03fb64b7b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/constrain_inputs.rs
@@ -0,0 +1,33 @@
+#![feature(type_alias_impl_trait)]
+
+mod lifetime_params {
+ type Ty<'a> = impl Sized;
+ fn defining(s: &str) -> Ty<'_> { s }
+ fn execute(ty: Ty<'_>) -> &str { todo!() }
+ //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+
+ type BadFnSig = fn(Ty<'_>) -> &str;
+ //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+ type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
+ //~^ ERROR binding for associated type `Output` references an anonymous lifetime
+}
+
+mod lifetime_params_2 {
+ type Ty<'a> = impl FnOnce() -> &'a str;
+ fn defining(s: &str) -> Ty<'_> { move || s }
+ fn execute(ty: Ty<'_>) -> &str { ty() }
+ //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+}
+
+// regression test for https://github.com/rust-lang/rust/issues/97104
+mod type_params {
+ type Ty<T> = impl Sized;
+ fn define<T>(s: T) -> Ty<T> { s }
+
+ type BadFnSig = fn(Ty<&str>) -> &str;
+ //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+ type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
+ //~^ ERROR binding for associated type `Output` references an anonymous lifetime
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs.stderr b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr
new file mode 100644
index 000000000..93953fd06
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/constrain_inputs.stderr
@@ -0,0 +1,58 @@
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+ --> $DIR/constrain_inputs.rs:6:31
+ |
+LL | fn execute(ty: Ty<'_>) -> &str { todo!() }
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+ --> $DIR/constrain_inputs.rs:9:35
+ |
+LL | type BadFnSig = fn(Ty<'_>) -> &str;
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
+ --> $DIR/constrain_inputs.rs:11:42
+ |
+LL | type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+ --> $DIR/constrain_inputs.rs:18:31
+ |
+LL | fn execute(ty: Ty<'_>) -> &str { ty() }
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+ --> $DIR/constrain_inputs.rs:27:37
+ |
+LL | type BadFnSig = fn(Ty<&str>) -> &str;
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
+ --> $DIR/constrain_inputs.rs:29:44
+ |
+LL | type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
+ | ^^^^
+ |
+ = note: lifetimes appearing in an associated or opaque type are not considered constrained
+ = note: consider introducing a named lifetime parameter
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0581, E0582.
+For more information about an error, try `rustc --explain E0581`.
diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
new file mode 100644
index 000000000..3bae0f173
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
@@ -0,0 +1,31 @@
+#![feature(type_alias_impl_trait)]
+
+trait Static: 'static {}
+impl Static for () {}
+
+type Gal<T> = impl Static;
+fn _defining<T>() -> Gal<T> {}
+
+trait Callable<Arg> { type Output; }
+
+/// We can infer `<C as Callable<Arg>>::Output: 'static`,
+/// because we know `C: 'static` and `Arg: 'static`,
+fn box_str<C, Arg>(s: C::Output) -> Box<dyn AsRef<str> + 'static>
+where
+ Arg: Static,
+ C: ?Sized + Callable<Arg> + 'static,
+ C::Output: AsRef<str>,
+{
+ Box::new(s)
+}
+
+fn extend_lifetime(s: &str) -> Box<dyn AsRef<str> + 'static> {
+ type MalformedTy = dyn for<'a> Callable<Gal<&'a ()>, Output = &'a str>;
+ //~^ ERROR binding for associated type `Output` references lifetime `'a`
+ box_str::<MalformedTy, _>(s)
+}
+
+fn main() {
+ let extended = extend_lifetime(&String::from("hello"));
+ println!("{}", extended.as_ref().as_ref());
+}
diff --git a/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr
new file mode 100644
index 000000000..d5fc46cb1
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr
@@ -0,0 +1,9 @@
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/constrain_inputs_unsound.rs:23:58
+ |
+LL | type MalformedTy = dyn for<'a> Callable<Gal<&'a ()>, Output = &'a str>;
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0582`.
diff --git a/tests/ui/type-alias-impl-trait/cross_crate_ice.rs b/tests/ui/type-alias-impl-trait/cross_crate_ice.rs
new file mode 100644
index 000000000..c30608176
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/cross_crate_ice2.rs b/tests/ui/type-alias-impl-trait/cross_crate_ice2.rs
new file mode 100644
index 000000000..3a7e49026
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/cross_inference.rs b/tests/ui/type-alias-impl-trait/cross_inference.rs
new file mode 100644
index 000000000..dafaf40a6
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
new file mode 100644
index 000000000..9a50c0f98
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
@@ -0,0 +1,9 @@
+// compile-flags: --edition=2021
+// check-pass
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+ type T = impl Copy;
+ let foo: T = (1u32, 2u32);
+ let (a, b): (u32, u32) = foo;
+}
diff --git a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
new file mode 100644
index 000000000..b929122a6
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug_no_type.rs
@@ -0,0 +1,13 @@
+// compile-flags: --edition=2021 --crate-type=lib
+// rustc-env:RUST_BACKTRACE=0
+// check-pass
+
+// tracked in https://github.com/rust-lang/rust/issues/96572
+
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+ type T = impl Copy;
+ let foo: T = (1u32, 2u32);
+ let (a, b) = foo; // this line used to make the code fail
+}
diff --git a/tests/ui/type-alias-impl-trait/cross_inference_rpit.rs b/tests/ui/type-alias-impl-trait/cross_inference_rpit.rs
new file mode 100644
index 000000000..f6affbf17
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/declared_but_never_defined.rs b/tests/ui/type-alias-impl-trait/declared_but_never_defined.rs
new file mode 100644
index 000000000..6febd0715
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr b/tests/ui/type-alias-impl-trait/declared_but_never_defined.stderr
new file mode 100644
index 000000000..60bc24320
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs b/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs
new file mode 100644
index 000000000..5bda5f0fc
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr b/tests/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.stderr
new file mode 100644
index 000000000..fbfa0ccf1
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/defining-use-submodule.rs b/tests/ui/type-alias-impl-trait/defining-use-submodule.rs
new file mode 100644
index 000000000..8b51f5571
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/destructuring.rs b/tests/ui/type-alias-impl-trait/destructuring.rs
new file mode 100644
index 000000000..b752e5838
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/destructuring.rs
@@ -0,0 +1,10 @@
+#![feature(type_alias_impl_trait)]
+
+// check-pass
+
+// issue: https://github.com/rust-lang/rust/issues/104551
+
+fn main() {
+ type T = impl Sized;
+ let (_a, _b): T = (1u32, 2u32);
+}
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses.rs b/tests/ui/type-alias-impl-trait/different_defining_uses.rs
new file mode 100644
index 000000000..4505c4d95
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses.stderr
new file mode 100644
index 000000000..a8b4cd7af
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs
new file mode 100644
index 000000000..0b8157fe3
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.rs
@@ -0,0 +1,18 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+// two definitions with different types
+type Foo = impl std::fmt::Debug;
+
+fn foo() -> Foo {
+ ""
+}
+
+fn bar() -> Foo { //~ ERROR: concrete type differs from previous defining opaque type use
+ panic!()
+}
+
+fn boo() -> Foo {
+ loop {}
+}
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr
new file mode 100644
index 000000000..09dadb0af
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/different_defining_uses_never_type.rs:12:13
+ |
+LL | fn bar() -> Foo {
+ | ^^^ expected `&'static str`, got `()`
+ |
+note: previous use here
+ --> $DIR/different_defining_uses_never_type.rs:9:5
+ |
+LL | ""
+ | ^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs
new file mode 100644
index 000000000..8549687ea
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs
new file mode 100644
index 000000000..bc827a8f2
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.rs
@@ -0,0 +1,12 @@
+#![feature(type_alias_impl_trait)]
+
+type Tait = impl Sized;
+
+struct One;
+fn one() -> Tait { One }
+
+struct Two<T>(T);
+fn two() -> Tait { Two::<()>(todo!()) }
+//~^ ERROR concrete type differs from previous defining opaque type use
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr
new file mode 100644
index 000000000..146a57cbb
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type3.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+ --> $DIR/different_defining_uses_never_type3.rs:9:13
+ |
+LL | fn two() -> Tait { Two::<()>(todo!()) }
+ | ^^^^ expected `One`, got `Two<()>`
+ |
+note: previous use here
+ --> $DIR/different_defining_uses_never_type3.rs:6:20
+ |
+LL | fn one() -> Tait { One }
+ | ^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs
new file mode 100644
index 000000000..5f75fdc71
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+pub trait Captures<'a> {}
+
+impl<'a, T: ?Sized> Captures<'a> for T {}
+
+type OneLifetime<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
+
+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/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr b/tests/ui/type-alias-impl-trait/different_lifetimes_defining_uses.stderr
new file mode 100644
index 000000000..546598e8a
--- /dev/null
+++ b/tests/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:15:5
+ |
+LL | b
+ | ^ expected `&'a u32`, got `&'b u32`
+ |
+note: previous use here
+ --> $DIR/different_lifetimes_defining_uses.rs:11:5
+ |
+LL | a
+ | ^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/fallback.rs b/tests/ui/type-alias-impl-trait/fallback.rs
new file mode 100644
index 000000000..d8cf7d71f
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/fallback.stderr b/tests/ui/type-alias-impl-trait/fallback.stderr
new file mode 100644
index 000000000..e767bfdb0
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/field-types.rs b/tests/ui/type-alias-impl-trait/field-types.rs
new file mode 100644
index 000000000..d99ed5812
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/future.rs b/tests/ui/type-alias-impl-trait/future.rs
new file mode 100644
index 000000000..56323216e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/future.stderr b/tests/ui/type-alias-impl-trait/future.stderr
new file mode 100644
index 000000000..7e76c120a
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.rs
new file mode 100644
index 000000000..8b683ad28
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr b/tests/ui/type-alias-impl-trait/generic_different_defining_uses.stderr
new file mode 100644
index 000000000..47ac33462
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs
new file mode 100644
index 000000000..9d938a616
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs
@@ -0,0 +1,14 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+pub trait Captures<'a> {}
+
+impl<'a, T: ?Sized> Captures<'a> for T {}
+
+type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
+
+fn one<'a>(t: &'a ()) -> Two<'a, 'a> {
+ t
+ //~^ ERROR non-defining opaque type use
+}
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.stderr
new file mode 100644
index 000000000..72e1ef4b4
--- /dev/null
+++ b/tests/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:12:5
+ |
+LL | t
+ | ^
+ |
+note: lifetime used multiple times
+ --> $DIR/generic_duplicate_lifetime_param.rs:9:10
+ |
+LL | type Two<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
+ | ^^ ^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
new file mode 100644
index 000000000..80462f8ac
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.rs
@@ -0,0 +1,33 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+fn main() {}
+
+// test that unused generic parameters are ok
+type TwoTys<T, U> = impl Debug;
+
+
+pub trait Captures<'a> {}
+
+impl<'a, T: ?Sized> Captures<'a> for T {}
+
+type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>;
+
+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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use.stderr
new file mode 100644
index 000000000..98e4bfea1
--- /dev/null
+++ b/tests/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:21: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:26:5
+ |
+LL | t
+ | ^
+ |
+note: lifetime used multiple times
+ --> $DIR/generic_duplicate_param_use.rs:15:19
+ |
+LL | type TwoLifetimes<'a, 'b> = impl Debug + Captures<'a> + Captures<'b>;
+ | ^^ ^^
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_duplicate_param_use.rs:31:5
+ |
+LL | t
+ | ^
+ |
+note: constant used multiple times
+ --> $DIR/generic_duplicate_param_use.rs:17:16
+ |
+LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
+ | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs
new file mode 100644
index 000000000..c17d595db
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs
new file mode 100644
index 000000000..201535efe
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use2.stderr
new file mode 100644
index 000000000..3dbfff745
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs
new file mode 100644
index 000000000..e7a25fc72
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use3.stderr
new file mode 100644
index 000000000..7bec38220
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs
new file mode 100644
index 000000000..d1e5a0f01
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use4.stderr
new file mode 100644
index 000000000..21a5369d9
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs
new file mode 100644
index 000000000..3bd1dda63
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use5.stderr
new file mode 100644
index 000000000..586ea8234
--- /dev/null
+++ b/tests/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 for `(T, U)` to 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_use5.rs:11:5
+ |
+LL | (t, u)
+ | ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required for `(T, U)` to implement `Debug`
+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 for `(U, T)` to implement `Debug`
+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 for `(U, T)` to implement `Debug`
+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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs
new file mode 100644
index 000000000..5120925e5
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use6.stderr
new file mode 100644
index 000000000..cb162d382
--- /dev/null
+++ b/tests/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 for `(T, T)` to 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_use6.rs:16:5
+ |
+LL | (u, t)
+ | ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required for `(U, T)` to implement `Debug`
+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 for `(U, T)` to implement `Debug`
+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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs
new file mode 100644
index 000000000..feebf81ee
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs
new file mode 100644
index 000000000..3a4b5047b
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use8.stderr
new file mode 100644
index 000000000..14cbfb380
--- /dev/null
+++ b/tests/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 for `(T, u32)` to 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_use8.rs:15:5
+ |
+LL | (u, 4u32)
+ | ^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+ |
+ = note: required for `(U, u32)` to 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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs
new file mode 100644
index 000000000..6afcdfe4d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/tests/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr
new file mode 100644
index 000000000..722693e42
--- /dev/null
+++ b/tests/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 for `(A, B, _)` to implement `Debug`
+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 for `(A, B, _)` to implement `Debug`
+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 for `(A, B, i32)` to implement `Debug`
+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 for `(A, B, i32)` to implement `Debug`
+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/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs b/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs
new file mode 100644
index 000000000..106efefba
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/generic_lifetime_param.rs
@@ -0,0 +1,12 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+type Region<'a> = impl std::fmt::Debug + 'a;
+
+
+fn region<'b>(a: &'b ()) -> Region<'b> {
+ a
+}
diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
new file mode 100644
index 000000000..f5045d382
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.rs
@@ -0,0 +1,28 @@
+#![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 expected generic type parameter, found `u32`
+}
+
+fn concrete_lifetime() -> OneLifetime<'static> {
+ 6u32
+ //~^ ERROR non-defining opaque type use in defining scope
+}
+
+fn concrete_const() -> OneConst<{ 123 }> {
+ 7u32
+ //~^ ERROR expected generic constant parameter, found `123`
+}
diff --git a/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
new file mode 100644
index 000000000..564648630
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/generic_nondefining_use.stderr
@@ -0,0 +1,30 @@
+error[E0792]: expected generic type parameter, found `u32`
+ --> $DIR/generic_nondefining_use.rs:16:5
+ |
+LL | type OneTy<T> = impl Debug;
+ | - this generic parameter must be used with a generic type parameter
+...
+LL | 5u32
+ | ^^^^
+
+error: non-defining opaque type use in defining scope
+ --> $DIR/generic_nondefining_use.rs:21: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[E0792]: expected generic constant parameter, found `123`
+ --> $DIR/generic_nondefining_use.rs:26:5
+ |
+LL | type OneConst<const X: usize> = impl Debug;
+ | -------------- this generic parameter must be used with a generic constant parameter
+...
+LL | 7u32
+ | ^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/generic_not_used.rs b/tests/ui/type-alias-impl-trait/generic_not_used.rs
new file mode 100644
index 000000000..c70f473cf
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_not_used.stderr b/tests/ui/type-alias-impl-trait/generic_not_used.stderr
new file mode 100644
index 000000000..fd720239a
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs
new file mode 100644
index 000000000..d3e169a70
--- /dev/null
+++ b/tests/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 expected generic type parameter, found `&'static i32
+}
+
+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/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
new file mode 100644
index 000000000..19115fd28
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
@@ -0,0 +1,30 @@
+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[E0792]: expected generic type parameter, found `&'static i32`
+ --> $DIR/generic_type_does_not_live_long_enough.rs:6:18
+ |
+LL | let z: i32 = x;
+ | ^
+...
+LL | type WrongGeneric<T> = impl 'static;
+ | - this generic parameter must be used with a generic type parameter
+
+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
+
+Some errors have detailed explanations: E0310, E0792.
+For more information about an error, try `rustc --explain E0310`.
diff --git a/tests/ui/type-alias-impl-trait/generic_underconstrained.rs b/tests/ui/type-alias-impl-trait/generic_underconstrained.rs
new file mode 100644
index 000000000..d87a25aad
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained.stderr
new file mode 100644
index 000000000..c73288329
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs b/tests/ui/type-alias-impl-trait/generic_underconstrained2.rs
new file mode 100644
index 000000000..8adc0bf32
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/tests/ui/type-alias-impl-trait/generic_underconstrained2.stderr
new file mode 100644
index 000000000..d77d978aa
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs
new file mode 100644
index 000000000..851c2f66c
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr
new file mode 100644
index 000000000..8cf8fb1d1
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs
new file mode 100644
index 000000000..0efbd1c2b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_generic_tait.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+trait Foo {
+ type Assoc;
+}
+
+impl Foo for i32 {
+ type Assoc = u32;
+}
+type ImplTrait = impl Sized;
+fn constrain() -> ImplTrait {
+ 1u64
+}
+impl Foo for i64 {
+ type Assoc = ImplTrait;
+}
+
+trait Bar<T> {}
+
+impl<T: Foo> Bar<<T as Foo>::Assoc> for T {}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs
new file mode 100644
index 000000000..3f1a9d12b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.rs
@@ -0,0 +1,33 @@
+#![feature(type_alias_impl_trait)]
+
+trait Foo {}
+impl Foo for () {}
+impl Foo for i32 {}
+
+type Bar<T: Foo> = impl std::fmt::Debug;
+fn defining_use<T: Foo>() -> Bar<T> {
+ 42
+}
+
+trait Bop {}
+
+impl Bop for Bar<()> {}
+
+// If the hidden type is the same, this is effectively a second impl for the same type.
+impl Bop for Bar<i32> {}
+//~^ ERROR conflicting implementations
+
+type Barr = impl std::fmt::Debug;
+fn defining_use2() -> Barr {
+ 42
+}
+
+// Even completely different opaque types must conflict.
+impl Bop for Barr {}
+//~^ ERROR conflicting implementations
+
+// And obviously the hidden type must conflict, too.
+impl Bop for i32 {}
+//~^ ERROR conflicting implementations
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
new file mode 100644
index 000000000..aaf75cc3d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
@@ -0,0 +1,30 @@
+error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
+ --> $DIR/impl_trait_for_same_tait.rs:17:1
+ |
+LL | impl Bop for Bar<()> {}
+ | -------------------- first implementation here
+...
+LL | impl Bop for Bar<i32> {}
+ | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
+
+error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
+ --> $DIR/impl_trait_for_same_tait.rs:26:1
+ |
+LL | impl Bop for Bar<()> {}
+ | -------------------- first implementation here
+...
+LL | impl Bop for Barr {}
+ | ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
+
+error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
+ --> $DIR/impl_trait_for_same_tait.rs:30:1
+ |
+LL | impl Bop for Bar<()> {}
+ | -------------------- first implementation here
+...
+LL | impl Bop for i32 {}
+ | ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs
new file mode 100644
index 000000000..9f32c5d88
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait.rs
@@ -0,0 +1,21 @@
+// compile-flags: --crate-type=lib
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+type Alias = impl Sized;
+
+fn constrain() -> Alias {
+ 1i32
+}
+
+trait HideIt {
+ type Assoc;
+}
+
+impl HideIt for () {
+ type Assoc = Alias;
+}
+
+pub trait Yay {}
+
+impl Yay for <() as HideIt>::Assoc {}
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs
new file mode 100644
index 000000000..8ec20acef
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+pub trait Yay { }
+impl Yay for Foo { }
+
+fn foo() {
+ is_yay::<u32>(); //~ ERROR: the trait bound `u32: Yay` is not satisfied
+ is_debug::<u32>(); // OK
+ is_yay::<Foo>(); // OK
+ is_debug::<Foo>(); // OK
+}
+
+fn is_yay<T: Yay>() { }
+fn is_debug<T: Debug>() { }
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr
new file mode 100644
index 000000000..1c83105a1
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `u32: Yay` is not satisfied
+ --> $DIR/impl_trait_for_tait_bound.rs:10:14
+ |
+LL | is_yay::<u32>();
+ | ^^^ the trait `Yay` is not implemented for `u32`
+ |
+ = help: the trait `Yay` is implemented for `Foo`
+note: required by a bound in `is_yay`
+ --> $DIR/impl_trait_for_tait_bound.rs:16:14
+ |
+LL | fn is_yay<T: Yay>() { }
+ | ^^^ required by this bound in `is_yay`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs
new file mode 100644
index 000000000..a4b8c2d19
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs
@@ -0,0 +1,16 @@
+#![feature(type_alias_impl_trait)]
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+
+pub trait Yay { }
+impl Yay for u32 { }
+
+fn foo() {
+ is_yay::<Foo>(); //~ ERROR: the trait bound `Foo: Yay` is not satisfied
+}
+
+fn is_yay<T: Yay>() { }
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr
new file mode 100644
index 000000000..a6440f02c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `Foo: Yay` is not satisfied
+ --> $DIR/impl_trait_for_tait_bound2.rs:11:14
+ |
+LL | is_yay::<Foo>();
+ | ^^^ the trait `Yay` is not implemented for `Foo`
+ |
+ = help: the trait `Yay` is implemented for `u32`
+note: required by a bound in `is_yay`
+ --> $DIR/impl_trait_for_tait_bound2.rs:14:14
+ |
+LL | fn is_yay<T: Yay>() { }
+ | ^^^ required by this bound in `is_yay`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds.rs b/tests/ui/type-alias-impl-trait/implied_bounds.rs
new file mode 100644
index 000000000..53cbf8d22
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_bounds.rs
@@ -0,0 +1,51 @@
+#![feature(type_alias_impl_trait)]
+
+type WithLifetime<'a> = impl Equals<SelfType = ()>;
+fn _defining_use<'a>() -> WithLifetime<'a> {}
+
+trait Convert<'a> {
+ type Witness;
+ fn convert<'b, T: ?Sized>(_proof: &'b Self::Witness, x: &'a T) -> &'b T;
+}
+
+impl<'a> Convert<'a> for () {
+ type Witness = WithLifetime<'a>;
+
+ fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<'a>, x: &'a T) -> &'b T {
+ // compiler used to think it gets to assume 'a: 'b here because
+ // of the `&'b WithLifetime<'a>` argument
+ x
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+ WithLifetime::<'a>::convert_helper::<(), T>(&(), x)
+}
+
+trait Equals {
+ type SelfType;
+ fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>(
+ proof: &'b Self::SelfType,
+ x: &'a T,
+ ) -> &'b T;
+}
+
+impl<S> Equals for S {
+ type SelfType = Self;
+ fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>(
+ proof: &'b Self,
+ x: &'a T,
+ ) -> &'b T {
+ W::convert(proof, x)
+ }
+}
+
+fn main() {
+ let r;
+ {
+ let x = String::from("Hello World?");
+ r = extend_lifetime(&x);
+ }
+ println!("{}", r);
+}
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds.stderr b/tests/ui/type-alias-impl-trait/implied_bounds.stderr
new file mode 100644
index 000000000..6f11b6663
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_bounds.stderr
@@ -0,0 +1,16 @@
+error: lifetime may not live long enough
+ --> $DIR/implied_bounds.rs:17:9
+ |
+LL | impl<'a> Convert<'a> for () {
+ | -- lifetime `'a` defined here
+...
+LL | fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<'a>, x: &'a T) -> &'b T {
+ | -- lifetime `'b` defined here
+...
+LL | x
+ | ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds2.rs b/tests/ui/type-alias-impl-trait/implied_bounds2.rs
new file mode 100644
index 000000000..b4c4c013c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_bounds2.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+type Ty<'a, A> = impl Sized + 'a;
+fn defining<'a, A>() -> Ty<'a, A> {}
+fn assert_static<T: 'static>() {}
+fn test<'a, A>() where Ty<'a, A>: 'static, { assert_static::<Ty<'a, A>>() }
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds3.rs b/tests/ui/type-alias-impl-trait/implied_bounds3.rs
new file mode 100644
index 000000000..e39c61328
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_bounds3.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+fn foo<F>(_: F)
+where
+ F: 'static,
+{
+}
+
+fn from<F: Send>(f: F) -> impl Send {
+ f
+}
+
+fn bar<T>() {
+ foo(from(|| ()))
+}
+
+fn main() {
+}
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_closure.rs b/tests/ui/type-alias-impl-trait/implied_bounds_closure.rs
new file mode 100644
index 000000000..4cf35f951
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_bounds_closure.rs
@@ -0,0 +1,31 @@
+trait StaticDefaultRef: 'static {
+ fn default_ref() -> &'static Self;
+}
+
+impl StaticDefaultRef for str {
+ fn default_ref() -> &'static str {
+ ""
+ }
+}
+
+fn into_impl(x: &str) -> &(impl ?Sized + AsRef<str> + StaticDefaultRef + '_) {
+ x
+}
+
+fn extend_lifetime<'a>(x: &'a str) -> &'static str {
+ let t = into_impl(x);
+ helper(|_| t) //~ ERROR lifetime may not live long enough
+}
+
+fn helper<T: ?Sized + AsRef<str> + StaticDefaultRef>(f: impl FnOnce(&T) -> &T) -> &'static str {
+ f(T::default_ref()).as_ref()
+}
+
+fn main() {
+ let r;
+ {
+ let x = String::from("Hello World?");
+ r = extend_lifetime(&x);
+ }
+ println!("{}", r);
+}
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_closure.stderr b/tests/ui/type-alias-impl-trait/implied_bounds_closure.stderr
new file mode 100644
index 000000000..151564c3b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_bounds_closure.stderr
@@ -0,0 +1,11 @@
+error: lifetime may not live long enough
+ --> $DIR/implied_bounds_closure.rs:17:16
+ |
+LL | fn extend_lifetime<'a>(x: &'a str) -> &'static str {
+ | -- lifetime `'a` defined here
+LL | let t = into_impl(x);
+LL | helper(|_| t)
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs
new file mode 100644
index 000000000..8023cd24f
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.rs
@@ -0,0 +1,51 @@
+#![feature(type_alias_impl_trait)]
+
+type WithLifetime<T> = impl Equals<SelfType = ()>;
+fn _defining_use<T>() -> WithLifetime<T> {}
+
+trait Convert<'a> {
+ type Witness;
+ fn convert<'b, T: ?Sized>(_proof: &'b Self::Witness, x: &'a T) -> &'b T;
+}
+
+impl<'a> Convert<'a> for () {
+ type Witness = WithLifetime<&'a ()>;
+
+ fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<&'a ()>, x: &'a T) -> &'b T {
+ // compiler used to think it gets to assume 'a: 'b here because
+ // of the `&'b WithLifetime<&'a ()>` argument
+ x
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+ WithLifetime::<&'a ()>::convert_helper::<(), T>(&(), x)
+}
+
+trait Equals {
+ type SelfType;
+ fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>(
+ proof: &'b Self::SelfType,
+ x: &'a T,
+ ) -> &'b T;
+}
+
+impl<S> Equals for S {
+ type SelfType = Self;
+ fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>(
+ proof: &'b Self,
+ x: &'a T,
+ ) -> &'b T {
+ W::convert(proof, x)
+ }
+}
+
+fn main() {
+ let r;
+ {
+ let x = String::from("Hello World?");
+ r = extend_lifetime(&x);
+ }
+ println!("{}", r);
+}
diff --git a/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr
new file mode 100644
index 000000000..cbc5e6073
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_bounds_from_types.stderr
@@ -0,0 +1,16 @@
+error: lifetime may not live long enough
+ --> $DIR/implied_bounds_from_types.rs:17:9
+ |
+LL | impl<'a> Convert<'a> for () {
+ | -- lifetime `'a` defined here
+...
+LL | fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<&'a ()>, x: &'a T) -> &'b T {
+ | -- lifetime `'b` defined here
+...
+LL | x
+ | ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs
new file mode 100644
index 000000000..b6a7264a5
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check.rs
@@ -0,0 +1,27 @@
+#![feature(type_alias_impl_trait)]
+
+// known-bug: #99840
+// this should not compile
+// check-pass
+
+type Alias = impl Sized;
+
+fn constrain() -> Alias {
+ 1i32
+}
+
+trait HideIt {
+ type Assoc;
+}
+
+impl HideIt for () {
+ type Assoc = Alias;
+}
+
+pub trait Yay {}
+
+impl Yay for <() as HideIt>::Assoc {}
+// impl Yay for i32 {} // this already errors
+// impl Yay for u32 {} // this also already errors
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs
new file mode 100644
index 000000000..07f825aea
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs
@@ -0,0 +1,43 @@
+#![feature(type_alias_impl_trait)]
+
+mod test_lifetime_param {
+ type Ty<'a> = impl Sized + 'a;
+ fn defining(a: &str) -> Ty<'_> { a }
+ fn assert_static<'a: 'static>() {}
+ //~^ WARN: unnecessary lifetime parameter `'a`
+ fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
+ //~^ ERROR: lifetime may not live long enough
+}
+
+mod test_higher_kinded_lifetime_param {
+ type Ty<'a> = impl Sized + 'a;
+ fn defining(a: &str) -> Ty<'_> { a }
+ fn assert_static<'a: 'static>() {}
+ //~^ WARN: unnecessary lifetime parameter `'a`
+ fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() }
+ //~^ ERROR: lifetime may not live long enough
+}
+
+mod test_higher_kinded_lifetime_param2 {
+ fn assert_static<'a: 'static>() {}
+ //~^ WARN: unnecessary lifetime parameter `'a`
+ fn test<'a>() { assert_static::<'a>() }
+ //~^ ERROR: lifetime may not live long enough
+}
+
+mod test_type_param {
+ type Ty<A> = impl Sized;
+ fn defining<A>(s: A) -> Ty<A> { s }
+ fn assert_static<A: 'static>() {}
+ fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
+ //~^ ERROR: parameter type `A` may not live long enough
+}
+
+mod test_implied_from_fn_sig {
+ type Opaque<T: 'static> = impl Sized;
+ fn defining<T: 'static>() -> Opaque<T> {}
+ fn assert_static<T: 'static>() {}
+ fn test<T>(_: Opaque<T>) { assert_static::<T>(); }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
new file mode 100644
index 000000000..887620a4d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
@@ -0,0 +1,58 @@
+warning: unnecessary lifetime parameter `'a`
+ --> $DIR/implied_lifetime_wf_check3.rs:6:22
+ |
+LL | fn assert_static<'a: 'static>() {}
+ | ^^
+ |
+ = help: you can use the `'static` lifetime directly, in place of `'a`
+
+warning: unnecessary lifetime parameter `'a`
+ --> $DIR/implied_lifetime_wf_check3.rs:15:22
+ |
+LL | fn assert_static<'a: 'static>() {}
+ | ^^
+ |
+ = help: you can use the `'static` lifetime directly, in place of `'a`
+
+warning: unnecessary lifetime parameter `'a`
+ --> $DIR/implied_lifetime_wf_check3.rs:22:22
+ |
+LL | fn assert_static<'a: 'static>() {}
+ | ^^
+ |
+ = help: you can use the `'static` lifetime directly, in place of `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/implied_lifetime_wf_check3.rs:8:43
+ |
+LL | fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() }
+ | -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/implied_lifetime_wf_check3.rs:17:46
+ |
+LL | fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() }
+ | -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/implied_lifetime_wf_check3.rs:24:21
+ |
+LL | fn test<'a>() { assert_static::<'a>() }
+ | -- ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+ | |
+ | lifetime `'a` defined here
+
+error[E0310]: the parameter type `A` may not live long enough
+ --> $DIR/implied_lifetime_wf_check3.rs:32:41
+ |
+LL | fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
+ | ^^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn test<A: 'static>() where Ty<A>: 'static { assert_static::<A>() }
+ | +++++++++
+
+error: aborting due to 4 previous errors; 3 warnings emitted
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs
new file mode 100644
index 000000000..ac32dbde0
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs
@@ -0,0 +1,11 @@
+#![feature(type_alias_impl_trait)]
+
+mod test_type_param_static {
+ type Ty<A> = impl Sized + 'static;
+ //~^ ERROR: the parameter type `A` may not live long enough
+ fn defining<A: 'static>(s: A) -> Ty<A> { s }
+ fn assert_static<A: 'static>() {}
+ fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
new file mode 100644
index 000000000..47bc31e78
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
@@ -0,0 +1,14 @@
+error[E0310]: the parameter type `A` may not live long enough
+ --> $DIR/implied_lifetime_wf_check4_static.rs:4:18
+ |
+LL | type Ty<A> = impl Sized + 'static;
+ | ^^^^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | type Ty<A: 'static> = impl Sized + 'static;
+ | +++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
new file mode 100644
index 000000000..ee9bce15d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+trait Callable {
+ type Output;
+ fn call() -> Self::Output;
+}
+
+impl<'a> Callable for &'a () {
+ type Output = impl Sized;
+ fn call() -> Self::Output {}
+}
+
+fn test<'a>() -> impl Sized {
+ <&'a () as Callable>::call()
+}
+
+fn want_static<T: 'static>(_: T) {}
+
+fn test2<'a>() {
+ want_static(<&'a () as Callable>::call());
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs
new file mode 100644
index 000000000..ae21a9134
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs
@@ -0,0 +1,38 @@
+#![feature(type_alias_impl_trait)]
+
+trait Callable {
+ type Output;
+ fn call(x: Self) -> Self::Output;
+}
+
+trait PlusOne {
+ fn plus_one(&mut self);
+}
+
+impl<'a> PlusOne for &'a mut i32 {
+ fn plus_one(&mut self) {
+ **self += 1;
+ }
+}
+
+impl<T: PlusOne> Callable for T {
+ type Output = impl PlusOne;
+ fn call(t: T) -> Self::Output { t }
+}
+
+fn test<'a>(y: &'a mut i32) -> impl PlusOne {
+ <&'a mut i32 as Callable>::call(y)
+ //~^ ERROR hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
+}
+
+fn main() {
+ let mut z = 42;
+ let mut thing = test(&mut z);
+ let mut thing2 = test(&mut z);
+ thing.plus_one();
+ assert_eq!(z, 43);
+ thing2.plus_one();
+ assert_eq!(z, 44);
+ thing.plus_one();
+ assert_eq!(z, 45);
+}
diff --git a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr
new file mode 100644
index 000000000..0ed8a703b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr
@@ -0,0 +1,16 @@
+error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds
+ --> $DIR/imply_bounds_from_bounds_param.rs:24:5
+ |
+LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne {
+ | -- hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here
+LL | <&'a mut i32 as Callable>::call(y)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound
+ |
+LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a {
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs b/tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs
new file mode 100644
index 000000000..685d76ee3
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr b/tests/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr
new file mode 100644
index 000000000..b93ea955c
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/incomplete-inference.rs b/tests/ui/type-alias-impl-trait/incomplete-inference.rs
new file mode 100644
index 000000000..4c8bf2cfc
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/incomplete-inference.stderr b/tests/ui/type-alias-impl-trait/incomplete-inference.stderr
new file mode 100644
index 000000000..9a0e71b4e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/inference-cycle.rs b/tests/ui/type-alias-impl-trait/inference-cycle.rs
new file mode 100644
index 000000000..79caddf79
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/inference-cycle.stderr b/tests/ui/type-alias-impl-trait/inference-cycle.stderr
new file mode 100644
index 000000000..b9d646b92
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-101750.rs b/tests/ui/type-alias-impl-trait/issue-101750.rs
new file mode 100644
index 000000000..f564f4fa7
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-101750.rs
@@ -0,0 +1,37 @@
+#![feature(type_alias_impl_trait)]
+
+// check-pass
+
+trait Trait {}
+
+type TAIT = impl Trait;
+
+struct Concrete;
+impl Trait for Concrete {}
+
+fn tait() -> TAIT {
+ Concrete
+}
+
+trait OuterTrait {
+ type Item;
+}
+struct Dummy<T> {
+ t: T,
+}
+impl<T> OuterTrait for Dummy<T> {
+ type Item = T;
+}
+
+fn tait_and_impl_trait() -> impl OuterTrait<Item = (TAIT, impl Trait)> {
+ Dummy {
+ t: (tait(), Concrete),
+ }
+}
+
+fn tait_and_dyn_trait() -> impl OuterTrait<Item = (TAIT, Box<dyn Trait>)> {
+ let b: Box<dyn Trait> = Box::new(Concrete);
+ Dummy { t: (tait(), b) }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-104817.rs b/tests/ui/type-alias-impl-trait/issue-104817.rs
new file mode 100644
index 000000000..0d3bace4d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-104817.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+#![cfg_attr(specialized, feature(specialization))]
+#![allow(incomplete_features)]
+
+// revisions: stock specialized
+// [specialized]check-pass
+
+trait OpaqueTrait {}
+impl<T> OpaqueTrait for T {}
+type OpaqueType = impl OpaqueTrait;
+fn mk_opaque() -> OpaqueType {
+ || 0
+}
+trait AnotherTrait {}
+impl<T: Send> AnotherTrait for T {}
+impl AnotherTrait for OpaqueType {}
+//[stock]~^ conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr
new file mode 100644
index 000000000..47bae8bd1
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr
@@ -0,0 +1,11 @@
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
+ --> $DIR/issue-104817.rs:16:1
+ |
+LL | impl<T: Send> AnotherTrait for T {}
+ | -------------------------------- first implementation here
+LL | impl AnotherTrait for OpaqueType {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs b/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs
new file mode 100644
index 000000000..50eeff0b1
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr b/tests/ui/type-alias-impl-trait/issue-52843-closure-constrain.stderr
new file mode 100644
index 000000000..4c5fd2255
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-52843.rs b/tests/ui/type-alias-impl-trait/issue-52843.rs
new file mode 100644
index 000000000..159d3ccd2
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-52843.stderr b/tests/ui/type-alias-impl-trait/issue-52843.stderr
new file mode 100644
index 000000000..acd40f980
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-53092-2.rs b/tests/ui/type-alias-impl-trait/issue-53092-2.rs
new file mode 100644
index 000000000..057930f0c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-53092-2.rs
@@ -0,0 +1,14 @@
+#![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| ()) };
+
+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/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
new file mode 100644
index 000000000..2565a28b4
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
@@ -0,0 +1,46 @@
+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[E0277]: the trait bound `U: From<T>` is not satisfied
+ --> $DIR/issue-53092-2.rs:9: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:8: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 2 previous errors
+
+Some errors have detailed explanations: E0277, E0391.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/issue-53092.rs b/tests/ui/type-alias-impl-trait/issue-53092.rs
new file mode 100644
index 000000000..1be5b46d6
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-53092.stderr b/tests/ui/type-alias-impl-trait/issue-53092.stderr
new file mode 100644
index 000000000..2109cf8a7
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-53096.rs b/tests/ui/type-alias-impl-trait/issue-53096.rs
new file mode 100644
index 000000000..007dcf3bc
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-53096.stderr b/tests/ui/type-alias-impl-trait/issue-53096.stderr
new file mode 100644
index 000000000..0af3a75f8
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
new file mode 100644
index 000000000..4a11bb502
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr
new file mode 100644
index 000000000..0a34e8486
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr
@@ -0,0 +1,12 @@
+error[E0275]: overflow evaluating the requirement `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`)
+ = note: required because it appears within the type `fn() -> Foo {foo}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/type-alias-impl-trait/issue-53598.rs b/tests/ui/type-alias-impl-trait/issue-53598.rs
new file mode 100644
index 000000000..9c1cbf926
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-53598.stderr b/tests/ui/type-alias-impl-trait/issue-53598.stderr
new file mode 100644
index 000000000..f8b8201e2
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs b/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs
new file mode 100644
index 000000000..a3f126d56
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr b/tests/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.stderr
new file mode 100644
index 000000000..eb1c9603a
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs b/tests/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs
new file mode 100644
index 000000000..af0780ab0
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs b/tests/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs
new file mode 100644
index 000000000..3a7a5da07
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/tests/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
new file mode 100644
index 000000000..cad3e0f66
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-57611-trait-alias.rs
@@ -0,0 +1,26 @@
+// check-pass
+// Regression test for issue #57611
+// Ensures that we don't ICE
+
+#![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/tests/ui/type-alias-impl-trait/issue-57700.rs b/tests/ui/type-alias-impl-trait/issue-57700.rs
new file mode 100644
index 000000000..484589387
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-57700.stderr b/tests/ui/type-alias-impl-trait/issue-57700.stderr
new file mode 100644
index 000000000..31b6df5d4
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-57807-associated-type.rs b/tests/ui/type-alias-impl-trait/issue-57807-associated-type.rs
new file mode 100644
index 000000000..fcab2c7db
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-57961.rs b/tests/ui/type-alias-impl-trait/issue-57961.rs
new file mode 100644
index 000000000..4aa5966ff
--- /dev/null
+++ b/tests/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 expected `IntoIter<u32>` to be an iterator that yields `X`, but it yields `u32`
+}
+
+fn incoherent() {
+ let f: X = 22_i32;
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-57961.stderr b/tests/ui/type-alias-impl-trait/issue-57961.stderr
new file mode 100644
index 000000000..8d11b4888
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-57961.stderr
@@ -0,0 +1,20 @@
+error[E0271]: expected `IntoIter<u32>` to be an iterator that yields `X`, but it yields `u32`
+ --> $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/tests/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs b/tests/ui/type-alias-impl-trait/issue-58662-generator-with-lifetime.rs
new file mode 100644
index 000000000..477b61390
--- /dev/null
+++ b/tests/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<'c> = impl Generator<Return = (), Yield = u64> + 'c;
+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/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs b/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs
new file mode 100644
index 000000000..27ca7d0fd
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-58662-simplified.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+#![feature(generators, generator_trait)]
+#![feature(type_alias_impl_trait)]
+
+trait Trait {}
+
+impl<T> Trait for T {}
+
+type Foo<'c> = impl Trait + 'c;
+fn foo<'a>(rng: &'a ()) -> Foo<'a> {
+ fn helper<'b>(rng: &'b ()) -> impl 'b + Trait {
+ rng
+ }
+
+ helper(rng)
+}
+
+fn main() {
+}
diff --git a/tests/ui/type-alias-impl-trait/issue-58887.rs b/tests/ui/type-alias-impl-trait/issue-58887.rs
new file mode 100644
index 000000000..96ac78602
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-58951-2.rs b/tests/ui/type-alias-impl-trait/issue-58951-2.rs
new file mode 100644
index 000000000..e4ba7f8e2
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-58951.rs b/tests/ui/type-alias-impl-trait/issue-58951.rs
new file mode 100644
index 000000000..7303cbab4
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-60371.rs b/tests/ui/type-alias-impl-trait/issue-60371.rs
new file mode 100644
index 000000000..9a40f3d9b
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-60371.stderr b/tests/ui/type-alias-impl-trait/issue-60371.stderr
new file mode 100644
index 000000000..d0c04371b
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-60407.rs b/tests/ui/type-alias-impl-trait/issue-60407.rs
new file mode 100644
index 000000000..b833429c7
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-60407.stderr b/tests/ui/type-alias-impl-trait/issue-60407.stderr
new file mode 100644
index 000000000..fecee2779
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-60564-working.rs b/tests/ui/type-alias-impl-trait/issue-60564-working.rs
new file mode 100644
index 000000000..38accc824
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-60564.rs b/tests/ui/type-alias-impl-trait/issue-60564.rs
new file mode 100644
index 000000000..c2f4c3708
--- /dev/null
+++ b/tests/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 expected generic type parameter, found `u8`
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-60564.stderr b/tests/ui/type-alias-impl-trait/issue-60564.stderr
new file mode 100644
index 000000000..f8fdb004d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-60564.stderr
@@ -0,0 +1,12 @@
+error[E0792]: expected generic type parameter, found `u8`
+ --> $DIR/issue-60564.rs:20:9
+ |
+LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
+ | - this generic parameter must be used with a generic type parameter
+...
+LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/issue-60662.rs b/tests/ui/type-alias-impl-trait/issue-60662.rs
new file mode 100644
index 000000000..b9faa668b
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-60662.stdout b/tests/ui/type-alias-impl-trait/issue-60662.stdout
new file mode 100644
index 000000000..5b3d7375d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs b/tests/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs
new file mode 100644
index 000000000..36779a0ce
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs b/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs
new file mode 100644
index 000000000..7414611a7
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-63279.rs b/tests/ui/type-alias-impl-trait/issue-63279.rs
new file mode 100644
index 000000000..97332e16d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-63279.stderr b/tests/ui/type-alias-impl-trait/issue-63279.stderr
new file mode 100644
index 000000000..110b8d1ee
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-63355.rs b/tests/ui/type-alias-impl-trait/issue-63355.rs
new file mode 100644
index 000000000..7066a0535
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs b/tests/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs
new file mode 100644
index 000000000..28f4a85c9
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-65384.rs b/tests/ui/type-alias-impl-trait/issue-65384.rs
new file mode 100644
index 000000000..9a9b2269f
--- /dev/null
+++ b/tests/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: conflicting implementations of trait `MyTrait` for type `()`
+
+fn bazr() -> Bar { }
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-65384.stderr b/tests/ui/type-alias-impl-trait/issue-65384.stderr
new file mode 100644
index 000000000..f6692ae32
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-65384.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `MyTrait` for type `()`
+ --> $DIR/issue-65384.rs:10:1
+ |
+LL | impl MyTrait for () {}
+ | ------------------- first implementation here
+...
+LL | impl MyTrait for Bar {}
+ | ^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
new file mode 100644
index 000000000..72c22827f
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-65918.rs b/tests/ui/type-alias-impl-trait/issue-65918.rs
new file mode 100644
index 000000000..af6d50109
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs b/tests/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs
new file mode 100644
index 000000000..d97270c31
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs b/tests/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs
new file mode 100644
index 000000000..cd219328a
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.rs
new file mode 100644
index 000000000..5e0a82a72
--- /dev/null
+++ b/tests/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 expected generic type parameter, found `()`
+
+fn main() {}
+
+impl<X> Trait<X> for () {}
diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
new file mode 100644
index 000000000..271743a40
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use-2.stderr
@@ -0,0 +1,12 @@
+error[E0792]: expected generic type parameter, found `()`
+ --> $DIR/issue-68368-non-defining-use-2.rs:9:29
+ |
+LL | type Alias<'a, U> = impl Trait<U>;
+ | - this generic parameter must be used with a generic type parameter
+LL |
+LL | fn f<'a>() -> Alias<'a, ()> {}
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs
new file mode 100644
index 000000000..3b32260c9
--- /dev/null
+++ b/tests/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 expected generic type parameter, found `()`
+
+fn main() {}
+
+impl Trait<()> for () {}
diff --git a/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
new file mode 100644
index 000000000..4d9a8d6ee
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-68368-non-defining-use.stderr
@@ -0,0 +1,12 @@
+error[E0792]: expected generic type parameter, found `()`
+ --> $DIR/issue-68368-non-defining-use.rs:9:29
+ |
+LL | type Alias<'a, U> = impl Trait<U>;
+ | - this generic parameter must be used with a generic type parameter
+LL |
+LL | fn f<'a>() -> Alias<'a, ()> {}
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs
new file mode 100644
index 000000000..7657fe2fb
--- /dev/null
+++ b/tests/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 expected generic type parameter, found `()`
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr
new file mode 100644
index 000000000..d1250786d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.stderr
@@ -0,0 +1,29 @@
+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[E0792]: expected generic type parameter, found `()`
+ --> $DIR/issue-69136-inner-lifetime-resolve-error.rs:20:27
+ |
+LL | type Return<A> = impl WithAssoc<A, AssocType = impl SomeTrait + 'a>;
+ | - this generic parameter must be used with a generic type parameter
+...
+LL | fn my_fun() -> Return<()> {}
+ | ^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0261, E0792.
+For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs b/tests/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs
new file mode 100644
index 000000000..a6916eda8
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-69323.rs b/tests/ui/type-alias-impl-trait/issue-69323.rs
new file mode 100644
index 000000000..a9bd6daf2
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-70121.rs b/tests/ui/type-alias-impl-trait/issue-70121.rs
new file mode 100644
index 000000000..dff0d89d4
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-72793.rs b/tests/ui/type-alias-impl-trait/issue-72793.rs
new file mode 100644
index 000000000..828c87114
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-74244.rs b/tests/ui/type-alias-impl-trait/issue-74244.rs
new file mode 100644
index 000000000..bb4104b3d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-74244.stderr b/tests/ui/type-alias-impl-trait/issue-74244.stderr
new file mode 100644
index 000000000..ff6bacd27
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-74280.rs b/tests/ui/type-alias-impl-trait/issue-74280.rs
new file mode 100644
index 000000000..ad641eaa0
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-74280.stderr b/tests/ui/type-alias-impl-trait/issue-74280.stderr
new file mode 100644
index 000000000..66886db6e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-74761-2.rs b/tests/ui/type-alias-impl-trait/issue-74761-2.rs
new file mode 100644
index 000000000..d26ca5c3e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-74761-2.stderr b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr
new file mode 100644
index 000000000..f15d0a069
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-74761.rs b/tests/ui/type-alias-impl-trait/issue-74761.rs
new file mode 100644
index 000000000..d26ca5c3e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-74761.stderr b/tests/ui/type-alias-impl-trait/issue-74761.stderr
new file mode 100644
index 000000000..1d016fe07
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
new file mode 100644
index 000000000..b97e444c6
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs
@@ -0,0 +1,31 @@
+// Regression test for issue #76202
+// Tests that we don't ICE when we have a trait impl on a TAIT.
+
+// check-pass
+
+#![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 {
+ fn test(self) {}
+}
+
+// Ok because `i32` does not implement `Dummy`,
+// so it can't possibly be the hidden type of `F`.
+impl Test for i32 {
+ fn test(self) {}
+}
+
+fn main() {
+ let x: F = f();
+ x.test();
+}
diff --git a/tests/ui/type-alias-impl-trait/issue-77179.rs b/tests/ui/type-alias-impl-trait/issue-77179.rs
new file mode 100644
index 000000000..8d818d4a3
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-77179.stderr b/tests/ui/type-alias-impl-trait/issue-77179.stderr
new file mode 100644
index 000000000..053546e4b
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-78450.rs b/tests/ui/type-alias-impl-trait/issue-78450.rs
new file mode 100644
index 000000000..fccbfb74f
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs b/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
new file mode 100644
index 000000000..2ba4befea
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-84660-trait-impl-for-tait.rs
@@ -0,0 +1,25 @@
+// 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.
+
+// check-pass
+
+#![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 () {
+ fn f() {
+ println!("ho");
+ }
+}
+
+fn main() {
+ <() as TraitArg<Bar>>::f();
+}
diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs
new file mode 100644
index 000000000..48d4b0c96
--- /dev/null
+++ b/tests/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 {
+ type Out = Out;
+ fn convert(_i: In) -> Self::Out {
+ unreachable!();
+ }
+}
+
+impl<In, Out> Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait<Bar, _>`
+ 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/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr
new file mode 100644
index 000000000..6a75e1bd2
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
+ --> $DIR/issue-84660-unsoundness.rs:23:1
+ |
+LL | impl<In, Out> Trait<Bar, In> for Out {
+ | ------------------------------------ first implementation here
+...
+LL | impl<In, Out> Trait<(), In> for Out {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs b/tests/ui/type-alias-impl-trait/issue-87455-static-lifetime-ice.rs
new file mode 100644
index 000000000..80a74eb63
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-89686.rs b/tests/ui/type-alias-impl-trait/issue-89686.rs
new file mode 100644
index 000000000..058417bdb
--- /dev/null
+++ b/tests/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 = ()> + 'a;
+
+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/tests/ui/type-alias-impl-trait/issue-89686.stderr b/tests/ui/type-alias-impl-trait/issue-89686.stderr
new file mode 100644
index 000000000..3b95a575a
--- /dev/null
+++ b/tests/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 = ()> + 'a;
+ | +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/issue-89952.rs b/tests/ui/type-alias-impl-trait/issue-89952.rs
new file mode 100644
index 000000000..dc0f19c04
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-90400-1.rs b/tests/ui/type-alias-impl-trait/issue-90400-1.rs
new file mode 100644
index 000000000..15aead2f6
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-90400-1.rs
@@ -0,0 +1,29 @@
+// Regression test for #90400,
+// taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836
+
+#![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/tests/ui/type-alias-impl-trait/issue-90400-1.stderr b/tests/ui/type-alias-impl-trait/issue-90400-1.stderr
new file mode 100644
index 000000000..ead28769f
--- /dev/null
+++ b/tests/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:22: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:21: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/tests/ui/type-alias-impl-trait/issue-90400-2.rs b/tests/ui/type-alias-impl-trait/issue-90400-2.rs
new file mode 100644
index 000000000..4c6e893c1
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-90400-2.rs
@@ -0,0 +1,37 @@
+// Regression test for #90400,
+// taken from https://github.com/rust-lang/rust/issues/90400#issuecomment-954927836
+
+#![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/tests/ui/type-alias-impl-trait/issue-90400-2.stderr b/tests/ui/type-alias-impl-trait/issue-90400-2.stderr
new file mode 100644
index 000000000..0c45046f5
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-90400-2.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `B: Bar` is not satisfied
+ --> $DIR/issue-90400-2.rs:25:9
+ |
+LL | MyBaz(bar)
+ | ^^^^^^^^^^ the trait `Bar` is not implemented for `B`
+ |
+note: required for `MyBaz<B>` to implement `Baz`
+ --> $DIR/issue-90400-2.rs:30:14
+ |
+LL | impl<B: Bar> Baz for MyBaz<B> {
+ | --- ^^^ ^^^^^^^^
+ | |
+ | unsatisfied trait bound introduced here
+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/tests/ui/type-alias-impl-trait/issue-93411.rs b/tests/ui/type-alias-impl-trait/issue-93411.rs
new file mode 100644
index 000000000..1f8c78926
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-94429.rs b/tests/ui/type-alias-impl-trait/issue-94429.rs
new file mode 100644
index 000000000..2c965b875
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-94429.stderr b/tests/ui/type-alias-impl-trait/issue-94429.stderr
new file mode 100644
index 000000000..8d7f7a07b
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.rs b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.rs
new file mode 100644
index 000000000..825710851
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.rs
@@ -0,0 +1,10 @@
+#![feature(type_alias_impl_trait)]
+
+fn main() {
+ type T = impl Copy;
+ let foo: T = Some((1u32, 2u32));
+ match foo {
+ None => (),
+ Some((a, b, c)) => (), //~ ERROR mismatched types
+ }
+}
diff --git a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.stderr b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.stderr
new file mode 100644
index 000000000..728244a18
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained-mismatch.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-96572-unconstrained-mismatch.rs:8:14
+ |
+LL | match foo {
+ | --- this expression has type `T`
+LL | None => (),
+LL | Some((a, b, c)) => (),
+ | ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
+ |
+ = note: expected tuple `(u32, u32)`
+ found tuple `(_, _, _)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs
new file mode 100644
index 000000000..2c740ccc1
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs
@@ -0,0 +1,92 @@
+#![feature(type_alias_impl_trait)]
+// check-pass
+
+fn main() {
+ type T = impl Copy;
+ let foo: T = Some((1u32, 2u32));
+ match foo {
+ None => (),
+ Some((a, b)) => (),
+ }
+}
+
+fn upvar() {
+ #[derive(Copy, Clone)]
+ struct Foo((u32, u32));
+
+ type T = impl Copy;
+ let foo: T = Foo((1u32, 2u32));
+ let x = move || {
+ let Foo((a, b)) = foo;
+ };
+}
+
+fn enum_upvar() {
+ type T = impl Copy;
+ let foo: T = Some((1u32, 2u32));
+ let x = move || {
+ match foo {
+ None => (),
+ Some((a, b)) => (),
+ }
+ };
+}
+
+fn r#struct() {
+ #[derive(Copy, Clone)]
+ struct Foo((u32, u32));
+
+ type U = impl Copy;
+ let foo: U = Foo((1u32, 2u32));
+ let Foo((a, b)) = foo;
+}
+
+mod only_pattern {
+ type T = impl Copy;
+
+ fn foo(foo: T) {
+ let (mut x, mut y) = foo;
+ x = 42;
+ y = "foo";
+ }
+
+ type U = impl Copy;
+
+ fn bar(bar: Option<U>) {
+ match bar {
+ Some((mut x, mut y)) => {
+ x = 42;
+ y = "foo";
+ }
+ None => {}
+ }
+ }
+}
+
+mod only_pattern_rpit {
+ #[allow(unconditional_recursion)]
+ fn foo(b: bool) -> impl Copy {
+ let (mut x, mut y) = foo(false);
+ x = 42;
+ y = "foo";
+ if b {
+ panic!()
+ } else {
+ foo(true)
+ }
+ }
+
+ fn bar(b: bool) -> Option<impl Copy> {
+ if b {
+ return None;
+ }
+ match bar(!b) {
+ Some((mut x, mut y)) => {
+ x = 42;
+ y = "foo";
+ }
+ None => {}
+ }
+ None
+ }
+}
diff --git a/tests/ui/type-alias-impl-trait/issue-98604.rs b/tests/ui/type-alias-impl-trait/issue-98604.rs
new file mode 100644
index 000000000..32c2f9ed5
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-98604.rs
@@ -0,0 +1,11 @@
+// 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 expected `fn() -> impl Future<Output = ()> {test}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
+}
diff --git a/tests/ui/type-alias-impl-trait/issue-98604.stderr b/tests/ui/type-alias-impl-trait/issue-98604.stderr
new file mode 100644
index 000000000..92d01eb0d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-98604.stderr
@@ -0,0 +1,18 @@
+error[E0271]: expected `fn() -> impl Future<Output = ()> {test}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
+ --> $DIR/issue-98604.rs:9: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:5: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/tests/ui/type-alias-impl-trait/issue-98608.rs b/tests/ui/type-alias-impl-trait/issue-98608.rs
new file mode 100644
index 000000000..1f89af045
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-98608.rs
@@ -0,0 +1,11 @@
+fn hi() -> impl Sized {
+ std::ptr::null::<u8>()
+}
+
+fn main() {
+ let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi);
+ //~^ ERROR expected `fn() -> impl Sized {hi}` to be a fn item that returns `Box<u8>`, but it returns `impl Sized`
+ let boxed = b();
+ let null = *boxed;
+ println!("{null:?}");
+}
diff --git a/tests/ui/type-alias-impl-trait/issue-98608.stderr b/tests/ui/type-alias-impl-trait/issue-98608.stderr
new file mode 100644
index 000000000..916a58451
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/issue-98608.stderr
@@ -0,0 +1,16 @@
+error[E0271]: expected `fn() -> impl Sized {hi}` to be a fn item that returns `Box<u8>`, but it returns `impl Sized`
+ --> $DIR/issue-98608.rs:6:39
+ |
+LL | fn hi() -> impl Sized {
+ | ---------- 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/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
new file mode 100644
index 000000000..01d1f5db1
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.rs
@@ -0,0 +1,7 @@
+#![feature(type_alias_impl_trait)]
+
+type Opaque<'a, T> = impl Sized;
+fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
+//~^ ERROR: hidden type for `Opaque<'a, T>` captures lifetime that does not appear in bounds
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
new file mode 100644
index 000000000..65a0af0d2
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/missing_lifetime_bound.stderr
@@ -0,0 +1,11 @@
+error[E0700]: hidden type for `Opaque<'a, T>` captures lifetime that does not appear in bounds
+ --> $DIR/missing_lifetime_bound.rs:4:47
+ |
+LL | fn defining<'a, T>(x: &'a i32) -> Opaque<T> { x }
+ | -- ^
+ | |
+ | hidden type `&'a i32` captures the lifetime `'a` as defined here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.rs
new file mode 100644
index 000000000..b887fcf30
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-infer.stderr
new file mode 100644
index 000000000..278117009
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs
new file mode 100644
index 000000000..65eb2952e
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.rs
@@ -0,0 +1,13 @@
+#![feature(type_alias_impl_trait)]
+
+pub trait Captures<'a> {}
+
+impl<'a, T: ?Sized> Captures<'a> for T {}
+
+type Foo<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
+
+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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-lifetimes.stderr
new file mode 100644
index 000000000..d7676b8e9
--- /dev/null
+++ b/tests/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:10: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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs
new file mode 100644
index 000000000..21fca047a
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn-pass.rs
@@ -0,0 +1,25 @@
+// 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)
+}
+
+pub trait Captures<'a> {}
+
+impl<'a, T: ?Sized> Captures<'a> for T {}
+
+type Foo<'a, 'b> = impl std::fmt::Debug + Captures<'a> + Captures<'b>;
+
+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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs
new file mode 100644
index 000000000..da845e861
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr
new file mode 100644
index 000000000..66a6b0bbf
--- /dev/null
+++ b/tests/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 for `&A` to implement `Into<&'static B>`
+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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs
new file mode 100644
index 000000000..14510a529
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr
new file mode 100644
index 000000000..0f752212a
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs
new file mode 100644
index 000000000..11a922443
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr
new file mode 100644
index 000000000..bbe709dcc
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/multiple_definitions.rs b/tests/ui/type-alias-impl-trait/multiple_definitions.rs
new file mode 100644
index 000000000..9e6268e63
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs
new file mode 100644
index 000000000..822489716
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/nested-tait-inference.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference.stderr
new file mode 100644
index 000000000..62db019ed
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs
new file mode 100644
index 000000000..0d7f5bad2
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.stderr
new file mode 100644
index 000000000..f4d96038d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference3.rs
new file mode 100644
index 000000000..b0ebdd1bf
--- /dev/null
+++ b/tests/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;
+//~^ ERROR unconstrained opaque type
+
+trait Foo<A> { }
+
+impl Foo<FooX> for () { }
+
+fn foo() -> impl Foo<FooX> {
+ ()
+}
+
+fn main() { }
diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr
new file mode 100644
index 000000000..b1d947a9c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/nested-tait-inference3.stderr
@@ -0,0 +1,10 @@
+error: unconstrained opaque type
+ --> $DIR/nested-tait-inference3.rs:6:13
+ |
+LL | type FooX = impl Debug;
+ | ^^^^^^^^^^
+ |
+ = note: `FooX` must be used in combination with a concrete type within the same module
+
+error: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/nested.rs b/tests/ui/type-alias-impl-trait/nested.rs
new file mode 100644
index 000000000..6b866be7d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/nested.stderr b/tests/ui/type-alias-impl-trait/nested.stderr
new file mode 100644
index 000000000..732af5c0b
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs
new file mode 100644
index 000000000..60b6e1aac
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr
new file mode 100644
index 000000000..fa6ecf68d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs b/tests/ui/type-alias-impl-trait/never_reveal_concrete_type.rs
new file mode 100644
index 000000000..fed5ac07c
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
new file mode 100644
index 000000000..0f0a02e97
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
@@ -0,0 +1,18 @@
+// 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);
+}
diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr
new file mode 100644
index 000000000..f3e8ae9c7
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr
@@ -0,0 +1,10 @@
+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: aborting due to previous error
+
diff --git a/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs
new file mode 100644
index 000000000..61153b1e1
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr b/tests/ui/type-alias-impl-trait/no_revealing_outside_defining_module.stderr
new file mode 100644
index 000000000..ae03a5b3e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/not_a_defining_use.rs b/tests/ui/type-alias-impl-trait/not_a_defining_use.rs
new file mode 100644
index 000000000..fa47d13f5
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr b/tests/ui/type-alias-impl-trait/not_a_defining_use.stderr
new file mode 100644
index 000000000..b11198c58
--- /dev/null
+++ b/tests/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 for `(T, i8)` to implement `Debug`
+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 for `(T, _)` to implement `Debug`
+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/tests/ui/type-alias-impl-trait/not_well_formed.rs b/tests/ui/type-alias-impl-trait/not_well_formed.rs
new file mode 100644
index 000000000..fbb7a4d58
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/not_well_formed.stderr b/tests/ui/type-alias-impl-trait/not_well_formed.stderr
new file mode 100644
index 000000000..c36b95f47
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/outlives-bound-var.rs b/tests/ui/type-alias-impl-trait/outlives-bound-var.rs
new file mode 100644
index 000000000..b8fac45b7
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/outlives-bound-var.rs
@@ -0,0 +1,18 @@
+// Here we process outlive obligations involving
+// opaque types with bound vars in substs.
+// This was an ICE.
+//
+// check-pass
+#![feature(type_alias_impl_trait)]
+
+type Ty<'a> = impl Sized + 'a;
+fn define<'a>() -> Ty<'a> {}
+
+// Ty<'^0>: 'static
+fn test1(_: &'static fn(Ty<'_>)) {}
+
+fn test2() {
+ None::<&fn(Ty<'_>)>;
+}
+
+fn main() { }
diff --git a/tests/ui/type-alias-impl-trait/reveal_local.rs b/tests/ui/type-alias-impl-trait/reveal_local.rs
new file mode 100644
index 000000000..7ecb55353
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/reveal_local.stderr b/tests/ui/type-alias-impl-trait/reveal_local.stderr
new file mode 100644
index 000000000..27fded333
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs
new file mode 100644
index 000000000..8781196c3
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/self-referential-2.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.stderr
new file mode 100644
index 000000000..c2cf70687
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/self-referential-2.stderr
@@ -0,0 +1,14 @@
+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 trait `PartialEq` is implemented for `i32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs
new file mode 100644
index 000000000..d40715717
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/self-referential-4.rs b/tests/ui/type-alias-impl-trait/self-referential-4.rs
new file mode 100644
index 000000000..36742c8ad
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/self-referential-4.stderr b/tests/ui/type-alias-impl-trait/self-referential-4.stderr
new file mode 100644
index 000000000..98c762e3d
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/self-referential-4.stderr
@@ -0,0 +1,36 @@
+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 trait `PartialEq` is implemented for `i32`
+
+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 trait `PartialEq` is implemented for `i32`
+
+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 trait `PartialEq` is implemented for `i32`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/self-referential.rs b/tests/ui/type-alias-impl-trait/self-referential.rs
new file mode 100644
index 000000000..3ff5406a3
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr
new file mode 100644
index 000000000..aff489d70
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/self-referential.stderr
@@ -0,0 +1,39 @@
+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 trait `PartialEq` is implemented for `i32`
+
+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 trait `PartialEq` is implemented for `i32`
+
+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 trait `PartialEq` is implemented for `i32`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/type-alias-impl-trait/self_implication.rs b/tests/ui/type-alias-impl-trait/self_implication.rs
new file mode 100644
index 000000000..4e805ee30
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/self_implication.rs
@@ -0,0 +1,38 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+fn foo() {
+ struct Foo<'a> {
+ x: &'a mut u8,
+ }
+ impl<'a> Foo<'a> {
+ fn foo(&self) -> impl Sized {}
+ }
+ // use site
+ let mut x = 5;
+ let y = Foo { x: &mut x };
+ let z = y.foo();
+ let _a = &x; // invalidate the `&'a mut`in `y`
+ let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live
+}
+
+fn bar() {
+ struct Foo<'a> {
+ x: &'a mut u8,
+ }
+
+ // desugared
+ type FooX<'a> = impl Sized;
+ impl<'a> Foo<'a> {
+ fn foo(&self) -> FooX<'a> {}
+ }
+
+ // use site
+ let mut x = 5;
+ let y = Foo { x: &mut x };
+ let z = y.foo();
+ let _a = &x; // invalidate the `&'a mut`in `y`
+ let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/static-const-types.rs b/tests/ui/type-alias-impl-trait/static-const-types.rs
new file mode 100644
index 000000000..748a279e4
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs b/tests/ui/type-alias-impl-trait/structural-match-no-leak.rs
new file mode 100644
index 000000000..c2ab6a9d1
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr b/tests/ui/type-alias-impl-trait/structural-match-no-leak.stderr
new file mode 100644
index 000000000..dbc183f54
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/structural-match.rs b/tests/ui/type-alias-impl-trait/structural-match.rs
new file mode 100644
index 000000000..7cc9ccaab
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/structural-match.stderr b/tests/ui/type-alias-impl-trait/structural-match.stderr
new file mode 100644
index 000000000..61287f268
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs
new file mode 100644
index 000000000..f6a830296
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs
new file mode 100644
index 000000000..fddecfcac
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs
new file mode 100644
index 000000000..5630e036b
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs
new file mode 100644
index 000000000..857066c78
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr
new file mode 100644
index 000000000..a31cf1a51
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs
new file mode 100644
index 000000000..07c891f06
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs
new file mode 100644
index 000000000..c5e8068e5
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs
new file mode 100644
index 000000000..1a4064055
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs
new file mode 100644
index 000000000..1f2d0e47e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs
new file mode 100644
index 000000000..efbf4f1e3
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr
new file mode 100644
index 000000000..8cdce2f8e
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs
new file mode 100644
index 000000000..e5e7fb677
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.stderr
new file mode 100644
index 000000000..a770eeac3
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs
new file mode 100644
index 000000000..7c7a1b405
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.stderr
new file mode 100644
index 000000000..3f3699ce5
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs
new file mode 100644
index 000000000..8ca279eec
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.stderr
new file mode 100644
index 000000000..3f7acd338
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait.rs
new file mode 100644
index 000000000..70c2ee427
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait2.rs
new file mode 100644
index 000000000..67f56bcde
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs b/tests/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs
new file mode 100644
index 000000000..fd954801d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type_of_a_let.rs b/tests/ui/type-alias-impl-trait/type_of_a_let.rs
new file mode 100644
index 000000000..4e9d1788b
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/type_of_a_let.stderr b/tests/ui/type-alias-impl-trait/type_of_a_let.stderr
new file mode 100644
index 000000000..1dabe4586
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs b/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs
new file mode 100644
index 000000000..f43ad7dce
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/unbounded_opaque_type.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+type Opaque<T> = impl Sized;
+fn defining<T>() -> Opaque<T> {}
+struct Ss<'a, T>(&'a Opaque<T>);
+
+
+fn test<'a, T>(_: Ss<'a, T>) {
+ // test that we have an implied bound `Opaque<T>: 'a` from fn signature
+ None::<&'a Opaque<T>>;
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/underconstrained_generic.rs b/tests/ui/type-alias-impl-trait/underconstrained_generic.rs
new file mode 100644
index 000000000..aa537dfc9
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr b/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr
new file mode 100644
index 000000000..103636b6c
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/underconstrained_generic.stderr
@@ -0,0 +1,21 @@
+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 for `()` to implement `ProofForConversion<T>`
+ --> $DIR/underconstrained_generic.rs:13:16
+ |
+LL | impl<X: Trait> ProofForConversion<X> for () {
+ | ----- ^^^^^^^^^^^^^^^^^^^^^ ^^
+ | |
+ | unsatisfied trait bound introduced here
+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/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.rs
new file mode 100644
index 000000000..c5b2e8a1c
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr b/tests/ui/type-alias-impl-trait/underconstrained_lifetime.stderr
new file mode 100644
index 000000000..12d85a49d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/unnameable_type.rs b/tests/ui/type-alias-impl-trait/unnameable_type.rs
new file mode 100644
index 000000000..1739ab006
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/unnameable_type.rs
@@ -0,0 +1,24 @@
+#![feature(type_alias_impl_trait)]
+
+// This test ensures that unnameable types stay unnameable
+// https://github.com/rust-lang/rust/issues/63063#issuecomment-1360053614
+
+// library
+mod private {
+ pub struct Private;
+ pub trait Trait {
+ fn dont_define_this(_private: Private) {}
+ }
+}
+
+use private::Trait;
+
+// downstream
+type MyPrivate = impl Sized;
+//~^ ERROR: unconstrained opaque type
+impl Trait for u32 {
+ fn dont_define_this(_private: MyPrivate) {}
+ //~^ ERROR: incompatible type for trait
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
new file mode 100644
index 000000000..7dc6efc4b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
@@ -0,0 +1,31 @@
+error: unconstrained opaque type
+ --> $DIR/unnameable_type.rs:17:18
+ |
+LL | type MyPrivate = impl Sized;
+ | ^^^^^^^^^^
+ |
+ = note: `MyPrivate` must be used in combination with a concrete type within the same module
+
+error[E0053]: method `dont_define_this` has an incompatible type for trait
+ --> $DIR/unnameable_type.rs:20:35
+ |
+LL | type MyPrivate = impl Sized;
+ | ---------- the found opaque type
+...
+LL | fn dont_define_this(_private: MyPrivate) {}
+ | ^^^^^^^^^
+ | |
+ | expected struct `Private`, found opaque type
+ | help: change the parameter type to match the trait: `Private`
+ |
+note: type in trait
+ --> $DIR/unnameable_type.rs:10:39
+ |
+LL | fn dont_define_this(_private: Private) {}
+ | ^^^^^^^
+ = note: expected signature `fn(Private)`
+ found signature `fn(MyPrivate)`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0053`.
diff --git a/tests/ui/type-alias-impl-trait/unused_generic_param.rs b/tests/ui/type-alias-impl-trait/unused_generic_param.rs
new file mode 100644
index 000000000..ad5e4918c
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/weird-return-types.rs b/tests/ui/type-alias-impl-trait/weird-return-types.rs
new file mode 100644
index 000000000..faad5ee95
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs b/tests/ui/type-alias-impl-trait/wf-check-fn-def.rs
new file mode 100644
index 000000000..449e9fbd0
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr b/tests/ui/type-alias-impl-trait/wf-check-fn-def.stderr
new file mode 100644
index 000000000..e0005489d
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs b/tests/ui/type-alias-impl-trait/wf-check-fn-ptrs.rs
new file mode 100644
index 000000000..3b8470e4a
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/wf_check_closures.rs b/tests/ui/type-alias-impl-trait/wf_check_closures.rs
new file mode 100644
index 000000000..2c70696ff
--- /dev/null
+++ b/tests/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/tests/ui/type-alias-impl-trait/wf_check_closures.stderr b/tests/ui/type-alias-impl-trait/wf_check_closures.stderr
new file mode 100644
index 000000000..58ae8617b
--- /dev/null
+++ b/tests/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`.