From a960f8304cee9af374aae7bade15554734f37480 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Fri, 19 Aug 2022 15:02:10 +0200 Subject: [PATCH] Make derived SessionDiagnostics generic on diagnostic level Deriving SessionDiagnostic on a type no longer forces that diagnostic to be one of warning, error, or fatal. The level is instead decided when the struct is passed to the respective Handler::emit_*() method. --- .../src/diagnostics/diagnostic.rs | 82 +++--------- .../src/diagnostics/diagnostic_builder.rs | 81 ++++++------ compiler/rustc_macros/src/lib.rs | 2 + .../session-diagnostic/diagnostic-derive.rs | 6 +- .../diagnostic-derive.stderr | 122 +++++++----------- 5 files changed, 108 insertions(+), 185 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 6b5b8b59320..244edec2841 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -21,7 +21,7 @@ impl<'a> SessionDiagnosticDerive<'a> { builder: DiagnosticDeriveBuilder { diag, fields: build_field_mapping(&structure), - kind: None, + kind: DiagnosticDeriveKind::SessionDiagnostic, code: None, slug: None, }, @@ -34,49 +34,31 @@ impl<'a> SessionDiagnosticDerive<'a> { let SessionDiagnosticDerive { mut structure, sess, mut builder } = self; let ast = structure.ast(); - let (implementation, param_ty) = { + let implementation = { if let syn::Data::Struct(..) = ast.data { let preamble = builder.preamble(&structure); let (attrs, args) = builder.body(&mut structure); let span = ast.span().unwrap(); let diag = &builder.diag; - let init = match (builder.kind.value(), builder.slug.value()) { - (None, _) => { - span_err(span, "diagnostic kind not specified") - .help("use the `#[error(...)]` attribute to create an error") - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - (Some(kind), None) => { + let init = match builder.slug.value() { + None => { span_err(span, "diagnostic slug not specified") .help(&format!( - "specify the slug as the first argument to the attribute, such as \ - `#[{}(typeck::example_error)]`", - kind.descr() + "specify the slug as the first argument to the `#[diag(...)]` attribute, \ + such as `#[diag(typeck::example_error)]`", )) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } - (Some(DiagnosticDeriveKind::Lint), _) => { - span_err(span, "only `#[error(..)]` and `#[warning(..)]` are supported") - .help("use the `#[error(...)]` attribute to create a error") - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - (Some(DiagnosticDeriveKind::Error), Some(slug)) => { + Some(slug) => { quote! { - let mut #diag = #sess.struct_err(rustc_errors::fluent::#slug); - } - } - (Some(DiagnosticDeriveKind::Warn), Some(slug)) => { - quote! { - let mut #diag = #sess.struct_warn(rustc_errors::fluent::#slug); + let mut #diag = #sess.struct_diagnostic(rustc_errors::fluent::#slug); } } }; - let implementation = quote! { + quote! { #init #preamble match self { @@ -86,18 +68,7 @@ impl<'a> SessionDiagnosticDerive<'a> { #args } #diag - }; - let param_ty = match builder.kind { - Some((DiagnosticDeriveKind::Error, _)) => { - quote! { rustc_errors::ErrorGuaranteed } - } - Some((DiagnosticDeriveKind::Lint | DiagnosticDeriveKind::Warn, _)) => { - quote! { () } - } - _ => unreachable!(), - }; - - (implementation, param_ty) + } } else { span_err( ast.span().unwrap(), @@ -105,20 +76,20 @@ impl<'a> SessionDiagnosticDerive<'a> { ) .emit(); - let implementation = DiagnosticDeriveError::ErrorHandled.to_compile_error(); - let param_ty = quote! { rustc_errors::ErrorGuaranteed }; - (implementation, param_ty) + DiagnosticDeriveError::ErrorHandled.to_compile_error() } }; structure.gen_impl(quote! { - gen impl<'__session_diagnostic_sess> rustc_session::SessionDiagnostic<'__session_diagnostic_sess, #param_ty> + gen impl<'__session_diagnostic_sess, G> + rustc_session::SessionDiagnostic<'__session_diagnostic_sess, G> for @Self + where G: rustc_errors::EmissionGuarantee { fn into_diagnostic( self, #sess: &'__session_diagnostic_sess rustc_session::parse::ParseSess - ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, #param_ty> { + ) -> rustc_errors::DiagnosticBuilder<'__session_diagnostic_sess, G> { use rustc_errors::IntoDiagnosticArg; #implementation } @@ -139,7 +110,7 @@ impl<'a> LintDiagnosticDerive<'a> { builder: DiagnosticDeriveBuilder { diag, fields: build_field_mapping(&structure), - kind: None, + kind: DiagnosticDeriveKind::LintDiagnostic, code: None, slug: None, }, @@ -158,30 +129,17 @@ impl<'a> LintDiagnosticDerive<'a> { let diag = &builder.diag; let span = ast.span().unwrap(); - let init = match (builder.kind.value(), builder.slug.value()) { - (None, _) => { - span_err(span, "diagnostic kind not specified") - .help("use the `#[error(...)]` attribute to create an error") - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - (Some(kind), None) => { + let init = match builder.slug.value() { + None => { span_err(span, "diagnostic slug not specified") .help(&format!( "specify the slug as the first argument to the attribute, such as \ - `#[{}(typeck::example_error)]`", - kind.descr() + `#[diag(typeck::example_error)]`", )) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } - (Some(DiagnosticDeriveKind::Error | DiagnosticDeriveKind::Warn), _) => { - span_err(span, "only `#[lint(..)]` is supported") - .help("use the `#[lint(...)]` attribute to create a lint") - .emit(); - return DiagnosticDeriveError::ErrorHandled.to_compile_error(); - } - (Some(DiagnosticDeriveKind::Lint), Some(slug)) => { + Some(slug) => { quote! { let mut #diag = #diag.build(rustc_errors::fluent::#slug); } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 6c9561925fe..6a5997512bd 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -18,30 +18,15 @@ use syn::{ }; use synstructure::{BindingInfo, Structure}; -/// What kind of diagnostic is being derived - an error, a warning or a lint? -#[derive(Copy, Clone)] +/// What kind of diagnostic is being derived - a fatal/error/warning or a lint? +#[derive(Copy, Clone, PartialEq, Eq)] pub(crate) enum DiagnosticDeriveKind { - /// `#[error(..)]` - Error, - /// `#[warn(..)]` - Warn, - /// `#[lint(..)]` - Lint, -} - -impl DiagnosticDeriveKind { - /// Returns human-readable string corresponding to the kind. - pub fn descr(&self) -> &'static str { - match self { - DiagnosticDeriveKind::Error => "error", - DiagnosticDeriveKind::Warn => "warning", - DiagnosticDeriveKind::Lint => "lint", - } - } + SessionDiagnostic, + LintDiagnostic, } /// Tracks persistent information required for building up individual calls to diagnostic methods -/// for generated diagnostic derives - both `SessionDiagnostic` for errors/warnings and +/// for generated diagnostic derives - both `SessionDiagnostic` for fatal/errors/warnings and /// `LintDiagnostic` for lints. pub(crate) struct DiagnosticDeriveBuilder { /// The identifier to use for the generated `DiagnosticBuilder` instance. @@ -51,8 +36,8 @@ pub(crate) struct DiagnosticDeriveBuilder { /// derive builder. pub fields: HashMap, - /// Kind of diagnostic requested via the struct attribute. - pub kind: Option<(DiagnosticDeriveKind, proc_macro::Span)>, + /// Kind of diagnostic that should be derived. + pub kind: DiagnosticDeriveKind, /// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that /// has the actual diagnostic message. pub slug: Option<(Path, proc_macro::Span)>, @@ -143,7 +128,7 @@ impl DiagnosticDeriveBuilder { } /// Establishes state in the `DiagnosticDeriveBuilder` resulting from the struct - /// attributes like `#[error(..)`, such as the diagnostic kind and slug. Generates + /// attributes like `#[diag(..)]`, such as the slug and error code. Generates /// diagnostic builder calls for setting error code and creating note/help messages. fn generate_structure_code_for_attr( &mut self, @@ -156,15 +141,15 @@ impl DiagnosticDeriveBuilder { let name = name.as_str(); let meta = attr.parse_meta()?; - let is_help_note_or_warn = matches!(name, "help" | "note" | "warn_"); + let is_diag = matches!(name, "error" | "warning" | "lint" | "diag"); let nested = match meta { - // Most attributes are lists, like `#[error(..)]`/`#[warning(..)]` for most cases or + // Most attributes are lists, like `#[diag(..)]` for most cases or // `#[help(..)]`/`#[note(..)]` when the user is specifying a alternative slug. Meta::List(MetaList { ref nested, .. }) => nested, // Subdiagnostics without spans can be applied to the type too, and these are just - // paths: `#[help]` and `#[note]` - Meta::Path(_) if is_help_note_or_warn => { + // paths: `#[help]`, `#[note]` and `#[warn_]` + Meta::Path(_) if !is_diag => { let fn_name = if name == "warn_" { Ident::new("warn", attr.span()) } else { @@ -178,23 +163,32 @@ impl DiagnosticDeriveBuilder { // Check the kind before doing any further processing so that there aren't misleading // "no kind specified" errors if there are failures later. match name { - "error" => self.kind.set_once((DiagnosticDeriveKind::Error, span)), - "warning" => self.kind.set_once((DiagnosticDeriveKind::Warn, span)), - "lint" => self.kind.set_once((DiagnosticDeriveKind::Lint, span)), - "help" | "note" | "warn_" => (), + "error" | "warning" => { + if self.kind == DiagnosticDeriveKind::LintDiagnostic { + span_err(span, "only `#[lint(..)]` is supported") + .help("use the `#[lint(...)]` attribute to create a lint") + .emit(); + } + } + "lint" => { + if self.kind == DiagnosticDeriveKind::SessionDiagnostic { + span_err(span, "only `#[error(..)]` and `#[warning(..)]` are supported") + .help("use the `#[error(...)]` attribute to create a error") + .emit(); + } + } + "diag" | "help" | "note" | "warn_" => (), _ => throw_invalid_attr!(attr, &meta, |diag| { - diag.help( - "only `error`, `warning`, `help`, `note` and `warn_` are valid attributes", - ) + diag.help("only `diag`, `help`, `note` and `warn_` are valid attributes") }), } - // First nested element should always be the path, e.g. `#[error(typeck::invalid)]` or + // First nested element should always be the path, e.g. `#[diag(typeck::invalid)]` or // `#[help(typeck::another_help)]`. let mut nested_iter = nested.into_iter(); if let Some(nested_attr) = nested_iter.next() { // Report an error if there are any other list items after the path. - if is_help_note_or_warn && nested_iter.next().is_some() { + if !is_diag && nested_iter.next().is_some() { throw_invalid_nested_attr!(attr, &nested_attr, |diag| { diag.help( "`help`, `note` and `warn_` struct attributes can only have one argument", @@ -203,16 +197,16 @@ impl DiagnosticDeriveBuilder { } match nested_attr { - NestedMeta::Meta(Meta::Path(path)) if is_help_note_or_warn => { - let fn_name = proc_macro2::Ident::new(name, attr.span()); - return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); }); - } NestedMeta::Meta(Meta::Path(path)) => { - self.slug.set_once((path.clone(), span)); + if is_diag { + self.slug.set_once((path.clone(), span)); + } else { + let fn_name = proc_macro2::Ident::new(name, attr.span()); + return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); }); + } } NestedMeta::Meta(meta @ Meta::NameValue(_)) - if !is_help_note_or_warn - && meta.path().segments.last().unwrap().ident == "code" => + if is_diag && meta.path().segments.last().unwrap().ident == "code" => { // don't error for valid follow-up attributes } @@ -347,6 +341,7 @@ impl DiagnosticDeriveBuilder { } "primary_span" => { report_error_if_not_applied_to_span(attr, &info)?; + Ok(quote! { #diag.set_span(#binding); }) diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index e01d035767b..fe4ff2fb6aa 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -132,6 +132,7 @@ decl_derive!( warning, error, lint, + diag, help, note, warn_, @@ -151,6 +152,7 @@ decl_derive!( warning, error, lint, + diag, help, note, warn_, diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 0a210cbdc94..8634fbc7aca 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -52,7 +52,7 @@ struct WrongStructAttrStyle {} #[derive(SessionDiagnostic)] #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] //~^ ERROR `#[nonsense(...)]` is not a valid attribute -//~^^ ERROR diagnostic kind not specified +//~^^ ERROR diagnostic slug not specified //~^^^ ERROR cannot find attribute `nonsense` in this scope struct InvalidStructAttr {} @@ -103,7 +103,6 @@ struct WrongPlaceField { #[error(typeck::ambiguous_lifetime_bound, code = "E0456")] //~^ ERROR specified multiple times //~^^ ERROR specified multiple times -//~^^^ ERROR specified multiple times struct ErrorSpecifiedTwice {} #[derive(SessionDiagnostic)] @@ -111,7 +110,6 @@ struct ErrorSpecifiedTwice {} #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] //~^ ERROR specified multiple times //~^^ ERROR specified multiple times -//~^^^ ERROR specified multiple times struct WarnSpecifiedAfterError {} #[derive(SessionDiagnostic)] @@ -125,7 +123,7 @@ struct CodeSpecifiedTwice {} struct SlugSpecifiedTwice {} #[derive(SessionDiagnostic)] -struct KindNotProvided {} //~ ERROR diagnostic kind not specified +struct KindNotProvided {} //~ ERROR diagnostic slug not specified #[derive(SessionDiagnostic)] #[error(code = "E0456")] diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index a1a054c67d4..8c826c9a284 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -21,9 +21,9 @@ error: `#[nonsense(...)]` is not a valid attribute LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: only `error`, `warning`, `help`, `note` and `warn_` are valid attributes + = help: only `diag`, `help`, `note` and `warn_` are valid attributes -error: diagnostic kind not specified +error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:53:1 | LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] @@ -33,7 +33,7 @@ LL | | LL | | struct InvalidStructAttr {} | |___________________________^ | - = help: use the `#[error(...)]` attribute to create an error + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` error: `#[error("...")]` is not a valid attribute --> $DIR/diagnostic-derive.rs:60:9 @@ -52,7 +52,7 @@ LL | | LL | | struct InvalidLitNestedAttr {} | |______________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` error: `#[error(nonsense(...))]` is not a valid attribute --> $DIR/diagnostic-derive.rs:71:9 @@ -71,7 +71,7 @@ LL | | LL | | struct InvalidNestedStructAttr1 {} | |__________________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` error: `#[error(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:77:9 @@ -90,7 +90,7 @@ LL | | LL | | struct InvalidNestedStructAttr2 {} | |__________________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` error: `#[error(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:83:9 @@ -109,7 +109,7 @@ LL | | LL | | struct InvalidNestedStructAttr3 {} | |__________________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` error: `#[error(slug = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:89:59 @@ -137,18 +137,6 @@ note: previously specified here LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: specified multiple times - --> $DIR/diagnostic-derive.rs:103:1 - | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:102:1 - | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: specified multiple times --> $DIR/diagnostic-derive.rs:103:50 | @@ -162,85 +150,73 @@ LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:111:1 + --> $DIR/diagnostic-derive.rs:110:1 | LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:110:1 + --> $DIR/diagnostic-derive.rs:109:1 | LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:111:1 - | -LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:110:1 - | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: specified multiple times - --> $DIR/diagnostic-derive.rs:111:52 + --> $DIR/diagnostic-derive.rs:110:52 | LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:110:50 + --> $DIR/diagnostic-derive.rs:109:50 | LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:118:66 + --> $DIR/diagnostic-derive.rs:116:66 | LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:118:50 + --> $DIR/diagnostic-derive.rs:116:50 | LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] | ^^^^^^^ error: `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:123:43 + --> $DIR/diagnostic-derive.rs:121:43 | LL | #[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: diagnostic kind not specified - --> $DIR/diagnostic-derive.rs:128:1 +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:126:1 | LL | struct KindNotProvided {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: use the `#[error(...)]` attribute to create an error + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:131:1 + --> $DIR/diagnostic-derive.rs:129:1 | LL | / #[error(code = "E0456")] LL | | LL | | struct SlugNotProvided {} | |_________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:142:5 + --> $DIR/diagnostic-derive.rs:140:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:150:5 + --> $DIR/diagnostic-derive.rs:148:5 | LL | #[nonsense] | ^^^^^^^^^^^ @@ -248,19 +224,19 @@ LL | #[nonsense] = help: only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:167:5 + --> $DIR/diagnostic-derive.rs:165:5 | LL | #[label(typeck::label)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:175:45 + --> $DIR/diagnostic-derive.rs:173:45 | LL | #[suggestion(typeck::suggestion, code = "{name}")] | ^^^^^^^^ error: invalid format string: expected `'}'` but string was terminated - --> $DIR/diagnostic-derive.rs:180:16 + --> $DIR/diagnostic-derive.rs:178:16 | LL | #[derive(SessionDiagnostic)] | - ^ expected `'}'` in format string @@ -271,7 +247,7 @@ LL | #[derive(SessionDiagnostic)] = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive.rs:190:15 + --> $DIR/diagnostic-derive.rs:188:15 | LL | #[derive(SessionDiagnostic)] | ^ unmatched `}` in format string @@ -280,13 +256,13 @@ LL | #[derive(SessionDiagnostic)] = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:210:5 + --> $DIR/diagnostic-derive.rs:208:5 | LL | #[label(typeck::label)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:235:18 + --> $DIR/diagnostic-derive.rs:233:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^ @@ -294,7 +270,7 @@ LL | #[suggestion(nonsense = "bar")] = help: only `message`, `code` and `applicability` are valid field attributes error: `#[suggestion(msg = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:243:18 + --> $DIR/diagnostic-derive.rs:241:18 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^ @@ -302,7 +278,7 @@ LL | #[suggestion(msg = "bar")] = help: only `message`, `code` and `applicability` are valid field attributes error: wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:265:5 + --> $DIR/diagnostic-derive.rs:263:5 | LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] LL | | @@ -312,7 +288,7 @@ LL | | suggestion: Applicability, = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: type of field annotated with `#[suggestion(...)]` contains more than one `Span` - --> $DIR/diagnostic-derive.rs:280:5 + --> $DIR/diagnostic-derive.rs:278:5 | LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] LL | | @@ -320,7 +296,7 @@ LL | | suggestion: (Span, Span, Applicability), | |___________________________________________^ error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability - --> $DIR/diagnostic-derive.rs:288:5 + --> $DIR/diagnostic-derive.rs:286:5 | LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] LL | | @@ -328,60 +304,54 @@ LL | | suggestion: (Applicability, Applicability, Span), | |____________________________________________________^ error: `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:296:5 + --> $DIR/diagnostic-derive.rs:294:5 | LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ error: applicability cannot be set in both the field and attribute - --> $DIR/diagnostic-derive.rs:447:52 + --> $DIR/diagnostic-derive.rs:445:52 | LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/diagnostic-derive.rs:455:52 + --> $DIR/diagnostic-derive.rs:453:52 | LL | #[suggestion(typeck::suggestion, code = "...", applicability = "batman")] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:518:5 + --> $DIR/diagnostic-derive.rs:516:5 | LL | #[label(typeck::label, foo)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:526:5 + --> $DIR/diagnostic-derive.rs:524:5 | LL | #[label(typeck::label, foo = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:534:5 + --> $DIR/diagnostic-derive.rs:532:5 | LL | #[label(typeck::label, foo("..."))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: only `#[error(..)]` and `#[warning(..)]` are supported - --> $DIR/diagnostic-derive.rs:540:1 + --> $DIR/diagnostic-derive.rs:538:1 | -LL | / #[lint(typeck::ambiguous_lifetime_bound)] -LL | | -LL | | struct LintsBad { -LL | | } - | |_^ +LL | #[lint(typeck::ambiguous_lifetime_bound)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use the `#[error(...)]` attribute to create a error error: only `#[lint(..)]` is supported - --> $DIR/diagnostic-derive.rs:551:1 + --> $DIR/diagnostic-derive.rs:549:1 | -LL | / #[error(typeck::ambiguous_lifetime_bound)] -LL | | -LL | | struct ErrorsBad { -LL | | } - | |_^ +LL | #[error(typeck::ambiguous_lifetime_bound)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use the `#[lint(...)]` attribute to create a lint @@ -392,7 +362,7 @@ LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:150:7 + --> $DIR/diagnostic-derive.rs:148:7 | LL | #[nonsense] | ^^^^^^^^ @@ -404,7 +374,7 @@ LL | #[error(nonsense, code = "E0123")] | ^^^^^^^^ not found in `rustc_errors::fluent` error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied - --> $DIR/diagnostic-derive.rs:340:10 + --> $DIR/diagnostic-derive.rs:338:10 | LL | #[derive(SessionDiagnostic)] | ^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello` @@ -417,7 +387,7 @@ LL | arg: impl IntoDiagnosticArg, | ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg` = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 48 previous errors +error: aborting due to 46 previous errors Some errors have detailed explanations: E0277, E0425. For more information about an error, try `rustc --explain E0277`.