Use span_suggestion_with_style in SessionSubdiagnostic derive

This commit is contained in:
Xiretza 2022-08-22 18:18:54 +02:00
parent 8af7f4208a
commit 6e8dad5c07

View File

@ -28,6 +28,39 @@ enum SubdiagnosticSuggestionKind {
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? /// Which kind of subdiagnostic is being created from a variant?
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
enum SubdiagnosticKind { enum SubdiagnosticKind {
@ -52,17 +85,15 @@ impl FromStr for SubdiagnosticKind {
"note" => Ok(SubdiagnosticKind::Note), "note" => Ok(SubdiagnosticKind::Note),
"help" => Ok(SubdiagnosticKind::Help), "help" => Ok(SubdiagnosticKind::Help),
"warning" => Ok(SubdiagnosticKind::Warn), "warning" => Ok(SubdiagnosticKind::Warn),
"suggestion" => Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Normal)), _ => {
"suggestion_short" => { if let Some(suggestion_kind) =
Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Short)) s.strip_prefix("suggestion").and_then(|s| s.parse().ok())
{
return Ok(SubdiagnosticKind::Suggestion(suggestion_kind));
};
Err(())
} }
"suggestion_hidden" => {
Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Hidden))
}
"suggestion_verbose" => {
Ok(SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Verbose))
}
_ => Err(()),
} }
} }
} }
@ -74,18 +105,7 @@ impl quote::IdentFragment for SubdiagnosticKind {
SubdiagnosticKind::Note => write!(f, "note"), SubdiagnosticKind::Note => write!(f, "note"),
SubdiagnosticKind::Help => write!(f, "help"), SubdiagnosticKind::Help => write!(f, "help"),
SubdiagnosticKind::Warn => write!(f, "warn"), SubdiagnosticKind::Warn => write!(f, "warn"),
SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Normal) => { SubdiagnosticKind::Suggestion(..) => write!(f, "suggestion_with_style"),
write!(f, "suggestion")
}
SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Short) => {
write!(f, "suggestion_short")
}
SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Hidden) => {
write!(f, "suggestion_hidden")
}
SubdiagnosticKind::Suggestion(SubdiagnosticSuggestionKind::Verbose) => {
write!(f, "suggestion_verbose")
}
} }
} }
@ -461,25 +481,31 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
let diag = &self.diag; let diag = &self.diag;
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 = if matches!(kind, SubdiagnosticKind::Suggestion(..)) { let call = match kind {
if let Some(span) = span_field { SubdiagnosticKind::Suggestion(style) => {
quote! { #diag.#name(#span, #message, #code, #applicability); } if let Some(span) = span_field {
} else { let style = style.to_suggestion_style();
span_err(self.span, "suggestion without `#[primary_span]` field").emit();
quote! { unreachable!(); } quote! { #diag.#name(#span, #message, #code, #applicability, #style); }
} else {
span_err(self.span, "suggestion without `#[primary_span]` field").emit();
quote! { unreachable!(); }
}
} }
} else if matches!(kind, SubdiagnosticKind::Label) { SubdiagnosticKind::Label => {
if let Some(span) = span_field { if let Some(span) = span_field {
quote! { #diag.#name(#span, #message); } quote! { #diag.#name(#span, #message); }
} else { } else {
span_err(self.span, "label without `#[primary_span]` field").emit(); span_err(self.span, "label without `#[primary_span]` field").emit();
quote! { unreachable!(); } quote! { unreachable!(); }
}
} }
} else { _ => {
if let Some(span) = span_field { if let Some(span) = span_field {
quote! { #diag.#name(#span, #message); } quote! { #diag.#name(#span, #message); }
} else { } else {
quote! { #diag.#name(#message); } quote! { #diag.#name(#message); }
}
} }
}; };