@@ -31,26 +31,21 @@ mod var_name;
31
31
enum ConstraintCategory {
32
32
Cast ,
33
33
Assignment ,
34
- AssignmentToUpvar ,
35
34
Return ,
36
- CallArgumentToUpvar ,
37
35
CallArgument ,
38
36
Other ,
39
37
Boring ,
40
38
}
41
39
42
40
impl fmt:: Display for ConstraintCategory {
43
41
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
42
+ // Must end with a space. Allows for empty names to be provided.
44
43
match self {
45
- ConstraintCategory :: Assignment | ConstraintCategory :: AssignmentToUpvar => {
46
- write ! ( f, "assignment" )
47
- }
48
- ConstraintCategory :: Return => write ! ( f, "return" ) ,
49
- ConstraintCategory :: Cast => write ! ( f, "cast" ) ,
50
- ConstraintCategory :: CallArgument | ConstraintCategory :: CallArgumentToUpvar => {
51
- write ! ( f, "argument" )
52
- }
53
- _ => write ! ( f, "free region" ) ,
44
+ ConstraintCategory :: Assignment => write ! ( f, "assignment " ) ,
45
+ ConstraintCategory :: Return => write ! ( f, "return " ) ,
46
+ ConstraintCategory :: Cast => write ! ( f, "cast " ) ,
47
+ ConstraintCategory :: CallArgument => write ! ( f, "argument " ) ,
48
+ _ => write ! ( f, "" ) ,
54
49
}
55
50
}
56
51
}
@@ -224,10 +219,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
224
219
"constraint_is_interesting: locations={:?} constraint={:?}" ,
225
220
constraint. locations, constraint
226
221
) ;
227
- if let Locations :: Interesting ( _ ) = constraint . locations {
228
- true
229
- } else {
230
- false
222
+
223
+ match constraint . locations {
224
+ Locations :: Interesting ( _ ) | Locations :: All => true ,
225
+ _ => false ,
231
226
}
232
227
}
233
228
@@ -320,45 +315,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
320
315
}
321
316
}
322
317
323
- let category = match (
324
- category,
318
+ let ( fr_is_local, outlived_fr_is_local) : ( bool , bool ) = (
325
319
self . universal_regions . is_local_free_region ( fr) ,
326
320
self . universal_regions . is_local_free_region ( outlived_fr) ,
327
- ) {
328
- ( ConstraintCategory :: Assignment , true , false ) => ConstraintCategory :: AssignmentToUpvar ,
329
- ( ConstraintCategory :: CallArgument , true , false ) => {
330
- ConstraintCategory :: CallArgumentToUpvar
331
- }
332
- ( category, _, _) => category,
321
+ ) ;
322
+ debug ! ( "report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}" ,
323
+ fr_is_local, outlived_fr_is_local, category) ;
324
+
325
+ match ( category, fr_is_local, outlived_fr_is_local) {
326
+ ( ConstraintCategory :: Assignment , true , false ) |
327
+ ( ConstraintCategory :: CallArgument , true , false ) =>
328
+ self . report_escaping_data_error ( mir, infcx, mir_def_id, fr, outlived_fr,
329
+ category, span, errors_buffer) ,
330
+ _ =>
331
+ self . report_general_error ( mir, infcx, mir_def_id, fr, fr_is_local,
332
+ outlived_fr, outlived_fr_is_local,
333
+ category, span, errors_buffer) ,
333
334
} ;
334
-
335
- debug ! ( "report_error: category={:?}" , category) ;
336
- match category {
337
- ConstraintCategory :: AssignmentToUpvar | ConstraintCategory :: CallArgumentToUpvar => self
338
- . report_closure_error (
339
- mir,
340
- infcx,
341
- mir_def_id,
342
- fr,
343
- outlived_fr,
344
- category,
345
- span,
346
- errors_buffer,
347
- ) ,
348
- _ => self . report_general_error (
349
- mir,
350
- infcx,
351
- mir_def_id,
352
- fr,
353
- outlived_fr,
354
- category,
355
- span,
356
- errors_buffer,
357
- ) ,
358
- }
359
335
}
360
336
361
- fn report_closure_error (
337
+ fn report_escaping_data_error (
362
338
& self ,
363
339
mir : & Mir < ' tcx > ,
364
340
infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
@@ -373,29 +349,23 @@ impl<'tcx> RegionInferenceContext<'tcx> {
373
349
let outlived_fr_name_and_span =
374
350
self . get_var_name_and_span_for_region ( infcx. tcx , mir, outlived_fr) ;
375
351
352
+ let escapes_from = if infcx. tcx . is_closure ( mir_def_id) { "closure" } else { "function" } ;
353
+
376
354
if fr_name_and_span. is_none ( ) && outlived_fr_name_and_span. is_none ( ) {
377
- return self . report_general_error (
378
- mir,
379
- infcx,
380
- mir_def_id,
381
- fr,
382
- outlived_fr,
383
- category,
384
- span,
385
- errors_buffer,
386
- ) ;
355
+ return self . report_general_error ( mir, infcx, mir_def_id,
356
+ fr, true , outlived_fr, false ,
357
+ category, span, errors_buffer) ;
387
358
}
388
359
389
- let mut diag = infcx
390
- . tcx
391
- . sess
392
- . struct_span_err ( span, & format ! ( "borrowed data escapes outside of closure" ) ) ;
360
+ let mut diag = infcx. tcx . sess . struct_span_err (
361
+ span, & format ! ( "borrowed data escapes outside of {}" , escapes_from) ,
362
+ ) ;
393
363
394
364
if let Some ( ( outlived_fr_name, outlived_fr_span) ) = outlived_fr_name_and_span {
395
365
if let Some ( name) = outlived_fr_name {
396
366
diag. span_label (
397
367
outlived_fr_span,
398
- format ! ( "`{}` is declared here, outside of the closure body" , name) ,
368
+ format ! ( "`{}` is declared here, outside of the {} body" , name, escapes_from ) ,
399
369
) ;
400
370
}
401
371
}
@@ -404,13 +374,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
404
374
if let Some ( name) = fr_name {
405
375
diag. span_label (
406
376
fr_span,
407
- format ! (
408
- "`{}` is a reference that is only valid in the closure body" ,
409
- name
410
- ) ,
377
+ format ! ( "`{}` is a reference that is only valid in the {} body" ,
378
+ name, escapes_from) ,
411
379
) ;
412
380
413
- diag. span_label ( span, format ! ( "`{}` escapes the closure body here" , name) ) ;
381
+ diag. span_label ( span, format ! ( "`{}` escapes the {} body here" ,
382
+ name, escapes_from) ) ;
414
383
}
415
384
}
416
385
@@ -423,7 +392,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
423
392
infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
424
393
mir_def_id : DefId ,
425
394
fr : RegionVid ,
395
+ fr_is_local : bool ,
426
396
outlived_fr : RegionVid ,
397
+ outlived_fr_is_local : bool ,
427
398
category : ConstraintCategory ,
428
399
span : Span ,
429
400
errors_buffer : & mut Vec < Diagnostic > ,
@@ -434,17 +405,28 @@ impl<'tcx> RegionInferenceContext<'tcx> {
434
405
) ;
435
406
436
407
let counter = & mut 1 ;
437
- let fr_name = self . give_region_a_name ( infcx. tcx , mir, mir_def_id, fr, counter, & mut diag) ;
438
- let outlived_fr_name =
439
- self . give_region_a_name ( infcx. tcx , mir, mir_def_id, outlived_fr, counter, & mut diag) ;
440
-
441
- diag. span_label (
442
- span,
443
- format ! (
444
- "{} requires that `{}` must outlive `{}`" ,
445
- category, fr_name, outlived_fr_name,
446
- ) ,
447
- ) ;
408
+ let fr_name = self . give_region_a_name (
409
+ infcx, mir, mir_def_id, fr, counter, & mut diag) ;
410
+ let outlived_fr_name = self . give_region_a_name (
411
+ infcx, mir, mir_def_id, outlived_fr, counter, & mut diag) ;
412
+
413
+ let mir_def_name = if infcx. tcx . is_closure ( mir_def_id) { "closure" } else { "function" } ;
414
+
415
+ match ( category, outlived_fr_is_local, fr_is_local) {
416
+ ( ConstraintCategory :: Return , true , _) => {
417
+ diag. span_label ( span, format ! (
418
+ "{} was supposed to return data with lifetime `{}` but it is returning \
419
+ data with lifetime `{}`",
420
+ mir_def_name, fr_name, outlived_fr_name,
421
+ ) ) ;
422
+ } ,
423
+ _ => {
424
+ diag. span_label ( span, format ! (
425
+ "{}requires that `{}` must outlive `{}`" ,
426
+ category, fr_name, outlived_fr_name,
427
+ ) ) ;
428
+ } ,
429
+ }
448
430
449
431
diag. buffer ( errors_buffer) ;
450
432
}
0 commit comments