1
+ #![ deny( rustc:: untranslatable_diagnostic) ]
2
+ #![ deny( rustc:: diagnostic_outside_of_impl) ]
1
3
//! Error reporting machinery for lifetime errors.
2
4
3
5
use rustc_data_structures:: fx:: FxHashSet ;
@@ -23,7 +25,10 @@ use rustc_span::symbol::{kw, sym, Ident};
23
25
use rustc_span:: Span ;
24
26
25
27
use crate :: borrowck_errors;
26
- use crate :: session_diagnostics:: GenericDoesNotLiveLongEnough ;
28
+ use crate :: session_diagnostics:: {
29
+ FnMutError , FnMutReturnTypeErr , GenericDoesNotLiveLongEnough , LifetimeOutliveErr ,
30
+ LifetimeReturnCategoryErr , RequireStaticErr , VarHereDenote ,
31
+ } ;
27
32
28
33
use super :: { OutlivesSuggestionBuilder , RegionName } ;
29
34
use crate :: region_infer:: BlameConstraint ;
@@ -488,32 +493,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
488
493
) -> DiagnosticBuilder < ' tcx , ErrorGuaranteed > {
489
494
let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
490
495
491
- let mut diag = self
492
- . infcx
493
- . tcx
494
- . sess
495
- . struct_span_err ( * span, "captured variable cannot escape `FnMut` closure body" ) ;
496
-
497
496
let mut output_ty = self . regioncx . universal_regions ( ) . unnormalized_output_ty ;
498
497
if let ty:: Opaque ( def_id, _) = * output_ty. kind ( ) {
499
498
output_ty = self . infcx . tcx . type_of ( def_id)
500
499
} ;
501
500
502
501
debug ! ( "report_fnmut_error: output_ty={:?}" , output_ty) ;
503
502
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
+ } ,
514
514
} ;
515
515
516
- diag. span_label ( * span , message ) ;
516
+ let mut diag = self . infcx . tcx . sess . create_err ( err ) ;
517
517
518
518
if let ReturnConstraint :: ClosureUpvar ( upvar_field) = kind {
519
519
let def_id = match self . regioncx . universal_regions ( ) . defining_ty {
@@ -532,20 +532,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
532
532
let upvars_map = self . infcx . tcx . upvars_mentioned ( def_id) . unwrap ( ) ;
533
533
let upvar_def_span = self . infcx . tcx . hir ( ) . span ( def_hir) ;
534
534
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 } ) ;
537
537
}
538
538
}
539
539
540
540
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 } ) ;
542
542
}
543
543
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" ) ;
549
544
self . suggest_move_on_borrowing_closure ( & mut diag) ;
550
545
551
546
diag
@@ -681,39 +676,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
681
676
..
682
677
} = errci;
683
678
684
- let mut diag =
685
- self . infcx . tcx . sess . struct_span_err ( * span, "lifetime may not live long enough" ) ;
686
-
687
679
let ( _, mir_def_name) =
688
680
self . infcx . tcx . article_and_description ( self . mir_def_id ( ) . to_def_id ( ) ) ;
689
681
682
+ let err = LifetimeOutliveErr { span : * span } ;
683
+ let mut diag = self . infcx . tcx . sess . create_err ( err) ;
684
+
690
685
let fr_name = self . give_region_a_name ( * fr) . unwrap ( ) ;
691
686
fr_name. highlight_region_name ( & mut diag) ;
692
687
let outlived_fr_name = self . give_region_a_name ( * outlived_fr) . unwrap ( ) ;
693
688
outlived_fr_name. highlight_region_name ( & mut diag) ;
694
689
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) ;
717
706
718
707
self . add_static_impl_trait_suggestion ( & mut diag, * fr, fr_name, * outlived_fr) ;
719
708
self . suggest_adding_lifetime_params ( & mut diag, * fr, * outlived_fr) ;
@@ -862,7 +851,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
862
851
ident. span ,
863
852
"calling this method introduces the `impl`'s 'static` requirement" ,
864
853
) ;
865
- err. span_note ( multi_span , "the used `impl` has a `'static` requirement" ) ;
854
+ err. subdiagnostic ( RequireStaticErr :: UsedImpl { multi_span } ) ;
866
855
err. span_suggestion_verbose (
867
856
span. shrink_to_hi ( ) ,
868
857
"consider relaxing the implicit `'static` requirement" ,
0 commit comments