Skip to content

Commit 99bc979

Browse files
committed
macros: use typed identifiers in diag derive
Using typed identifiers instead of strings with the Fluent identifier enables the diagnostic derive to benefit from the compile-time validation that comes with typed identifiers - use of a non-existent Fluent identifier will not compile. Signed-off-by: David Wood <[email protected]>
1 parent fc96600 commit 99bc979

File tree

11 files changed

+673
-455
lines changed

11 files changed

+673
-455
lines changed

compiler/rustc_builtin_macros/src/cfg.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ pub fn expand_cfg(
3636
}
3737

3838
#[derive(SessionDiagnostic)]
39-
#[error(slug = "builtin-macros-requires-cfg-pattern")]
39+
#[error(builtin_macros::requires_cfg_pattern)]
4040
struct RequiresCfgPattern {
4141
#[primary_span]
4242
#[label]
4343
span: Span,
4444
}
4545

4646
#[derive(SessionDiagnostic)]
47-
#[error(slug = "builtin-macros-expected-one-cfg-pattern")]
47+
#[error(builtin_macros::expected_one_cfg_pattern)]
4848
struct OneCfgPattern {
4949
#[primary_span]
5050
span: Span,
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
builtin-macros-requires-cfg-pattern =
1+
builtin_macros-requires-cfg-pattern =
22
macro requires a cfg-pattern as an argument
33
.label = cfg-pattern required
44
5-
builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern
5+
builtin_macros-expected-one-cfg-pattern = expected 1 cfg-pattern

compiler/rustc_macros/src/diagnostics/diagnostic.rs

+284-176
Large diffs are not rendered by default.

compiler/rustc_macros/src/diagnostics/error.rs

+23-14
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ pub(crate) fn _throw_err(
3939
SessionDiagnosticDeriveError::ErrorHandled
4040
}
4141

42+
/// Helper function for printing `syn::Path` - doesn't handle arguments in paths and these are
43+
/// unlikely to come up much in use of the macro.
44+
fn path_to_string(path: &syn::Path) -> String {
45+
let mut out = String::new();
46+
for (i, segment) in path.segments.iter().enumerate() {
47+
if i > 0 || path.leading_colon.is_some() {
48+
out.push_str("::");
49+
}
50+
out.push_str(&segment.ident.to_string());
51+
}
52+
out
53+
}
54+
4255
/// Returns an error diagnostic on span `span` with msg `msg`.
4356
pub(crate) fn span_err(span: impl MultiSpan, msg: &str) -> Diagnostic {
4457
Diagnostic::spanned(span, Level::Error, msg)
@@ -61,15 +74,13 @@ pub(crate) use throw_span_err;
6174
/// Returns an error diagnostic for an invalid attribute.
6275
pub(crate) fn invalid_attr(attr: &Attribute, meta: &Meta) -> Diagnostic {
6376
let span = attr.span().unwrap();
64-
let name = attr.path.segments.last().unwrap().ident.to_string();
65-
let name = name.as_str();
66-
77+
let path = path_to_string(&attr.path);
6778
match meta {
68-
Meta::Path(_) => span_err(span, &format!("`#[{}]` is not a valid attribute", name)),
79+
Meta::Path(_) => span_err(span, &format!("`#[{}]` is not a valid attribute", path)),
6980
Meta::NameValue(_) => {
70-
span_err(span, &format!("`#[{} = ...]` is not a valid attribute", name))
81+
span_err(span, &format!("`#[{} = ...]` is not a valid attribute", path))
7182
}
72-
Meta::List(_) => span_err(span, &format!("`#[{}(...)]` is not a valid attribute", name)),
83+
Meta::List(_) => span_err(span, &format!("`#[{}(...)]` is not a valid attribute", path)),
7384
}
7485
}
7586

@@ -101,18 +112,16 @@ pub(crate) fn invalid_nested_attr(attr: &Attribute, nested: &NestedMeta) -> Diag
101112
};
102113

103114
let span = meta.span().unwrap();
104-
let nested_name = meta.path().segments.last().unwrap().ident.to_string();
105-
let nested_name = nested_name.as_str();
115+
let path = path_to_string(meta.path());
106116
match meta {
107-
Meta::NameValue(..) => span_err(
108-
span,
109-
&format!("`#[{}({} = ...)]` is not a valid attribute", name, nested_name),
110-
),
117+
Meta::NameValue(..) => {
118+
span_err(span, &format!("`#[{}({} = ...)]` is not a valid attribute", name, path))
119+
}
111120
Meta::Path(..) => {
112-
span_err(span, &format!("`#[{}({})]` is not a valid attribute", name, nested_name))
121+
span_err(span, &format!("`#[{}({})]` is not a valid attribute", name, path))
113122
}
114123
Meta::List(..) => {
115-
span_err(span, &format!("`#[{}({}(...))]` is not a valid attribute", name, nested_name))
124+
span_err(span, &format!("`#[{}({}(...))]` is not a valid attribute", name, path))
116125
}
117126
}
118127
}

compiler/rustc_macros/src/diagnostics/fluent.rs

+11
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,17 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
254254
];
255255

256256
#generated
257+
258+
pub mod _subdiag {
259+
pub const note: crate::SubdiagnosticMessage =
260+
crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note"));
261+
pub const help: crate::SubdiagnosticMessage =
262+
crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help"));
263+
pub const label: crate::SubdiagnosticMessage =
264+
crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label"));
265+
pub const suggestion: crate::SubdiagnosticMessage =
266+
crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion"));
267+
}
257268
}
258269
}
259270
.into()

compiler/rustc_macros/src/diagnostics/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ use synstructure::Structure;
2222
/// # extern crate rust_middle;
2323
/// # use rustc_middle::ty::Ty;
2424
/// #[derive(SessionDiagnostic)]
25-
/// #[error(code = "E0505", slug = "borrowck-move-out-of-borrow")]
25+
/// #[error(borrowck::move_out_of_borrow, code = "E0505")]
2626
/// pub struct MoveOutOfBorrowError<'tcx> {
2727
/// pub name: Ident,
2828
/// pub ty: Ty<'tcx>,
2929
/// #[primary_span]
3030
/// #[label]
3131
/// pub span: Span,
32-
/// #[label = "first-borrow-label"]
32+
/// #[label(borrowck::first_borrow_label)]
3333
/// pub first_borrow_span: Span,
3434
/// #[suggestion(code = "{name}.clone()")]
3535
/// pub clone_sugg: Option<(Span, Applicability)>

compiler/rustc_parse/src/parser/diagnostics.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ impl MultiSugg {
244244
}
245245

246246
#[derive(SessionDiagnostic)]
247-
#[error(slug = "parser-maybe-report-ambiguous-plus")]
247+
#[error(parser::maybe_report_ambiguous_plus)]
248248
struct AmbiguousPlus {
249249
pub sum_ty: String,
250250
#[primary_span]
@@ -253,7 +253,7 @@ struct AmbiguousPlus {
253253
}
254254

255255
#[derive(SessionDiagnostic)]
256-
#[error(code = "E0178", slug = "parser-maybe-recover-from-bad-type-plus")]
256+
#[error(parser::maybe_recover_from_bad_type_plus, code = "E0178")]
257257
struct BadTypePlus {
258258
pub ty: String,
259259
#[primary_span]
@@ -287,7 +287,7 @@ pub enum BadTypePlusSub {
287287
}
288288

289289
#[derive(SessionDiagnostic)]
290-
#[error(slug = "parser-maybe-recover-from-bad-qpath-stage-2")]
290+
#[error(parser::maybe_recover_from_bad_qpath_stage_2)]
291291
struct BadQPathStage2 {
292292
#[primary_span]
293293
#[suggestion(applicability = "maybe-incorrect")]
@@ -296,7 +296,7 @@ struct BadQPathStage2 {
296296
}
297297

298298
#[derive(SessionDiagnostic)]
299-
#[error(slug = "parser-incorrect-semicolon")]
299+
#[error(parser::incorrect_semicolon)]
300300
struct IncorrectSemicolon<'a> {
301301
#[primary_span]
302302
#[suggestion_short(applicability = "machine-applicable")]
@@ -307,26 +307,26 @@ struct IncorrectSemicolon<'a> {
307307
}
308308

309309
#[derive(SessionDiagnostic)]
310-
#[error(slug = "parser-incorrect-use-of-await")]
310+
#[error(parser::incorrect_use_of_await)]
311311
struct IncorrectUseOfAwait {
312312
#[primary_span]
313-
#[suggestion(message = "parentheses-suggestion", applicability = "machine-applicable")]
313+
#[suggestion(parser::parentheses_suggestion, applicability = "machine-applicable")]
314314
span: Span,
315315
}
316316

317317
#[derive(SessionDiagnostic)]
318-
#[error(slug = "parser-incorrect-use-of-await")]
318+
#[error(parser::incorrect_use_of_await)]
319319
struct IncorrectAwait {
320320
#[primary_span]
321321
span: Span,
322-
#[suggestion(message = "postfix-suggestion", code = "{expr}.await{question_mark}")]
322+
#[suggestion(parser::postfix_suggestion, code = "{expr}.await{question_mark}")]
323323
sugg_span: (Span, Applicability),
324324
expr: String,
325325
question_mark: &'static str,
326326
}
327327

328328
#[derive(SessionDiagnostic)]
329-
#[error(slug = "parser-in-in-typo")]
329+
#[error(parser::in_in_typo)]
330330
struct InInTypo {
331331
#[primary_span]
332332
span: Span,

0 commit comments

Comments
 (0)