@@ -12,7 +12,7 @@ use rustc_trait_selection::traits::check_args_compatible;
12
12
use crate :: errors:: { DuplicateArg , NotParam } ;
13
13
use crate :: sig_types:: SpannedTypeVisitor ;
14
14
15
- struct OpaqueTypeCollector < ' tcx > {
15
+ struct OpaqueTypeCollector < ' tcx , ' a > {
16
16
tcx : TyCtxt < ' tcx > ,
17
17
opaques : Vec < LocalDefId > ,
18
18
/// The `DefId` of the item which we are collecting opaque types for.
@@ -21,31 +21,30 @@ struct OpaqueTypeCollector<'tcx> {
21
21
/// Avoid infinite recursion due to recursive declarations.
22
22
seen : FxHashSet < LocalDefId > ,
23
23
24
- span : Option < Span > ,
24
+ get_span : & ' a dyn Fn ( ) -> Span ,
25
25
26
26
mode : CollectionMode ,
27
27
}
28
28
29
+ #[ derive( Copy , Clone ) ]
29
30
enum CollectionMode {
30
31
/// For impl trait in assoc types we only permit collecting them from
31
32
/// associated types of the same impl block.
32
33
ImplTraitInAssocTypes ,
33
34
TypeAliasImplTraitTransition ,
34
35
}
35
36
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 {
38
39
let mode = match tcx. def_kind ( tcx. local_parent ( item) ) {
39
40
DefKind :: Impl { of_trait : true } => CollectionMode :: ImplTraitInAssocTypes ,
40
41
_ => CollectionMode :: TypeAliasImplTraitTransition ,
41
42
} ;
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 }
43
44
}
44
45
45
46
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 ) ( )
49
48
}
50
49
51
50
fn parent_trait_ref ( & self ) -> Option < ty:: TraitRef < ' tcx > > {
@@ -103,10 +102,10 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
103
102
#[ instrument( level = "trace" , skip( self ) ) ]
104
103
fn collect_taits_declared_in_body ( & mut self ) {
105
104
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 > ,
108
107
}
109
- impl < ' v > intravisit:: Visitor < ' v > for TaitInBodyFinder < ' _ , ' _ > {
108
+ impl < ' v > intravisit:: Visitor < ' v > for TaitInBodyFinder < ' _ , ' _ , ' _ > {
110
109
#[ instrument( level = "trace" , skip( self ) ) ]
111
110
fn visit_nested_item ( & mut self , id : rustc_hir:: ItemId ) {
112
111
let id = id. owner_id . def_id ;
@@ -189,17 +188,25 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
189
188
}
190
189
}
191
190
192
- impl < ' tcx > SpannedTypeVisitor < ' tcx > for OpaqueTypeCollector < ' tcx > {
191
+ impl < ' tcx > SpannedTypeVisitor < ' tcx > for OpaqueTypeCollector < ' tcx , ' _ > {
193
192
#[ instrument( skip( self ) , ret, level = "trace" ) ]
194
193
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 ;
199
206
}
200
207
}
201
208
202
- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for OpaqueTypeCollector < ' tcx > {
209
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for OpaqueTypeCollector < ' tcx , ' _ > {
203
210
#[ instrument( skip( self ) , ret, level = "trace" ) ]
204
211
fn visit_ty ( & mut self , t : Ty < ' tcx > ) {
205
212
t. super_visit_with ( self ) ;
@@ -291,7 +298,8 @@ fn opaque_types_defined_by<'tcx>(
291
298
) -> & ' tcx ty:: List < LocalDefId > {
292
299
let kind = tcx. def_kind ( item) ;
293
300
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) ;
295
303
super :: sig_types:: walk_types ( tcx, item, & mut collector) ;
296
304
match kind {
297
305
DefKind :: AssocFn
0 commit comments