@@ -12,7 +12,7 @@ use rustc_trait_selection::traits::check_args_compatible;
1212use crate :: errors:: { DuplicateArg , NotParam } ;
1313use crate :: sig_types:: SpannedTypeVisitor ;
1414
15- struct OpaqueTypeCollector < ' tcx > {
15+ struct OpaqueTypeCollector < ' tcx , ' a > {
1616 tcx : TyCtxt < ' tcx > ,
1717 opaques : Vec < LocalDefId > ,
1818 /// The `DefId` of the item which we are collecting opaque types for.
@@ -21,31 +21,30 @@ struct OpaqueTypeCollector<'tcx> {
2121 /// Avoid infinite recursion due to recursive declarations.
2222 seen : FxHashSet < LocalDefId > ,
2323
24- span : Option < Span > ,
24+ get_span : & ' a dyn Fn ( ) -> Span ,
2525
2626 mode : CollectionMode ,
2727}
2828
29+ #[ derive( Copy , Clone ) ]
2930enum CollectionMode {
3031 /// For impl trait in assoc types we only permit collecting them from
3132 /// associated types of the same impl block.
3233 ImplTraitInAssocTypes ,
3334 TypeAliasImplTraitTransition ,
3435}
3536
36- impl < ' tcx > OpaqueTypeCollector < ' tcx > {
37- fn new ( tcx : TyCtxt < ' tcx > , item : LocalDefId ) -> Self {
37+ impl < ' tcx , ' a > OpaqueTypeCollector < ' tcx , ' a > {
38+ fn new ( tcx : TyCtxt < ' tcx > , item : LocalDefId , get_span : & ' a dyn Fn ( ) -> Span ) -> Self {
3839 let mode = match tcx. def_kind ( tcx. local_parent ( item) ) {
3940 DefKind :: Impl { of_trait : true } => CollectionMode :: ImplTraitInAssocTypes ,
4041 _ => CollectionMode :: TypeAliasImplTraitTransition ,
4142 } ;
42- Self { tcx, opaques : Vec :: new ( ) , item, seen : Default :: default ( ) , span : None , mode }
43+ Self { tcx, opaques : Vec :: new ( ) , item, seen : Default :: default ( ) , get_span , mode }
4344 }
4445
4546 fn span ( & self ) -> Span {
46- self . span . unwrap_or_else ( || {
47- self . tcx . def_ident_span ( self . item ) . unwrap_or_else ( || self . tcx . def_span ( self . item ) )
48- } )
47+ ( self . get_span ) ( )
4948 }
5049
5150 fn parent_trait_ref ( & self ) -> Option < ty:: TraitRef < ' tcx > > {
@@ -103,10 +102,10 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
103102 #[ instrument( level = "trace" , skip( self ) ) ]
104103 fn collect_taits_declared_in_body ( & mut self ) {
105104 let body = self . tcx . hir ( ) . body ( self . tcx . hir ( ) . body_owned_by ( self . item ) ) . value ;
106- struct TaitInBodyFinder < ' a , ' tcx > {
107- collector : & ' a mut OpaqueTypeCollector < ' tcx > ,
105+ struct TaitInBodyFinder < ' a , ' b , ' tcx > {
106+ collector : & ' a mut OpaqueTypeCollector < ' tcx , ' b > ,
108107 }
109- impl < ' v > intravisit:: Visitor < ' v > for TaitInBodyFinder < ' _ , ' _ > {
108+ impl < ' v > intravisit:: Visitor < ' v > for TaitInBodyFinder < ' _ , ' _ , ' _ > {
110109 #[ instrument( level = "trace" , skip( self ) ) ]
111110 fn visit_nested_item ( & mut self , id : rustc_hir:: ItemId ) {
112111 let id = id. owner_id . def_id ;
@@ -189,17 +188,25 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
189188 }
190189}
191190
192- impl < ' tcx > SpannedTypeVisitor < ' tcx > for OpaqueTypeCollector < ' tcx > {
191+ impl < ' tcx > SpannedTypeVisitor < ' tcx > for OpaqueTypeCollector < ' tcx , ' _ > {
193192 #[ instrument( skip( self ) , ret, level = "trace" ) ]
194193 fn visit ( & mut self , span : Span , value : impl TypeVisitable < TyCtxt < ' tcx > > ) {
195- let old = self . span ;
196- self . span = Some ( span) ;
197- value. visit_with ( self ) ;
198- self . span = old;
194+ let get_span = || span;
195+ let mut nested = OpaqueTypeCollector {
196+ get_span : & get_span,
197+ tcx : self . tcx ,
198+ opaques : std:: mem:: take ( & mut self . opaques ) ,
199+ item : self . item ,
200+ seen : std:: mem:: take ( & mut self . seen ) ,
201+ mode : self . mode ,
202+ } ;
203+ value. visit_with ( & mut nested) ;
204+ self . opaques = nested. opaques ;
205+ self . seen = nested. seen ;
199206 }
200207}
201208
202- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for OpaqueTypeCollector < ' tcx > {
209+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for OpaqueTypeCollector < ' tcx , ' _ > {
203210 #[ instrument( skip( self ) , ret, level = "trace" ) ]
204211 fn visit_ty ( & mut self , t : Ty < ' tcx > ) {
205212 t. super_visit_with ( self ) ;
@@ -291,7 +298,8 @@ fn opaque_types_defined_by<'tcx>(
291298) -> & ' tcx ty:: List < LocalDefId > {
292299 let kind = tcx. def_kind ( item) ;
293300 trace ! ( ?kind) ;
294- let mut collector = OpaqueTypeCollector :: new ( tcx, item) ;
301+ let default_span = || tcx. def_ident_span ( item) . unwrap_or_else ( || tcx. def_span ( item) ) ;
302+ let mut collector = OpaqueTypeCollector :: new ( tcx, item, & default_span) ;
295303 super :: sig_types:: walk_types ( tcx, item, & mut collector) ;
296304 match kind {
297305 DefKind :: AssocFn
0 commit comments