@@ -15,7 +15,7 @@ use rustc::hir::def_id::DefId;
1515use rustc:: infer:: error_reporting:: nice_region_error:: NiceRegionError ;
1616use rustc:: infer:: InferCtxt ;
1717use 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 } ;
1919use rustc_data_structures:: indexed_vec:: IndexVec ;
2020use rustc_errors:: Diagnostic ;
2121use std:: collections:: VecDeque ;
@@ -344,7 +344,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
344344 ) ;
345345
346346 // 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) {
348350 let tables = infcx. tcx . typeck_tables_of ( mir_def_id) ;
349351 let nice = NiceRegionError :: new_from_span ( infcx. tcx , span, o, f, Some ( tables) ) ;
350352 if let Some ( _error_reported) = nice. try_report_from_nll ( ) {
@@ -356,17 +358,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
356358 self . universal_regions . is_local_free_region ( fr) ,
357359 self . universal_regions . is_local_free_region ( outlived_fr) ,
358360 ) ;
359- debug ! ( "report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}" ,
360- fr_is_local, outlived_fr_is_local, category) ;
361361
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) ;
362365 match ( category, fr_is_local, outlived_fr_is_local) {
363366 ( ConstraintCategory :: Assignment , true , false ) |
364367 ( 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) ,
367370 _ =>
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 ,
370373 category, span, errors_buffer) ,
371374 } ;
372375 }
@@ -377,7 +380,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
377380 infcx : & InferCtxt < ' _ , ' _ , ' tcx > ,
378381 mir_def_id : DefId ,
379382 fr : RegionVid ,
383+ fr_region : Option < Region < ' tcx > > ,
380384 outlived_fr : RegionVid ,
385+ outlived_fr_region : Option < Region < ' tcx > > ,
381386 category : ConstraintCategory ,
382387 span : Span ,
383388 errors_buffer : & mut Vec < Diagnostic > ,
@@ -390,7 +395,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
390395
391396 if fr_name_and_span. is_none ( ) && outlived_fr_name_and_span. is_none ( ) {
392397 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,
394400 category, span, errors_buffer) ;
395401 }
396402
@@ -430,8 +436,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
430436 mir_def_id : DefId ,
431437 fr : RegionVid ,
432438 fr_is_local : bool ,
439+ fr_region : Option < Region < ' tcx > > ,
433440 outlived_fr : RegionVid ,
434441 outlived_fr_is_local : bool ,
442+ outlived_fr_region : Option < Region < ' tcx > > ,
435443 category : ConstraintCategory ,
436444 span : Span ,
437445 errors_buffer : & mut Vec < Diagnostic > ,
@@ -465,6 +473,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
465473 } ,
466474 }
467475
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+
468496 diag. buffer ( errors_buffer) ;
469497 }
470498
@@ -490,4 +518,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
490518 let ( _, span, _) = self . best_blame_constraint ( mir, tcx, fr1, |r| r == fr2) ;
491519 span
492520 }
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+ }
493532}
0 commit comments