@@ -16,6 +16,7 @@ use rustc_span::Span;
16
16
17
17
struct InteriorVisitor < ' a , ' tcx > {
18
18
fcx : & ' a FnCtxt < ' a , ' tcx > ,
19
+ closure_def_id : DefId ,
19
20
types : FxHashMap < ty:: GeneratorInteriorTypeCause < ' tcx > , usize > ,
20
21
region_scope_tree : & ' tcx region:: ScopeTree ,
21
22
expr_count : usize ,
@@ -30,6 +31,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
30
31
scope : Option < region:: Scope > ,
31
32
expr : Option < & ' tcx Expr < ' tcx > > ,
32
33
source_span : Span ,
34
+ is_upvar : bool ,
33
35
) {
34
36
use rustc_span:: DUMMY_SP ;
35
37
@@ -96,7 +98,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
96
98
span : source_span,
97
99
ty : & ty,
98
100
scope_span,
99
- yield_span : yield_data. span ,
101
+ yield_span : Some ( yield_data. span ) ,
100
102
expr : expr. map ( |e| e. hir_id ) ,
101
103
} )
102
104
. or_insert ( entries) ;
@@ -117,6 +119,20 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
117
119
unresolved_type, unresolved_type_span
118
120
) ;
119
121
self . prev_unresolved_span = unresolved_type_span;
122
+ } else {
123
+ if is_upvar {
124
+ let entries = self . types . len ( ) ;
125
+ let scope_span = scope. map ( |s| s. span ( self . fcx . tcx , self . region_scope_tree ) ) ;
126
+ self . types
127
+ . entry ( ty:: GeneratorInteriorTypeCause {
128
+ span : source_span,
129
+ ty : & ty,
130
+ scope_span,
131
+ yield_span : None ,
132
+ expr : expr. map ( |e| e. hir_id ) ,
133
+ } )
134
+ . or_insert ( entries) ;
135
+ }
120
136
}
121
137
}
122
138
}
@@ -130,8 +146,12 @@ pub fn resolve_interior<'a, 'tcx>(
130
146
kind : hir:: GeneratorKind ,
131
147
) {
132
148
let body = fcx. tcx . hir ( ) . body ( body_id) ;
149
+
150
+ let closure_def_id = fcx. tcx . hir ( ) . body_owner_def_id ( body_id) . to_def_id ( ) ;
151
+
133
152
let mut visitor = InteriorVisitor {
134
153
fcx,
154
+ closure_def_id,
135
155
types : FxHashMap :: default ( ) ,
136
156
region_scope_tree : fcx. tcx . region_scope_tree ( def_id) ,
137
157
expr_count : 0 ,
@@ -223,7 +243,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
223
243
if let PatKind :: Binding ( ..) = pat. kind {
224
244
let scope = self . region_scope_tree . var_scope ( pat. hir_id . local_id ) ;
225
245
let ty = self . fcx . tables . borrow ( ) . pat_ty ( pat) ;
226
- self . record ( ty, Some ( scope) , None , pat. span ) ;
246
+ self . record ( ty, Some ( scope) , None , pat. span , false ) ;
227
247
}
228
248
}
229
249
@@ -264,7 +284,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
264
284
// If there are adjustments, then record the final type --
265
285
// this is the actual value that is being produced.
266
286
if let Some ( adjusted_ty) = self . fcx . tables . borrow ( ) . expr_ty_adjusted_opt ( expr) {
267
- self . record ( adjusted_ty, scope, Some ( expr) , expr. span ) ;
287
+ self . record ( adjusted_ty, scope, Some ( expr) , expr. span , false ) ;
268
288
}
269
289
270
290
// Also record the unadjusted type (which is the only type if
@@ -292,9 +312,17 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
292
312
// The type table might not have information for this expression
293
313
// if it is in a malformed scope. (#66387)
294
314
if let Some ( ty) = self . fcx . tables . borrow ( ) . expr_ty_opt ( expr) {
295
- self . record ( ty, scope, Some ( expr) , expr. span ) ;
315
+ self . record ( ty, scope, Some ( expr) , expr. span , false ) ;
296
316
} else {
297
317
self . fcx . tcx . sess . delay_span_bug ( expr. span , "no type for node" ) ;
298
318
}
319
+
320
+ if let Some ( upvars) = self . fcx . tcx . upvars ( self . closure_def_id ) {
321
+ for ( upvar_id, upvar) in upvars. iter ( ) {
322
+ let upvar_ty = self . fcx . tables . borrow ( ) . node_type ( * upvar_id) ;
323
+ debug ! ( "type of upvar: {:?}" , upvar_ty) ;
324
+ self . record ( upvar_ty, scope, Some ( expr) , upvar. span , true ) ;
325
+ }
326
+ }
299
327
}
300
328
}
0 commit comments