mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Add style= parameter to suggestion attributes
This commit is contained in:
parent
629a414d7b
commit
368c4a35b9
@ -472,7 +472,7 @@ pub(super) fn build_suggestion_code(
|
||||
}
|
||||
|
||||
/// Possible styles for suggestion subdiagnostics.
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub(super) enum SuggestionKind {
|
||||
/// `#[suggestion]`
|
||||
Normal,
|
||||
@ -489,10 +489,10 @@ impl FromStr for SuggestionKind {
|
||||
|
||||
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),
|
||||
"normal" => Ok(SuggestionKind::Normal),
|
||||
"short" => Ok(SuggestionKind::Short),
|
||||
"hidden" => Ok(SuggestionKind::Hidden),
|
||||
"verbose" => Ok(SuggestionKind::Verbose),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
@ -515,6 +515,16 @@ impl SuggestionKind {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn from_suffix(s: &str) -> Option<Self> {
|
||||
match s {
|
||||
"" => Some(SuggestionKind::Normal),
|
||||
"_short" => Some(SuggestionKind::Short),
|
||||
"_hidden" => Some(SuggestionKind::Hidden),
|
||||
"_verbose" => Some(SuggestionKind::Verbose),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Types of subdiagnostics that can be created using attributes
|
||||
@ -565,6 +575,8 @@ impl SubdiagnosticKind {
|
||||
let name = name.as_str();
|
||||
|
||||
let meta = attr.parse_meta()?;
|
||||
|
||||
let mut opt_suggestion_kind = None;
|
||||
let mut kind = match name {
|
||||
"label" => SubdiagnosticKind::Label,
|
||||
"note" => SubdiagnosticKind::Note,
|
||||
@ -572,18 +584,31 @@ impl SubdiagnosticKind {
|
||||
"warning" => SubdiagnosticKind::Warn,
|
||||
_ => {
|
||||
if let Some(suggestion_kind) =
|
||||
name.strip_prefix("suggestion").and_then(|s| s.parse().ok())
|
||||
name.strip_prefix("suggestion").and_then(SuggestionKind::from_suffix)
|
||||
{
|
||||
if suggestion_kind != SuggestionKind::Normal {
|
||||
// Plain `#[suggestion]` can have a `style = "..."` attribute later, so don't set it here
|
||||
opt_suggestion_kind.set_once(suggestion_kind, attr.path.span().unwrap());
|
||||
}
|
||||
|
||||
SubdiagnosticKind::Suggestion {
|
||||
suggestion_kind,
|
||||
suggestion_kind: SuggestionKind::Normal,
|
||||
applicability: None,
|
||||
code_field: new_code_ident(),
|
||||
code_init: TokenStream::new(),
|
||||
}
|
||||
} else if let Some(suggestion_kind) =
|
||||
name.strip_prefix("multipart_suggestion").and_then(|s| s.parse().ok())
|
||||
name.strip_prefix("multipart_suggestion").and_then(SuggestionKind::from_suffix)
|
||||
{
|
||||
SubdiagnosticKind::MultipartSuggestion { suggestion_kind, applicability: None }
|
||||
if suggestion_kind != SuggestionKind::Normal {
|
||||
// Plain `#[multipart_suggestion]` can have a `style = "..."` attribute later, so don't set it here
|
||||
opt_suggestion_kind.set_once(suggestion_kind, attr.path.span().unwrap());
|
||||
}
|
||||
|
||||
SubdiagnosticKind::MultipartSuggestion {
|
||||
suggestion_kind: SuggestionKind::Normal,
|
||||
applicability: None,
|
||||
}
|
||||
} else {
|
||||
throw_invalid_attr!(attr, &meta);
|
||||
}
|
||||
@ -682,16 +707,37 @@ impl SubdiagnosticKind {
|
||||
});
|
||||
applicability.set_once(value, span);
|
||||
}
|
||||
(
|
||||
"style",
|
||||
SubdiagnosticKind::Suggestion { .. }
|
||||
| SubdiagnosticKind::MultipartSuggestion { .. },
|
||||
) => {
|
||||
let Some(value) = string_value else {
|
||||
invalid_nested_attr(attr, &nested_attr).emit();
|
||||
continue;
|
||||
};
|
||||
|
||||
let value = value.value().parse().unwrap_or_else(|()| {
|
||||
span_err(value.span().unwrap(), "invalid suggestion style")
|
||||
.help("valid styles are `normal`, `short`, `hidden` and `verbose`")
|
||||
.emit();
|
||||
SuggestionKind::Normal
|
||||
});
|
||||
|
||||
opt_suggestion_kind.set_once(value, span);
|
||||
}
|
||||
|
||||
// Invalid nested attribute
|
||||
(_, SubdiagnosticKind::Suggestion { .. }) => {
|
||||
invalid_nested_attr(attr, &nested_attr)
|
||||
.help("only `code` and `applicability` are valid nested attributes")
|
||||
.help(
|
||||
"only `style`, `code` and `applicability` are valid nested attributes",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
(_, SubdiagnosticKind::MultipartSuggestion { .. }) => {
|
||||
invalid_nested_attr(attr, &nested_attr)
|
||||
.help("only `applicability` is a valid nested attributes")
|
||||
.help("only `style` and `applicability` are valid nested attributes")
|
||||
.emit()
|
||||
}
|
||||
_ => {
|
||||
@ -701,7 +747,16 @@ impl SubdiagnosticKind {
|
||||
}
|
||||
|
||||
match kind {
|
||||
SubdiagnosticKind::Suggestion { ref code_field, ref mut code_init, .. } => {
|
||||
SubdiagnosticKind::Suggestion {
|
||||
ref code_field,
|
||||
ref mut code_init,
|
||||
ref mut suggestion_kind,
|
||||
..
|
||||
} => {
|
||||
if let Some(kind) = opt_suggestion_kind.value() {
|
||||
*suggestion_kind = kind;
|
||||
}
|
||||
|
||||
*code_init = if let Some(init) = code.value() {
|
||||
init
|
||||
} else {
|
||||
@ -709,11 +764,15 @@ impl SubdiagnosticKind {
|
||||
quote! { let #code_field = std::iter::empty(); }
|
||||
};
|
||||
}
|
||||
SubdiagnosticKind::MultipartSuggestion { ref mut suggestion_kind, .. } => {
|
||||
if let Some(kind) = opt_suggestion_kind.value() {
|
||||
*suggestion_kind = kind;
|
||||
}
|
||||
}
|
||||
SubdiagnosticKind::Label
|
||||
| SubdiagnosticKind::Note
|
||||
| SubdiagnosticKind::Help
|
||||
| SubdiagnosticKind::Warn
|
||||
| SubdiagnosticKind::MultipartSuggestion { .. } => {}
|
||||
| SubdiagnosticKind::Warn => {}
|
||||
}
|
||||
|
||||
Ok(Some((kind, slug)))
|
||||
|
@ -796,3 +796,10 @@ struct SuggestionsInvalidLiteral {
|
||||
//~^ ERROR `code = "..."`/`code(...)` must contain only string literals
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(compiletest_example)]
|
||||
struct SuggestionStyleGood {
|
||||
#[suggestion(code = "", style = "hidden")]
|
||||
sub: Span,
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ error: `#[suggestion(nonsense = ...)]` is not a valid attribute
|
||||
LL | #[suggestion(nonsense = "bar")]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: only `code` and `applicability` are valid nested attributes
|
||||
= help: only `style`, `code` and `applicability` are valid nested attributes
|
||||
|
||||
error: suggestion without `code = "..."`
|
||||
--> $DIR/diagnostic-derive.rs:231:5
|
||||
@ -286,7 +286,7 @@ error: `#[suggestion(msg = ...)]` is not a valid attribute
|
||||
LL | #[suggestion(msg = "bar")]
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: only `code` and `applicability` are valid nested attributes
|
||||
= help: only `style`, `code` and `applicability` are valid nested attributes
|
||||
|
||||
error: suggestion without `code = "..."`
|
||||
--> $DIR/diagnostic-derive.rs:240:5
|
||||
|
@ -706,3 +706,81 @@ struct BQ {
|
||||
span: Span,
|
||||
r#type: String,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(parser_add_paren, code = "")]
|
||||
struct SuggestionStyleDefault {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(parser_add_paren, code = "", style = "short")]
|
||||
struct SuggestionStyleShort {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(parser_add_paren, code = "", style = "hidden")]
|
||||
struct SuggestionStyleHidden {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(parser_add_paren, code = "", style = "verbose")]
|
||||
struct SuggestionStyleVerbose {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")]
|
||||
//~^ ERROR specified multiple times
|
||||
//~| NOTE previously specified here
|
||||
struct SuggestionStyleTwice {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion_hidden(parser_add_paren, code = "", style = "normal")]
|
||||
//~^ ERROR specified multiple times
|
||||
//~| NOTE previously specified here
|
||||
struct SuggestionStyleTwiceExplicit {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(parser_add_paren, code = "", style = "foo")]
|
||||
//~^ ERROR invalid suggestion style
|
||||
struct SuggestionStyleInvalid1 {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(parser_add_paren, code = "", style = 42)]
|
||||
//~^ ERROR `#[suggestion(style = ...)]` is not a valid attribute
|
||||
struct SuggestionStyleInvalid2 {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(parser_add_paren, code = "", style)]
|
||||
//~^ ERROR `#[suggestion(style)]` is not a valid attribute
|
||||
struct SuggestionStyleInvalid3 {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(parser_add_paren, code = "", style("foo"))]
|
||||
//~^ ERROR `#[suggestion(style(...))]` is not a valid attribute
|
||||
struct SuggestionStyleInvalid4 {
|
||||
#[primary_span]
|
||||
sub: Span,
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ error: `#[multipart_suggestion(code = ...)]` is not a valid attribute
|
||||
LL | #[multipart_suggestion(parser_add_paren, code = "...", applicability = "machine-applicable")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: only `applicability` is a valid nested attributes
|
||||
= help: only `style` and `applicability` are valid nested attributes
|
||||
|
||||
error: multipart suggestion without any `#[suggestion_part(...)]` fields
|
||||
--> $DIR/subdiagnostic-derive.rs:536:1
|
||||
@ -445,6 +445,58 @@ error: `code = "..."`/`code(...)` must contain only string literals
|
||||
LL | #[suggestion_part(code = 3)]
|
||||
| ^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:739:61
|
||||
|
|
||||
LL | #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:739:43
|
||||
|
|
||||
LL | #[suggestion(parser_add_paren, code = "", style = "hidden", style = "normal")]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:748:50
|
||||
|
|
||||
LL | #[suggestion_hidden(parser_add_paren, code = "", style = "normal")]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:748:3
|
||||
|
|
||||
LL | #[suggestion_hidden(parser_add_paren, code = "", style = "normal")]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid suggestion style
|
||||
--> $DIR/subdiagnostic-derive.rs:757:51
|
||||
|
|
||||
LL | #[suggestion(parser_add_paren, code = "", style = "foo")]
|
||||
| ^^^^^
|
||||
|
|
||||
= help: valid styles are `normal`, `short`, `hidden` and `verbose`
|
||||
|
||||
error: `#[suggestion(style = ...)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:765:43
|
||||
|
|
||||
LL | #[suggestion(parser_add_paren, code = "", style = 42)]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: `#[suggestion(style)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:773:43
|
||||
|
|
||||
LL | #[suggestion(parser_add_paren, code = "", style)]
|
||||
| ^^^^^
|
||||
|
|
||||
= help: a diagnostic slug must be the first argument to the attribute
|
||||
|
||||
error: `#[suggestion(style(...))]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:781:43
|
||||
|
|
||||
LL | #[suggestion(parser_add_paren, code = "", style("foo"))]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `foo` in this scope
|
||||
--> $DIR/subdiagnostic-derive.rs:63:3
|
||||
|
|
||||
@ -505,6 +557,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
|
||||
LL | #[label(slug)]
|
||||
| ^^^^ not found in `rustc_errors::fluent`
|
||||
|
||||
error: aborting due to 72 previous errors
|
||||
error: aborting due to 78 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
|
Loading…
Reference in New Issue
Block a user