@@ -54,7 +54,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
54
54
self . span = old;
55
55
}
56
56
57
- fn parent_trait_ref ( & self ) -> Option < ty:: TraitRef < ' tcx > > {
57
+ fn parent_impl_trait_ref ( & self ) -> Option < ty:: TraitRef < ' tcx > > {
58
58
let parent = self . parent ( ) ?;
59
59
if matches ! ( self . tcx. def_kind( parent) , DefKind :: Impl { .. } ) {
60
60
Some ( self . tcx . impl_trait_ref ( parent) ?. instantiate_identity ( ) )
@@ -217,26 +217,15 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
217
217
. instantiate ( self . tcx , alias_ty. args )
218
218
. visit_with ( self ) ;
219
219
}
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
- }
231
220
ty:: Alias ( ty:: Projection , alias_ty) => {
232
221
// This avoids having to do normalization of `Self::AssocTy` by only
233
222
// supporting the case of a method defining opaque types from assoc types
234
223
// 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 ( ) {
236
225
// If the trait ref of the associated item and the impl differs,
237
226
// then we can't use the impl's identity args below, so
238
227
// just skip.
239
- if alias_ty. trait_ref ( self . tcx ) == parent_trait_ref {
228
+ if alias_ty. trait_ref ( self . tcx ) == impl_trait_ref {
240
229
let parent = self . parent ( ) . expect ( "we should have a parent here" ) ;
241
230
242
231
for & assoc in self . tcx . associated_items ( parent) . in_definition_order ( ) {
@@ -253,7 +242,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
253
242
254
243
let impl_args = alias_ty. args . rebase_onto (
255
244
self . tcx ,
256
- parent_trait_ref . def_id ,
245
+ impl_trait_ref . def_id ,
257
246
ty:: GenericArgs :: identity_for_item ( self . tcx , parent) ,
258
247
) ;
259
248
@@ -271,6 +260,24 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
271
260
}
272
261
}
273
262
}
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) ;
274
281
}
275
282
}
276
283
ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => {
0 commit comments