1+ #![ deny( rustc:: untranslatable_diagnostic) ]
2+ #![ deny( rustc:: diagnostic_outside_of_impl) ]
13//! Error reporting machinery for lifetime errors.
24
35use rustc_data_structures:: fx:: FxHashSet ;
@@ -23,7 +25,10 @@ use rustc_span::symbol::{kw, sym, Ident};
2325use rustc_span:: Span ;
2426
2527use crate :: borrowck_errors;
26- use crate :: session_diagnostics:: GenericDoesNotLiveLongEnough ;
28+ use crate :: session_diagnostics:: {
29+ FnMutError , FnMutReturnTypeErr , GenericDoesNotLiveLongEnough , LifetimeOutliveErr ,
30+ LifetimeReturnCategoryErr , RequireStaticErr , VarHereDenote ,
31+ } ;
2732
2833use super :: { OutlivesSuggestionBuilder , RegionName } ;
2934use crate :: region_infer:: BlameConstraint ;
@@ -488,32 +493,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
488493 ) -> DiagnosticBuilder < ' tcx , ErrorGuaranteed > {
489494 let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
490495
491- let mut diag = self
492- . infcx
493- . tcx
494- . sess
495- . struct_span_err ( * span, "captured variable cannot escape `FnMut` closure body" ) ;
496-
497496 let mut output_ty = self . regioncx . universal_regions ( ) . unnormalized_output_ty ;
498497 if let ty:: Opaque ( def_id, _) = * output_ty. kind ( ) {
499498 output_ty = self . infcx . tcx . type_of ( def_id)
500499 } ;
501500
502501 debug ! ( "report_fnmut_error: output_ty={:?}" , output_ty) ;
503502
504- let message = match output_ty. kind ( ) {
505- ty:: Closure ( _, _) => {
506- "returns a closure that contains a reference to a captured variable, which then \
507- escapes the closure body"
508- }
509- ty:: Adt ( def, _) if self . infcx . tcx . is_diagnostic_item ( sym:: gen_future, def. did ( ) ) => {
510- "returns an `async` block that contains a reference to a captured variable, which then \
511- escapes the closure body"
512- }
513- _ => "returns a reference to a captured variable which escapes the closure body" ,
503+ let err = FnMutError {
504+ span : * span,
505+ ty_err : match output_ty. kind ( ) {
506+ ty:: Closure ( _, _) => FnMutReturnTypeErr :: ReturnClosure { span : * span } ,
507+ ty:: Adt ( def, _)
508+ if self . infcx . tcx . is_diagnostic_item ( sym:: gen_future, def. did ( ) ) =>
509+ {
510+ FnMutReturnTypeErr :: ReturnAsyncBlock { span : * span }
511+ }
512+ _ => FnMutReturnTypeErr :: ReturnRef { span : * span } ,
513+ } ,
514514 } ;
515515
516- diag. span_label ( * span , message ) ;
516+ let mut diag = self . infcx . tcx . sess . create_err ( err ) ;
517517
518518 if let ReturnConstraint :: ClosureUpvar ( upvar_field) = kind {
519519 let def_id = match self . regioncx . universal_regions ( ) . defining_ty {
@@ -532,20 +532,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
532532 let upvars_map = self . infcx . tcx . upvars_mentioned ( def_id) . unwrap ( ) ;
533533 let upvar_def_span = self . infcx . tcx . hir ( ) . span ( def_hir) ;
534534 let upvar_span = upvars_map. get ( & def_hir) . unwrap ( ) . span ;
535- diag. span_label ( upvar_def_span , "variable defined here" ) ;
536- diag. span_label ( upvar_span , "variable captured here" ) ;
535+ diag. subdiagnostic ( VarHereDenote :: Defined { span : upvar_def_span } ) ;
536+ diag. subdiagnostic ( VarHereDenote :: Captured { span : upvar_span } ) ;
537537 }
538538 }
539539
540540 if let Some ( fr_span) = self . give_region_a_name ( * outlived_fr) . unwrap ( ) . span ( ) {
541- diag. span_label ( fr_span , "inferred to be a `FnMut` closure" ) ;
541+ diag. subdiagnostic ( VarHereDenote :: FnMutInferred { span : fr_span } ) ;
542542 }
543543
544- diag. note (
545- "`FnMut` closures only have access to their captured variables while they are \
546- executing...",
547- ) ;
548- diag. note ( "...therefore, they cannot allow references to captured variables to escape" ) ;
549544 self . suggest_move_on_borrowing_closure ( & mut diag) ;
550545
551546 diag
@@ -681,39 +676,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
681676 ..
682677 } = errci;
683678
684- let mut diag =
685- self . infcx . tcx . sess . struct_span_err ( * span, "lifetime may not live long enough" ) ;
686-
687679 let ( _, mir_def_name) =
688680 self . infcx . tcx . article_and_description ( self . mir_def_id ( ) . to_def_id ( ) ) ;
689681
682+ let err = LifetimeOutliveErr { span : * span } ;
683+ let mut diag = self . infcx . tcx . sess . create_err ( err) ;
684+
690685 let fr_name = self . give_region_a_name ( * fr) . unwrap ( ) ;
691686 fr_name. highlight_region_name ( & mut diag) ;
692687 let outlived_fr_name = self . give_region_a_name ( * outlived_fr) . unwrap ( ) ;
693688 outlived_fr_name. highlight_region_name ( & mut diag) ;
694689
695- match ( category, outlived_fr_is_local, fr_is_local) {
696- ( ConstraintCategory :: Return ( _) , true , _) => {
697- diag. span_label (
698- * span,
699- format ! (
700- "{mir_def_name} was supposed to return data with lifetime `{outlived_fr_name}` but it is returning \
701- data with lifetime `{fr_name}`",
702- ) ,
703- ) ;
704- }
705- _ => {
706- diag. span_label (
707- * span,
708- format ! (
709- "{}requires that `{}` must outlive `{}`" ,
710- category. description( ) ,
711- fr_name,
712- outlived_fr_name,
713- ) ,
714- ) ;
715- }
716- }
690+ let err_category = match ( category, outlived_fr_is_local, fr_is_local) {
691+ ( ConstraintCategory :: Return ( _) , true , _) => LifetimeReturnCategoryErr :: WrongReturn {
692+ span : * span,
693+ mir_def_name,
694+ outlived_fr_name,
695+ fr_name : & fr_name,
696+ } ,
697+ _ => LifetimeReturnCategoryErr :: ShortReturn {
698+ span : * span,
699+ category_desc : category. description ( ) ,
700+ free_region_name : & fr_name,
701+ outlived_fr_name,
702+ } ,
703+ } ;
704+
705+ diag. subdiagnostic ( err_category) ;
717706
718707 self . add_static_impl_trait_suggestion ( & mut diag, * fr, fr_name, * outlived_fr) ;
719708 self . suggest_adding_lifetime_params ( & mut diag, * fr, * outlived_fr) ;
@@ -862,7 +851,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
862851 ident. span ,
863852 "calling this method introduces the `impl`'s 'static` requirement" ,
864853 ) ;
865- err. span_note ( multi_span , "the used `impl` has a `'static` requirement" ) ;
854+ err. subdiagnostic ( RequireStaticErr :: UsedImpl { multi_span } ) ;
866855 err. span_suggestion_verbose (
867856 span. shrink_to_hi ( ) ,
868857 "consider relaxing the implicit `'static` requirement" ,
0 commit comments