@@ -54,7 +54,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
5454 self . span = old;
5555 }
5656
57- fn parent_trait_ref ( & self ) -> Option < ty:: TraitRef < ' tcx > > {
57+ fn parent_impl_trait_ref ( & self ) -> Option < ty:: TraitRef < ' tcx > > {
5858 let parent = self . parent ( ) ?;
5959 if matches ! ( self . tcx. def_kind( parent) , DefKind :: Impl { .. } ) {
6060 Some ( self . tcx . impl_trait_ref ( parent) ?. instantiate_identity ( ) )
@@ -217,26 +217,15 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
217217 . instantiate ( self . tcx , alias_ty. args )
218218 . visit_with ( self ) ;
219219 }
220- // RPITIT are encoded as projections, not opaque types, make sure to handle these special
221- // projections independently of the projection handling below.
222- ty:: Alias ( ty:: Projection , alias_ty)
223- if let Some ( ty:: ImplTraitInTraitData :: Trait { fn_def_id, .. } ) =
224- self . tcx . opt_rpitit_info ( alias_ty. def_id )
225- && fn_def_id == self . item . into ( ) =>
226- {
227- let ty = self . tcx . type_of ( alias_ty. def_id ) . instantiate ( self . tcx , alias_ty. args ) ;
228- let ty:: Alias ( ty:: Opaque , alias_ty) = ty. kind ( ) else { bug ! ( "{ty:?}" ) } ;
229- self . visit_opaque_ty ( alias_ty) ;
230- }
231220 ty:: Alias ( ty:: Projection , alias_ty) => {
232221 // This avoids having to do normalization of `Self::AssocTy` by only
233222 // supporting the case of a method defining opaque types from assoc types
234223 // in the same impl block.
235- if let Some ( parent_trait_ref ) = self . parent_trait_ref ( ) {
224+ if let Some ( impl_trait_ref ) = self . parent_impl_trait_ref ( ) {
236225 // If the trait ref of the associated item and the impl differs,
237226 // then we can't use the impl's identity args below, so
238227 // just skip.
239- if alias_ty. trait_ref ( self . tcx ) == parent_trait_ref {
228+ if alias_ty. trait_ref ( self . tcx ) == impl_trait_ref {
240229 let parent = self . parent ( ) . expect ( "we should have a parent here" ) ;
241230
242231 for & assoc in self . tcx . associated_items ( parent) . in_definition_order ( ) {
@@ -253,7 +242,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
253242
254243 let impl_args = alias_ty. args . rebase_onto (
255244 self . tcx ,
256- parent_trait_ref . def_id ,
245+ impl_trait_ref . def_id ,
257246 ty:: GenericArgs :: identity_for_item ( self . tcx , parent) ,
258247 ) ;
259248
@@ -271,6 +260,24 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
271260 }
272261 }
273262 }
263+ } else if let Some ( ty:: ImplTraitInTraitData :: Trait { fn_def_id, .. } ) =
264+ self . tcx . opt_rpitit_info ( alias_ty. def_id )
265+ && fn_def_id == self . item . into ( )
266+ {
267+ // RPITIT in trait definitions get desugared to an associated type. For
268+ // default methods we also create an opaque type this associated type
269+ // normalizes to. The associated type is only known to normalize to the
270+ // opaque if it is fully concrete. There could otherwise be an impl
271+ // overwriting the default method.
272+ //
273+ // However, we have to be able to normalize the associated type while inside
274+ // of the default method. This is normally handled by adding an unchecked
275+ // `Projection(<Self as Trait>::synthetic_assoc_ty, trait_def::opaque)`
276+ // assumption to the `param_env` of the default method. We also separately
277+ // rely on that assumption here.
278+ let ty = self . tcx . type_of ( alias_ty. def_id ) . instantiate ( self . tcx , alias_ty. args ) ;
279+ let ty:: Alias ( ty:: Opaque , alias_ty) = ty. kind ( ) else { bug ! ( "{ty:?}" ) } ;
280+ self . visit_opaque_ty ( alias_ty) ;
274281 }
275282 }
276283 ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => {
0 commit comments