@@ -99,7 +99,7 @@ use self::VarKind::*;
99
99
100
100
use crate :: hir:: def:: * ;
101
101
use crate :: hir:: Node ;
102
- use crate :: ty:: { self , TyCtxt } ;
102
+ use crate :: ty:: { self , DefIdTree , TyCtxt } ;
103
103
use crate :: ty:: query:: Providers ;
104
104
use crate :: lint;
105
105
use crate :: util:: nodemap:: { HirIdMap , HirIdSet } ;
@@ -182,7 +182,10 @@ impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> {
182
182
}
183
183
184
184
fn check_mod_liveness < ' tcx > ( tcx : TyCtxt < ' _ , ' tcx , ' tcx > , module_def_id : DefId ) {
185
- tcx. hir ( ) . visit_item_likes_in_module ( module_def_id, & mut IrMaps :: new ( tcx) . as_deep_visitor ( ) ) ;
185
+ tcx. hir ( ) . visit_item_likes_in_module (
186
+ module_def_id,
187
+ & mut IrMaps :: new ( tcx, module_def_id) . as_deep_visitor ( ) ,
188
+ ) ;
186
189
}
187
190
188
191
pub fn provide ( providers : & mut Providers < ' _ > ) {
@@ -255,6 +258,7 @@ enum VarKind {
255
258
256
259
struct IrMaps < ' a , ' tcx : ' a > {
257
260
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
261
+ body_owner : DefId ,
258
262
num_live_nodes : usize ,
259
263
num_vars : usize ,
260
264
live_node_map : HirIdMap < LiveNode > ,
@@ -265,9 +269,10 @@ struct IrMaps<'a, 'tcx: 'a> {
265
269
}
266
270
267
271
impl < ' a , ' tcx > IrMaps < ' a , ' tcx > {
268
- fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> IrMaps < ' a , ' tcx > {
272
+ fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , body_owner : DefId ) -> IrMaps < ' a , ' tcx > {
269
273
IrMaps {
270
274
tcx,
275
+ body_owner,
271
276
num_live_nodes : 0 ,
272
277
num_vars : 0 ,
273
278
live_node_map : HirIdMap :: default ( ) ,
@@ -356,7 +361,8 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
356
361
debug ! ( "visit_fn" ) ;
357
362
358
363
// swap in a new set of IR maps for this function body:
359
- let mut fn_maps = IrMaps :: new ( ir. tcx ) ;
364
+ let def_id = ir. tcx . hir ( ) . local_def_id_from_hir_id ( id) ;
365
+ let mut fn_maps = IrMaps :: new ( ir. tcx , def_id) ;
360
366
361
367
// Don't run unused pass for #[derive()]
362
368
if let FnKind :: Method ( ..) = fk {
@@ -485,8 +491,15 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
485
491
let mut call_caps = Vec :: new ( ) ;
486
492
let closure_def_id = ir. tcx . hir ( ) . local_def_id_from_hir_id ( expr. hir_id ) ;
487
493
if let Some ( upvars) = ir. tcx . upvars ( closure_def_id) {
494
+ let parent_upvars = ir. tcx . upvars ( ir. body_owner ) ;
488
495
call_caps. extend ( upvars. iter ( ) . filter_map ( |( & var_id, upvar) | {
489
- if !upvar. has_parent {
496
+ if upvar. has_parent {
497
+ assert_eq ! ( ir. body_owner, ir. tcx. parent( closure_def_id) . unwrap( ) ) ;
498
+ }
499
+ let has_parent = parent_upvars
500
+ . map_or ( false , |upvars| upvars. contains_key ( & var_id) ) ;
501
+ assert_eq ! ( upvar. has_parent, has_parent) ;
502
+ if !has_parent {
490
503
let upvar_ln = ir. add_live_node ( UpvarNode ( upvar. span ) ) ;
491
504
Some ( CaptureInfo { ln : upvar_ln, var_hid : var_id } )
492
505
} else {
@@ -495,8 +508,10 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
495
508
} ) ) ;
496
509
}
497
510
ir. set_captures ( expr. hir_id , call_caps) ;
498
-
511
+ let old_body_owner = ir. body_owner ;
512
+ ir. body_owner = closure_def_id;
499
513
intravisit:: walk_expr ( ir, expr) ;
514
+ ir. body_owner = old_body_owner;
500
515
}
501
516
502
517
// live nodes required for interesting control flow:
0 commit comments