@@ -47,11 +47,11 @@ use middle::mem_categorization as mc;
47
47
use middle:: mem_categorization:: Categorization ;
48
48
use rustc:: ty:: { self , Ty } ;
49
49
use rustc:: infer:: UpvarRegion ;
50
- use std:: collections:: HashSet ;
51
50
use syntax:: ast;
52
51
use syntax_pos:: Span ;
53
52
use rustc:: hir;
54
53
use rustc:: hir:: intravisit:: { self , Visitor } ;
54
+ use rustc:: util:: nodemap:: NodeMap ;
55
55
56
56
///////////////////////////////////////////////////////////////////////////
57
57
// PUBLIC ENTRY POINTS
@@ -60,9 +60,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
60
60
pub fn closure_analyze_fn ( & self , body : & hir:: Block ) {
61
61
let mut seed = SeedBorrowKind :: new ( self ) ;
62
62
seed. visit_block ( body) ;
63
- let closures_with_inferred_kinds = seed. closures_with_inferred_kinds ;
64
63
65
- let mut adjust = AdjustBorrowKind :: new ( self , & closures_with_inferred_kinds ) ;
64
+ let mut adjust = AdjustBorrowKind :: new ( self , seed . temp_closure_kinds ) ;
66
65
adjust. visit_block ( body) ;
67
66
68
67
// it's our job to process these.
@@ -72,9 +71,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
72
71
pub fn closure_analyze_const ( & self , body : & hir:: Expr ) {
73
72
let mut seed = SeedBorrowKind :: new ( self ) ;
74
73
seed. visit_expr ( body) ;
75
- let closures_with_inferred_kinds = seed. closures_with_inferred_kinds ;
76
74
77
- let mut adjust = AdjustBorrowKind :: new ( self , & closures_with_inferred_kinds ) ;
75
+ let mut adjust = AdjustBorrowKind :: new ( self , seed . temp_closure_kinds ) ;
78
76
adjust. visit_expr ( body) ;
79
77
80
78
// it's our job to process these.
@@ -87,7 +85,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
87
85
88
86
struct SeedBorrowKind < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
89
87
fcx : & ' a FnCtxt < ' a , ' gcx , ' tcx > ,
90
- closures_with_inferred_kinds : HashSet < ast :: NodeId > ,
88
+ temp_closure_kinds : NodeMap < ty :: ClosureKind > ,
91
89
}
92
90
93
91
impl < ' 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> {
106
104
107
105
impl < ' a , ' gcx , ' tcx > SeedBorrowKind < ' a , ' gcx , ' tcx > {
108
106
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 ( ) }
110
108
}
111
109
112
110
fn check_closure ( & mut self ,
@@ -116,11 +114,8 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> {
116
114
{
117
115
let closure_def_id = self . fcx . tcx . map . local_def_id ( expr. id ) ;
118
116
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) ;
124
119
}
125
120
126
121
self . fcx . tcx . with_freevars ( expr. id , |freevars| {
@@ -154,14 +149,14 @@ impl<'a, 'gcx, 'tcx> SeedBorrowKind<'a, 'gcx, 'tcx> {
154
149
155
150
struct AdjustBorrowKind < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
156
151
fcx : & ' a FnCtxt < ' a , ' gcx , ' tcx > ,
157
- closures_with_inferred_kinds : & ' a HashSet < ast :: NodeId > ,
152
+ temp_closure_kinds : NodeMap < ty :: ClosureKind > ,
158
153
}
159
154
160
155
impl < ' a , ' gcx , ' tcx > AdjustBorrowKind < ' a , ' gcx , ' tcx > {
161
156
fn new ( fcx : & ' a FnCtxt < ' a , ' gcx , ' tcx > ,
162
- closures_with_inferred_kinds : & ' a HashSet < ast :: NodeId > )
157
+ temp_closure_kinds : NodeMap < ty :: ClosureKind > )
163
158
-> 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 }
165
160
}
166
161
167
162
fn analyze_closure ( & mut self ,
@@ -176,8 +171,10 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
176
171
debug ! ( "analyze_closure(id={:?}, body.id={:?})" , id, body. id) ;
177
172
178
173
{
174
+ self . fcx . set_during_closure_kind_inference ( true ) ;
179
175
let mut euv = euv:: ExprUseVisitor :: new ( self , self . fcx ) ;
180
176
euv. walk_fn ( decl, body) ;
177
+ self . fcx . set_during_closure_kind_inference ( false ) ;
181
178
}
182
179
183
180
// Now that we've analyzed the closure, we know how each
@@ -211,10 +208,14 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
211
208
self . fcx . demand_eqtype ( span, final_upvar_ty, upvar_ty) ;
212
209
}
213
210
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 .
216
213
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
+
218
219
let mut deferred_call_resolutions =
219
220
self . fcx . remove_deferred_call_resolutions ( closure_def_id) ;
220
221
for deferred_call_resolution in & mut deferred_call_resolutions {
@@ -259,7 +260,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
259
260
} )
260
261
}
261
262
262
- fn adjust_upvar_borrow_kind_for_consume ( & self ,
263
+ fn adjust_upvar_borrow_kind_for_consume ( & mut self ,
263
264
cmt : mc:: cmt < ' tcx > ,
264
265
mode : euv:: ConsumeMode )
265
266
{
@@ -350,7 +351,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
350
351
}
351
352
}
352
353
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 > ) {
354
355
debug ! ( "adjust_upvar_borrow_kind_for_unique(cmt={:?})" ,
355
356
cmt) ;
356
357
@@ -381,7 +382,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
381
382
}
382
383
}
383
384
384
- fn try_adjust_upvar_deref ( & self ,
385
+ fn try_adjust_upvar_deref ( & mut self ,
385
386
note : & mc:: Note ,
386
387
borrow_kind : ty:: BorrowKind )
387
388
-> bool
@@ -430,7 +431,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
430
431
/// moving from left to right as needed (but never right to left).
431
432
/// Here the argument `mutbl` is the borrow_kind that is required by
432
433
/// some particular use.
433
- fn adjust_upvar_borrow_kind ( & self ,
434
+ fn adjust_upvar_borrow_kind ( & mut self ,
434
435
upvar_id : ty:: UpvarId ,
435
436
upvar_capture : & mut ty:: UpvarCapture ,
436
437
kind : ty:: BorrowKind ) {
@@ -460,36 +461,30 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
460
461
}
461
462
}
462
463
463
- fn adjust_closure_kind ( & self ,
464
+ fn adjust_closure_kind ( & mut self ,
464
465
closure_id : ast:: NodeId ,
465
466
new_kind : ty:: ClosureKind ) {
466
467
debug ! ( "adjust_closure_kind(closure_id={}, new_kind={:?})" ,
467
468
closure_id, new_kind) ;
468
469
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) ;
476
473
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
+ }
487
481
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
+ }
493
488
}
494
489
}
495
490
}
0 commit comments