@@ -12,7 +12,8 @@ use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
12
12
use borrow_check:: { Context , MirBorrowckCtxt } ;
13
13
use borrow_check:: borrow_set:: BorrowData ;
14
14
use rustc:: mir:: visit:: { MirVisitable , PlaceContext , Visitor } ;
15
- use rustc:: mir:: { Local , Location , Mir } ;
15
+ use rustc:: mir:: { BasicBlock , Local , Location , Mir , Statement , Terminator , TerminatorKind } ;
16
+ use rustc:: mir:: RETURN_PLACE ;
16
17
use rustc_data_structures:: fx:: FxHashSet ;
17
18
use rustc_errors:: DiagnosticBuilder ;
18
19
use util:: liveness:: { self , DefUse , LivenessMode } ;
@@ -38,9 +39,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
38
39
Cause :: LiveVar ( local, location) => {
39
40
match find_regular_use ( mir, regioncx, borrow, location, local) {
40
41
Some ( p) => {
41
- err . span_label (
42
- mir . source_info ( p ) . span ,
43
- format ! ( "borrow later used here" ) ,
42
+ mir . visitable ( p ) . apply (
43
+ p ,
44
+ & mut LaterUsedReporter { err , mir } ,
44
45
) ;
45
46
}
46
47
@@ -232,4 +233,61 @@ impl<'tcx> Visitor<'tcx> for DefUseVisitor {
232
233
}
233
234
}
234
235
}
236
+
237
+ fn visit_terminator (
238
+ & mut self ,
239
+ block : BasicBlock ,
240
+ terminator : & Terminator < ' tcx > ,
241
+ location : Location ,
242
+ ) {
243
+ if let TerminatorKind :: Return = terminator. kind {
244
+ if self . local == RETURN_PLACE {
245
+ self . used = true ;
246
+ }
247
+ }
248
+ self . super_terminator ( block, terminator, location) ;
249
+ }
250
+ }
251
+
252
+ struct LaterUsedReporter < ' cx , ' diag : ' cx , ' tcx : ' cx > {
253
+ err : & ' cx mut DiagnosticBuilder < ' diag > ,
254
+ mir : & ' cx Mir < ' tcx > ,
255
+ }
256
+
257
+ impl < ' cx , ' diag , ' tcx > LaterUsedReporter < ' cx , ' diag , ' tcx > {
258
+ fn base_report ( & mut self , location : Location ) {
259
+ self . err . span_label (
260
+ self . mir . source_info ( location) . span ,
261
+ format ! ( "borrow later used here" ) ,
262
+ ) ;
263
+ }
264
+ }
265
+
266
+ impl < ' cx , ' diag , ' tcx > Visitor < ' tcx > for LaterUsedReporter < ' cx , ' diag , ' tcx > {
267
+ fn visit_statement (
268
+ & mut self ,
269
+ _block : BasicBlock ,
270
+ _statement : & Statement < ' tcx > ,
271
+ location : Location
272
+ ) {
273
+ self . base_report ( location) ;
274
+ }
275
+
276
+ fn visit_terminator (
277
+ & mut self ,
278
+ _block : BasicBlock ,
279
+ terminator : & Terminator < ' tcx > ,
280
+ location : Location ,
281
+ ) {
282
+ match terminator. kind {
283
+ TerminatorKind :: Return => {
284
+ // If the last use is the `Return` terminator
285
+ // then for now we don't add any label, as it's
286
+ // not clear what to say that is helpful.
287
+ }
288
+ _ => {
289
+ self . base_report ( location) ;
290
+ }
291
+ }
292
+ }
235
293
}
0 commit comments