@@ -71,7 +71,15 @@ enum ProjectionCandidate<'tcx> {
7171 /// From an "impl" (or a "pseudo-impl" returned by select)
7272 Select ( Selection < ' tcx > ) ,
7373
74- ImplTraitInTrait ( ImplSourceUserDefinedData < ' tcx , PredicateObligation < ' tcx > > ) ,
74+ ImplTraitInTrait ( ImplTraitInTraitCandidate < ' tcx > ) ,
75+ }
76+
77+ #[ derive( PartialEq , Eq , Debug ) ]
78+ enum ImplTraitInTraitCandidate < ' tcx > {
79+ // The `impl Trait` from a trait function's default body
80+ Trait ,
81+ // A concrete type provided from a trait's `impl Trait` from an impl
82+ Impl ( ImplSourceUserDefinedData < ' tcx , PredicateObligation < ' tcx > > ) ,
7583}
7684
7785enum ProjectionCandidateSet < ' tcx > {
@@ -1317,6 +1325,17 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
13171325) {
13181326 let tcx = selcx. tcx ( ) ;
13191327 if tcx. def_kind ( obligation. predicate . item_def_id ) == DefKind :: ImplTraitPlaceholder {
1328+ // If we are trying to project an RPITIT with the _identity_ substs,
1329+ // then we must be within a default trait body.
1330+ if obligation. predicate . substs
1331+ == ty:: InternalSubsts :: identity_for_item ( tcx, obligation. predicate . item_def_id )
1332+ {
1333+ candidate_set. push_candidate ( ProjectionCandidate :: ImplTraitInTrait (
1334+ ImplTraitInTraitCandidate :: Trait ,
1335+ ) ) ;
1336+ return ;
1337+ }
1338+
13201339 let trait_fn_def_id = tcx. impl_trait_in_trait_parent ( obligation. predicate . item_def_id ) ;
13211340 let trait_def_id = tcx. parent ( trait_fn_def_id) ;
13221341 let trait_substs =
@@ -1329,7 +1348,9 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
13291348 let _ =
13301349 selcx. infcx ( ) . commit_if_ok ( |_| match selcx. select ( & obligation. with ( trait_predicate) ) {
13311350 Ok ( Some ( super :: ImplSource :: UserDefined ( data) ) ) => {
1332- candidate_set. push_candidate ( ProjectionCandidate :: ImplTraitInTrait ( data) ) ;
1351+ candidate_set. push_candidate ( ProjectionCandidate :: ImplTraitInTrait (
1352+ ImplTraitInTraitCandidate :: Impl ( data) ,
1353+ ) ) ;
13331354 Ok ( ( ) )
13341355 }
13351356 Ok ( None ) => {
@@ -1792,9 +1813,18 @@ fn confirm_candidate<'cx, 'tcx>(
17921813 ProjectionCandidate :: Select ( impl_source) => {
17931814 confirm_select_candidate ( selcx, obligation, impl_source)
17941815 }
1795- ProjectionCandidate :: ImplTraitInTrait ( data) => {
1816+ ProjectionCandidate :: ImplTraitInTrait ( ImplTraitInTraitCandidate :: Impl ( data) ) => {
17961817 confirm_impl_trait_in_trait_candidate ( selcx, obligation, data)
17971818 }
1819+ // If we're projecting an RPITIT for a default trait body, that's just
1820+ // the same def-id, but as an opaque type (with regular RPIT semantics).
1821+ ProjectionCandidate :: ImplTraitInTrait ( ImplTraitInTraitCandidate :: Trait ) => Progress {
1822+ term : selcx
1823+ . tcx ( )
1824+ . mk_opaque ( obligation. predicate . item_def_id , obligation. predicate . substs )
1825+ . into ( ) ,
1826+ obligations : vec ! [ ] ,
1827+ } ,
17981828 } ;
17991829
18001830 // When checking for cycle during evaluation, we compare predicates with
@@ -2212,6 +2242,16 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
22122242 return Progress { term : tcx. ty_error ( ) . into ( ) , obligations } ;
22132243 }
22142244
2245+ // Use the default `impl Trait` for the trait, e.g., for a default trait body
2246+ if leaf_def. item . container == ty:: AssocItemContainer :: TraitContainer {
2247+ return Progress {
2248+ term : tcx
2249+ . mk_opaque ( obligation. predicate . item_def_id , obligation. predicate . substs )
2250+ . into ( ) ,
2251+ obligations,
2252+ } ;
2253+ }
2254+
22152255 let impl_fn_def_id = leaf_def. item . def_id ;
22162256 let impl_fn_substs = obligation. predicate . substs . rebase_onto ( tcx, trait_fn_def_id, data. substs ) ;
22172257
0 commit comments