@@ -47,11 +47,11 @@ use middle::mem_categorization as mc;
4747use  middle:: mem_categorization:: Categorization ; 
4848use  rustc:: ty:: { self ,  Ty } ; 
4949use  rustc:: infer:: UpvarRegion ; 
50- use  std:: collections:: HashSet ; 
5150use  syntax:: ast; 
5251use  syntax_pos:: Span ; 
5352use  rustc:: hir; 
5453use  rustc:: hir:: intravisit:: { self ,  Visitor } ; 
54+ use  rustc:: util:: nodemap:: NodeMap ; 
5555
5656/////////////////////////////////////////////////////////////////////////// 
5757// PUBLIC ENTRY POINTS 
@@ -60,9 +60,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
6060    pub  fn  closure_analyze_fn ( & self ,  body :  & hir:: Block )  { 
6161        let  mut  seed = SeedBorrowKind :: new ( self ) ; 
6262        seed. visit_block ( body) ; 
63-         let  closures_with_inferred_kinds = seed. closures_with_inferred_kinds ; 
6463
65-         let  mut  adjust = AdjustBorrowKind :: new ( self ,  & closures_with_inferred_kinds ) ; 
64+         let  mut  adjust = AdjustBorrowKind :: new ( self ,  seed . temp_closure_kinds ) ; 
6665        adjust. visit_block ( body) ; 
6766
6867        // it's our job to process these. 
@@ -72,9 +71,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
7271    pub  fn  closure_analyze_const ( & self ,  body :  & hir:: Expr )  { 
7372        let  mut  seed = SeedBorrowKind :: new ( self ) ; 
7473        seed. visit_expr ( body) ; 
75-         let  closures_with_inferred_kinds = seed. closures_with_inferred_kinds ; 
7674
77-         let  mut  adjust = AdjustBorrowKind :: new ( self ,  & closures_with_inferred_kinds ) ; 
75+         let  mut  adjust = AdjustBorrowKind :: new ( self ,  seed . temp_closure_kinds ) ; 
7876        adjust. visit_expr ( body) ; 
7977
8078        // it's our job to process these. 
@@ -87,7 +85,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
8785
8886struct  SeedBorrowKind < ' a ,  ' gcx :  ' a +' tcx ,  ' tcx :  ' a >  { 
8987    fcx :  & ' a  FnCtxt < ' a ,  ' gcx ,  ' tcx > , 
90-     closures_with_inferred_kinds :   HashSet < ast :: NodeId > , 
88+     temp_closure_kinds :   NodeMap < ty :: ClosureKind > , 
9189} 
9290
9391impl < ' a ,  ' gcx ,  ' tcx ,  ' v >  Visitor < ' v >  for  SeedBorrowKind < ' a ,  ' gcx ,  ' tcx >  { 
@@ -106,7 +104,7 @@ impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for SeedBorrowKind<'a, 'gcx, 'tcx> {
106104
107105impl < ' a ,  ' gcx ,  ' tcx >  SeedBorrowKind < ' a ,  ' gcx ,  ' tcx >  { 
108106    fn  new ( fcx :  & ' a  FnCtxt < ' a ,  ' gcx ,  ' tcx > )  -> SeedBorrowKind < ' a ,  ' gcx ,  ' tcx >  { 
109-         SeedBorrowKind  {  fcx :  fcx,  closures_with_inferred_kinds :   HashSet :: new ( )  } 
107+         SeedBorrowKind  {  fcx :  fcx,  temp_closure_kinds :   NodeMap ( )  } 
110108    } 
111109
112110    fn  check_closure ( & mut  self , 
@@ -116,11 +114,8 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> {
116114    { 
117115        let  closure_def_id = self . fcx . tcx . map . local_def_id ( expr. id ) ; 
118116        if  !self . fcx . tables . borrow ( ) . closure_kinds . contains_key ( & closure_def_id)  { 
119-             self . closures_with_inferred_kinds . insert ( expr. id ) ; 
120-             self . fcx . tables . borrow_mut ( ) . closure_kinds 
121-                                         . insert ( closure_def_id,  ty:: ClosureKind :: Fn ) ; 
122-             debug ! ( "check_closure: adding closure_id={:?} to closures_with_inferred_kinds" , 
123-                    closure_def_id) ; 
117+             self . temp_closure_kinds . insert ( expr. id ,  ty:: ClosureKind :: Fn ) ; 
118+             debug ! ( "check_closure: adding closure {:?} as Fn" ,  expr. id) ; 
124119        } 
125120
126121        self . fcx . tcx . with_freevars ( expr. id ,  |freevars| { 
@@ -154,14 +149,14 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> {
154149
155150struct  AdjustBorrowKind < ' a ,  ' gcx :  ' a +' tcx ,  ' tcx :  ' a >  { 
156151    fcx :  & ' a  FnCtxt < ' a ,  ' gcx ,  ' tcx > , 
157-     closures_with_inferred_kinds :   & ' a   HashSet < ast :: NodeId > , 
152+     temp_closure_kinds :   NodeMap < ty :: ClosureKind > , 
158153} 
159154
160155impl < ' a ,  ' gcx ,  ' tcx >  AdjustBorrowKind < ' a ,  ' gcx ,  ' tcx >  { 
161156    fn  new ( fcx :  & ' a  FnCtxt < ' a ,  ' gcx ,  ' tcx > , 
162-            closures_with_inferred_kinds :   & ' a   HashSet < ast :: NodeId > ) 
157+            temp_closure_kinds :   NodeMap < ty :: ClosureKind > ) 
163158           -> AdjustBorrowKind < ' a ,  ' gcx ,  ' tcx >  { 
164-         AdjustBorrowKind  {  fcx :  fcx,  closures_with_inferred_kinds :  closures_with_inferred_kinds  } 
159+         AdjustBorrowKind  {  fcx :  fcx,  temp_closure_kinds :  temp_closure_kinds  } 
165160    } 
166161
167162    fn  analyze_closure ( & mut  self , 
@@ -176,8 +171,10 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
176171        debug ! ( "analyze_closure(id={:?}, body.id={:?})" ,  id,  body. id) ; 
177172
178173        { 
174+             self . fcx . set_during_closure_kind_inference ( true ) ; 
179175            let  mut  euv = euv:: ExprUseVisitor :: new ( self ,  self . fcx ) ; 
180176            euv. walk_fn ( decl,  body) ; 
177+             self . fcx . set_during_closure_kind_inference ( false ) ; 
181178        } 
182179
183180        // Now that we've analyzed the closure, we know how each 
@@ -211,10 +208,14 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
211208            self . fcx . demand_eqtype ( span,  final_upvar_ty,  upvar_ty) ; 
212209        } 
213210
214-         // Now  we must process and remove any deferred resolutions,  
215-         // since we have a concrete closure kind . 
211+         // If  we are also inferred the closure kind here, update the  
212+         // main table and process any deferred resolutions . 
216213        let  closure_def_id = self . fcx . tcx . map . local_def_id ( id) ; 
217-         if  self . closures_with_inferred_kinds . contains ( & id)  { 
214+         if  let  Some ( & kind)  = self . temp_closure_kinds . get ( & id)  { 
215+             self . fcx . tables . borrow_mut ( ) . closure_kinds 
216+                                         . insert ( closure_def_id,  kind) ; 
217+             debug ! ( "closure_kind({:?}) = {:?}" ,  closure_def_id,  kind) ; 
218+ 
218219            let  mut  deferred_call_resolutions =
219220                self . fcx . remove_deferred_call_resolutions ( closure_def_id) ; 
220221            for  deferred_call_resolution in  & mut  deferred_call_resolutions { 
@@ -259,7 +260,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
259260            } ) 
260261    } 
261262
262-     fn  adjust_upvar_borrow_kind_for_consume ( & self , 
263+     fn  adjust_upvar_borrow_kind_for_consume ( & mut   self , 
263264                                            cmt :  mc:: cmt < ' tcx > , 
264265                                            mode :  euv:: ConsumeMode ) 
265266    { 
@@ -350,7 +351,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
350351        } 
351352    } 
352353
353-     fn  adjust_upvar_borrow_kind_for_unique ( & self ,  cmt :  mc:: cmt < ' tcx > )  { 
354+     fn  adjust_upvar_borrow_kind_for_unique ( & mut   self ,  cmt :  mc:: cmt < ' tcx > )  { 
354355        debug ! ( "adjust_upvar_borrow_kind_for_unique(cmt={:?})" , 
355356               cmt) ; 
356357
@@ -381,7 +382,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
381382        } 
382383    } 
383384
384-     fn  try_adjust_upvar_deref ( & self , 
385+     fn  try_adjust_upvar_deref ( & mut   self , 
385386                              note :  & mc:: Note , 
386387                              borrow_kind :  ty:: BorrowKind ) 
387388                              -> bool 
@@ -430,7 +431,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
430431/// moving from left to right as needed (but never right to left). 
431432/// Here the argument `mutbl` is the borrow_kind that is required by 
432433/// some particular use. 
433- fn  adjust_upvar_borrow_kind ( & self , 
434+ fn  adjust_upvar_borrow_kind ( & mut   self , 
434435                                upvar_id :  ty:: UpvarId , 
435436                                upvar_capture :  & mut  ty:: UpvarCapture , 
436437                                kind :  ty:: BorrowKind )  { 
@@ -460,36 +461,30 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
460461        } 
461462    } 
462463
463-     fn  adjust_closure_kind ( & self , 
464+     fn  adjust_closure_kind ( & mut   self , 
464465                           closure_id :  ast:: NodeId , 
465466                           new_kind :  ty:: ClosureKind )  { 
466467        debug ! ( "adjust_closure_kind(closure_id={}, new_kind={:?})" , 
467468               closure_id,  new_kind) ; 
468469
469-         if  !self . closures_with_inferred_kinds . contains ( & closure_id)  { 
470-             return ; 
471-         } 
472- 
473-         let  closure_def_id = self . fcx . tcx . map . local_def_id ( closure_id) ; 
474-         let  closure_kinds = & mut  self . fcx . tables . borrow_mut ( ) . closure_kinds ; 
475-         let  existing_kind = * closure_kinds. get ( & closure_def_id) . unwrap ( ) ; 
470+         if  let  Some ( & existing_kind)  = self . temp_closure_kinds . get ( & closure_id)  { 
471+             debug ! ( "adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}" , 
472+                    closure_id,  existing_kind,  new_kind) ; 
476473
477-         debug ! ( "adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}" , 
478-                closure_id,  existing_kind,  new_kind) ; 
479- 
480-         match  ( existing_kind,  new_kind)  { 
481-             ( ty:: ClosureKind :: Fn ,  ty:: ClosureKind :: Fn )  |
482-             ( ty:: ClosureKind :: FnMut ,  ty:: ClosureKind :: Fn )  |
483-             ( ty:: ClosureKind :: FnMut ,  ty:: ClosureKind :: FnMut )  |
484-             ( ty:: ClosureKind :: FnOnce ,  _)  => { 
485-                 // no change needed 
486-             } 
474+             match  ( existing_kind,  new_kind)  { 
475+                 ( ty:: ClosureKind :: Fn ,  ty:: ClosureKind :: Fn )  |
476+                 ( ty:: ClosureKind :: FnMut ,  ty:: ClosureKind :: Fn )  |
477+                 ( ty:: ClosureKind :: FnMut ,  ty:: ClosureKind :: FnMut )  |
478+                 ( ty:: ClosureKind :: FnOnce ,  _)  => { 
479+                     // no change needed 
480+                 } 
487481
488-             ( ty:: ClosureKind :: Fn ,  ty:: ClosureKind :: FnMut )  |
489-             ( ty:: ClosureKind :: Fn ,  ty:: ClosureKind :: FnOnce )  |
490-             ( ty:: ClosureKind :: FnMut ,  ty:: ClosureKind :: FnOnce )  => { 
491-                 // new kind is stronger than the old kind 
492-                 closure_kinds. insert ( closure_def_id,  new_kind) ; 
482+                 ( ty:: ClosureKind :: Fn ,  ty:: ClosureKind :: FnMut )  |
483+                 ( ty:: ClosureKind :: Fn ,  ty:: ClosureKind :: FnOnce )  |
484+                 ( ty:: ClosureKind :: FnMut ,  ty:: ClosureKind :: FnOnce )  => { 
485+                     // new kind is stronger than the old kind 
486+                     self . temp_closure_kinds . insert ( closure_id,  new_kind) ; 
487+                 } 
493488            } 
494489        } 
495490    } 
0 commit comments