@@ -2,15 +2,14 @@ use std::collections::VecDeque;
2
2
3
3
use crate :: borrow_check:: borrow_set:: BorrowData ;
4
4
use crate :: borrow_check:: error_reporting:: UseSpans ;
5
- use crate :: borrow_check:: nll:: ConstraintDescription ;
6
5
use crate :: borrow_check:: nll:: region_infer:: { Cause , RegionName } ;
6
+ use crate :: borrow_check:: nll:: ConstraintDescription ;
7
7
use crate :: borrow_check:: { Context , MirBorrowckCtxt , WriteKind } ;
8
- use rustc:: ty:: { self , TyCtxt } ;
9
8
use rustc:: mir:: {
10
- CastKind , ConstraintCategory , FakeReadCause , Local , Location , Mir , Operand ,
11
- Place , Projection , ProjectionElem , Rvalue , Statement , StatementKind ,
12
- TerminatorKind
9
+ CastKind , ConstraintCategory , FakeReadCause , Local , Location , Mir , Operand , Place , Projection ,
10
+ ProjectionElem , Rvalue , Statement , StatementKind , TerminatorKind ,
13
11
} ;
12
+ use rustc:: ty:: { self , TyCtxt } ;
14
13
use rustc_data_structures:: fx:: FxHashSet ;
15
14
use rustc_errors:: DiagnosticBuilder ;
16
15
use syntax_pos:: Span ;
@@ -63,50 +62,58 @@ impl BorrowExplanation {
63
62
let message = match later_use_kind {
64
63
LaterUseKind :: TraitCapture => "borrow later captured here by trait object" ,
65
64
LaterUseKind :: ClosureCapture => "borrow later captured here by closure" ,
66
- LaterUseKind :: Call => "borrow later used by call" ,
65
+ LaterUseKind :: Call => "borrow later used by call" ,
67
66
LaterUseKind :: FakeLetRead => "borrow later stored here" ,
68
67
LaterUseKind :: Other => "borrow later used here" ,
69
68
} ;
70
69
err. span_label ( var_or_use_span, format ! ( "{}{}" , borrow_desc, message) ) ;
71
- } ,
70
+ }
72
71
BorrowExplanation :: UsedLaterInLoop ( later_use_kind, var_or_use_span) => {
73
72
let message = match later_use_kind {
74
- LaterUseKind :: TraitCapture =>
75
- "borrow captured here by trait object, in later iteration of loop" ,
76
- LaterUseKind :: ClosureCapture =>
77
- "borrow captured here by closure, in later iteration of loop" ,
78
- LaterUseKind :: Call => "borrow used by call, in later iteration of loop" ,
73
+ LaterUseKind :: TraitCapture => {
74
+ "borrow captured here by trait object, in later iteration of loop"
75
+ }
76
+ LaterUseKind :: ClosureCapture => {
77
+ "borrow captured here by closure, in later iteration of loop"
78
+ }
79
+ LaterUseKind :: Call => "borrow used by call, in later iteration of loop" ,
79
80
LaterUseKind :: FakeLetRead => "borrow later stored here" ,
80
81
LaterUseKind :: Other => "borrow used here, in later iteration of loop" ,
81
82
} ;
82
83
err. span_label ( var_or_use_span, format ! ( "{}{}" , borrow_desc, message) ) ;
83
- } ,
84
- BorrowExplanation :: UsedLaterWhenDropped { drop_loc, dropped_local,
85
- should_note_order } =>
86
- {
84
+ }
85
+ BorrowExplanation :: UsedLaterWhenDropped {
86
+ drop_loc,
87
+ dropped_local,
88
+ should_note_order,
89
+ } => {
87
90
let local_decl = & mir. local_decls [ dropped_local] ;
88
91
let ( dtor_desc, type_desc) = match local_decl. ty . sty {
89
92
// If type is an ADT that implements Drop, then
90
93
// simplify output by reporting just the ADT name.
91
- ty:: Adt ( adt, _substs) if adt. has_dtor ( tcx) && !adt. is_box ( ) =>
92
- ( "`Drop` code" , format ! ( "type `{}`" , tcx. item_path_str( adt. did) ) ) ,
94
+ ty:: Adt ( adt, _substs) if adt. has_dtor ( tcx) && !adt. is_box ( ) => (
95
+ "`Drop` code" ,
96
+ format ! ( "type `{}`" , tcx. item_path_str( adt. did) ) ,
97
+ ) ,
93
98
94
99
// Otherwise, just report the whole type (and use
95
100
// the intentionally fuzzy phrase "destructor")
96
- ty:: Closure ( ..) =>
97
- ( "destructor" , "closure" . to_owned ( ) ) ,
98
- ty:: Generator ( ..) =>
99
- ( "destructor" , "generator" . to_owned ( ) ) ,
101
+ ty:: Closure ( ..) => ( "destructor" , "closure" . to_owned ( ) ) ,
102
+ ty:: Generator ( ..) => ( "destructor" , "generator" . to_owned ( ) ) ,
100
103
101
104
_ => ( "destructor" , format ! ( "type `{}`" , local_decl. ty) ) ,
102
105
} ;
103
106
104
107
match local_decl. name {
105
108
Some ( local_name) => {
106
- let message =
107
- format ! ( "{B}borrow might be used here, when `{LOC}` is dropped \
108
- and runs the {DTOR} for {TYPE}",
109
- B =borrow_desc, LOC =local_name, TYPE =type_desc, DTOR =dtor_desc) ;
109
+ let message = format ! (
110
+ "{B}borrow might be used here, when `{LOC}` is dropped \
111
+ and runs the {DTOR} for {TYPE}",
112
+ B = borrow_desc,
113
+ LOC = local_name,
114
+ TYPE = type_desc,
115
+ DTOR = dtor_desc
116
+ ) ;
110
117
err. span_label ( mir. source_info ( drop_loc) . span , message) ;
111
118
112
119
if should_note_order {
@@ -117,15 +124,22 @@ impl BorrowExplanation {
117
124
}
118
125
}
119
126
None => {
120
- err. span_label ( local_decl. source_info . span ,
121
- format ! ( "a temporary with access to the {B}borrow \
122
- is created here ...",
123
- B =borrow_desc) ) ;
124
- let message =
125
- format ! ( "... and the {B}borrow might be used here, \
126
- when that temporary is dropped \
127
- and runs the {DTOR} for {TYPE}",
128
- B =borrow_desc, TYPE =type_desc, DTOR =dtor_desc) ;
127
+ err. span_label (
128
+ local_decl. source_info . span ,
129
+ format ! (
130
+ "a temporary with access to the {B}borrow \
131
+ is created here ...",
132
+ B = borrow_desc
133
+ ) ,
134
+ ) ;
135
+ let message = format ! (
136
+ "... and the {B}borrow might be used here, \
137
+ when that temporary is dropped \
138
+ and runs the {DTOR} for {TYPE}",
139
+ B = borrow_desc,
140
+ TYPE = type_desc,
141
+ DTOR = dtor_desc
142
+ ) ;
129
143
err. span_label ( mir. source_info ( drop_loc) . span , message) ;
130
144
131
145
if let Some ( info) = & local_decl. is_block_tail {
@@ -149,7 +163,7 @@ impl BorrowExplanation {
149
163
}
150
164
}
151
165
}
152
- } ,
166
+ }
153
167
BorrowExplanation :: MustBeValidFor {
154
168
category,
155
169
span,
@@ -160,18 +174,28 @@ impl BorrowExplanation {
160
174
region_name. highlight_region_name ( err) ;
161
175
162
176
if let Some ( desc) = opt_place_desc {
163
- err. span_label ( span, format ! (
164
- "{}requires that `{}` is borrowed for `{}`" ,
165
- category. description( ) , desc, region_name,
166
- ) ) ;
177
+ err. span_label (
178
+ span,
179
+ format ! (
180
+ "{}requires that `{}` is borrowed for `{}`" ,
181
+ category. description( ) ,
182
+ desc,
183
+ region_name,
184
+ ) ,
185
+ ) ;
167
186
} else {
168
- err. span_label ( span, format ! (
169
- "{}requires that {}borrow lasts for `{}`" ,
170
- category. description( ) , borrow_desc, region_name,
171
- ) ) ;
187
+ err. span_label (
188
+ span,
189
+ format ! (
190
+ "{}requires that {}borrow lasts for `{}`" ,
191
+ category. description( ) ,
192
+ borrow_desc,
193
+ region_name,
194
+ ) ,
195
+ ) ;
172
196
} ;
173
- } ,
174
- _ => { } ,
197
+ }
198
+ _ => { }
175
199
}
176
200
}
177
201
}
@@ -217,10 +241,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
217
241
region_sub
218
242
) ;
219
243
220
- match find_use:: find ( mir, regioncx, tcx, region_sub, context. loc ) {
244
+ match find_use:: find ( mir, regioncx, tcx, region_sub, context. loc ) {
221
245
Some ( Cause :: LiveVar ( local, location) ) => {
222
246
let span = mir. source_info ( location) . span ;
223
- let spans = self . move_spans ( & Place :: Local ( local) , location)
247
+ let spans = self
248
+ . move_spans ( & Place :: Local ( local) , location)
224
249
. or_else ( || self . borrow_spans ( span, location) ) ;
225
250
226
251
let borrow_location = context. loc ;
@@ -236,55 +261,56 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
236
261
}
237
262
}
238
263
239
- Some ( Cause :: DropVar ( local, location) ) => {
240
- let mut should_note_order = false ;
241
- if mir. local_decls [ local] . name . is_some ( ) {
242
- if let Some ( ( WriteKind :: StorageDeadOrDrop , place) ) = kind_place {
243
- if let Place :: Local ( borrowed_local) = place {
244
- let dropped_local_scope = mir. local_decls [ local] . visibility_scope ;
245
- let borrowed_local_scope =
246
- mir. local_decls [ * borrowed_local] . visibility_scope ;
247
-
248
- if mir. is_sub_scope ( borrowed_local_scope, dropped_local_scope)
249
- && local != * borrowed_local
250
- {
251
- should_note_order = true ;
252
- }
253
- }
254
- }
255
- }
256
-
257
- BorrowExplanation :: UsedLaterWhenDropped {
258
- drop_loc : location,
259
- dropped_local : local,
260
- should_note_order,
261
- }
264
+ Some ( Cause :: DropVar ( local, location) ) => {
265
+ let mut should_note_order = false ;
266
+ if mir. local_decls [ local] . name . is_some ( ) {
267
+ if let Some ( ( WriteKind :: StorageDeadOrDrop , place) ) = kind_place {
268
+ if let Place :: Local ( borrowed_local) = place {
269
+ let dropped_local_scope = mir. local_decls [ local] . visibility_scope ;
270
+ let borrowed_local_scope =
271
+ mir. local_decls [ * borrowed_local] . visibility_scope ;
272
+
273
+ if mir. is_sub_scope ( borrowed_local_scope, dropped_local_scope)
274
+ && local != * borrowed_local
275
+ {
276
+ should_note_order = true ;
277
+ }
278
+ }
279
+ }
280
+ }
281
+
282
+ BorrowExplanation :: UsedLaterWhenDropped {
283
+ drop_loc : location,
284
+ dropped_local : local,
285
+ should_note_order,
286
+ }
262
287
}
263
288
264
- None => if let Some ( region) = regioncx. to_error_region_vid ( borrow_region_vid) {
265
- let ( category, from_closure, span, region_name) = self
266
- . nonlexical_regioncx
267
- . free_region_constraint_info (
268
- self . mir ,
269
- self . mir_def_id ,
270
- self . infcx ,
271
- borrow_region_vid,
272
- region,
273
- ) ;
274
- if let Some ( region_name) = region_name {
275
- let opt_place_desc = self . describe_place ( & borrow. borrowed_place ) ;
276
- BorrowExplanation :: MustBeValidFor {
277
- category,
278
- from_closure,
279
- span,
280
- region_name,
281
- opt_place_desc,
289
+ None => {
290
+ if let Some ( region) = regioncx. to_error_region_vid ( borrow_region_vid) {
291
+ let ( category, from_closure, span, region_name) =
292
+ self . nonlexical_regioncx . free_region_constraint_info (
293
+ self . mir ,
294
+ self . mir_def_id ,
295
+ self . infcx ,
296
+ borrow_region_vid,
297
+ region,
298
+ ) ;
299
+ if let Some ( region_name) = region_name {
300
+ let opt_place_desc = self . describe_place ( & borrow. borrowed_place ) ;
301
+ BorrowExplanation :: MustBeValidFor {
302
+ category,
303
+ from_closure,
304
+ span,
305
+ region_name,
306
+ opt_place_desc,
307
+ }
308
+ } else {
309
+ BorrowExplanation :: Unexplained
282
310
}
283
311
} else {
284
312
BorrowExplanation :: Unexplained
285
313
}
286
- } else {
287
- BorrowExplanation :: Unexplained
288
314
}
289
315
}
290
316
}
@@ -427,27 +453,31 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
427
453
& self ,
428
454
borrow : & BorrowData < ' tcx > ,
429
455
use_spans : UseSpans ,
430
- location : Location
456
+ location : Location ,
431
457
) -> ( LaterUseKind , Span ) {
432
458
match use_spans {
433
459
UseSpans :: ClosureUse { var_span, .. } => {
434
460
// Used in a closure.
435
461
( LaterUseKind :: ClosureCapture , var_span)
436
- } ,
462
+ }
437
463
UseSpans :: OtherUse ( span) => {
438
464
let block = & self . mir . basic_blocks ( ) [ location. block ] ;
439
465
440
466
let kind = if let Some ( & Statement {
441
467
kind : StatementKind :: FakeRead ( FakeReadCause :: ForLet , _) ,
442
468
..
443
- } ) = block. statements . get ( location. statement_index ) {
469
+ } ) = block. statements . get ( location. statement_index )
470
+ {
444
471
LaterUseKind :: FakeLetRead
445
472
} else if self . was_captured_by_trait_object ( borrow) {
446
473
LaterUseKind :: TraitCapture
447
474
} else if location. statement_index == block. statements . len ( ) {
448
475
if let TerminatorKind :: Call {
449
- ref func, from_hir_call : true , ..
450
- } = block. terminator ( ) . kind {
476
+ ref func,
477
+ from_hir_call : true ,
478
+ ..
479
+ } = block. terminator ( ) . kind
480
+ {
451
481
// Just point to the function, to reduce the chance of overlapping spans.
452
482
let function_span = match func {
453
483
Operand :: Constant ( c) => c. span ,
@@ -458,7 +488,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
458
488
} else {
459
489
span
460
490
}
461
- } ,
491
+ }
462
492
_ => span,
463
493
} ;
464
494
return ( LaterUseKind :: Call , function_span) ;
@@ -482,7 +512,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
482
512
let location = borrow. reserve_location ;
483
513
let block = & self . mir [ location. block ] ;
484
514
let stmt = block. statements . get ( location. statement_index ) ;
485
- debug ! ( "was_captured_by_trait_object: location={:?} stmt={:?}" , location, stmt) ;
515
+ debug ! (
516
+ "was_captured_by_trait_object: location={:?} stmt={:?}" ,
517
+ location, stmt
518
+ ) ;
486
519
487
520
// We make a `queue` vector that has the locations we want to visit. As of writing, this
488
521
// will only ever have one item at any given time, but by using a vector, we can pop from
@@ -491,13 +524,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
491
524
let mut target = if let Some ( & Statement {
492
525
kind : StatementKind :: Assign ( Place :: Local ( local) , _) ,
493
526
..
494
- } ) = stmt {
527
+ } ) = stmt
528
+ {
495
529
local
496
530
} else {
497
531
return false ;
498
532
} ;
499
533
500
- debug ! ( "was_captured_by_trait: target={:?} queue={:?}" , target, queue) ;
534
+ debug ! (
535
+ "was_captured_by_trait: target={:?} queue={:?}" ,
536
+ target, queue
537
+ ) ;
501
538
while let Some ( current_location) = queue. pop ( ) {
502
539
debug ! ( "was_captured_by_trait: target={:?}" , target) ;
503
540
let block = & self . mir [ current_location. block ] ;
@@ -508,55 +545,55 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
508
545
debug ! ( "was_captured_by_trait_object: stmt={:?}" , stmt) ;
509
546
510
547
// The only kind of statement that we care about is assignments...
511
- if let StatementKind :: Assign (
512
- place,
513
- box rvalue,
514
- ) = & stmt. kind {
548
+ if let StatementKind :: Assign ( place, box rvalue) = & stmt. kind {
515
549
let into = match place {
516
550
Place :: Local ( into) => into,
517
551
Place :: Projection ( box Projection {
518
552
base : Place :: Local ( into) ,
519
553
elem : ProjectionElem :: Deref ,
520
554
} ) => into,
521
- _ => {
555
+ _ => {
522
556
// Continue at the next location.
523
557
queue. push ( current_location. successor_within_block ( ) ) ;
524
558
continue ;
525
- } ,
559
+ }
526
560
} ;
527
561
528
562
match rvalue {
529
563
// If we see a use, we should check whether it is our data, and if so
530
564
// update the place that we're looking for to that new place.
531
565
Rvalue :: Use ( operand) => match operand {
532
- Operand :: Copy ( Place :: Local ( from) ) |
533
- Operand :: Move ( Place :: Local ( from) ) if * from == target => {
566
+ Operand :: Copy ( Place :: Local ( from) )
567
+ | Operand :: Move ( Place :: Local ( from) )
568
+ if * from == target =>
569
+ {
534
570
target = * into;
535
- } ,
536
- _ => { } ,
571
+ }
572
+ _ => { }
537
573
} ,
538
574
// If we see a unsized cast, then if it is our data we should check
539
575
// whether it is being cast to a trait object.
540
576
Rvalue :: Cast ( CastKind :: Unsize , operand, ty) => match operand {
541
- Operand :: Copy ( Place :: Local ( from) ) |
542
- Operand :: Move ( Place :: Local ( from) ) if * from == target => {
577
+ Operand :: Copy ( Place :: Local ( from) )
578
+ | Operand :: Move ( Place :: Local ( from) )
579
+ if * from == target =>
580
+ {
543
581
debug ! ( "was_captured_by_trait_object: ty={:?}" , ty) ;
544
582
// Check the type for a trait object.
545
583
return match ty. sty {
546
584
// `&dyn Trait`
547
585
ty:: TyKind :: Ref ( _, ty, _) if ty. is_trait ( ) => true ,
548
586
// `Box<dyn Trait>`
549
- _ if ty. is_box ( ) && ty. boxed_ty ( ) . is_trait ( ) =>
550
- true ,
587
+ _ if ty. is_box ( ) && ty. boxed_ty ( ) . is_trait ( ) => true ,
551
588
// `dyn Trait`
552
589
_ if ty. is_trait ( ) => true ,
553
590
// Anything else.
554
591
_ => false ,
555
592
} ;
556
- } ,
593
+ }
557
594
_ => return false ,
558
595
} ,
559
- _ => { } ,
596
+ _ => { }
560
597
}
561
598
}
562
599
@@ -571,7 +608,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
571
608
destination : Some ( ( Place :: Local ( dest) , block) ) ,
572
609
args,
573
610
..
574
- } = & terminator. kind {
611
+ } = & terminator. kind
612
+ {
575
613
debug ! (
576
614
"was_captured_by_trait_object: target={:?} dest={:?} args={:?}" ,
577
615
target, dest, args
0 commit comments