@@ -15,7 +15,7 @@ use rustc::hir::def_id::DefId;
15
15
use rustc:: infer:: error_reporting:: nice_region_error:: NiceRegionError ;
16
16
use rustc:: infer:: InferCtxt ;
17
17
use rustc:: mir:: { self , Location , Mir , Place , Rvalue , StatementKind , TerminatorKind } ;
18
- use rustc:: ty:: { TyCtxt , RegionVid } ;
18
+ use rustc:: ty:: { TyCtxt , Ty , TyS , TyKind , Region , RegionKind , RegionVid } ;
19
19
use rustc_data_structures:: indexed_vec:: IndexVec ;
20
20
use rustc_errors:: Diagnostic ;
21
21
use std:: collections:: VecDeque ;
@@ -344,7 +344,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
344
344
) ;
345
345
346
346
// Check if we can use one of the "nice region errors".
347
- if let ( Some ( f) , Some ( o) ) = ( self . to_error_region ( fr) , self . to_error_region ( outlived_fr) ) {
347
+ let fr_region = self . to_error_region ( fr) ;
348
+ let outlived_fr_region = self . to_error_region ( outlived_fr) ;
349
+ if let ( Some ( f) , Some ( o) ) = ( fr_region, outlived_fr_region) {
348
350
let tables = infcx. tcx . typeck_tables_of ( mir_def_id) ;
349
351
let nice = NiceRegionError :: new_from_span ( infcx. tcx , span, o, f, Some ( tables) ) ;
350
352
if let Some ( _error_reported) = nice. try_report_from_nll ( ) {
@@ -356,17 +358,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
356
358
self . universal_regions . is_local_free_region ( fr) ,
357
359
self . universal_regions . is_local_free_region ( outlived_fr) ,
358
360
) ;
359
- debug ! ( "report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}" ,
360
- fr_is_local, outlived_fr_is_local, category) ;
361
361
362
+ debug ! ( "report_error: fr_is_local={:?} outlived_fr_is_local={:?} fr_region={:?} \
363
+ outlived_fr_region={:?} category={:?}",
364
+ fr_is_local, outlived_fr_is_local, fr_region, outlived_fr_region, category) ;
362
365
match ( category, fr_is_local, outlived_fr_is_local) {
363
366
( ConstraintCategory :: Assignment , true , false ) |
364
367
( ConstraintCategory :: CallArgument , true , false ) =>
365
- self . report_escaping_data_error ( mir, infcx, mir_def_id, fr, outlived_fr,
366
- category, span, errors_buffer) ,
368
+ self . report_escaping_data_error ( mir, infcx, mir_def_id, fr, fr_region , outlived_fr,
369
+ outlived_fr_region , category, span, errors_buffer) ,
367
370
_ =>
368
- self . report_general_error ( mir, infcx, mir_def_id, fr, fr_is_local,
369
- outlived_fr, outlived_fr_is_local,
371
+ self . report_general_error ( mir, infcx, mir_def_id, fr, fr_is_local, fr_region ,
372
+ outlived_fr, outlived_fr_is_local, outlived_fr_region ,
370
373
category, span, errors_buffer) ,
371
374
} ;
372
375
}
@@ -377,7 +380,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
377
380
infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
378
381
mir_def_id : DefId ,
379
382
fr : RegionVid ,
383
+ fr_region : Option < Region < ' tcx > > ,
380
384
outlived_fr : RegionVid ,
385
+ outlived_fr_region : Option < Region < ' tcx > > ,
381
386
category : ConstraintCategory ,
382
387
span : Span ,
383
388
errors_buffer : & mut Vec < Diagnostic > ,
@@ -390,7 +395,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
390
395
391
396
if fr_name_and_span. is_none ( ) && outlived_fr_name_and_span. is_none ( ) {
392
397
return self . report_general_error ( mir, infcx, mir_def_id,
393
- fr, true , outlived_fr, false ,
398
+ fr, true , fr_region,
399
+ outlived_fr, false , outlived_fr_region,
394
400
category, span, errors_buffer) ;
395
401
}
396
402
@@ -430,8 +436,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
430
436
mir_def_id : DefId ,
431
437
fr : RegionVid ,
432
438
fr_is_local : bool ,
439
+ fr_region : Option < Region < ' tcx > > ,
433
440
outlived_fr : RegionVid ,
434
441
outlived_fr_is_local : bool ,
442
+ outlived_fr_region : Option < Region < ' tcx > > ,
435
443
category : ConstraintCategory ,
436
444
span : Span ,
437
445
errors_buffer : & mut Vec < Diagnostic > ,
@@ -465,6 +473,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
465
473
} ,
466
474
}
467
475
476
+ if let ( Some ( f) , Some ( RegionKind :: ReStatic ) ) = ( fr_region, outlived_fr_region) {
477
+ if let Some ( TyS {
478
+ sty : TyKind :: Anon ( did, _) ,
479
+ ..
480
+ } ) = self . return_type_impl_trait ( infcx, f) {
481
+ let span = infcx. tcx . def_span ( * did) ;
482
+ if let Ok ( snippet) = infcx. tcx . sess . source_map ( ) . span_to_snippet ( span) {
483
+ diag. span_suggestion (
484
+ span,
485
+ & format ! (
486
+ "you can add a constraint to the return type to make it last \
487
+ less than `'static` and match {}",
488
+ fr_name,
489
+ ) ,
490
+ format ! ( "{} + {}" , snippet, fr_name) ,
491
+ ) ;
492
+ }
493
+ }
494
+ }
495
+
468
496
diag. buffer ( errors_buffer) ;
469
497
}
470
498
@@ -490,4 +518,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
490
518
let ( _, span, _) = self . best_blame_constraint ( mir, tcx, fr1, |r| r == fr2) ;
491
519
span
492
520
}
521
+
522
+ fn return_type_impl_trait < ' cx > (
523
+ & self ,
524
+ infcx : & ' cx InferCtxt < ' _ , ' _ , ' tcx > ,
525
+ outlived_fr_region : Region < ' tcx > ,
526
+ ) -> Option < Ty < ' cx > > {
527
+ infcx. tcx . is_suitable_region ( outlived_fr_region)
528
+ . map ( |r| r. def_id )
529
+ . map ( |id| infcx. tcx . return_type_impl_trait ( id) )
530
+ . unwrap_or ( None )
531
+ }
493
532
}
0 commit comments