@@ -275,11 +275,89 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
275275 }
276276}
277277
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+
278354fn impl_trait_in_assoc_types_defined_by < ' tcx > (
279355 tcx : TyCtxt < ' tcx > ,
280356 item : LocalDefId ,
281357) -> & ' 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 )
283361}
284362
285363fn opaque_types_defined_by < ' tcx > (
0 commit comments