@@ -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,7 +171,12 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
176
171
debug ! ( "analyze_closure(id={:?}, body.id={:?})" , id, body. id) ;
177
172
178
173
{
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
+ } ) ;
180
180
euv. walk_fn ( decl, body) ;
181
181
}
182
182
@@ -211,10 +211,14 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
211
211
self . fcx . demand_eqtype ( span, final_upvar_ty, upvar_ty) ;
212
212
}
213
213
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 .
216
216
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
+
218
222
let mut deferred_call_resolutions =
219
223
self . fcx . remove_deferred_call_resolutions ( closure_def_id) ;
220
224
for deferred_call_resolution in & mut deferred_call_resolutions {
@@ -259,7 +263,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
259
263
} )
260
264
}
261
265
262
- fn adjust_upvar_borrow_kind_for_consume ( & self ,
266
+ fn adjust_upvar_borrow_kind_for_consume ( & mut self ,
263
267
cmt : mc:: cmt < ' tcx > ,
264
268
mode : euv:: ConsumeMode )
265
269
{
@@ -350,7 +354,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
350
354
}
351
355
}
352
356
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 > ) {
354
358
debug ! ( "adjust_upvar_borrow_kind_for_unique(cmt={:?})" ,
355
359
cmt) ;
356
360
@@ -381,7 +385,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
381
385
}
382
386
}
383
387
384
- fn try_adjust_upvar_deref ( & self ,
388
+ fn try_adjust_upvar_deref ( & mut self ,
385
389
note : & mc:: Note ,
386
390
borrow_kind : ty:: BorrowKind )
387
391
-> bool
@@ -430,7 +434,7 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
430
434
/// moving from left to right as needed (but never right to left).
431
435
/// Here the argument `mutbl` is the borrow_kind that is required by
432
436
/// some particular use.
433
- fn adjust_upvar_borrow_kind ( & self ,
437
+ fn adjust_upvar_borrow_kind ( & mut self ,
434
438
upvar_id : ty:: UpvarId ,
435
439
upvar_capture : & mut ty:: UpvarCapture ,
436
440
kind : ty:: BorrowKind ) {
@@ -460,36 +464,30 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> {
460
464
}
461
465
}
462
466
463
- fn adjust_closure_kind ( & self ,
467
+ fn adjust_closure_kind ( & mut self ,
464
468
closure_id : ast:: NodeId ,
465
469
new_kind : ty:: ClosureKind ) {
466
470
debug ! ( "adjust_closure_kind(closure_id={}, new_kind={:?})" ,
467
471
closure_id, new_kind) ;
468
472
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) ;
476
476
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
+ }
487
484
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
+ }
493
491
}
494
492
}
495
493
}
0 commit comments