Skip to content

Commit 72dec56

Browse files
committed
macros: optional error codes
In an effort to make it easier to port diagnostics to `SessionDiagnostic` (for translation) and since translation slugs could replace error codes, make error codes optional in the `SessionDiagnostic` derive. Signed-off-by: David Wood <david.wood@huawei.com>
1 parent 70ee0c9 commit 72dec56

File tree

3 files changed

+21
-34
lines changed

3 files changed

+21
-34
lines changed

compiler/rustc_macros/src/session_diagnostic.rs

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -229,38 +229,30 @@ impl<'a> SessionDiagnosticDerive<'a> {
229229

230230
let span = ast.span().unwrap();
231231
let (diag, sess) = (&builder.diag, &builder.sess);
232-
let init = match (builder.kind, builder.slug, builder.code) {
233-
(None, _, _) => {
232+
let init = match (builder.kind, builder.slug) {
233+
(None, _) => {
234234
span_err(span, "diagnostic kind not specified")
235235
.help("use the `#[error(...)]` attribute to create an error")
236236
.emit();
237237
return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error();
238238
}
239-
(Some((kind, _)), None, _) => {
239+
(Some((kind, _)), None) => {
240240
span_err(span, "`slug` not specified")
241241
.help(&format!("use the `#[{}(slug = \"...\")]` attribute to set this diagnostic's slug", kind.descr()))
242242
.emit();
243243
return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error();
244244
}
245-
(Some((kind, _)), _, None) => {
246-
span_err(span, "`code` not specified")
247-
.help(&format!("use the `#[{}(code = \"...\")]` attribute to set this diagnostic's error code", kind.descr()))
248-
.emit();
249-
return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error();
250-
}
251-
(Some((SessionDiagnosticKind::Error, _)), Some((slug, _)), Some((code, _))) => {
245+
(Some((SessionDiagnosticKind::Error, _)), Some((slug, _))) => {
252246
quote! {
253-
let mut #diag = #sess.struct_err_with_code(
247+
let mut #diag = #sess.struct_err(
254248
rustc_errors::DiagnosticMessage::fluent(#slug),
255-
rustc_errors::DiagnosticId::Error(#code.to_string())
256249
);
257250
}
258251
}
259-
(Some((SessionDiagnosticKind::Warn, _)), Some((slug, _)), Some((code, _))) => {
252+
(Some((SessionDiagnosticKind::Warn, _)), Some((slug, _))) => {
260253
quote! {
261-
let mut #diag = #sess.struct_warn_with_code(
254+
let mut #diag = #sess.struct_warn(
262255
rustc_errors::DiagnosticMessage::fluent(#slug),
263-
rustc_errors::DiagnosticId::Error(#code.to_string())
264256
);
265257
}
266258
}
@@ -363,9 +355,9 @@ struct SessionDiagnosticDeriveBuilder<'a> {
363355
/// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that
364356
/// has the actual diagnostic message.
365357
slug: Option<(String, proc_macro::Span)>,
366-
/// Error codes are a mandatory part of the struct attribute. Slugs may replace error codes
367-
/// in future but it is desirable to mandate error codes until such a time.
368-
code: Option<(String, proc_macro::Span)>,
358+
/// Error codes are a optional part of the struct attribute - this is only set to detect
359+
/// multiple specifications.
360+
code: Option<proc_macro::Span>,
369361
}
370362

371363
impl<'a> SessionDiagnosticDeriveBuilder<'a> {
@@ -403,6 +395,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
403395
};
404396
self.set_kind_once(kind, span)?;
405397

398+
let mut tokens = Vec::new();
406399
for attr in nested {
407400
let span = attr.span().unwrap();
408401
let meta = match attr {
@@ -427,7 +420,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
427420
self.set_slug_once(s.value(), s.span().unwrap());
428421
}
429422
"code" => {
430-
self.set_code_once(s.value(), s.span().unwrap());
423+
tokens.push(self.set_code_once(s.value(), s.span().unwrap()));
431424
}
432425
other => {
433426
let diag = span_err(
@@ -475,7 +468,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
475468
}
476469
}
477470

478-
Ok(quote! {})
471+
Ok(tokens.drain(..).collect())
479472
}
480473

481474
#[must_use]
@@ -504,17 +497,20 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
504497
}
505498
}
506499

507-
fn set_code_once(&mut self, code: String, span: proc_macro::Span) {
500+
fn set_code_once(&mut self, code: String, span: proc_macro::Span) -> proc_macro2::TokenStream {
508501
match self.code {
509502
None => {
510-
self.code = Some((code, span));
503+
self.code = Some(span);
511504
}
512-
Some((_, prev_span)) => {
505+
Some(prev_span) => {
513506
span_err(span, "`code` specified multiple times")
514507
.span_note(prev_span, "previously specified here")
515508
.emit();
516509
}
517510
}
511+
512+
let diag = &self.diag;
513+
quote! { #diag.code(rustc_errors::DiagnosticId::Error(#code.to_string())); }
518514
}
519515

520516
fn set_slug_once(&mut self, slug: String, span: proc_macro::Span) {

src/test/ui-fulldeps/session-derive-errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ struct KindNotProvided {} //~ ERROR diagnostic kind not specified
115115
struct SlugNotProvided {}
116116

117117
#[derive(SessionDiagnostic)]
118-
#[error(slug = "foo")] //~ ERROR `code` not specified
118+
#[error(slug = "foo")]
119119
struct CodeNotProvided {}
120120

121121
#[derive(SessionDiagnostic)]

src/test/ui-fulldeps/session-derive-errors.stderr

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,6 @@ LL | | struct SlugNotProvided {}
147147
|
148148
= help: use the `#[error(slug = "...")]` attribute to set this diagnostic's slug
149149

150-
error: `code` not specified
151-
--> $DIR/session-derive-errors.rs:118:1
152-
|
153-
LL | / #[error(slug = "foo")]
154-
LL | | struct CodeNotProvided {}
155-
| |_________________________^
156-
|
157-
= help: use the `#[error(code = "...")]` attribute to set this diagnostic's error code
158-
159150
error: the `#[primary_span]` attribute can only be applied to fields of type `Span`
160151
--> $DIR/session-derive-errors.rs:124:5
161152
|
@@ -285,6 +276,6 @@ LL | #[derive(SessionDiagnostic)]
285276
|
286277
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
287278

288-
error: aborting due to 35 previous errors
279+
error: aborting due to 34 previous errors
289280

290281
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)