@@ -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,39 @@ 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 ( & Self ) -> 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
+ impl < ' tcx > OpaqueTypeCollector < ' tcx , ' _ > {
37
38
fn new ( tcx : TyCtxt < ' tcx > , item : LocalDefId ) -> 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 {
44
+ tcx,
45
+ opaques : Vec :: new ( ) ,
46
+ item,
47
+ seen : Default :: default ( ) ,
48
+ get_span : & |this| {
49
+ this. tcx . def_ident_span ( this. item ) . unwrap_or_else ( || this. tcx . def_span ( this. item ) )
50
+ } ,
51
+ mode,
52
+ }
43
53
}
44
54
45
55
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
- } )
56
+ ( self . get_span ) ( self )
49
57
}
50
58
51
59
fn parent_trait_ref ( & self ) -> Option < ty:: TraitRef < ' tcx > > {
@@ -105,10 +113,10 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
105
113
// Some things not necessarily have bodies, like method declarations in traits.
106
114
let Some ( body_owner) = self . tcx . hir ( ) . maybe_body_owned_by ( self . item ) else { return } ;
107
115
let body = self . tcx . hir ( ) . body ( body_owner) . value ;
108
- struct TaitInBodyFinder < ' a , ' tcx > {
109
- collector : & ' a mut OpaqueTypeCollector < ' tcx > ,
116
+ struct TaitInBodyFinder < ' a , ' b , ' tcx > {
117
+ collector : & ' a mut OpaqueTypeCollector < ' tcx , ' b > ,
110
118
}
111
- impl < ' v > intravisit:: Visitor < ' v > for TaitInBodyFinder < ' _ , ' _ > {
119
+ impl < ' v > intravisit:: Visitor < ' v > for TaitInBodyFinder < ' _ , ' _ , ' _ > {
112
120
#[ instrument( level = "trace" , skip( self ) ) ]
113
121
fn visit_nested_item ( & mut self , id : rustc_hir:: ItemId ) {
114
122
let id = id. owner_id . def_id ;
@@ -191,17 +199,25 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
191
199
}
192
200
}
193
201
194
- impl < ' tcx > SpannedTypeVisitor < ' tcx > for OpaqueTypeCollector < ' tcx > {
202
+ impl < ' tcx > SpannedTypeVisitor < ' tcx > for OpaqueTypeCollector < ' tcx , ' _ > {
195
203
#[ instrument( skip( self ) , ret, level = "trace" ) ]
196
204
fn visit ( & mut self , span : Span , value : impl TypeVisitable < TyCtxt < ' tcx > > ) {
197
- let old = self . span ;
198
- self . span = Some ( span) ;
199
- value. visit_with ( self ) ;
200
- self . span = old;
205
+ let get_span = |_this : & _ | span;
206
+ let mut nested = OpaqueTypeCollector {
207
+ get_span : & get_span,
208
+ tcx : self . tcx ,
209
+ opaques : std:: mem:: take ( & mut self . opaques ) ,
210
+ item : self . item ,
211
+ seen : std:: mem:: take ( & mut self . seen ) ,
212
+ mode : self . mode ,
213
+ } ;
214
+ value. visit_with ( & mut nested) ;
215
+ self . opaques = nested. opaques ;
216
+ self . seen = nested. seen ;
201
217
}
202
218
}
203
219
204
- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for OpaqueTypeCollector < ' tcx > {
220
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for OpaqueTypeCollector < ' tcx , ' _ > {
205
221
#[ instrument( skip( self ) , ret, level = "trace" ) ]
206
222
fn visit_ty ( & mut self , t : Ty < ' tcx > ) {
207
223
t. super_visit_with ( self ) ;
0 commit comments