mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Extract subdiagnostic attribute parsing
This commit is contained in:
parent
d4a1a6f698
commit
e7251cc441
@ -4,100 +4,16 @@ use crate::diagnostics::error::{
|
|||||||
span_err, throw_invalid_attr, throw_invalid_nested_attr, throw_span_err, DiagnosticDeriveError,
|
span_err, throw_invalid_attr, throw_invalid_nested_attr, throw_span_err, DiagnosticDeriveError,
|
||||||
};
|
};
|
||||||
use crate::diagnostics::utils::{
|
use crate::diagnostics::utils::{
|
||||||
report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span,
|
report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span, FieldInfo,
|
||||||
Applicability, FieldInfo, FieldInnerTy, HasFieldMap, SetOnce,
|
FieldInnerTy, HasFieldMap, SetOnce,
|
||||||
};
|
};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use syn::{spanned::Spanned, Attribute, Meta, MetaList, MetaNameValue, NestedMeta, Path};
|
use syn::{spanned::Spanned, Attribute, Meta, MetaList, MetaNameValue, NestedMeta, Path};
|
||||||
use synstructure::{BindingInfo, Structure, VariantInfo};
|
use synstructure::{BindingInfo, Structure, VariantInfo};
|
||||||
|
|
||||||
use super::utils::SpannedOption;
|
use super::utils::{SpannedOption, SubdiagnosticKind};
|
||||||
|
|
||||||
/// Which kind of suggestion is being created?
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
enum SubdiagnosticSuggestionKind {
|
|
||||||
/// `#[suggestion]`
|
|
||||||
Normal,
|
|
||||||
/// `#[suggestion_short]`
|
|
||||||
Short,
|
|
||||||
/// `#[suggestion_hidden]`
|
|
||||||
Hidden,
|
|
||||||
/// `#[suggestion_verbose]`
|
|
||||||
Verbose,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for SubdiagnosticSuggestionKind {
|
|
||||||
type Err = ();
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
match s {
|
|
||||||
"" => Ok(SubdiagnosticSuggestionKind::Normal),
|
|
||||||
"_short" => Ok(SubdiagnosticSuggestionKind::Short),
|
|
||||||
"_hidden" => Ok(SubdiagnosticSuggestionKind::Hidden),
|
|
||||||
"_verbose" => Ok(SubdiagnosticSuggestionKind::Verbose),
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SubdiagnosticSuggestionKind {
|
|
||||||
pub fn to_suggestion_style(&self) -> TokenStream {
|
|
||||||
match self {
|
|
||||||
SubdiagnosticSuggestionKind::Normal => {
|
|
||||||
quote! { rustc_errors::SuggestionStyle::ShowCode }
|
|
||||||
}
|
|
||||||
SubdiagnosticSuggestionKind::Short => {
|
|
||||||
quote! { rustc_errors::SuggestionStyle::HideCodeInline }
|
|
||||||
}
|
|
||||||
SubdiagnosticSuggestionKind::Hidden => {
|
|
||||||
quote! { rustc_errors::SuggestionStyle::HideCodeAlways }
|
|
||||||
}
|
|
||||||
SubdiagnosticSuggestionKind::Verbose => {
|
|
||||||
quote! { rustc_errors::SuggestionStyle::ShowAlways }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Which kind of subdiagnostic is being created from a variant?
|
|
||||||
#[derive(Clone)]
|
|
||||||
enum SubdiagnosticKind {
|
|
||||||
/// `#[label(...)]`
|
|
||||||
Label,
|
|
||||||
/// `#[note(...)]`
|
|
||||||
Note,
|
|
||||||
/// `#[help(...)]`
|
|
||||||
Help,
|
|
||||||
/// `#[warning(...)]`
|
|
||||||
Warn,
|
|
||||||
/// `#[suggestion{,_short,_hidden,_verbose}]`
|
|
||||||
Suggestion { suggestion_kind: SubdiagnosticSuggestionKind, code: TokenStream },
|
|
||||||
/// `#[multipart_suggestion{,_short,_hidden,_verbose}]`
|
|
||||||
MultipartSuggestion { suggestion_kind: SubdiagnosticSuggestionKind },
|
|
||||||
}
|
|
||||||
|
|
||||||
impl quote::IdentFragment for SubdiagnosticKind {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
SubdiagnosticKind::Label => write!(f, "label"),
|
|
||||||
SubdiagnosticKind::Note => write!(f, "note"),
|
|
||||||
SubdiagnosticKind::Help => write!(f, "help"),
|
|
||||||
SubdiagnosticKind::Warn => write!(f, "warn"),
|
|
||||||
SubdiagnosticKind::Suggestion { .. } => write!(f, "suggestion_with_style"),
|
|
||||||
SubdiagnosticKind::MultipartSuggestion { .. } => {
|
|
||||||
write!(f, "multipart_suggestion_with_style")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn span(&self) -> Option<proc_macro2::Span> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The central struct for constructing the `add_to_diagnostic` method from an annotated struct.
|
/// The central struct for constructing the `add_to_diagnostic` method from an annotated struct.
|
||||||
pub(crate) struct SubdiagnosticDerive<'a> {
|
pub(crate) struct SubdiagnosticDerive<'a> {
|
||||||
@ -198,8 +114,8 @@ struct SubdiagnosticDeriveBuilder<'a> {
|
|||||||
|
|
||||||
/// Identifier for the binding to the `#[primary_span]` field.
|
/// Identifier for the binding to the `#[primary_span]` field.
|
||||||
span_field: SpannedOption<proc_macro2::Ident>,
|
span_field: SpannedOption<proc_macro2::Ident>,
|
||||||
/// If a suggestion, the identifier for the binding to the `#[applicability]` field or a
|
|
||||||
/// `rustc_errors::Applicability::*` variant directly.
|
/// The binding to the `#[applicability]` field, if present.
|
||||||
applicability: SpannedOption<TokenStream>,
|
applicability: SpannedOption<TokenStream>,
|
||||||
|
|
||||||
/// Set to true when a `#[suggestion_part]` field is encountered, used to generate an error
|
/// Set to true when a `#[suggestion_part]` field is encountered, used to generate an error
|
||||||
@ -219,6 +135,7 @@ struct KindsStatistics {
|
|||||||
has_multipart_suggestion: bool,
|
has_multipart_suggestion: bool,
|
||||||
all_multipart_suggestions: bool,
|
all_multipart_suggestions: bool,
|
||||||
has_normal_suggestion: bool,
|
has_normal_suggestion: bool,
|
||||||
|
all_applicabilities_static: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromIterator<&'a SubdiagnosticKind> for KindsStatistics {
|
impl<'a> FromIterator<&'a SubdiagnosticKind> for KindsStatistics {
|
||||||
@ -227,8 +144,15 @@ impl<'a> FromIterator<&'a SubdiagnosticKind> for KindsStatistics {
|
|||||||
has_multipart_suggestion: false,
|
has_multipart_suggestion: false,
|
||||||
all_multipart_suggestions: true,
|
all_multipart_suggestions: true,
|
||||||
has_normal_suggestion: false,
|
has_normal_suggestion: false,
|
||||||
|
all_applicabilities_static: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
for kind in kinds {
|
for kind in kinds {
|
||||||
|
if let SubdiagnosticKind::MultipartSuggestion { applicability: None, .. }
|
||||||
|
| SubdiagnosticKind::Suggestion { applicability: None, .. } = kind
|
||||||
|
{
|
||||||
|
ret.all_applicabilities_static = false;
|
||||||
|
}
|
||||||
if let SubdiagnosticKind::MultipartSuggestion { .. } = kind {
|
if let SubdiagnosticKind::MultipartSuggestion { .. } = kind {
|
||||||
ret.has_multipart_suggestion = true;
|
ret.has_multipart_suggestion = true;
|
||||||
} else {
|
} else {
|
||||||
@ -248,129 +172,14 @@ impl<'a> SubdiagnosticDeriveBuilder<'a> {
|
|||||||
let mut kind_slugs = vec![];
|
let mut kind_slugs = vec![];
|
||||||
|
|
||||||
for attr in self.variant.ast().attrs {
|
for attr in self.variant.ast().attrs {
|
||||||
let span = attr.span().unwrap();
|
let (kind, slug) = SubdiagnosticKind::from_attr(attr, self)?;
|
||||||
|
|
||||||
let name = attr.path.segments.last().unwrap().ident.to_string();
|
let Some(slug) = slug else {
|
||||||
let name = name.as_str();
|
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||||
|
let name = name.as_str();
|
||||||
|
|
||||||
let meta = attr.parse_meta()?;
|
|
||||||
let Meta::List(MetaList { ref nested, .. }) = meta else {
|
|
||||||
throw_invalid_attr!(attr, &meta);
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut kind = match name {
|
|
||||||
"label" => SubdiagnosticKind::Label,
|
|
||||||
"note" => SubdiagnosticKind::Note,
|
|
||||||
"help" => SubdiagnosticKind::Help,
|
|
||||||
"warning" => SubdiagnosticKind::Warn,
|
|
||||||
_ => {
|
|
||||||
if let Some(suggestion_kind) =
|
|
||||||
name.strip_prefix("suggestion").and_then(|s| s.parse().ok())
|
|
||||||
{
|
|
||||||
SubdiagnosticKind::Suggestion { suggestion_kind, code: TokenStream::new() }
|
|
||||||
} else if let Some(suggestion_kind) =
|
|
||||||
name.strip_prefix("multipart_suggestion").and_then(|s| s.parse().ok())
|
|
||||||
{
|
|
||||||
SubdiagnosticKind::MultipartSuggestion { suggestion_kind }
|
|
||||||
} else {
|
|
||||||
throw_invalid_attr!(attr, &meta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut slug = None;
|
|
||||||
let mut code = None;
|
|
||||||
|
|
||||||
let mut nested_iter = nested.into_iter();
|
|
||||||
if let Some(nested_attr) = nested_iter.next() {
|
|
||||||
match nested_attr {
|
|
||||||
NestedMeta::Meta(Meta::Path(path)) => {
|
|
||||||
slug.set_once(path.clone(), span);
|
|
||||||
}
|
|
||||||
NestedMeta::Meta(meta @ Meta::NameValue(_))
|
|
||||||
if matches!(
|
|
||||||
meta.path().segments.last().unwrap().ident.to_string().as_str(),
|
|
||||||
"code" | "applicability"
|
|
||||||
) =>
|
|
||||||
{
|
|
||||||
// Don't error for valid follow-up attributes.
|
|
||||||
}
|
|
||||||
nested_attr => {
|
|
||||||
throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
|
|
||||||
diag.help(
|
|
||||||
"first argument of the attribute should be the diagnostic \
|
|
||||||
slug",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
for nested_attr in nested_iter {
|
|
||||||
let meta = match nested_attr {
|
|
||||||
NestedMeta::Meta(ref meta) => meta,
|
|
||||||
_ => 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();
|
|
||||||
|
|
||||||
let value = match meta {
|
|
||||||
Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(value), .. }) => value,
|
|
||||||
Meta::Path(_) => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
|
|
||||||
diag.help("a diagnostic slug must be the first argument to the attribute")
|
|
||||||
}),
|
|
||||||
_ => throw_invalid_nested_attr!(attr, &nested_attr),
|
|
||||||
};
|
|
||||||
|
|
||||||
match nested_name {
|
|
||||||
"code" => {
|
|
||||||
if matches!(kind, SubdiagnosticKind::Suggestion { .. }) {
|
|
||||||
let formatted_str = self.build_format(&value.value(), value.span());
|
|
||||||
code.set_once(formatted_str, span);
|
|
||||||
} else {
|
|
||||||
span_err(
|
|
||||||
span,
|
|
||||||
&format!(
|
|
||||||
"`code` is not a valid nested attribute of a `{}` attribute",
|
|
||||||
name
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"applicability" => {
|
|
||||||
if matches!(
|
|
||||||
kind,
|
|
||||||
SubdiagnosticKind::Suggestion { .. }
|
|
||||||
| SubdiagnosticKind::MultipartSuggestion { .. }
|
|
||||||
) {
|
|
||||||
let value =
|
|
||||||
Applicability::from_str(&value.value()).unwrap_or_else(|()| {
|
|
||||||
span_err(span, "invalid applicability").emit();
|
|
||||||
Applicability::Unspecified
|
|
||||||
});
|
|
||||||
self.applicability.set_once(quote! { #value }, span);
|
|
||||||
} else {
|
|
||||||
span_err(
|
|
||||||
span,
|
|
||||||
&format!(
|
|
||||||
"`applicability` is not a valid nested attribute of a `{}` attribute",
|
|
||||||
name
|
|
||||||
)
|
|
||||||
).emit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
|
|
||||||
diag.help("only `code` and `applicability` are valid nested attributes")
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let Some((slug, _)) = slug else {
|
|
||||||
throw_span_err!(
|
throw_span_err!(
|
||||||
span,
|
attr.span().unwrap(),
|
||||||
&format!(
|
&format!(
|
||||||
"diagnostic slug must be first argument of a `#[{}(...)]` attribute",
|
"diagnostic slug must be first argument of a `#[{}(...)]` attribute",
|
||||||
name
|
name
|
||||||
@ -378,21 +187,7 @@ impl<'a> SubdiagnosticDeriveBuilder<'a> {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
match kind {
|
kind_slugs.push((kind, slug));
|
||||||
SubdiagnosticKind::Suggestion { code: ref mut code_field, .. } => {
|
|
||||||
let Some((code, _)) = code else {
|
|
||||||
throw_span_err!(span, "suggestion without `code = \"...\"`");
|
|
||||||
};
|
|
||||||
*code_field = code;
|
|
||||||
}
|
|
||||||
SubdiagnosticKind::Label
|
|
||||||
| SubdiagnosticKind::Note
|
|
||||||
| SubdiagnosticKind::Help
|
|
||||||
| SubdiagnosticKind::Warn
|
|
||||||
| SubdiagnosticKind::MultipartSuggestion { .. } => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
kind_slugs.push((kind, slug))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(kind_slugs)
|
Ok(kind_slugs)
|
||||||
@ -510,6 +305,15 @@ impl<'a> SubdiagnosticDeriveBuilder<'a> {
|
|||||||
if kind_stats.has_multipart_suggestion || kind_stats.has_normal_suggestion {
|
if kind_stats.has_multipart_suggestion || kind_stats.has_normal_suggestion {
|
||||||
report_error_if_not_applied_to_applicability(attr, &info)?;
|
report_error_if_not_applied_to_applicability(attr, &info)?;
|
||||||
|
|
||||||
|
if kind_stats.all_applicabilities_static {
|
||||||
|
span_err(
|
||||||
|
span,
|
||||||
|
"`#[applicability]` has no effect if all `#[suggestion]`/\
|
||||||
|
`#[multipart_suggestion]` attributes have a static \
|
||||||
|
`applicability = \"...\"`",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
let binding = info.binding.binding.clone();
|
let binding = info.binding.binding.clone();
|
||||||
self.applicability.set_once(quote! { #binding }, span);
|
self.applicability.set_once(quote! { #binding }, span);
|
||||||
} else {
|
} else {
|
||||||
@ -638,11 +442,6 @@ impl<'a> SubdiagnosticDeriveBuilder<'a> {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let span_field = self.span_field.value_ref();
|
let span_field = self.span_field.value_ref();
|
||||||
let applicability = self
|
|
||||||
.applicability
|
|
||||||
.take()
|
|
||||||
.value()
|
|
||||||
.unwrap_or_else(|| quote! { rustc_errors::Applicability::Unspecified });
|
|
||||||
|
|
||||||
let diag = &self.diag;
|
let diag = &self.diag;
|
||||||
let mut calls = TokenStream::new();
|
let mut calls = TokenStream::new();
|
||||||
@ -650,7 +449,13 @@ impl<'a> SubdiagnosticDeriveBuilder<'a> {
|
|||||||
let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind);
|
let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind);
|
||||||
let message = quote! { rustc_errors::fluent::#slug };
|
let message = quote! { rustc_errors::fluent::#slug };
|
||||||
let call = match kind {
|
let call = match kind {
|
||||||
SubdiagnosticKind::Suggestion { suggestion_kind, code } => {
|
SubdiagnosticKind::Suggestion { suggestion_kind, applicability, code } => {
|
||||||
|
let applicability = applicability
|
||||||
|
.value()
|
||||||
|
.map(|a| quote! { #a })
|
||||||
|
.or_else(|| self.applicability.take().value())
|
||||||
|
.unwrap_or_else(|| quote! { rustc_errors::Applicability::Unspecified });
|
||||||
|
|
||||||
if let Some(span) = span_field {
|
if let Some(span) = span_field {
|
||||||
let style = suggestion_kind.to_suggestion_style();
|
let style = suggestion_kind.to_suggestion_style();
|
||||||
|
|
||||||
@ -660,7 +465,13 @@ impl<'a> SubdiagnosticDeriveBuilder<'a> {
|
|||||||
quote! { unreachable!(); }
|
quote! { unreachable!(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SubdiagnosticKind::MultipartSuggestion { suggestion_kind } => {
|
SubdiagnosticKind::MultipartSuggestion { suggestion_kind, applicability } => {
|
||||||
|
let applicability = applicability
|
||||||
|
.value()
|
||||||
|
.map(|a| quote! { #a })
|
||||||
|
.or_else(|| self.applicability.take().value())
|
||||||
|
.unwrap_or_else(|| quote! { rustc_errors::Applicability::Unspecified });
|
||||||
|
|
||||||
if !self.has_suggestion_parts {
|
if !self.has_suggestion_parts {
|
||||||
span_err(
|
span_err(
|
||||||
self.span,
|
self.span,
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
use crate::diagnostics::error::{span_err, throw_span_err, DiagnosticDeriveError};
|
use crate::diagnostics::error::{
|
||||||
|
span_err, throw_invalid_attr, throw_invalid_nested_attr, throw_span_err, DiagnosticDeriveError,
|
||||||
|
};
|
||||||
use proc_macro::Span;
|
use proc_macro::Span;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::{format_ident, quote, ToTokens};
|
use quote::{format_ident, quote, ToTokens};
|
||||||
use std::collections::{BTreeSet, HashMap};
|
use std::collections::{BTreeSet, HashMap};
|
||||||
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use syn::{spanned::Spanned, Attribute, Meta, Type, TypeTuple};
|
use syn::{spanned::Spanned, Attribute, Meta, Type, TypeTuple};
|
||||||
|
use syn::{MetaList, MetaNameValue, NestedMeta, Path};
|
||||||
use synstructure::{BindingInfo, Structure};
|
use synstructure::{BindingInfo, Structure};
|
||||||
|
|
||||||
|
use super::error::invalid_nested_attr;
|
||||||
|
|
||||||
/// Checks whether the type name of `ty` matches `name`.
|
/// Checks whether the type name of `ty` matches `name`.
|
||||||
///
|
///
|
||||||
/// Given some struct at `a::b::c::Foo`, this will return true for `c::Foo`, `b::c::Foo`, or
|
/// Given some struct at `a::b::c::Foo`, this will return true for `c::Foo`, `b::c::Foo`, or
|
||||||
@ -311,6 +317,7 @@ pub(crate) trait HasFieldMap {
|
|||||||
|
|
||||||
/// `Applicability` of a suggestion - mirrors `rustc_errors::Applicability` - and used to represent
|
/// `Applicability` of a suggestion - mirrors `rustc_errors::Applicability` - and used to represent
|
||||||
/// the user's selection of applicability if specified in an attribute.
|
/// the user's selection of applicability if specified in an attribute.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub(crate) enum Applicability {
|
pub(crate) enum Applicability {
|
||||||
MachineApplicable,
|
MachineApplicable,
|
||||||
MaybeIncorrect,
|
MaybeIncorrect,
|
||||||
@ -367,3 +374,250 @@ pub(crate) fn build_field_mapping<'a>(structure: &Structure<'a>) -> HashMap<Stri
|
|||||||
|
|
||||||
fields_map
|
fields_map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Possible styles for suggestion subdiagnostics.
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub(super) enum SuggestionKind {
|
||||||
|
/// `#[suggestion]`
|
||||||
|
Normal,
|
||||||
|
/// `#[suggestion_short]`
|
||||||
|
Short,
|
||||||
|
/// `#[suggestion_hidden]`
|
||||||
|
Hidden,
|
||||||
|
/// `#[suggestion_verbose]`
|
||||||
|
Verbose,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for SuggestionKind {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"" => Ok(SuggestionKind::Normal),
|
||||||
|
"_short" => Ok(SuggestionKind::Short),
|
||||||
|
"_hidden" => Ok(SuggestionKind::Hidden),
|
||||||
|
"_verbose" => Ok(SuggestionKind::Verbose),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SuggestionKind {
|
||||||
|
pub fn to_suggestion_style(&self) -> TokenStream {
|
||||||
|
match self {
|
||||||
|
SuggestionKind::Normal => {
|
||||||
|
quote! { rustc_errors::SuggestionStyle::ShowCode }
|
||||||
|
}
|
||||||
|
SuggestionKind::Short => {
|
||||||
|
quote! { rustc_errors::SuggestionStyle::HideCodeInline }
|
||||||
|
}
|
||||||
|
SuggestionKind::Hidden => {
|
||||||
|
quote! { rustc_errors::SuggestionStyle::HideCodeAlways }
|
||||||
|
}
|
||||||
|
SuggestionKind::Verbose => {
|
||||||
|
quote! { rustc_errors::SuggestionStyle::ShowAlways }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Types of subdiagnostics that can be created using attributes
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(super) enum SubdiagnosticKind {
|
||||||
|
/// `#[label(...)]`
|
||||||
|
Label,
|
||||||
|
/// `#[note(...)]`
|
||||||
|
Note,
|
||||||
|
/// `#[help(...)]`
|
||||||
|
Help,
|
||||||
|
/// `#[warning(...)]`
|
||||||
|
Warn,
|
||||||
|
/// `#[suggestion{,_short,_hidden,_verbose}]`
|
||||||
|
Suggestion {
|
||||||
|
suggestion_kind: SuggestionKind,
|
||||||
|
applicability: SpannedOption<Applicability>,
|
||||||
|
code: TokenStream,
|
||||||
|
},
|
||||||
|
/// `#[multipart_suggestion{,_short,_hidden,_verbose}]`
|
||||||
|
MultipartSuggestion {
|
||||||
|
suggestion_kind: SuggestionKind,
|
||||||
|
applicability: SpannedOption<Applicability>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SubdiagnosticKind {
|
||||||
|
/// Constructs a `SubdiagnosticKind` from a field or type attribute such as `#[note]`,
|
||||||
|
/// `#[error(parser::add_paren)]` or `#[suggestion(code = "...")]`. Returns the
|
||||||
|
/// `SubdiagnosticKind` and the diagnostic slug, if specified.
|
||||||
|
pub(super) fn from_attr(
|
||||||
|
attr: &Attribute,
|
||||||
|
fields: &impl HasFieldMap,
|
||||||
|
) -> Result<(SubdiagnosticKind, Option<Path>), DiagnosticDeriveError> {
|
||||||
|
let span = attr.span().unwrap();
|
||||||
|
|
||||||
|
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||||
|
let name = name.as_str();
|
||||||
|
|
||||||
|
let meta = attr.parse_meta()?;
|
||||||
|
let mut kind = match name {
|
||||||
|
"label" => SubdiagnosticKind::Label,
|
||||||
|
"note" => SubdiagnosticKind::Note,
|
||||||
|
"help" => SubdiagnosticKind::Help,
|
||||||
|
"warning" => SubdiagnosticKind::Warn,
|
||||||
|
_ => {
|
||||||
|
if let Some(suggestion_kind) =
|
||||||
|
name.strip_prefix("suggestion").and_then(|s| s.parse().ok())
|
||||||
|
{
|
||||||
|
SubdiagnosticKind::Suggestion {
|
||||||
|
suggestion_kind,
|
||||||
|
applicability: None,
|
||||||
|
code: TokenStream::new(),
|
||||||
|
}
|
||||||
|
} else if let Some(suggestion_kind) =
|
||||||
|
name.strip_prefix("multipart_suggestion").and_then(|s| s.parse().ok())
|
||||||
|
{
|
||||||
|
SubdiagnosticKind::MultipartSuggestion { suggestion_kind, applicability: None }
|
||||||
|
} else {
|
||||||
|
throw_invalid_attr!(attr, &meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let nested = match meta {
|
||||||
|
Meta::List(MetaList { ref nested, .. }) => {
|
||||||
|
// An attribute with properties, such as `#[suggestion(code = "...")]` or
|
||||||
|
// `#[error(some::slug)]`
|
||||||
|
nested
|
||||||
|
}
|
||||||
|
Meta::Path(_) => {
|
||||||
|
// An attribute without a slug or other properties, such as `#[note]` - return
|
||||||
|
// without further processing.
|
||||||
|
//
|
||||||
|
// Only allow this if there are no mandatory properties, such as `code = "..."` in
|
||||||
|
// `#[suggestion(...)]`
|
||||||
|
match kind {
|
||||||
|
SubdiagnosticKind::Label
|
||||||
|
| SubdiagnosticKind::Note
|
||||||
|
| SubdiagnosticKind::Help
|
||||||
|
| SubdiagnosticKind::Warn
|
||||||
|
| SubdiagnosticKind::MultipartSuggestion { .. } => return Ok((kind, None)),
|
||||||
|
SubdiagnosticKind::Suggestion { .. } => {
|
||||||
|
throw_span_err!(span, "suggestion without `code = \"...\"`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
throw_invalid_attr!(attr, &meta)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut code = None;
|
||||||
|
|
||||||
|
let mut nested_iter = nested.into_iter().peekable();
|
||||||
|
|
||||||
|
// Peek at the first nested attribute: if it's a slug path, consume it.
|
||||||
|
let slug = if let Some(NestedMeta::Meta(Meta::Path(path))) = nested_iter.peek() {
|
||||||
|
let path = path.clone();
|
||||||
|
// Advance the iterator.
|
||||||
|
nested_iter.next();
|
||||||
|
Some(path)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
for nested_attr in nested_iter {
|
||||||
|
let meta = match nested_attr {
|
||||||
|
NestedMeta::Meta(ref meta) => meta,
|
||||||
|
NestedMeta::Lit(_) => {
|
||||||
|
invalid_nested_attr(attr, &nested_attr).emit();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let span = meta.span().unwrap();
|
||||||
|
let nested_name = meta.path().segments.last().unwrap().ident.to_string();
|
||||||
|
let nested_name = nested_name.as_str();
|
||||||
|
|
||||||
|
let value = match meta {
|
||||||
|
Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(value), .. }) => value,
|
||||||
|
Meta::Path(_) => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
|
||||||
|
diag.help("a diagnostic slug must be the first argument to the attribute")
|
||||||
|
}),
|
||||||
|
_ => {
|
||||||
|
invalid_nested_attr(attr, &nested_attr).emit();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match (nested_name, &mut kind) {
|
||||||
|
("code", SubdiagnosticKind::Suggestion { .. }) => {
|
||||||
|
let formatted_str = fields.build_format(&value.value(), value.span());
|
||||||
|
code.set_once(formatted_str, span);
|
||||||
|
}
|
||||||
|
(
|
||||||
|
"applicability",
|
||||||
|
SubdiagnosticKind::Suggestion { ref mut applicability, .. }
|
||||||
|
| SubdiagnosticKind::MultipartSuggestion { ref mut applicability, .. },
|
||||||
|
) => {
|
||||||
|
let value = Applicability::from_str(&value.value()).unwrap_or_else(|()| {
|
||||||
|
span_err(span, "invalid applicability").emit();
|
||||||
|
Applicability::Unspecified
|
||||||
|
});
|
||||||
|
applicability.set_once(value, span);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid nested attribute
|
||||||
|
(_, SubdiagnosticKind::Suggestion { .. }) => {
|
||||||
|
invalid_nested_attr(attr, &nested_attr)
|
||||||
|
.help("only `code` and `applicability` are valid nested attributes")
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
(_, SubdiagnosticKind::MultipartSuggestion { .. }) => {
|
||||||
|
invalid_nested_attr(attr, &nested_attr)
|
||||||
|
.help("only `applicability` is a valid nested attributes")
|
||||||
|
.emit()
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
invalid_nested_attr(attr, &nested_attr).emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match kind {
|
||||||
|
SubdiagnosticKind::Suggestion { code: ref mut code_field, .. } => {
|
||||||
|
*code_field = if let Some((code, _)) = code {
|
||||||
|
code
|
||||||
|
} else {
|
||||||
|
span_err(span, "suggestion without `code = \"...\"`").emit();
|
||||||
|
quote! { "" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SubdiagnosticKind::Label
|
||||||
|
| SubdiagnosticKind::Note
|
||||||
|
| SubdiagnosticKind::Help
|
||||||
|
| SubdiagnosticKind::Warn
|
||||||
|
| SubdiagnosticKind::MultipartSuggestion { .. } => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((kind, slug))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl quote::IdentFragment for SubdiagnosticKind {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
SubdiagnosticKind::Label => write!(f, "label"),
|
||||||
|
SubdiagnosticKind::Note => write!(f, "note"),
|
||||||
|
SubdiagnosticKind::Help => write!(f, "help"),
|
||||||
|
SubdiagnosticKind::Warn => write!(f, "warn"),
|
||||||
|
SubdiagnosticKind::Suggestion { .. } => write!(f, "suggestion_with_style"),
|
||||||
|
SubdiagnosticKind::MultipartSuggestion { .. } => {
|
||||||
|
write!(f, "multipart_suggestion_with_style")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn span(&self) -> Option<proc_macro2::Span> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -52,7 +52,7 @@ struct C {
|
|||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[label]
|
#[label]
|
||||||
//~^ ERROR `#[label]` is not a valid attribute
|
//~^ ERROR diagnostic slug must be first argument
|
||||||
struct D {
|
struct D {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -81,6 +81,7 @@ struct F {
|
|||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[label(bug = "...")]
|
#[label(bug = "...")]
|
||||||
//~^ ERROR `#[label(bug = ...)]` is not a valid attribute
|
//~^ ERROR `#[label(bug = ...)]` is not a valid attribute
|
||||||
|
//~| ERROR diagnostic slug must be first argument
|
||||||
struct G {
|
struct G {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -90,6 +91,7 @@ struct G {
|
|||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[label("...")]
|
#[label("...")]
|
||||||
//~^ ERROR `#[label("...")]` is not a valid attribute
|
//~^ ERROR `#[label("...")]` is not a valid attribute
|
||||||
|
//~| ERROR diagnostic slug must be first argument
|
||||||
struct H {
|
struct H {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -99,6 +101,7 @@ struct H {
|
|||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[label(slug = 4)]
|
#[label(slug = 4)]
|
||||||
//~^ ERROR `#[label(slug = ...)]` is not a valid attribute
|
//~^ ERROR `#[label(slug = ...)]` is not a valid attribute
|
||||||
|
//~| ERROR diagnostic slug must be first argument
|
||||||
struct J {
|
struct J {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -108,6 +111,7 @@ struct J {
|
|||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[label(slug("..."))]
|
#[label(slug("..."))]
|
||||||
//~^ ERROR `#[label(slug(...))]` is not a valid attribute
|
//~^ ERROR `#[label(slug(...))]` is not a valid attribute
|
||||||
|
//~| ERROR diagnostic slug must be first argument
|
||||||
struct K {
|
struct K {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -135,7 +139,7 @@ struct M {
|
|||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[label(parser::add_paren, code = "...")]
|
#[label(parser::add_paren, code = "...")]
|
||||||
//~^ ERROR `code` is not a valid nested attribute of a `label` attribute
|
//~^ ERROR `#[label(code = ...)]` is not a valid attribute
|
||||||
struct N {
|
struct N {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -144,7 +148,7 @@ struct N {
|
|||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[label(parser::add_paren, applicability = "machine-applicable")]
|
#[label(parser::add_paren, applicability = "machine-applicable")]
|
||||||
//~^ ERROR `applicability` is not a valid nested attribute of a `label` attribute
|
//~^ ERROR `#[label(applicability = ...)]` is not a valid attribute
|
||||||
struct O {
|
struct O {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -216,6 +220,7 @@ enum T {
|
|||||||
enum U {
|
enum U {
|
||||||
#[label(code = "...")]
|
#[label(code = "...")]
|
||||||
//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
|
//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute
|
||||||
|
//~| ERROR `#[label(code = ...)]` is not a valid attribute
|
||||||
A {
|
A {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
span: Span,
|
span: Span,
|
||||||
@ -531,7 +536,7 @@ struct BA {
|
|||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
#[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
||||||
//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
|
//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields
|
||||||
//~| ERROR `code` is not a valid nested attribute of a `multipart_suggestion` attribute
|
//~| ERROR `#[multipart_suggestion(code = ...)]` is not a valid attribute
|
||||||
struct BBa {
|
struct BBa {
|
||||||
var: String,
|
var: String,
|
||||||
}
|
}
|
||||||
@ -612,10 +617,9 @@ struct BG {
|
|||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
|
#[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
|
||||||
//~^ NOTE previously specified here
|
|
||||||
struct BH {
|
struct BH {
|
||||||
#[applicability]
|
#[applicability]
|
||||||
//~^ ERROR specified multiple times
|
//~^ ERROR `#[applicability]` has no effect
|
||||||
appl: Applicability,
|
appl: Applicability,
|
||||||
#[suggestion_part(code = "(")]
|
#[suggestion_part(code = "(")]
|
||||||
first: Span,
|
first: Span,
|
||||||
|
@ -8,7 +8,7 @@ LL | | var: String,
|
|||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `#[label]` is not a valid attribute
|
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:54:1
|
--> $DIR/subdiagnostic-derive.rs:54:1
|
||||||
|
|
|
|
||||||
LL | #[label]
|
LL | #[label]
|
||||||
@ -31,101 +31,123 @@ error: `#[label(bug = ...)]` is not a valid attribute
|
|||||||
|
|
|
|
||||||
LL | #[label(bug = "...")]
|
LL | #[label(bug = "...")]
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
||||||
|
--> $DIR/subdiagnostic-derive.rs:82:1
|
||||||
|
|
|
|
||||||
= help: first argument of the attribute should be the diagnostic slug
|
LL | #[label(bug = "...")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[label("...")]` is not a valid attribute
|
error: `#[label("...")]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:91:9
|
--> $DIR/subdiagnostic-derive.rs:92:9
|
||||||
|
|
|
|
||||||
LL | #[label("...")]
|
LL | #[label("...")]
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
|
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
||||||
|
--> $DIR/subdiagnostic-derive.rs:92:1
|
||||||
|
|
|
|
||||||
= help: first argument of the attribute should be the diagnostic slug
|
LL | #[label("...")]
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[label(slug = ...)]` is not a valid attribute
|
error: `#[label(slug = ...)]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:100:9
|
--> $DIR/subdiagnostic-derive.rs:102:9
|
||||||
|
|
|
|
||||||
LL | #[label(slug = 4)]
|
LL | #[label(slug = 4)]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
||||||
|
--> $DIR/subdiagnostic-derive.rs:102:1
|
||||||
|
|
|
|
||||||
= help: first argument of the attribute should be the diagnostic slug
|
LL | #[label(slug = 4)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[label(slug(...))]` is not a valid attribute
|
error: `#[label(slug(...))]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:109:9
|
--> $DIR/subdiagnostic-derive.rs:112:9
|
||||||
|
|
|
|
||||||
LL | #[label(slug("..."))]
|
LL | #[label(slug("..."))]
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
= help: first argument of the attribute should be the diagnostic slug
|
|
||||||
|
|
||||||
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:128:1
|
--> $DIR/subdiagnostic-derive.rs:112:1
|
||||||
|
|
|
||||||
|
LL | #[label(slug("..."))]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
||||||
|
--> $DIR/subdiagnostic-derive.rs:132:1
|
||||||
|
|
|
|
||||||
LL | #[label()]
|
LL | #[label()]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: `code` is not a valid nested attribute of a `label` attribute
|
error: `#[label(code = ...)]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:137:28
|
--> $DIR/subdiagnostic-derive.rs:141:28
|
||||||
|
|
|
|
||||||
LL | #[label(parser::add_paren, code = "...")]
|
LL | #[label(parser::add_paren, code = "...")]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `applicability` is not a valid nested attribute of a `label` attribute
|
error: `#[label(applicability = ...)]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:146:28
|
--> $DIR/subdiagnostic-derive.rs:150:28
|
||||||
|
|
|
|
||||||
LL | #[label(parser::add_paren, applicability = "machine-applicable")]
|
LL | #[label(parser::add_paren, applicability = "machine-applicable")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unsupported type attribute for subdiagnostic enum
|
error: unsupported type attribute for subdiagnostic enum
|
||||||
--> $DIR/subdiagnostic-derive.rs:155:1
|
--> $DIR/subdiagnostic-derive.rs:159:1
|
||||||
|
|
|
|
||||||
LL | #[foo]
|
LL | #[foo]
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: `#[bar]` is not a valid attribute
|
error: `#[bar]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:169:5
|
--> $DIR/subdiagnostic-derive.rs:173:5
|
||||||
|
|
|
|
||||||
LL | #[bar]
|
LL | #[bar]
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: `#[bar = ...]` is not a valid attribute
|
error: `#[bar = ...]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:181:5
|
--> $DIR/subdiagnostic-derive.rs:185:5
|
||||||
|
|
|
|
||||||
LL | #[bar = "..."]
|
LL | #[bar = "..."]
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[bar = ...]` is not a valid attribute
|
error: `#[bar = ...]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:193:5
|
--> $DIR/subdiagnostic-derive.rs:197:5
|
||||||
|
|
|
|
||||||
LL | #[bar = 4]
|
LL | #[bar = 4]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[bar(...)]` is not a valid attribute
|
error: `#[bar(...)]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:205:5
|
--> $DIR/subdiagnostic-derive.rs:209:5
|
||||||
|
|
|
|
||||||
LL | #[bar("...")]
|
LL | #[bar("...")]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: `#[label(code = ...)]` is not a valid attribute
|
||||||
|
--> $DIR/subdiagnostic-derive.rs:221:13
|
||||||
|
|
|
||||||
|
LL | #[label(code = "...")]
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:217:5
|
--> $DIR/subdiagnostic-derive.rs:221:5
|
||||||
|
|
|
|
||||||
LL | #[label(code = "...")]
|
LL | #[label(code = "...")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: subdiagnostic kind not specified
|
error: subdiagnostic kind not specified
|
||||||
--> $DIR/subdiagnostic-derive.rs:234:5
|
--> $DIR/subdiagnostic-derive.rs:239:5
|
||||||
|
|
|
|
||||||
LL | B {
|
LL | B {
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
||||||
--> $DIR/subdiagnostic-derive.rs:246:5
|
--> $DIR/subdiagnostic-derive.rs:251:5
|
||||||
|
|
|
|
||||||
LL | #[primary_span]
|
LL | #[primary_span]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: label without `#[primary_span]` field
|
error: label without `#[primary_span]` field
|
||||||
--> $DIR/subdiagnostic-derive.rs:243:1
|
--> $DIR/subdiagnostic-derive.rs:248:1
|
||||||
|
|
|
|
||||||
LL | / #[label(parser::add_paren)]
|
LL | / #[label(parser::add_paren)]
|
||||||
LL | |
|
LL | |
|
||||||
@ -137,13 +159,13 @@ LL | | }
|
|||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `#[applicability]` is only valid on suggestions
|
error: `#[applicability]` is only valid on suggestions
|
||||||
--> $DIR/subdiagnostic-derive.rs:256:5
|
--> $DIR/subdiagnostic-derive.rs:261:5
|
||||||
|
|
|
|
||||||
LL | #[applicability]
|
LL | #[applicability]
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[bar]` is not a valid attribute
|
error: `#[bar]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:266:5
|
--> $DIR/subdiagnostic-derive.rs:271:5
|
||||||
|
|
|
|
||||||
LL | #[bar]
|
LL | #[bar]
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
@ -151,13 +173,13 @@ LL | #[bar]
|
|||||||
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
|
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
|
||||||
|
|
||||||
error: `#[bar = ...]` is not a valid attribute
|
error: `#[bar = ...]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:277:5
|
--> $DIR/subdiagnostic-derive.rs:282:5
|
||||||
|
|
|
|
||||||
LL | #[bar = "..."]
|
LL | #[bar = "..."]
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[bar(...)]` is not a valid attribute
|
error: `#[bar(...)]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:288:5
|
--> $DIR/subdiagnostic-derive.rs:293:5
|
||||||
|
|
|
|
||||||
LL | #[bar("...")]
|
LL | #[bar("...")]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
@ -165,7 +187,7 @@ LL | #[bar("...")]
|
|||||||
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
|
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
|
||||||
|
|
||||||
error: unexpected unsupported untagged union
|
error: unexpected unsupported untagged union
|
||||||
--> $DIR/subdiagnostic-derive.rs:304:1
|
--> $DIR/subdiagnostic-derive.rs:309:1
|
||||||
|
|
|
|
||||||
LL | / union AC {
|
LL | / union AC {
|
||||||
LL | |
|
LL | |
|
||||||
@ -175,7 +197,7 @@ LL | | }
|
|||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `#[label(parser::add_paren)]` is not a valid attribute
|
error: `#[label(parser::add_paren)]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:319:28
|
--> $DIR/subdiagnostic-derive.rs:324:28
|
||||||
|
|
|
|
||||||
LL | #[label(parser::add_paren, parser::add_paren)]
|
LL | #[label(parser::add_paren, parser::add_paren)]
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
@ -183,67 +205,67 @@ LL | #[label(parser::add_paren, parser::add_paren)]
|
|||||||
= help: a diagnostic slug must be the first argument to the attribute
|
= help: a diagnostic slug must be the first argument to the attribute
|
||||||
|
|
||||||
error: specified multiple times
|
error: specified multiple times
|
||||||
--> $DIR/subdiagnostic-derive.rs:332:5
|
--> $DIR/subdiagnostic-derive.rs:337:5
|
||||||
|
|
|
|
||||||
LL | #[primary_span]
|
LL | #[primary_span]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: previously specified here
|
note: previously specified here
|
||||||
--> $DIR/subdiagnostic-derive.rs:329:5
|
--> $DIR/subdiagnostic-derive.rs:334:5
|
||||||
|
|
|
|
||||||
LL | #[primary_span]
|
LL | #[primary_span]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: subdiagnostic kind not specified
|
error: subdiagnostic kind not specified
|
||||||
--> $DIR/subdiagnostic-derive.rs:338:8
|
--> $DIR/subdiagnostic-derive.rs:343:8
|
||||||
|
|
|
|
||||||
LL | struct AG {
|
LL | struct AG {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: specified multiple times
|
error: specified multiple times
|
||||||
--> $DIR/subdiagnostic-derive.rs:375:47
|
--> $DIR/subdiagnostic-derive.rs:380:47
|
||||||
|
|
|
|
||||||
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
|
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: previously specified here
|
note: previously specified here
|
||||||
--> $DIR/subdiagnostic-derive.rs:375:33
|
--> $DIR/subdiagnostic-derive.rs:380:33
|
||||||
|
|
|
|
||||||
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
|
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error: specified multiple times
|
error: specified multiple times
|
||||||
--> $DIR/subdiagnostic-derive.rs:393:5
|
--> $DIR/subdiagnostic-derive.rs:398:5
|
||||||
|
|
|
|
||||||
LL | #[applicability]
|
LL | #[applicability]
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: previously specified here
|
note: previously specified here
|
||||||
--> $DIR/subdiagnostic-derive.rs:390:5
|
--> $DIR/subdiagnostic-derive.rs:395:5
|
||||||
|
|
|
|
||||||
LL | #[applicability]
|
LL | #[applicability]
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
|
error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
|
||||||
--> $DIR/subdiagnostic-derive.rs:403:5
|
--> $DIR/subdiagnostic-derive.rs:408:5
|
||||||
|
|
|
|
||||||
LL | #[applicability]
|
LL | #[applicability]
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: suggestion without `code = "..."`
|
error: suggestion without `code = "..."`
|
||||||
--> $DIR/subdiagnostic-derive.rs:416:1
|
--> $DIR/subdiagnostic-derive.rs:421:1
|
||||||
|
|
|
|
||||||
LL | #[suggestion(parser::add_paren)]
|
LL | #[suggestion(parser::add_paren)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: invalid applicability
|
error: invalid applicability
|
||||||
--> $DIR/subdiagnostic-derive.rs:426:46
|
--> $DIR/subdiagnostic-derive.rs:431:46
|
||||||
|
|
|
|
||||||
LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")]
|
LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: suggestion without `#[primary_span]` field
|
error: suggestion without `#[primary_span]` field
|
||||||
--> $DIR/subdiagnostic-derive.rs:444:1
|
--> $DIR/subdiagnostic-derive.rs:449:1
|
||||||
|
|
|
|
||||||
LL | / #[suggestion(parser::add_paren, code = "...")]
|
LL | / #[suggestion(parser::add_paren, code = "...")]
|
||||||
LL | |
|
LL | |
|
||||||
@ -253,25 +275,25 @@ LL | | }
|
|||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: unsupported type attribute for subdiagnostic enum
|
error: unsupported type attribute for subdiagnostic enum
|
||||||
--> $DIR/subdiagnostic-derive.rs:458:1
|
--> $DIR/subdiagnostic-derive.rs:463:1
|
||||||
|
|
|
|
||||||
LL | #[label]
|
LL | #[label]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
error: `var` doesn't refer to a field on this type
|
error: `var` doesn't refer to a field on this type
|
||||||
--> $DIR/subdiagnostic-derive.rs:478:39
|
--> $DIR/subdiagnostic-derive.rs:483:39
|
||||||
|
|
|
|
||||||
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
|
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: `var` doesn't refer to a field on this type
|
error: `var` doesn't refer to a field on this type
|
||||||
--> $DIR/subdiagnostic-derive.rs:497:43
|
--> $DIR/subdiagnostic-derive.rs:502:43
|
||||||
|
|
|
|
||||||
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
|
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: `#[suggestion_part]` is not a valid attribute
|
error: `#[suggestion_part]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:520:5
|
--> $DIR/subdiagnostic-derive.rs:525:5
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part]
|
LL | #[suggestion_part]
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
@ -279,7 +301,7 @@ LL | #[suggestion_part]
|
|||||||
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead
|
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead
|
||||||
|
|
||||||
error: `#[suggestion_part(...)]` is not a valid attribute
|
error: `#[suggestion_part(...)]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:523:5
|
--> $DIR/subdiagnostic-derive.rs:528:5
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part(code = "...")]
|
LL | #[suggestion_part(code = "...")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -287,7 +309,7 @@ LL | #[suggestion_part(code = "...")]
|
|||||||
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions
|
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions
|
||||||
|
|
||||||
error: suggestion without `#[primary_span]` field
|
error: suggestion without `#[primary_span]` field
|
||||||
--> $DIR/subdiagnostic-derive.rs:517:1
|
--> $DIR/subdiagnostic-derive.rs:522:1
|
||||||
|
|
|
|
||||||
LL | / #[suggestion(parser::add_paren, code = "...")]
|
LL | / #[suggestion(parser::add_paren, code = "...")]
|
||||||
LL | |
|
LL | |
|
||||||
@ -298,14 +320,16 @@ LL | | var: String,
|
|||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `code` is not a valid nested attribute of a `multipart_suggestion` attribute
|
error: `#[multipart_suggestion(code = ...)]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:532:43
|
--> $DIR/subdiagnostic-derive.rs:537:43
|
||||||
|
|
|
|
||||||
LL | #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
LL | #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: only `applicability` is a valid nested attributes
|
||||||
|
|
||||||
error: multipart suggestion without any `#[suggestion_part(...)]` fields
|
error: multipart suggestion without any `#[suggestion_part(...)]` fields
|
||||||
--> $DIR/subdiagnostic-derive.rs:532:1
|
--> $DIR/subdiagnostic-derive.rs:537:1
|
||||||
|
|
|
|
||||||
LL | / #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
LL | / #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
||||||
LL | |
|
LL | |
|
||||||
@ -316,19 +340,19 @@ LL | | }
|
|||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||||
--> $DIR/subdiagnostic-derive.rs:542:5
|
--> $DIR/subdiagnostic-derive.rs:547:5
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part]
|
LL | #[suggestion_part]
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||||
--> $DIR/subdiagnostic-derive.rs:550:5
|
--> $DIR/subdiagnostic-derive.rs:555:5
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part()]
|
LL | #[suggestion_part()]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[primary_span]` is not a valid attribute
|
error: `#[primary_span]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:559:5
|
--> $DIR/subdiagnostic-derive.rs:564:5
|
||||||
|
|
|
|
||||||
LL | #[primary_span]
|
LL | #[primary_span]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
@ -336,7 +360,7 @@ LL | #[primary_span]
|
|||||||
= help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]`
|
= help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]`
|
||||||
|
|
||||||
error: multipart suggestion without any `#[suggestion_part(...)]` fields
|
error: multipart suggestion without any `#[suggestion_part(...)]` fields
|
||||||
--> $DIR/subdiagnostic-derive.rs:556:1
|
--> $DIR/subdiagnostic-derive.rs:561:1
|
||||||
|
|
|
|
||||||
LL | / #[multipart_suggestion(parser::add_paren)]
|
LL | / #[multipart_suggestion(parser::add_paren)]
|
||||||
LL | |
|
LL | |
|
||||||
@ -348,19 +372,19 @@ LL | | }
|
|||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||||
--> $DIR/subdiagnostic-derive.rs:567:5
|
--> $DIR/subdiagnostic-derive.rs:572:5
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part]
|
LL | #[suggestion_part]
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||||
--> $DIR/subdiagnostic-derive.rs:570:5
|
--> $DIR/subdiagnostic-derive.rs:575:5
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part()]
|
LL | #[suggestion_part()]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: `#[suggestion_part(foo = ...)]` is not a valid attribute
|
error: `#[suggestion_part(foo = ...)]` is not a valid attribute
|
||||||
--> $DIR/subdiagnostic-derive.rs:573:23
|
--> $DIR/subdiagnostic-derive.rs:578:23
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part(foo = "bar")]
|
LL | #[suggestion_part(foo = "bar")]
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
@ -368,40 +392,34 @@ LL | #[suggestion_part(foo = "bar")]
|
|||||||
= help: `code` is the only valid nested attribute
|
= help: `code` is the only valid nested attribute
|
||||||
|
|
||||||
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
||||||
--> $DIR/subdiagnostic-derive.rs:576:5
|
--> $DIR/subdiagnostic-derive.rs:581:5
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part(code = "...")]
|
LL | #[suggestion_part(code = "...")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
||||||
--> $DIR/subdiagnostic-derive.rs:579:5
|
--> $DIR/subdiagnostic-derive.rs:584:5
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part()]
|
LL | #[suggestion_part()]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: specified multiple times
|
error: specified multiple times
|
||||||
--> $DIR/subdiagnostic-derive.rs:587:37
|
--> $DIR/subdiagnostic-derive.rs:592:37
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part(code = "...", code = ",,,")]
|
LL | #[suggestion_part(code = "...", code = ",,,")]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: previously specified here
|
note: previously specified here
|
||||||
--> $DIR/subdiagnostic-derive.rs:587:23
|
--> $DIR/subdiagnostic-derive.rs:592:23
|
||||||
|
|
|
|
||||||
LL | #[suggestion_part(code = "...", code = ",,,")]
|
LL | #[suggestion_part(code = "...", code = ",,,")]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error: specified multiple times
|
error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."`
|
||||||
--> $DIR/subdiagnostic-derive.rs:617:5
|
--> $DIR/subdiagnostic-derive.rs:621:5
|
||||||
|
|
|
|
||||||
LL | #[applicability]
|
LL | #[applicability]
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
note: previously specified here
|
|
||||||
--> $DIR/subdiagnostic-derive.rs:614:43
|
|
||||||
|
|
|
||||||
LL | #[multipart_suggestion(parser::add_paren, applicability = "machine-applicable")]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: cannot find attribute `foo` in this scope
|
error: cannot find attribute `foo` in this scope
|
||||||
--> $DIR/subdiagnostic-derive.rs:63:3
|
--> $DIR/subdiagnostic-derive.rs:63:3
|
||||||
@ -410,59 +428,59 @@ LL | #[foo]
|
|||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: cannot find attribute `foo` in this scope
|
error: cannot find attribute `foo` in this scope
|
||||||
--> $DIR/subdiagnostic-derive.rs:155:3
|
--> $DIR/subdiagnostic-derive.rs:159:3
|
||||||
|
|
|
|
||||||
LL | #[foo]
|
LL | #[foo]
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: cannot find attribute `bar` in this scope
|
error: cannot find attribute `bar` in this scope
|
||||||
--> $DIR/subdiagnostic-derive.rs:169:7
|
--> $DIR/subdiagnostic-derive.rs:173:7
|
||||||
|
|
|
|
||||||
LL | #[bar]
|
LL | #[bar]
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: cannot find attribute `bar` in this scope
|
error: cannot find attribute `bar` in this scope
|
||||||
--> $DIR/subdiagnostic-derive.rs:181:7
|
--> $DIR/subdiagnostic-derive.rs:185:7
|
||||||
|
|
|
|
||||||
LL | #[bar = "..."]
|
LL | #[bar = "..."]
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: cannot find attribute `bar` in this scope
|
error: cannot find attribute `bar` in this scope
|
||||||
--> $DIR/subdiagnostic-derive.rs:193:7
|
--> $DIR/subdiagnostic-derive.rs:197:7
|
||||||
|
|
|
|
||||||
LL | #[bar = 4]
|
LL | #[bar = 4]
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: cannot find attribute `bar` in this scope
|
error: cannot find attribute `bar` in this scope
|
||||||
--> $DIR/subdiagnostic-derive.rs:205:7
|
--> $DIR/subdiagnostic-derive.rs:209:7
|
||||||
|
|
|
|
||||||
LL | #[bar("...")]
|
LL | #[bar("...")]
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: cannot find attribute `bar` in this scope
|
error: cannot find attribute `bar` in this scope
|
||||||
--> $DIR/subdiagnostic-derive.rs:266:7
|
--> $DIR/subdiagnostic-derive.rs:271:7
|
||||||
|
|
|
|
||||||
LL | #[bar]
|
LL | #[bar]
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: cannot find attribute `bar` in this scope
|
error: cannot find attribute `bar` in this scope
|
||||||
--> $DIR/subdiagnostic-derive.rs:277:7
|
--> $DIR/subdiagnostic-derive.rs:282:7
|
||||||
|
|
|
|
||||||
LL | #[bar = "..."]
|
LL | #[bar = "..."]
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: cannot find attribute `bar` in this scope
|
error: cannot find attribute `bar` in this scope
|
||||||
--> $DIR/subdiagnostic-derive.rs:288:7
|
--> $DIR/subdiagnostic-derive.rs:293:7
|
||||||
|
|
|
|
||||||
LL | #[bar("...")]
|
LL | #[bar("...")]
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
|
error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
|
||||||
--> $DIR/subdiagnostic-derive.rs:118:9
|
--> $DIR/subdiagnostic-derive.rs:122:9
|
||||||
|
|
|
|
||||||
LL | #[label(slug)]
|
LL | #[label(slug)]
|
||||||
| ^^^^ not found in `rustc_errors::fluent`
|
| ^^^^ not found in `rustc_errors::fluent`
|
||||||
|
|
||||||
error: aborting due to 63 previous errors
|
error: aborting due to 68 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0425`.
|
For more information about this error, try `rustc --explain E0425`.
|
||||||
|
Loading…
Reference in New Issue
Block a user