@@ -286,6 +286,7 @@ struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
286
286
/// (A match binding can have two locals; the 2nd is for the arm's guard.)
287
287
var_indices : NodeMap < LocalsForNode > ,
288
288
local_decls : IndexVec < Local , LocalDecl < ' tcx > > ,
289
+ upvar_decls : Vec < UpvarDecl > ,
289
290
unit_temp : Option < Place < ' tcx > > ,
290
291
291
292
/// cached block with the RESUME terminator; this is created
@@ -472,11 +473,52 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
472
473
473
474
let tcx = hir. tcx ( ) ;
474
475
let span = tcx. hir . span ( fn_id) ;
476
+
477
+ // Gather the upvars of a closure, if any.
478
+ let upvar_decls: Vec < _ > = tcx. with_freevars ( fn_id, |freevars| {
479
+ freevars. iter ( ) . map ( |fv| {
480
+ let var_id = fv. var_id ( ) ;
481
+ let var_hir_id = tcx. hir . node_to_hir_id ( var_id) ;
482
+ let closure_expr_id = tcx. hir . local_def_id ( fn_id) ;
483
+ let capture = hir. tables ( ) . upvar_capture ( ty:: UpvarId {
484
+ var_id : var_hir_id,
485
+ closure_expr_id : LocalDefId :: from_def_id ( closure_expr_id) ,
486
+ } ) ;
487
+ let by_ref = match capture {
488
+ ty:: UpvarCapture :: ByValue => false ,
489
+ ty:: UpvarCapture :: ByRef ( ..) => true
490
+ } ;
491
+ let mut decl = UpvarDecl {
492
+ debug_name : keywords:: Invalid . name ( ) ,
493
+ var_hir_id : ClearCrossCrate :: Set ( var_hir_id) ,
494
+ by_ref,
495
+ mutability : Mutability :: Not ,
496
+ } ;
497
+ if let Some ( hir:: map:: NodeBinding ( pat) ) = tcx. hir . find ( var_id) {
498
+ if let hir:: PatKind :: Binding ( _, _, ident, _) = pat. node {
499
+ decl. debug_name = ident. name ;
500
+
501
+ if let Some ( & bm) = hir. tables . pat_binding_modes ( ) . get ( pat. hir_id ) {
502
+ if bm == ty:: BindByValue ( hir:: MutMutable ) {
503
+ decl. mutability = Mutability :: Mut ;
504
+ } else {
505
+ decl. mutability = Mutability :: Not ;
506
+ }
507
+ } else {
508
+ tcx. sess . delay_span_bug ( pat. span , "missing binding mode" ) ;
509
+ }
510
+ }
511
+ }
512
+ decl
513
+ } ) . collect ( )
514
+ } ) ;
515
+
475
516
let mut builder = Builder :: new ( hir. clone ( ) ,
476
517
span,
477
518
arguments. len ( ) ,
478
519
safety,
479
- return_ty) ;
520
+ return_ty,
521
+ upvar_decls) ;
480
522
481
523
let fn_def_id = tcx. hir . local_def_id ( fn_id) ;
482
524
let call_site_scope = region:: Scope :: CallSite ( body. value . hir_id . local_id ) ;
@@ -519,46 +561,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
519
561
info ! ( "fn_id {:?} has attrs {:?}" , closure_expr_id,
520
562
tcx. get_attrs( closure_expr_id) ) ;
521
563
522
- // Gather the upvars of a closure, if any.
523
- let upvar_decls: Vec < _ > = tcx. with_freevars ( fn_id, |freevars| {
524
- freevars. iter ( ) . map ( |fv| {
525
- let var_id = fv. var_id ( ) ;
526
- let var_hir_id = tcx. hir . node_to_hir_id ( var_id) ;
527
- let closure_expr_id = tcx. hir . local_def_id ( fn_id) ;
528
- let capture = hir. tables ( ) . upvar_capture ( ty:: UpvarId {
529
- var_id : var_hir_id,
530
- closure_expr_id : LocalDefId :: from_def_id ( closure_expr_id) ,
531
- } ) ;
532
- let by_ref = match capture {
533
- ty:: UpvarCapture :: ByValue => false ,
534
- ty:: UpvarCapture :: ByRef ( ..) => true
535
- } ;
536
- let mut decl = UpvarDecl {
537
- debug_name : keywords:: Invalid . name ( ) ,
538
- var_hir_id : ClearCrossCrate :: Set ( var_hir_id) ,
539
- by_ref,
540
- mutability : Mutability :: Not ,
541
- } ;
542
- if let Some ( hir:: map:: NodeBinding ( pat) ) = tcx. hir . find ( var_id) {
543
- if let hir:: PatKind :: Binding ( _, _, ident, _) = pat. node {
544
- decl. debug_name = ident. name ;
545
-
546
- if let Some ( & bm) = hir. tables . pat_binding_modes ( ) . get ( pat. hir_id ) {
547
- if bm == ty:: BindByValue ( hir:: MutMutable ) {
548
- decl. mutability = Mutability :: Mut ;
549
- } else {
550
- decl. mutability = Mutability :: Not ;
551
- }
552
- } else {
553
- tcx. sess . delay_span_bug ( pat. span , "missing binding mode" ) ;
554
- }
555
- }
556
- }
557
- decl
558
- } ) . collect ( )
559
- } ) ;
560
-
561
- let mut mir = builder. finish ( upvar_decls, yield_ty) ;
564
+ let mut mir = builder. finish ( yield_ty) ;
562
565
mir. spread_arg = spread_arg;
563
566
mir
564
567
}
@@ -571,7 +574,7 @@ fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
571
574
let ty = hir. tables ( ) . expr_ty_adjusted ( ast_expr) ;
572
575
let owner_id = tcx. hir . body_owner ( body_id) ;
573
576
let span = tcx. hir . span ( owner_id) ;
574
- let mut builder = Builder :: new ( hir. clone ( ) , span, 0 , Safety :: Safe , ty) ;
577
+ let mut builder = Builder :: new ( hir. clone ( ) , span, 0 , Safety :: Safe , ty, vec ! [ ] ) ;
575
578
576
579
let mut block = START_BLOCK ;
577
580
let expr = builder. hir . mirror ( ast_expr) ;
@@ -590,7 +593,7 @@ fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
590
593
TerminatorKind :: Unreachable ) ;
591
594
}
592
595
593
- builder. finish ( vec ! [ ] , None )
596
+ builder. finish ( None )
594
597
}
595
598
596
599
fn construct_error < ' a , ' gcx , ' tcx > ( hir : Cx < ' a , ' gcx , ' tcx > ,
@@ -599,18 +602,19 @@ fn construct_error<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
599
602
let owner_id = hir. tcx ( ) . hir . body_owner ( body_id) ;
600
603
let span = hir. tcx ( ) . hir . span ( owner_id) ;
601
604
let ty = hir. tcx ( ) . types . err ;
602
- let mut builder = Builder :: new ( hir, span, 0 , Safety :: Safe , ty) ;
605
+ let mut builder = Builder :: new ( hir, span, 0 , Safety :: Safe , ty, vec ! [ ] ) ;
603
606
let source_info = builder. source_info ( span) ;
604
607
builder. cfg . terminate ( START_BLOCK , source_info, TerminatorKind :: Unreachable ) ;
605
- builder. finish ( vec ! [ ] , None )
608
+ builder. finish ( None )
606
609
}
607
610
608
611
impl < ' a , ' gcx , ' tcx > Builder < ' a , ' gcx , ' tcx > {
609
612
fn new ( hir : Cx < ' a , ' gcx , ' tcx > ,
610
613
span : Span ,
611
614
arg_count : usize ,
612
615
safety : Safety ,
613
- return_ty : Ty < ' tcx > )
616
+ return_ty : Ty < ' tcx > ,
617
+ upvar_decls : Vec < UpvarDecl > )
614
618
-> Builder < ' a , ' gcx , ' tcx > {
615
619
let lint_level = LintLevel :: Explicit ( hir. root_lint_level ) ;
616
620
let mut builder = Builder {
@@ -628,6 +632,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
628
632
breakable_scopes : vec ! [ ] ,
629
633
local_decls : IndexVec :: from_elem_n ( LocalDecl :: new_return_place ( return_ty,
630
634
span) , 1 ) ,
635
+ upvar_decls,
631
636
var_indices : NodeMap ( ) ,
632
637
unit_temp : None ,
633
638
cached_resume_block : None ,
@@ -645,7 +650,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
645
650
}
646
651
647
652
fn finish ( self ,
648
- upvar_decls : Vec < UpvarDecl > ,
649
653
yield_ty : Option < Ty < ' tcx > > )
650
654
-> Mir < ' tcx > {
651
655
for ( index, block) in self . cfg . basic_blocks . iter ( ) . enumerate ( ) {
@@ -661,7 +665,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
661
665
yield_ty,
662
666
self . local_decls ,
663
667
self . arg_count ,
664
- upvar_decls,
668
+ self . upvar_decls ,
665
669
self . fn_span
666
670
)
667
671
}
0 commit comments