Skip to content

Commit 5fea6a0

Browse files
authored
Rollup merge of #100900 - AndyJado:diag-migrate, r=davidtwco
on `region_errors.rs` `@rustbot` label +A-translation
2 parents 63519c5 + 622217d commit 5fea6a0

File tree

5 files changed

+211
-76
lines changed

5 files changed

+211
-76
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+41-52
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![deny(rustc::untranslatable_diagnostic)]
2+
#![deny(rustc::diagnostic_outside_of_impl)]
13
//! Error reporting machinery for lifetime errors.
24
35
use rustc_data_structures::fx::FxHashSet;
@@ -23,7 +25,10 @@ use rustc_span::symbol::{kw, sym, Ident};
2325
use rustc_span::Span;
2426

2527
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+
};
2732

2833
use super::{OutlivesSuggestionBuilder, RegionName};
2934
use 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",

compiler/rustc_borrowck/src/lib.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ extern crate tracing;
1818

1919
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2020
use rustc_data_structures::graph::dominators::Dominators;
21-
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
21+
use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
2222
use rustc_hir as hir;
2323
use rustc_hir::def_id::LocalDefId;
2424
use rustc_index::bit_set::ChunkedBitSet;
@@ -50,6 +50,8 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveData, MoveE
5050
use rustc_mir_dataflow::Analysis;
5151
use rustc_mir_dataflow::MoveDataParamEnv;
5252

53+
use crate::session_diagnostics::VarNeedNotMut;
54+
5355
use self::diagnostics::{AccessKind, RegionName};
5456
use self::location::LocationTable;
5557
use self::prefixes::PrefixSet;
@@ -424,17 +426,9 @@ fn do_mir_borrowck<'a, 'tcx>(
424426
continue;
425427
}
426428

427-
tcx.struct_span_lint_hir(UNUSED_MUT, lint_root, span, |lint| {
428-
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
429-
lint.build("variable does not need to be mutable")
430-
.span_suggestion_short(
431-
mut_span,
432-
"remove this `mut`",
433-
"",
434-
Applicability::MachineApplicable,
435-
)
436-
.emit();
437-
})
429+
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
430+
431+
tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
438432
}
439433

440434
let tainted_by_errors = mbcx.emit_errors();

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use rustc_span::Span;
1616
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
1717
use rustc_trait_selection::traits::TraitEngineExt as _;
1818

19+
use crate::session_diagnostics::ConstNotUsedTraitAlias;
20+
1921
use super::RegionInferenceContext;
2022

2123
impl<'tcx> RegionInferenceContext<'tcx> {
@@ -639,17 +641,10 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
639641
Some(GenericArgKind::Const(c1)) => c1,
640642
Some(u) => panic!("const mapped to unexpected kind: {:?}", u),
641643
None => {
642-
self.tcx
643-
.sess
644-
.struct_span_err(
645-
self.span,
646-
&format!(
647-
"const parameter `{}` is part of concrete type but not \
648-
used in parameter list for the `impl Trait` type alias",
649-
ct
650-
),
651-
)
652-
.emit();
644+
self.tcx.sess.emit_err(ConstNotUsedTraitAlias {
645+
ct: ct.to_string(),
646+
span: self.span,
647+
});
653648

654649
self.tcx().const_error(ct.ty())
655650
}

compiler/rustc_borrowck/src/session_diagnostics.rs

+116-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
1+
use rustc_errors::{IntoDiagnosticArg, MultiSpan};
2+
use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
23
use rustc_middle::ty::Ty;
34
use rustc_span::Span;
45

6+
use crate::diagnostics::RegionName;
7+
58
#[derive(SessionDiagnostic)]
69
#[diag(borrowck::move_unsized, code = "E0161")]
710
pub(crate) struct MoveUnsized<'tcx> {
@@ -42,3 +45,115 @@ pub(crate) struct GenericDoesNotLiveLongEnough {
4245
#[primary_span]
4346
pub span: Span,
4447
}
48+
49+
#[derive(LintDiagnostic)]
50+
#[diag(borrowck::var_does_not_need_mut)]
51+
pub(crate) struct VarNeedNotMut {
52+
#[suggestion_short(applicability = "machine-applicable", code = "")]
53+
pub span: Span,
54+
}
55+
56+
#[derive(SessionDiagnostic)]
57+
#[diag(borrowck::const_not_used_in_type_alias)]
58+
pub(crate) struct ConstNotUsedTraitAlias {
59+
pub ct: String,
60+
#[primary_span]
61+
pub span: Span,
62+
}
63+
64+
#[derive(SessionDiagnostic)]
65+
#[diag(borrowck::var_cannot_escape_closure)]
66+
#[note]
67+
#[note(borrowck::cannot_escape)]
68+
pub(crate) struct FnMutError {
69+
#[primary_span]
70+
pub span: Span,
71+
#[subdiagnostic]
72+
pub ty_err: FnMutReturnTypeErr,
73+
}
74+
75+
#[derive(SessionSubdiagnostic)]
76+
pub(crate) enum VarHereDenote {
77+
#[label(borrowck::var_here_captured)]
78+
Captured {
79+
#[primary_span]
80+
span: Span,
81+
},
82+
#[label(borrowck::var_here_defined)]
83+
Defined {
84+
#[primary_span]
85+
span: Span,
86+
},
87+
#[label(borrowck::closure_inferred_mut)]
88+
FnMutInferred {
89+
#[primary_span]
90+
span: Span,
91+
},
92+
}
93+
94+
#[derive(SessionSubdiagnostic)]
95+
pub(crate) enum FnMutReturnTypeErr {
96+
#[label(borrowck::returned_closure_escaped)]
97+
ReturnClosure {
98+
#[primary_span]
99+
span: Span,
100+
},
101+
#[label(borrowck::returned_async_block_escaped)]
102+
ReturnAsyncBlock {
103+
#[primary_span]
104+
span: Span,
105+
},
106+
#[label(borrowck::returned_ref_escaped)]
107+
ReturnRef {
108+
#[primary_span]
109+
span: Span,
110+
},
111+
}
112+
113+
#[derive(SessionDiagnostic)]
114+
#[diag(borrowck::lifetime_constraints_error)]
115+
pub(crate) struct LifetimeOutliveErr {
116+
#[primary_span]
117+
pub span: Span,
118+
}
119+
120+
#[derive(SessionSubdiagnostic)]
121+
pub(crate) enum LifetimeReturnCategoryErr<'a> {
122+
#[label(borrowck::returned_lifetime_wrong)]
123+
WrongReturn {
124+
#[primary_span]
125+
span: Span,
126+
mir_def_name: &'a str,
127+
outlived_fr_name: RegionName,
128+
fr_name: &'a RegionName,
129+
},
130+
#[label(borrowck::returned_lifetime_short)]
131+
ShortReturn {
132+
#[primary_span]
133+
span: Span,
134+
category_desc: &'static str,
135+
free_region_name: &'a RegionName,
136+
outlived_fr_name: RegionName,
137+
},
138+
}
139+
140+
impl IntoDiagnosticArg for &RegionName {
141+
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
142+
format!("{}", self).into_diagnostic_arg()
143+
}
144+
}
145+
146+
impl IntoDiagnosticArg for RegionName {
147+
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
148+
format!("{}", self).into_diagnostic_arg()
149+
}
150+
}
151+
152+
#[derive(SessionSubdiagnostic)]
153+
pub(crate) enum RequireStaticErr {
154+
#[note(borrowck::used_impl_require_static)]
155+
UsedImpl {
156+
#[primary_span]
157+
multi_span: MultiSpan,
158+
},
159+
}

compiler/rustc_error_messages/locales/en-US/borrowck.ftl

+42
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,45 @@ borrowck_higher_ranked_subtype_error =
1616
1717
borrowck_generic_does_not_live_long_enough =
1818
`{$kind}` does not live long enough
19+
20+
borrowck_move_borrowed =
21+
cannot move out of `{$desc}` beacause it is borrowed
22+
23+
borrowck_var_does_not_need_mut =
24+
variable does not need to be mutable
25+
.suggestion = remove this `mut`
26+
27+
borrowck_const_not_used_in_type_alias =
28+
const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias
29+
30+
borrowck_var_cannot_escape_closure =
31+
captured variable cannot escape `FnMut` closure body
32+
.note = `FnMut` closures only have access to their captured variables while they are executing...
33+
.cannot_escape = ...therefore, they cannot allow references to captured variables to escape
34+
35+
borrowck_var_here_defined = variable defined here
36+
37+
borrowck_var_here_captured = variable captured here
38+
39+
borrowck_closure_inferred_mut = inferred to be a `FnMut` closure
40+
41+
borrowck_returned_closure_escaped =
42+
returns a closure that contains a reference to a captured variable, which then escapes the closure body
43+
44+
borrowck_returned_async_block_escaped =
45+
returns an `async` block that contains a reference to a captured variable, which then escapes the closure body
46+
47+
borrowck_returned_ref_escaped =
48+
returns a reference to a captured variable which escapes the closure body
49+
50+
borrowck_lifetime_constraints_error =
51+
lifetime may not live long enough
52+
53+
borrowck_returned_lifetime_wrong =
54+
{$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}`
55+
56+
borrowck_returned_lifetime_short =
57+
{$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}`
58+
59+
borrowck_used_impl_require_static =
60+
the used `impl` has a `'static` requirement

0 commit comments

Comments
 (0)