@@ -275,11 +275,89 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
275
275
}
276
276
}
277
277
278
+ struct ImplTraitInAssocTypeCollector < ' tcx > ( OpaqueTypeCollector < ' tcx > ) ;
279
+
280
+ impl < ' tcx > super :: sig_types:: SpannedTypeVisitor < ' tcx > for ImplTraitInAssocTypeCollector < ' tcx > {
281
+ #[ instrument( skip( self ) , ret, level = "trace" ) ]
282
+ fn visit ( & mut self , span : Span , value : impl TypeVisitable < TyCtxt < ' tcx > > ) -> ControlFlow < !> {
283
+ let old = self . 0 . span ;
284
+ self . 0 . span = Some ( span) ;
285
+ value. visit_with ( self ) ;
286
+ self . 0 . span = old;
287
+
288
+ ControlFlow :: Continue ( ( ) )
289
+ }
290
+ }
291
+
292
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for ImplTraitInAssocTypeCollector < ' tcx > {
293
+ #[ instrument( skip( self ) , ret, level = "trace" ) ]
294
+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < !> {
295
+ t. super_visit_with ( self ) ?;
296
+ match t. kind ( ) {
297
+ ty:: Alias ( ty:: Opaque , alias_ty) if alias_ty. def_id . is_local ( ) => {
298
+ self . 0 . visit_opaque_ty ( alias_ty) ;
299
+ }
300
+ ty:: Alias ( ty:: Projection , alias_ty) => {
301
+ // This avoids having to do normalization of `Self::AssocTy` by only
302
+ // supporting the case of a method defining opaque types from assoc types
303
+ // in the same impl block.
304
+ let parent_trait_ref = self
305
+ . 0
306
+ . parent_trait_ref ( )
307
+ . expect ( "impl trait in assoc type collector used on non-assoc item" ) ;
308
+ // If the trait ref of the associated item and the impl differs,
309
+ // then we can't use the impl's identity substitutions below, so
310
+ // just skip.
311
+ if alias_ty. trait_ref ( self . 0 . tcx ) == parent_trait_ref {
312
+ let parent = self . 0 . parent ( ) . expect ( "we should have a parent here" ) ;
313
+
314
+ for & assoc in self . 0 . tcx . associated_items ( parent) . in_definition_order ( ) {
315
+ trace ! ( ?assoc) ;
316
+ if assoc. trait_item_def_id != Some ( alias_ty. def_id ) {
317
+ continue ;
318
+ }
319
+
320
+ // If the type is further specializable, then the type_of
321
+ // is not actually correct below.
322
+ if !assoc. defaultness ( self . 0 . tcx ) . is_final ( ) {
323
+ continue ;
324
+ }
325
+
326
+ let impl_args = alias_ty. args . rebase_onto (
327
+ self . 0 . tcx ,
328
+ parent_trait_ref. def_id ,
329
+ ty:: GenericArgs :: identity_for_item ( self . 0 . tcx , parent) ,
330
+ ) ;
331
+
332
+ if check_args_compatible ( self . 0 . tcx , assoc, impl_args) {
333
+ return self
334
+ . 0
335
+ . tcx
336
+ . type_of ( assoc. def_id )
337
+ . instantiate ( self . 0 . tcx , impl_args)
338
+ . visit_with ( self ) ;
339
+ } else {
340
+ self . 0 . tcx . dcx ( ) . span_delayed_bug (
341
+ self . 0 . tcx . def_span ( assoc. def_id ) ,
342
+ "item had incorrect args" ,
343
+ ) ;
344
+ }
345
+ }
346
+ }
347
+ }
348
+ _ => trace ! ( kind=?t. kind( ) ) ,
349
+ }
350
+ ControlFlow :: Continue ( ( ) )
351
+ }
352
+ }
353
+
278
354
fn impl_trait_in_assoc_types_defined_by < ' tcx > (
279
355
tcx : TyCtxt < ' tcx > ,
280
356
item : LocalDefId ,
281
357
) -> & ' tcx ty:: List < LocalDefId > {
282
- opaque_types_defined_by ( tcx, item)
358
+ let mut collector = ImplTraitInAssocTypeCollector ( OpaqueTypeCollector :: new ( tcx, item) ) ;
359
+ super :: sig_types:: walk_types ( tcx, item, & mut collector) ;
360
+ tcx. mk_local_def_ids ( & collector. 0 . opaques )
283
361
}
284
362
285
363
fn opaque_types_defined_by < ' tcx > (
0 commit comments