@@ -286,6 +286,7 @@ struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
286286 /// (A match binding can have two locals; the 2nd is for the arm's guard.)
287287 var_indices : NodeMap < LocalsForNode > ,
288288 local_decls : IndexVec < Local , LocalDecl < ' tcx > > ,
289+ upvar_decls : Vec < UpvarDecl > ,
289290 unit_temp : Option < Place < ' tcx > > ,
290291
291292 /// 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>,
472473
473474 let tcx = hir. tcx ( ) ;
474475 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+
475516 let mut builder = Builder :: new ( hir. clone ( ) ,
476517 span,
477518 arguments. len ( ) ,
478519 safety,
479- return_ty) ;
520+ return_ty,
521+ upvar_decls) ;
480522
481523 let fn_def_id = tcx. hir . local_def_id ( fn_id) ;
482524 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>,
519561 info ! ( "fn_id {:?} has attrs {:?}" , closure_expr_id,
520562 tcx. get_attrs( closure_expr_id) ) ;
521563
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) ;
562565 mir. spread_arg = spread_arg;
563566 mir
564567}
@@ -571,7 +574,7 @@ fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
571574 let ty = hir. tables ( ) . expr_ty_adjusted ( ast_expr) ;
572575 let owner_id = tcx. hir . body_owner ( body_id) ;
573576 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 ! [ ] ) ;
575578
576579 let mut block = START_BLOCK ;
577580 let expr = builder. hir . mirror ( ast_expr) ;
@@ -590,7 +593,7 @@ fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
590593 TerminatorKind :: Unreachable ) ;
591594 }
592595
593- builder. finish ( vec ! [ ] , None )
596+ builder. finish ( None )
594597}
595598
596599fn 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>,
599602 let owner_id = hir. tcx ( ) . hir . body_owner ( body_id) ;
600603 let span = hir. tcx ( ) . hir . span ( owner_id) ;
601604 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 ! [ ] ) ;
603606 let source_info = builder. source_info ( span) ;
604607 builder. cfg . terminate ( START_BLOCK , source_info, TerminatorKind :: Unreachable ) ;
605- builder. finish ( vec ! [ ] , None )
608+ builder. finish ( None )
606609}
607610
608611impl < ' a , ' gcx , ' tcx > Builder < ' a , ' gcx , ' tcx > {
609612 fn new ( hir : Cx < ' a , ' gcx , ' tcx > ,
610613 span : Span ,
611614 arg_count : usize ,
612615 safety : Safety ,
613- return_ty : Ty < ' tcx > )
616+ return_ty : Ty < ' tcx > ,
617+ upvar_decls : Vec < UpvarDecl > )
614618 -> Builder < ' a , ' gcx , ' tcx > {
615619 let lint_level = LintLevel :: Explicit ( hir. root_lint_level ) ;
616620 let mut builder = Builder {
@@ -628,6 +632,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
628632 breakable_scopes : vec ! [ ] ,
629633 local_decls : IndexVec :: from_elem_n ( LocalDecl :: new_return_place ( return_ty,
630634 span) , 1 ) ,
635+ upvar_decls,
631636 var_indices : NodeMap ( ) ,
632637 unit_temp : None ,
633638 cached_resume_block : None ,
@@ -645,7 +650,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
645650 }
646651
647652 fn finish ( self ,
648- upvar_decls : Vec < UpvarDecl > ,
649653 yield_ty : Option < Ty < ' tcx > > )
650654 -> Mir < ' tcx > {
651655 for ( index, block) in self . cfg . basic_blocks . iter ( ) . enumerate ( ) {
@@ -661,7 +665,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
661665 yield_ty,
662666 self . local_decls ,
663667 self . arg_count ,
664- upvar_decls,
668+ self . upvar_decls ,
665669 self . fn_span
666670 )
667671 }
0 commit comments