@@ -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,7 +171,12 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
176171 debug ! ( "analyze_closure(id={:?}, body.id={:?})" , id, body. id) ;
177172
178173 {
179- let mut euv = euv:: ExprUseVisitor :: new ( self , self . fcx ) ;
174+ let mut euv =
175+ euv:: ExprUseVisitor :: with_options ( self ,
176+ self . fcx ,
177+ mc:: MemCategorizationOptions {
178+ during_closure_kind_inference : true
179+ } ) ;
180180 euv. walk_fn ( decl, body) ;
181181 }
182182
@@ -211,10 +211,14 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
211211 self . fcx . demand_eqtype ( span, final_upvar_ty, upvar_ty) ;
212212 }
213213
214- // Now we must process and remove any deferred resolutions,
215- // since we have a concrete closure kind .
214+ // If we are also inferred the closure kind here, update the
215+ // main table and process any deferred resolutions .
216216 let closure_def_id = self . fcx . tcx . map . local_def_id ( id) ;
217- if self . closures_with_inferred_kinds . contains ( & id) {
217+ if let Some ( & kind) = self . temp_closure_kinds . get ( & id) {
218+ self . fcx . tables . borrow_mut ( ) . closure_kinds
219+ . insert ( closure_def_id, kind) ;
220+ debug ! ( "closure_kind({:?}) = {:?}" , closure_def_id, kind) ;
221+
218222 let mut deferred_call_resolutions =
219223 self . fcx . remove_deferred_call_resolutions ( closure_def_id) ;
220224 for deferred_call_resolution in & mut deferred_call_resolutions {
@@ -259,7 +263,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
259263 } )
260264 }
261265
262- fn adjust_upvar_borrow_kind_for_consume ( & self ,
266+ fn adjust_upvar_borrow_kind_for_consume ( & mut self ,
263267 cmt : mc:: cmt < ' tcx > ,
264268 mode : euv:: ConsumeMode )
265269 {
@@ -350,7 +354,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
350354 }
351355 }
352356
353- fn adjust_upvar_borrow_kind_for_unique ( & self , cmt : mc:: cmt < ' tcx > ) {
357+ fn adjust_upvar_borrow_kind_for_unique ( & mut self , cmt : mc:: cmt < ' tcx > ) {
354358 debug ! ( "adjust_upvar_borrow_kind_for_unique(cmt={:?})" ,
355359 cmt) ;
356360
@@ -381,7 +385,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
381385 }
382386 }
383387
384- fn try_adjust_upvar_deref ( & self ,
388+ fn try_adjust_upvar_deref ( & mut self ,
385389 note : & mc:: Note ,
386390 borrow_kind : ty:: BorrowKind )
387391 -> bool
@@ -430,7 +434,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
430434 /// moving from left to right as needed (but never right to left).
431435 /// Here the argument `mutbl` is the borrow_kind that is required by
432436 /// some particular use.
433- fn adjust_upvar_borrow_kind ( & self ,
437+ fn adjust_upvar_borrow_kind ( & mut self ,
434438 upvar_id : ty:: UpvarId ,
435439 upvar_capture : & mut ty:: UpvarCapture ,
436440 kind : ty:: BorrowKind ) {
@@ -460,36 +464,30 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
460464 }
461465 }
462466
463- fn adjust_closure_kind ( & self ,
467+ fn adjust_closure_kind ( & mut self ,
464468 closure_id : ast:: NodeId ,
465469 new_kind : ty:: ClosureKind ) {
466470 debug ! ( "adjust_closure_kind(closure_id={}, new_kind={:?})" ,
467471 closure_id, new_kind) ;
468472
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 ( ) ;
473+ if let Some ( & existing_kind) = self . temp_closure_kinds . get ( & closure_id) {
474+ debug ! ( "adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}" ,
475+ closure_id, existing_kind, new_kind) ;
476476
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- }
477+ match ( existing_kind, new_kind) {
478+ ( ty:: ClosureKind :: Fn , ty:: ClosureKind :: Fn ) |
479+ ( ty:: ClosureKind :: FnMut , ty:: ClosureKind :: Fn ) |
480+ ( ty:: ClosureKind :: FnMut , ty:: ClosureKind :: FnMut ) |
481+ ( ty:: ClosureKind :: FnOnce , _) => {
482+ // no change needed
483+ }
487484
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) ;
485+ ( ty:: ClosureKind :: Fn , ty:: ClosureKind :: FnMut ) |
486+ ( ty:: ClosureKind :: Fn , ty:: ClosureKind :: FnOnce ) |
487+ ( ty:: ClosureKind :: FnMut , ty:: ClosureKind :: FnOnce ) => {
488+ // new kind is stronger than the old kind
489+ self . temp_closure_kinds . insert ( closure_id, new_kind) ;
490+ }
493491 }
494492 }
495493 }
0 commit comments