@@ -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