@@ -22,11 +22,20 @@ struct OpaqueTypeCollector<'tcx> {
2222 seen : FxHashSet < LocalDefId > ,
2323
2424 span : Option < Span > ,
25+
26+ mode : CollectionMode ,
27+ }
28+
29+ enum CollectionMode {
30+ /// For impl trait in assoc types we only permit collecting them from
31+ /// associated types of the same impl block.
32+ ImplTraitInAssocTypes ,
33+ TypeAliasImplTraitTransition ,
2534}
2635
2736impl < ' tcx > OpaqueTypeCollector < ' tcx > {
28- fn new ( tcx : TyCtxt < ' tcx > , item : LocalDefId ) -> Self {
29- Self { tcx, opaques : Vec :: new ( ) , item, seen : Default :: default ( ) , span : None }
37+ fn new ( tcx : TyCtxt < ' tcx > , item : LocalDefId , mode : CollectionMode ) -> Self {
38+ Self { tcx, opaques : Vec :: new ( ) , item, seen : Default :: default ( ) , span : None , mode }
3039 }
3140
3241 fn span ( & self ) -> Span {
@@ -251,6 +260,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
251260 }
252261 }
253262 ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => {
263+ if let CollectionMode :: ImplTraitInAssocTypes = self . mode {
264+ return ControlFlow :: Continue ( ( ) ) ;
265+ }
254266 if !self . seen . insert ( def. did ( ) . expect_local ( ) ) {
255267 return ControlFlow :: Continue ( ( ) ) ;
256268 }
@@ -275,89 +287,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
275287 }
276288}
277289
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 args 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_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-
354290fn impl_trait_in_assoc_types_defined_by < ' tcx > (
355291 tcx : TyCtxt < ' tcx > ,
356292 item : LocalDefId ,
357293) -> & ' tcx ty:: List < LocalDefId > {
358- let mut collector = ImplTraitInAssocTypeCollector ( OpaqueTypeCollector :: new ( tcx, item) ) ;
294+ let mut collector = OpaqueTypeCollector :: new ( tcx, item, CollectionMode :: ImplTraitInAssocTypes ) ;
359295 super :: sig_types:: walk_types ( tcx, item, & mut collector) ;
360- tcx. mk_local_def_ids ( & collector. 0 . opaques )
296+ tcx. mk_local_def_ids ( & collector. opaques )
361297}
362298
363299fn opaque_types_defined_by < ' tcx > (
@@ -366,7 +302,8 @@ fn opaque_types_defined_by<'tcx>(
366302) -> & ' tcx ty:: List < LocalDefId > {
367303 let kind = tcx. def_kind ( item) ;
368304 trace ! ( ?kind) ;
369- let mut collector = OpaqueTypeCollector :: new ( tcx, item) ;
305+ let mut collector =
306+ OpaqueTypeCollector :: new ( tcx, item, CollectionMode :: TypeAliasImplTraitTransition ) ;
370307 super :: sig_types:: walk_types ( tcx, item, & mut collector) ;
371308 match kind {
372309 DefKind :: AssocFn
0 commit comments