From 36a396ce51391ff6b0c41898a4c21fc6d303c4a4 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 27 Apr 2022 04:06:13 +0100 Subject: [PATCH] macros: add helper functions for invalid attrs Remove some duplicated code between both diagnostic derives by introducing helper functions for reporting an error in case of a invalid attribute. Signed-off-by: David Wood --- .../src/diagnostics/diagnostic.rs | 170 ++++-------------- .../rustc_macros/src/diagnostics/error.rs | 110 ++++++++++-- .../src/diagnostics/subdiagnostic.rs | 100 +++-------- .../session-diagnostic/diagnostic-derive.rs | 24 +-- .../diagnostic-derive.stderr | 40 +++-- .../subdiagnostic-derive.rs | 30 ++-- .../subdiagnostic-derive.stderr | 44 ++--- 7 files changed, 226 insertions(+), 292 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index cdaee3ed2d7..2336186dc71 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -1,6 +1,9 @@ #![deny(unused_must_use)] -use crate::diagnostics::error::{span_err, throw_span_err, SessionDiagnosticDeriveError}; +use crate::diagnostics::error::{ + invalid_nested_attr, span_err, throw_invalid_attr, throw_invalid_nested_attr, throw_span_err, + SessionDiagnosticDeriveError, +}; use crate::diagnostics::utils::{ option_inner_ty, report_error_if_not_applied_to_span, type_matches_path, FieldInfo, HasFieldMap, }; @@ -292,39 +295,24 @@ impl SessionDiagnosticDeriveBuilder { } let nested = match meta { - Meta::List(MetaList { nested, .. }) => nested, - Meta::Path(..) => throw_span_err!( - span, - &format!("`#[{}]` is not a valid `SessionDiagnostic` struct attribute", name) - ), - Meta::NameValue(..) => throw_span_err!( - span, - &format!("`#[{} = ...]` is not a valid `SessionDiagnostic` struct attribute", name) - ), + Meta::List(MetaList { ref nested, .. }) => nested, + _ => throw_invalid_attr!(attr, &meta), }; let kind = match name { "error" => SessionDiagnosticKind::Error, "warning" => SessionDiagnosticKind::Warn, - other => throw_span_err!( - span, - &format!("`#[{}(...)]` is not a valid `SessionDiagnostic` struct attribute", other) - ), + _ => throw_invalid_attr!(attr, &meta, |diag| { + diag.help("only `error` and `warning` are valid attributes") + }), }; self.set_kind_once(kind, span)?; let mut tokens = Vec::new(); - for attr in nested { - let span = attr.span().unwrap(); - let meta = match attr { + for nested_attr in nested { + let meta = match nested_attr { syn::NestedMeta::Meta(meta) => meta, - syn::NestedMeta::Lit(_) => throw_span_err!( - span, - &format!( - "`#[{}(\"...\")]` is not a valid `SessionDiagnostic` struct attribute", - name - ) - ), + _ => throw_invalid_nested_attr!(attr, &nested_attr), }; let path = meta.path(); @@ -340,49 +328,12 @@ impl SessionDiagnosticDeriveBuilder { "code" => { tokens.push(self.set_code_once(s.value(), s.span().unwrap())); } - other => { - let diag = span_err( - span, - &format!( - "`#[{}({} = ...)]` is not a valid `SessionDiagnostic` struct attribute", - name, other - ), - ); - diag.emit(); - } + _ => invalid_nested_attr(attr, &nested_attr) + .help("only `slug` and `code` are valid nested attributes") + .emit(), } } - Meta::NameValue(..) => { - span_err( - span, - &format!( - "`#[{}({} = ...)]` is not a valid `SessionDiagnostic` struct attribute", - name, nested_name - ), - ) - .help("value must be a string") - .emit(); - } - Meta::Path(..) => { - span_err( - span, - &format!( - "`#[{}({})]` is not a valid `SessionDiagnostic` struct attribute", - name, nested_name - ), - ) - .emit(); - } - Meta::List(..) => { - span_err( - span, - &format!( - "`#[{}({}(...))]` is not a valid `SessionDiagnostic` struct attribute", - name, nested_name - ), - ) - .emit(); - } + _ => invalid_nested_attr(attr, &nested_attr).emit(), } } @@ -478,7 +429,6 @@ impl SessionDiagnosticDeriveBuilder { info: FieldInfo<'_>, ) -> Result { let diag = &self.diag; - let span = attr.span().unwrap(); let field_binding = &info.binding.binding; let name = attr.path.segments.last().unwrap().ident.to_string(); @@ -502,43 +452,31 @@ impl SessionDiagnosticDeriveBuilder { report_error_if_not_applied_to_span(attr, &info)?; Ok(self.add_subdiagnostic(field_binding, name, name)) } - other => throw_span_err!( - span, - &format!("`#[{}]` is not a valid `SessionDiagnostic` field attribute", other) - ), + _ => throw_invalid_attr!(attr, &meta, |diag| { + diag + .help("only `skip_arg`, `primary_span`, `label`, `note` and `help` are valid field attributes") + }), }, - Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => match name { + Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(ref s), .. }) => match name { "label" | "note" | "help" => { report_error_if_not_applied_to_span(attr, &info)?; Ok(self.add_subdiagnostic(field_binding, name, &s.value())) } - other => throw_span_err!( - span, - &format!( - "`#[{} = ...]` is not a valid `SessionDiagnostic` field attribute", - other - ) - ), + _ => throw_invalid_attr!(attr, &meta, |diag| { + diag.help("only `label`, `note` and `help` are valid field attributes") + }), }, - Meta::NameValue(_) => throw_span_err!( - span, - &format!("`#[{} = ...]` is not a valid `SessionDiagnostic` field attribute", name), - |diag| diag.help("value must be a string") - ), - Meta::List(MetaList { path, nested, .. }) => { + Meta::List(MetaList { ref path, ref nested, .. }) => { let name = path.segments.last().unwrap().ident.to_string(); let name = name.as_ref(); match name { "suggestion" | "suggestion_short" | "suggestion_hidden" | "suggestion_verbose" => (), - other => throw_span_err!( - span, - &format!( - "`#[{}(...)]` is not a valid `SessionDiagnostic` field attribute", - other - ) - ), + _ => throw_invalid_attr!(attr, &meta, |diag| { + diag + .help("only `suggestion{,_short,_hidden,_verbose}` are valid field attributes") + }), }; let (span_, applicability) = self.span_and_applicability_of_ty(info)?; @@ -546,22 +484,14 @@ impl SessionDiagnosticDeriveBuilder { let mut msg = None; let mut code = None; - for attr in nested { - let meta = match attr { - syn::NestedMeta::Meta(meta) => meta, - syn::NestedMeta::Lit(_) => throw_span_err!( - span, - &format!( - "`#[{}(\"...\")]` is not a valid `SessionDiagnostic` field attribute", - name - ) - ), + for nested_attr in nested { + let meta = match nested_attr { + syn::NestedMeta::Meta(ref meta) => meta, + syn::NestedMeta::Lit(_) => throw_invalid_nested_attr!(attr, &nested_attr), }; - let span = meta.span().unwrap(); let nested_name = meta.path().segments.last().unwrap().ident.to_string(); let nested_name = nested_name.as_str(); - match meta { Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => { match nested_name { @@ -572,37 +502,14 @@ impl SessionDiagnosticDeriveBuilder { let formatted_str = self.build_format(&s.value(), s.span()); code = Some(formatted_str); } - other => throw_span_err!( - span, - &format!( - "`#[{}({} = ...)]` is not a valid `SessionDiagnostic` field attribute", - name, other + _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { + diag.help( + "only `message` and `code` are valid field attributes", ) - ), + }), } } - Meta::NameValue(..) => throw_span_err!( - span, - &format!( - "`#[{}({} = ...)]` is not a valid `SessionDiagnostic` struct attribute", - name, nested_name - ), - |diag| diag.help("value must be a string") - ), - Meta::Path(..) => throw_span_err!( - span, - &format!( - "`#[{}({})]` is not a valid `SessionDiagnostic` struct attribute", - name, nested_name - ) - ), - Meta::List(..) => throw_span_err!( - span, - &format!( - "`#[{}({}(...))]` is not a valid `SessionDiagnostic` struct attribute", - name, nested_name - ) - ), + _ => throw_invalid_nested_attr!(attr, &nested_attr), } } @@ -619,6 +526,7 @@ impl SessionDiagnosticDeriveBuilder { Ok(quote! { #diag.#method(#span_, #msg, #code, #applicability); }) } + _ => throw_invalid_attr!(attr, &meta), } } diff --git a/compiler/rustc_macros/src/diagnostics/error.rs b/compiler/rustc_macros/src/diagnostics/error.rs index 2a56b6cad02..fd1dc2f3073 100644 --- a/compiler/rustc_macros/src/diagnostics/error.rs +++ b/compiler/rustc_macros/src/diagnostics/error.rs @@ -1,11 +1,11 @@ use proc_macro::{Diagnostic, Level, MultiSpan}; use proc_macro2::TokenStream; use quote::quote; -use syn; +use syn::{spanned::Spanned, Attribute, Error as SynError, Meta, NestedMeta}; #[derive(Debug)] pub(crate) enum SessionDiagnosticDeriveError { - SynError(syn::Error), + SynError(SynError), ErrorHandled, } @@ -24,37 +24,109 @@ impl SessionDiagnosticDeriveError { } } +impl From for SessionDiagnosticDeriveError { + fn from(e: SynError) -> Self { + SessionDiagnosticDeriveError::SynError(e) + } +} + +/// Helper function for use with `throw_*` macros - constraints `$f` to an `impl FnOnce`. +pub(crate) fn _throw_err( + diag: Diagnostic, + f: impl FnOnce(Diagnostic) -> Diagnostic, +) -> SessionDiagnosticDeriveError { + f(diag).emit(); + SessionDiagnosticDeriveError::ErrorHandled +} + +/// Returns an error diagnostic on span `span` with msg `msg`. pub(crate) fn span_err(span: impl MultiSpan, msg: &str) -> Diagnostic { Diagnostic::spanned(span, Level::Error, msg) } -/// For methods that return a `Result<_, SessionDiagnosticDeriveError>`: -/// /// Emit a diagnostic on span `$span` with msg `$msg` (optionally performing additional decoration /// using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`. +/// +/// For methods that return a `Result<_, SessionDiagnosticDeriveError>`: macro_rules! throw_span_err { ($span:expr, $msg:expr) => {{ throw_span_err!($span, $msg, |diag| diag) }}; ($span:expr, $msg:expr, $f:expr) => {{ - return Err(crate::diagnostics::error::_throw_span_err($span, $msg, $f)); + let diag = span_err($span, $msg); + return Err(crate::diagnostics::error::_throw_err(diag, $f)); }}; } pub(crate) use throw_span_err; -/// When possible, prefer using `throw_span_err!` over using this function directly. This only -/// exists as a function to constrain `f` to an `impl FnOnce`. -pub(crate) fn _throw_span_err( - span: impl MultiSpan, - msg: &str, - f: impl FnOnce(Diagnostic) -> Diagnostic, -) -> SessionDiagnosticDeriveError { - let diag = span_err(span, msg); - f(diag).emit(); - SessionDiagnosticDeriveError::ErrorHandled -} +/// Returns an error diagnostic for an invalid attribute. +pub(crate) fn invalid_attr(attr: &Attribute, meta: &Meta) -> Diagnostic { + let span = attr.span().unwrap(); + let name = attr.path.segments.last().unwrap().ident.to_string(); + let name = name.as_str(); -impl From for SessionDiagnosticDeriveError { - fn from(e: syn::Error) -> Self { - SessionDiagnosticDeriveError::SynError(e) + match meta { + Meta::Path(_) => span_err(span, &format!("`#[{}]` is not a valid attribute", name)), + Meta::NameValue(_) => { + span_err(span, &format!("`#[{} = ...]` is not a valid attribute", name)) + } + Meta::List(_) => span_err(span, &format!("`#[{}(...)]` is not a valid attribute", name)), } } + +/// Emit a error diagnostic for an invalid attribute (optionally performing additional decoration +/// using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`. +/// +/// For methods that return a `Result<_, SessionDiagnosticDeriveError>`: +macro_rules! throw_invalid_attr { + ($attr:expr, $meta:expr) => {{ throw_invalid_attr!($attr, $meta, |diag| diag) }}; + ($attr:expr, $meta:expr, $f:expr) => {{ + let diag = crate::diagnostics::error::invalid_attr($attr, $meta); + return Err(crate::diagnostics::error::_throw_err(diag, $f)); + }}; +} + +pub(crate) use throw_invalid_attr; + +/// Returns an error diagnostic for an invalid nested attribute. +pub(crate) fn invalid_nested_attr(attr: &Attribute, nested: &NestedMeta) -> Diagnostic { + let name = attr.path.segments.last().unwrap().ident.to_string(); + let name = name.as_str(); + + let span = nested.span().unwrap(); + let meta = match nested { + syn::NestedMeta::Meta(meta) => meta, + syn::NestedMeta::Lit(_) => { + return span_err(span, &format!("`#[{}(\"...\")]` is not a valid attribute", name)); + } + }; + + let span = meta.span().unwrap(); + let nested_name = meta.path().segments.last().unwrap().ident.to_string(); + let nested_name = nested_name.as_str(); + match meta { + Meta::NameValue(..) => span_err( + span, + &format!("`#[{}({} = ...)]` is not a valid attribute", name, nested_name), + ), + Meta::Path(..) => { + span_err(span, &format!("`#[{}({})]` is not a valid attribute", name, nested_name)) + } + Meta::List(..) => { + span_err(span, &format!("`#[{}({}(...))]` is not a valid attribute", name, nested_name)) + } + } +} + +/// Emit a error diagnostic for an invalid nested attribute (optionally performing additional +/// decoration using the `FnOnce` passed in `diag`) and return `Err(ErrorHandled)`. +/// +/// For methods that return a `Result<_, SessionDiagnosticDeriveError>`: +macro_rules! throw_invalid_nested_attr { + ($attr:expr, $nested_attr:expr) => {{ throw_invalid_nested_attr!($attr, $nested_attr, |diag| diag) }}; + ($attr:expr, $nested_attr:expr, $f:expr) => {{ + let diag = crate::diagnostics::error::invalid_nested_attr($attr, $nested_attr); + return Err(crate::diagnostics::error::_throw_err(diag, $f)); + }}; +} + +pub(crate) use throw_invalid_nested_attr; diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 4d1ec826e9b..b644773b32b 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -1,6 +1,9 @@ #![deny(unused_must_use)] -use crate::diagnostics::error::{span_err, throw_span_err, SessionDiagnosticDeriveError}; +use crate::diagnostics::error::{ + span_err, throw_invalid_attr, throw_invalid_nested_attr, throw_span_err, + SessionDiagnosticDeriveError, +}; use crate::diagnostics::utils::{ option_inner_ty, report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span, FieldInfo, HasFieldMap, SetOnce, @@ -253,25 +256,11 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { let meta = attr.parse_meta()?; let kind = match meta { - Meta::Path(_) => throw_span_err!( - span, - &format!("`#[{}]` is not a valid `SessionSubdiagnostic` attribute", name) - ), - Meta::NameValue(_) => throw_span_err!( - span, - &format!("`#[{} = ...]` is not a valid `SessionSubdiagnostic` attribute", name) - ), - Meta::List(MetaList { nested, .. }) => { - for attr in nested { - let meta = match attr { - syn::NestedMeta::Meta(meta) => meta, - syn::NestedMeta::Lit(_) => throw_span_err!( - span, - &format!( - "`#[{}(\"...\")]` is not a valid `SessionSubdiagnostic` attribute", - name - ) - ), + Meta::List(MetaList { ref nested, .. }) => { + for nested_attr in nested { + let meta = match nested_attr { + syn::NestedMeta::Meta(ref meta) => meta, + _ => throw_invalid_nested_attr!(attr, &nested_attr), }; let span = meta.span().unwrap(); @@ -296,51 +285,22 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { }; self.applicability.set_once((quote! { #value }, span)); } - other => throw_span_err!( - span, - &format!( - "`#[{}({} = ...)]` is not a valid `SessionSubdiagnostic` attribute", - name, other - ) - ), + _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { + diag.help("only `code`, `slug` and `applicability` are valid nested attributes") + }), } } - Meta::NameValue(..) => throw_span_err!( - span, - &format!( - "`#[{}({} = ...)]` is not a valid `SessionSubdiagnostic` attribute", - name, nested_name - ), - |diag| diag.help("value must be a string") - ), - Meta::Path(..) => throw_span_err!( - span, - &format!( - "`#[{}({})]` is not a valid `SessionSubdiagnostic` attribute", - name, nested_name - ) - ), - Meta::List(..) => throw_span_err!( - span, - &format!( - "`#[{}({}(...))]` is not a valid `SessionSubdiagnostic` attribute", - name, nested_name - ) - ), + _ => throw_invalid_nested_attr!(attr, &nested_attr), } } let Ok(kind) = SubdiagnosticKind::from_str(name) else { - throw_span_err!( - span, - &format!( - "`#[{}(...)]` is not a valid `SessionSubdiagnostic` attribute", - name - ) - ); + throw_invalid_attr!(attr, &meta) }; + kind } + _ => throw_invalid_attr!(attr, &meta), }; if matches!( @@ -408,31 +368,11 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { "skip_arg" => { return Ok(quote! {}); } - other => span_err( - span, - &format!( - "`#[{}]` is not a valid `SessionSubdiagnostic` field attribute", - other - ), - ) - .emit(), + _ => throw_invalid_attr!(attr, &meta, |diag| { + diag.help("only `primary_span`, `applicability` and `skip_arg` are valid field attributes") + }), }, - Meta::NameValue(_) => span_err( - span, - &format!( - "`#[{} = ...]` is not a valid `SessionSubdiagnostic` field attribute", - name - ), - ) - .emit(), - Meta::List(_) => span_err( - span, - &format!( - "`#[{}(...)]` is not a valid `SessionSubdiagnostic` field attribute", - name - ), - ) - .emit(), + _ => throw_invalid_attr!(attr, &meta), } } diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index adec548b390..5f55492edf9 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -44,47 +44,47 @@ enum SessionDiagnosticOnEnum { #[derive(SessionDiagnostic)] #[error(code = "E0123", slug = "foo")] #[error = "E0123"] -//~^ ERROR `#[error = ...]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error = ...]` is not a valid attribute struct WrongStructAttrStyle {} #[derive(SessionDiagnostic)] #[nonsense(code = "E0123", slug = "foo")] -//~^ ERROR `#[nonsense(...)]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[nonsense(...)]` is not a valid attribute //~^^ ERROR diagnostic kind not specified //~^^^ ERROR cannot find attribute `nonsense` in this scope struct InvalidStructAttr {} #[derive(SessionDiagnostic)] #[error("E0123")] -//~^ ERROR `#[error("...")]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error("...")]` is not a valid attribute //~^^ ERROR `slug` not specified struct InvalidLitNestedAttr {} #[derive(SessionDiagnostic)] #[error(nonsense, code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense)]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error(nonsense)]` is not a valid attribute struct InvalidNestedStructAttr {} #[derive(SessionDiagnostic)] #[error(nonsense("foo"), code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense(...))]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error(nonsense(...))]` is not a valid attribute struct InvalidNestedStructAttr1 {} #[derive(SessionDiagnostic)] #[error(nonsense = "...", code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense = ...)]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute struct InvalidNestedStructAttr2 {} #[derive(SessionDiagnostic)] #[error(nonsense = 4, code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense = ...)]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute struct InvalidNestedStructAttr3 {} #[derive(SessionDiagnostic)] #[error(code = "E0123", slug = "foo")] struct WrongPlaceField { #[suggestion = "bar"] - //~^ ERROR `#[suggestion = ...]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[suggestion = ...]` is not a valid attribute sp: Span, } @@ -130,7 +130,7 @@ struct MessageWrongType { #[error(code = "E0123", slug = "foo")] struct InvalidPathFieldAttr { #[nonsense] - //~^ ERROR `#[nonsense]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[nonsense]` is not a valid attribute //~^^ ERROR cannot find attribute `nonsense` in this scope foo: String, } @@ -215,7 +215,7 @@ struct SuggestWithoutCode { #[error(code = "E0123", slug = "foo")] struct SuggestWithBadKey { #[suggestion(nonsense = "bar")] - //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute suggestion: (Span, Applicability), } @@ -223,7 +223,7 @@ struct SuggestWithBadKey { #[error(code = "E0123", slug = "foo")] struct SuggestWithShorthandMsg { #[suggestion(msg = "bar")] - //~^ ERROR `#[suggestion(msg = ...)]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute suggestion: (Span, Applicability), } @@ -276,7 +276,7 @@ struct SuggestWithDuplicateApplicabilityAndSpan { #[error(code = "E0123", slug = "foo")] struct WrongKindOfAnnotation { #[label("bar")] - //~^ ERROR `#[label(...)]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[label(...)]` is not a valid attribute z: Span, } diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 902d8251576..ef4950ba3af 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -9,17 +9,19 @@ LL | | Bar, LL | | } | |_^ -error: `#[error = ...]` is not a valid `SessionDiagnostic` struct attribute +error: `#[error = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:46:1 | LL | #[error = "E0123"] | ^^^^^^^^^^^^^^^^^^ -error: `#[nonsense(...)]` is not a valid `SessionDiagnostic` struct attribute +error: `#[nonsense(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:51:1 | LL | #[nonsense(code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `error` and `warning` are valid attributes error: diagnostic kind not specified --> $DIR/diagnostic-derive.rs:51:1 @@ -33,7 +35,7 @@ LL | | struct InvalidStructAttr {} | = help: use the `#[error(...)]` attribute to create an error -error: `#[error("...")]` is not a valid `SessionDiagnostic` struct attribute +error: `#[error("...")]` is not a valid attribute --> $DIR/diagnostic-derive.rs:58:9 | LL | #[error("E0123")] @@ -50,37 +52,39 @@ LL | | struct InvalidLitNestedAttr {} | = help: use the `#[error(slug = "...")]` attribute to set this diagnostic's slug -error: `#[error(nonsense)]` is not a valid `SessionDiagnostic` struct attribute +error: `#[error(nonsense)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:64:9 | LL | #[error(nonsense, code = "E0123", slug = "foo")] | ^^^^^^^^ -error: `#[error(nonsense(...))]` is not a valid `SessionDiagnostic` struct attribute +error: `#[error(nonsense(...))]` is not a valid attribute --> $DIR/diagnostic-derive.rs:69:9 | LL | #[error(nonsense("foo"), code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^ -error: `#[error(nonsense = ...)]` is not a valid `SessionDiagnostic` struct attribute +error: `#[error(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:74:9 | LL | #[error(nonsense = "...", code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^^ + | + = help: only `slug` and `code` are valid nested attributes -error: `#[error(nonsense = ...)]` is not a valid `SessionDiagnostic` struct attribute +error: `#[error(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:79:9 | LL | #[error(nonsense = 4, code = "E0123", slug = "foo")] | ^^^^^^^^^^^^ - | - = help: value must be a string -error: `#[suggestion = ...]` is not a valid `SessionDiagnostic` field attribute +error: `#[suggestion = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:86:5 | LL | #[suggestion = "bar"] | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `label`, `note` and `help` are valid field attributes error: `error` specified multiple times --> $DIR/diagnostic-derive.rs:93:1 @@ -153,11 +157,13 @@ error: the `#[primary_span]` attribute can only be applied to fields of type `Sp LL | #[primary_span] | ^^^^^^^^^^^^^^^ -error: `#[nonsense]` is not a valid `SessionDiagnostic` field attribute +error: `#[nonsense]` is not a valid attribute --> $DIR/diagnostic-derive.rs:132:5 | LL | #[nonsense] | ^^^^^^^^^^^ + | + = help: only `skip_arg`, `primary_span`, `label`, `note` and `help` are valid field attributes error: the `#[label = ...]` attribute can only be applied to fields of type `Span` --> $DIR/diagnostic-derive.rs:149:5 @@ -197,17 +203,21 @@ error: the `#[label = ...]` attribute can only be applied to fields of type `Spa LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ -error: `#[suggestion(nonsense = ...)]` is not a valid `SessionDiagnostic` field attribute +error: `#[suggestion(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:217:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^ + | + = help: only `message` and `code` are valid field attributes -error: `#[suggestion(msg = ...)]` is not a valid `SessionDiagnostic` field attribute +error: `#[suggestion(msg = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:225:18 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^ + | + = help: only `message` and `code` are valid field attributes error: wrong field type for suggestion --> $DIR/diagnostic-derive.rs:247:5 @@ -235,11 +245,13 @@ LL | | LL | | suggestion: (Applicability, Applicability, Span), | |____________________________________________________^ -error: `#[label(...)]` is not a valid `SessionDiagnostic` field attribute +error: `#[label(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:278:5 | LL | #[label("bar")] | ^^^^^^^^^^^^^^^ + | + = help: only `suggestion{,_short,_hidden,_verbose}` are valid field attributes error: `#[help]` must come after `#[error(..)]` or `#[warn(..)]` --> $DIR/diagnostic-derive.rs:399:1 diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index a587bd2cbb2..bb406c35c0e 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -52,7 +52,7 @@ struct C { #[derive(SessionSubdiagnostic)] #[label] -//~^ ERROR `#[label]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[label]` is not a valid attribute struct D { #[primary_span] span: Span, @@ -61,7 +61,7 @@ struct D { #[derive(SessionSubdiagnostic)] #[foo] -//~^ ERROR `#[foo]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[foo]` is not a valid attribute //~^^ ERROR cannot find attribute `foo` in this scope struct E { #[primary_span] @@ -71,7 +71,7 @@ struct E { #[derive(SessionSubdiagnostic)] #[label = "..."] -//~^ ERROR `#[label = ...]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[label = ...]` is not a valid attribute struct F { #[primary_span] span: Span, @@ -80,7 +80,7 @@ struct F { #[derive(SessionSubdiagnostic)] #[label(bug = "...")] -//~^ ERROR `#[label(bug = ...)]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[label(bug = ...)]` is not a valid attribute struct G { #[primary_span] span: Span, @@ -89,7 +89,7 @@ struct G { #[derive(SessionSubdiagnostic)] #[label("...")] -//~^ ERROR `#[label("...")]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[label("...")]` is not a valid attribute struct H { #[primary_span] span: Span, @@ -98,7 +98,7 @@ struct H { #[derive(SessionSubdiagnostic)] #[label(slug = 4)] -//~^ ERROR `#[label(slug = ...)]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[label(slug = ...)]` is not a valid attribute struct J { #[primary_span] span: Span, @@ -107,7 +107,7 @@ struct J { #[derive(SessionSubdiagnostic)] #[label(slug("..."))] -//~^ ERROR `#[label(slug(...))]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[label(slug(...))]` is not a valid attribute struct K { #[primary_span] span: Span, @@ -116,7 +116,7 @@ struct K { #[derive(SessionSubdiagnostic)] #[label(slug)] -//~^ ERROR `#[label(slug)]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[label(slug)]` is not a valid attribute struct L { #[primary_span] span: Span, @@ -157,7 +157,7 @@ enum O { #[derive(SessionSubdiagnostic)] enum P { #[bar] -//~^ ERROR `#[bar]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[bar]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope A { #[primary_span] @@ -169,7 +169,7 @@ enum P { #[derive(SessionSubdiagnostic)] enum Q { #[bar = "..."] -//~^ ERROR `#[bar = ...]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[bar = ...]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope A { #[primary_span] @@ -181,7 +181,7 @@ enum Q { #[derive(SessionSubdiagnostic)] enum R { #[bar = 4] -//~^ ERROR `#[bar = ...]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[bar = ...]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope A { #[primary_span] @@ -193,7 +193,7 @@ enum R { #[derive(SessionSubdiagnostic)] enum S { #[bar("...")] -//~^ ERROR `#[bar("...")]` is not a valid `SessionSubdiagnostic` attribute +//~^ ERROR `#[bar("...")]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope A { #[primary_span] @@ -254,7 +254,7 @@ struct X { #[primary_span] span: Span, #[bar] - //~^ ERROR `#[bar]` is not a valid `SessionSubdiagnostic` field attribute + //~^ ERROR `#[bar]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope bar: String, } @@ -265,7 +265,7 @@ struct Y { #[primary_span] span: Span, #[bar = "..."] - //~^ ERROR `#[bar = ...]` is not a valid `SessionSubdiagnostic` field attribute + //~^ ERROR `#[bar = ...]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope bar: String, } @@ -276,7 +276,7 @@ struct Z { #[primary_span] span: Span, #[bar("...")] - //~^ ERROR `#[bar(...)]` is not a valid `SessionSubdiagnostic` field attribute + //~^ ERROR `#[bar(...)]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope bar: String, } diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index bc96fcf771b..4984cc4b318 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -8,51 +8,51 @@ LL | | var: String, LL | | } | |_^ -error: `#[label]` is not a valid `SessionSubdiagnostic` attribute +error: `#[label]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:54:1 | LL | #[label] | ^^^^^^^^ -error: `#[foo]` is not a valid `SessionSubdiagnostic` attribute +error: `#[foo]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:63:1 | LL | #[foo] | ^^^^^^ -error: `#[label = ...]` is not a valid `SessionSubdiagnostic` attribute +error: `#[label = ...]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:73:1 | LL | #[label = "..."] | ^^^^^^^^^^^^^^^^ -error: `#[label(bug = ...)]` is not a valid `SessionSubdiagnostic` attribute +error: `#[label(bug = ...)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:82:9 | LL | #[label(bug = "...")] | ^^^^^^^^^^^ + | + = help: only `code`, `slug` and `applicability` are valid nested attributes -error: `#[label("...")]` is not a valid `SessionSubdiagnostic` attribute - --> $DIR/subdiagnostic-derive.rs:91:1 +error: `#[label("...")]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:91:9 | LL | #[label("...")] - | ^^^^^^^^^^^^^^^ + | ^^^^^ -error: `#[label(slug = ...)]` is not a valid `SessionSubdiagnostic` attribute +error: `#[label(slug = ...)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:100:9 | LL | #[label(slug = 4)] | ^^^^^^^^ - | - = help: value must be a string -error: `#[label(slug(...))]` is not a valid `SessionSubdiagnostic` attribute +error: `#[label(slug(...))]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:109:9 | LL | #[label(slug("..."))] | ^^^^^^^^^^^ -error: `#[label(slug)]` is not a valid `SessionSubdiagnostic` attribute +error: `#[label(slug)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:118:9 | LL | #[label(slug)] @@ -76,29 +76,29 @@ error: unsupported type attribute for subdiagnostic enum LL | #[foo] | ^^^^^^ -error: `#[bar]` is not a valid `SessionSubdiagnostic` attribute +error: `#[bar]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:159:5 | LL | #[bar] | ^^^^^^ -error: `#[bar = ...]` is not a valid `SessionSubdiagnostic` attribute +error: `#[bar = ...]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:171:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ -error: `#[bar = ...]` is not a valid `SessionSubdiagnostic` attribute +error: `#[bar = ...]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:183:5 | LL | #[bar = 4] | ^^^^^^^^^^ -error: `#[bar("...")]` is not a valid `SessionSubdiagnostic` attribute - --> $DIR/subdiagnostic-derive.rs:195:5 +error: `#[bar("...")]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:195:11 | LL | #[bar("...")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: `code` is not a valid nested attribute of a `label` attribute --> $DIR/subdiagnostic-derive.rs:207:5 @@ -136,19 +136,21 @@ error: `#[applicability]` is only valid on suggestions LL | #[applicability] | ^^^^^^^^^^^^^^^^ -error: `#[bar]` is not a valid `SessionSubdiagnostic` field attribute +error: `#[bar]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:256:5 | LL | #[bar] | ^^^^^^ + | + = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes -error: `#[bar = ...]` is not a valid `SessionSubdiagnostic` field attribute +error: `#[bar = ...]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:267:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ -error: `#[bar(...)]` is not a valid `SessionSubdiagnostic` field attribute +error: `#[bar(...)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:278:5 | LL | #[bar("...")]