Skip to content

Commit f540b27

Browse files
Rollup merge of #153508 - JonathanBrouwer:improved_eager_format, r=GuillaumeGomez
Clean up the eager formatting API For #151366 (comment) Previously eager formatting worked by throwing the arguments into a diag, formatting, then removing the args again. This is ugly so instead we now just do the formatting completely separately. This PR has nice commits, so I recommend reviewing commit by commit. r? @GuillaumeGomez
2 parents ec5e4aa + 7baf2be commit f540b27

23 files changed

Lines changed: 270 additions & 320 deletions

File tree

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::collections::BTreeMap;
44

55
use rustc_abi::{FieldIdx, VariantIdx};
66
use rustc_data_structures::fx::FxIndexMap;
7+
use rustc_errors::formatting::DiagMessageAddArg;
78
use rustc_errors::{Applicability, Diag, DiagMessage, EmissionGuarantee, MultiSpan, listify, msg};
89
use rustc_hir::def::{CtorKind, Namespace};
910
use rustc_hir::{
@@ -1309,12 +1310,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
13091310
&& !spans.is_empty()
13101311
{
13111312
let mut span: MultiSpan = spans.clone().into();
1312-
err.arg("ty", param_ty.to_string());
1313-
let msg = err.dcx.eagerly_format_to_string(
1314-
msg!("`{$ty}` is made to be an `FnOnce` closure here"),
1315-
err.args.iter(),
1316-
);
1317-
err.remove_arg("ty");
1313+
let msg = msg!("`{$ty}` is made to be an `FnOnce` closure here")
1314+
.arg("ty", param_ty.to_string())
1315+
.format();
13181316
for sp in spans {
13191317
span.push_span_label(sp, msg.clone());
13201318
}

compiler/rustc_builtin_macros/src/errors.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rustc_errors::codes::*;
2+
use rustc_errors::formatting::DiagMessageAddArg;
23
use rustc_errors::{
34
Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, SingleLabelManySpans,
45
Subdiagnostic, msg,
@@ -763,15 +764,17 @@ pub(crate) struct FormatUnusedArg {
763764
// form of diagnostic.
764765
impl Subdiagnostic for FormatUnusedArg {
765766
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
766-
diag.arg("named", self.named);
767-
let msg = diag.eagerly_format(msg!(
768-
"{$named ->
769-
[true] named argument
770-
*[false] argument
771-
} never used"
772-
));
773-
diag.remove_arg("named");
774-
diag.span_label(self.span, msg);
767+
diag.span_label(
768+
self.span,
769+
msg!(
770+
"{$named ->
771+
[true] named argument
772+
*[false] argument
773+
} never used"
774+
)
775+
.arg("named", self.named)
776+
.format(),
777+
);
775778
}
776779
}
777780

@@ -946,17 +949,14 @@ pub(crate) struct AsmClobberNoReg {
946949

947950
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AsmClobberNoReg {
948951
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
949-
// eager translation as `span_labels` takes `AsRef<str>`
950-
let lbl1 = dcx.eagerly_format_to_string(msg!("clobber_abi"), [].into_iter());
951-
let lbl2 = dcx.eagerly_format_to_string(msg!("generic outputs"), [].into_iter());
952952
Diag::new(
953953
dcx,
954954
level,
955955
msg!("asm with `clobber_abi` must specify explicit registers for outputs"),
956956
)
957957
.with_span(self.spans.clone())
958-
.with_span_labels(self.clobbers, &lbl1)
959-
.with_span_labels(self.spans, &lbl2)
958+
.with_span_labels(self.clobbers, "clobber_abi")
959+
.with_span_labels(self.spans, "generic outputs")
960960
}
961961
}
962962

compiler/rustc_codegen_llvm/src/errors.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ use std::ffi::CString;
22
use std::path::Path;
33

44
use rustc_data_structures::small_c_str::SmallCStr;
5-
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, msg};
5+
use rustc_errors::{
6+
Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, format_diag_message, msg,
7+
};
68
use rustc_macros::Diagnostic;
79
use rustc_span::Span;
810

@@ -24,7 +26,7 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ParseTargetMachineConfig<'_> {
2426
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
2527
let diag: Diag<'_, G> = self.0.into_diag(dcx, level);
2628
let (message, _) = diag.messages.first().expect("`LlvmError` with no message");
27-
let message = dcx.eagerly_format_to_string(message.clone(), diag.args.iter());
29+
let message = format_diag_message(message, &diag.args);
2830
Diag::new(
2931
dcx,
3032
level,

compiler/rustc_const_eval/src/check_consts/ops.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ fn build_error_for_const_call<'tcx>(
265265
}
266266
}
267267
CallKind::FnCall { fn_trait_id, self_ty } => {
268+
let kind = ccx.const_kind();
268269
let note = match self_ty.kind() {
269270
FnDef(def_id, ..) => {
270271
let span = tcx.def_span(*def_id);
@@ -274,8 +275,8 @@ fn build_error_for_const_call<'tcx>(
274275

275276
Some(errors::NonConstClosureNote::FnDef { span })
276277
}
277-
FnPtr(..) => Some(errors::NonConstClosureNote::FnPtr),
278-
Closure(..) => Some(errors::NonConstClosureNote::Closure),
278+
FnPtr(..) => Some(errors::NonConstClosureNote::FnPtr { kind }),
279+
Closure(..) => Some(errors::NonConstClosureNote::Closure { kind }),
279280
_ => None,
280281
};
281282

compiler/rustc_const_eval/src/errors.rs

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ use std::fmt::Write;
44
use either::Either;
55
use rustc_abi::WrappingRange;
66
use rustc_errors::codes::*;
7+
use rustc_errors::formatting::DiagMessageAddArg;
78
use rustc_errors::{
8-
Diag, DiagArgValue, DiagMessage, Diagnostic, EmissionGuarantee, Level, MultiSpan,
9-
Subdiagnostic, msg,
9+
Diag, DiagArgMap, DiagArgValue, DiagMessage, Diagnostic, EmissionGuarantee, Level, MultiSpan,
10+
Subdiagnostic, format_diag_message, msg,
1011
};
1112
use rustc_hir::ConstContext;
1213
use rustc_macros::{Diagnostic, Subdiagnostic};
@@ -359,14 +360,11 @@ pub struct FrameNote {
359360

360361
impl Subdiagnostic for FrameNote {
361362
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
362-
diag.arg("times", self.times);
363-
diag.arg("where_", self.where_);
364-
diag.arg("instance", self.instance);
365363
let mut span: MultiSpan = self.span.into();
366364
if self.has_label && !self.span.is_dummy() {
367365
span.push_span_label(self.span, msg!("the failure occurred here"));
368366
}
369-
let msg = diag.eagerly_format(msg!(
367+
let msg = msg!(
370368
r#"{$times ->
371369
[0] inside {$where_ ->
372370
[closure] closure
@@ -379,10 +377,11 @@ impl Subdiagnostic for FrameNote {
379377
*[other] {""}
380378
} ...]
381379
}"#
382-
));
383-
diag.remove_arg("times");
384-
diag.remove_arg("where_");
385-
diag.remove_arg("instance");
380+
)
381+
.arg("times", self.times)
382+
.arg("where_", self.where_)
383+
.arg("instance", self.instance)
384+
.format();
386385
diag.span_note(span, msg);
387386
}
388387
}
@@ -534,7 +533,7 @@ pub enum NonConstClosureNote {
534533
*[other] {""}
535534
}s"#
536535
)]
537-
FnPtr,
536+
FnPtr { kind: ConstContext },
538537
#[note(
539538
r#"closures need an RFC before allowed to be called in {$kind ->
540539
[const] constant
@@ -543,7 +542,7 @@ pub enum NonConstClosureNote {
543542
*[other] {""}
544543
}s"#
545544
)]
546-
Closure,
545+
Closure { kind: ConstContext },
547546
}
548547

549548
#[derive(Subdiagnostic)]
@@ -624,7 +623,7 @@ pub trait ReportErrorExt {
624623
let mut diag = dcx.struct_allow(DiagMessage::Str(String::new().into()));
625624
let message = self.diagnostic_message();
626625
self.add_args(&mut diag);
627-
let s = dcx.eagerly_format_to_string(message, diag.args.iter());
626+
let s = format_diag_message(&message, &diag.args).into_owned();
628627
diag.cancel();
629628
s
630629
})
@@ -1086,12 +1085,12 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
10861085
}
10871086

10881087
let message = if let Some(path) = self.path {
1089-
err.dcx.eagerly_format_to_string(
1090-
msg!("constructing invalid value at {$path}"),
1091-
[("path".into(), DiagArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)),
1088+
format_diag_message(
1089+
&msg!("constructing invalid value at {$path}"),
1090+
&DiagArgMap::from_iter([("path".into(), DiagArgValue::Str(path.into()))]),
10921091
)
10931092
} else {
1094-
err.dcx.eagerly_format_to_string(msg!("constructing invalid value"), [].into_iter())
1093+
Cow::Borrowed("constructing invalid value")
10951094
};
10961095

10971096
err.arg("front_matter", message);
@@ -1117,12 +1116,13 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
11171116
msg!("in the range {$lo}..={$hi}")
11181117
};
11191118

1120-
let args = [
1121-
("lo".into(), DiagArgValue::Str(lo.to_string().into())),
1122-
("hi".into(), DiagArgValue::Str(hi.to_string().into())),
1123-
];
1124-
let args = args.iter().map(|(a, b)| (a, b));
1125-
let message = err.dcx.eagerly_format_to_string(msg, args);
1119+
let message = format_diag_message(
1120+
&msg,
1121+
&DiagArgMap::from_iter([
1122+
("lo".into(), DiagArgValue::Str(lo.to_string().into())),
1123+
("hi".into(), DiagArgValue::Str(hi.to_string().into())),
1124+
]),
1125+
);
11261126
err.arg("in_range", message);
11271127
}
11281128

@@ -1132,19 +1132,18 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
11321132
}
11331133
PointerAsInt { expected } | Uninit { expected } => {
11341134
let msg = match expected {
1135-
ExpectedKind::Reference => msg!("expected a reference"),
1136-
ExpectedKind::Box => msg!("expected a box"),
1137-
ExpectedKind::RawPtr => msg!("expected a raw pointer"),
1138-
ExpectedKind::InitScalar => msg!("expected initialized scalar value"),
1139-
ExpectedKind::Bool => msg!("expected a boolean"),
1140-
ExpectedKind::Char => msg!("expected a unicode scalar value"),
1141-
ExpectedKind::Float => msg!("expected a floating point number"),
1142-
ExpectedKind::Int => msg!("expected an integer"),
1143-
ExpectedKind::FnPtr => msg!("expected a function pointer"),
1144-
ExpectedKind::EnumTag => msg!("expected a valid enum tag"),
1145-
ExpectedKind::Str => msg!("expected a string"),
1135+
ExpectedKind::Reference => "expected a reference",
1136+
ExpectedKind::Box => "expected a box",
1137+
ExpectedKind::RawPtr => "expected a raw pointer",
1138+
ExpectedKind::InitScalar => "expected initialized scalar value",
1139+
ExpectedKind::Bool => "expected a boolean",
1140+
ExpectedKind::Char => "expected a unicode scalar value",
1141+
ExpectedKind::Float => "expected a floating point number",
1142+
ExpectedKind::Int => "expected an integer",
1143+
ExpectedKind::FnPtr => "expected a function pointer",
1144+
ExpectedKind::EnumTag => "expected a valid enum tag",
1145+
ExpectedKind::Str => "expected a string",
11461146
};
1147-
let msg = err.dcx.eagerly_format_to_string(msg, [].into_iter());
11481147
err.arg("expected", msg);
11491148
}
11501149
InvalidEnumTag { value }

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use either::{Left, Right};
22
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout};
33
use rustc_data_structures::debug_assert_matches;
4-
use rustc_errors::{DiagCtxtHandle, msg};
4+
use rustc_errors::{DiagCtxtHandle, format_diag_message, msg};
55
use rustc_hir::def_id::DefId;
66
use rustc_hir::limit::Limit;
77
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
@@ -235,9 +235,9 @@ pub fn format_interp_error<'tcx>(dcx: DiagCtxtHandle<'_>, e: InterpErrorInfo<'tc
235235
let mut diag = dcx.struct_allow("");
236236
let msg = e.diagnostic_message();
237237
e.add_args(&mut diag);
238-
let s = dcx.eagerly_format_to_string(msg, diag.args.iter());
238+
let msg = format_diag_message(&msg, &diag.args).into_owned();
239239
diag.cancel();
240-
s
240+
msg
241241
}
242242

243243
impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

compiler/rustc_errors/src/diagnostic.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,6 @@ pub struct DiagInner {
236236
pub suggestions: Suggestions,
237237
pub args: DiagArgMap,
238238

239-
// This is used to store args and restore them after a subdiagnostic is rendered.
240-
pub reserved_args: DiagArgMap,
241-
242239
/// This is not used for highlighting or rendering any error message. Rather, it can be used
243240
/// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
244241
/// `span` if there is one. Otherwise, it is `DUMMY_SP`.
@@ -269,7 +266,6 @@ impl DiagInner {
269266
children: vec![],
270267
suggestions: Suggestions::Enabled(vec![]),
271268
args: Default::default(),
272-
reserved_args: Default::default(),
273269
sort_span: DUMMY_SP,
274270
is_lint: None,
275271
long_ty_path: None,
@@ -334,14 +330,6 @@ impl DiagInner {
334330
self.args.swap_remove(name);
335331
}
336332

337-
pub fn store_args(&mut self) {
338-
self.reserved_args = self.args.clone();
339-
}
340-
341-
pub fn restore_args(&mut self) {
342-
self.args = std::mem::take(&mut self.reserved_args);
343-
}
344-
345333
pub fn emitted_at_sub_diag(&self) -> Subdiag {
346334
let track = format!("-Ztrack-diagnostics: created at {}", self.emitted_at);
347335
Subdiag {
@@ -1144,16 +1132,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
11441132
self
11451133
}
11461134

1147-
/// Fluent variables are not namespaced from each other, so when
1148-
/// `Diagnostic`s and `Subdiagnostic`s use the same variable name,
1149-
/// one value will clobber the other. Eagerly formatting the
1150-
/// diagnostic uses the variables defined right then, before the
1151-
/// clobbering occurs.
1152-
pub fn eagerly_format(&self, msg: impl Into<DiagMessage>) -> DiagMessage {
1153-
let args = self.args.iter();
1154-
self.dcx.eagerly_format(msg.into(), args)
1155-
}
1156-
11571135
with_fn! { with_span,
11581136
/// Add a span.
11591137
pub fn span(&mut self, sp: impl Into<MultiSpan>) -> &mut Self {
@@ -1341,12 +1319,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
13411319
self.downgrade_to_delayed_bug();
13421320
self.emit()
13431321
}
1344-
1345-
pub fn remove_arg(&mut self, name: &str) {
1346-
if let Some(diag) = self.diag.as_mut() {
1347-
diag.remove_arg(name);
1348-
}
1349-
}
13501322
}
13511323

13521324
/// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.)

0 commit comments

Comments
 (0)