Skip to content

Commit

Permalink
Rollup merge of #103575 - Xiretza:suggestions-style-attr, r=davidtwco
Browse files Browse the repository at this point in the history
Change #[suggestion_*] attributes to use style="..."

As discussed [on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/336883-i18n/topic/.23100717.20tool_only_span_suggestion), this changes `#[(multipart_)suggestion_{short,verbose,hidden}(...)]` attributes to plain `#[(multipart_)suggestion(...)]` attributes with a `style = "{short,verbose,hidden}"` parameter.

It also adds a new style, `tool-only`, that corresponds to `tool_only_span_suggestion`/`tool_only_multipart_suggestion` and causes the suggestion to not be shown in human-readable output at all.

Best reviewed commit-by-commit, there's a bit of noise in there.

cc #100717 `@compiler-errors`
r? `@davidtwco`
  • Loading branch information
Manishearth committed Nov 2, 2022
2 parents d4bd794 + 2eeb780 commit 69e7055
Show file tree
Hide file tree
Showing 15 changed files with 405 additions and 135 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_ast_lowering/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,9 @@ pub struct RegisterConflict<'a> {
pub struct SubTupleBinding<'a> {
#[primary_span]
#[label]
#[suggestion_verbose(
#[suggestion(
ast_lowering_sub_tuple_binding_suggestion,
style = "verbose",
code = "..",
applicability = "maybe-incorrect"
)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub(crate) struct GenericDoesNotLiveLongEnough {
#[derive(LintDiagnostic)]
#[diag(borrowck_var_does_not_need_mut)]
pub(crate) struct VarNeedNotMut {
#[suggestion_short(applicability = "machine-applicable", code = "")]
#[suggestion(style = "short", applicability = "machine-applicable", code = "")]
pub span: Span,
}
#[derive(Diagnostic)]
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub struct TypeofReservedKeywordUsed<'tcx> {
#[primary_span]
#[label]
pub span: Span,
#[suggestion_verbose(code = "{ty}")]
#[suggestion(style = "verbose", code = "{ty}")]
pub opt_sugg: Option<(Span, Applicability)>,
}

Expand Down Expand Up @@ -239,7 +239,11 @@ pub struct UnusedExternCrate {
#[derive(LintDiagnostic)]
#[diag(hir_analysis_extern_crate_not_idiomatic)]
pub struct ExternCrateNotIdiomatic {
#[suggestion_short(applicability = "machine-applicable", code = "{suggestion_code}")]
#[suggestion(
style = "short",
applicability = "machine-applicable",
code = "{suggestion_code}"
)]
pub span: Span,
pub msg_code: String,
pub suggestion_code: String,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,9 @@ pub struct MissingParentheseInRange {
}

#[derive(Subdiagnostic)]
#[multipart_suggestion_verbose(
#[multipart_suggestion(
hir_analysis_add_missing_parentheses_in_range,
style = "verbose",
applicability = "maybe-incorrect"
)]
pub struct AddMissingParenthesesInRange {
Expand Down
15 changes: 10 additions & 5 deletions compiler/rustc_infer/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ pub struct InferenceBadError<'a> {

#[derive(Subdiagnostic)]
pub enum SourceKindSubdiag<'a> {
#[suggestion_verbose(
#[suggestion(
infer_source_kind_subdiag_let,
style = "verbose",
code = ": {type_name}",
applicability = "has-placeholders"
)]
Expand All @@ -135,8 +136,9 @@ pub enum SourceKindSubdiag<'a> {
parent_prefix: String,
parent_name: String,
},
#[suggestion_verbose(
#[suggestion(
infer_source_kind_subdiag_generic_suggestion,
style = "verbose",
code = "::<{args}>",
applicability = "has-placeholders"
)]
Expand All @@ -150,8 +152,9 @@ pub enum SourceKindSubdiag<'a> {

#[derive(Subdiagnostic)]
pub enum SourceKindMultiSuggestion<'a> {
#[multipart_suggestion_verbose(
#[multipart_suggestion(
infer_source_kind_fully_qualified,
style = "verbose",
applicability = "has-placeholders"
)]
FullyQualified {
Expand All @@ -163,8 +166,9 @@ pub enum SourceKindMultiSuggestion<'a> {
adjustment: &'a str,
successor_pos: &'a str,
},
#[multipart_suggestion_verbose(
#[multipart_suggestion(
infer_source_kind_closure_return,
style = "verbose",
applicability = "has-placeholders"
)]
ClosureReturn {
Expand Down Expand Up @@ -478,8 +482,9 @@ pub enum ImplicitStaticLifetimeSubdiag {
#[primary_span]
span: Span,
},
#[suggestion_verbose(
#[suggestion(
infer_implicit_static_lifetime_suggestion,
style = "verbose",
code = " + '_",
applicability = "maybe-incorrect"
)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub struct UnknownToolInScopedLint {
pub struct BuiltinEllpisisInclusiveRangePatterns {
#[primary_span]
pub span: Span,
#[suggestion_short(code = "{replace}", applicability = "machine-applicable")]
#[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")]
pub suggestion: Span,
pub replace: String,
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,9 @@ struct OpaqueHiddenInferredBoundLint<'tcx> {
}

#[derive(Subdiagnostic)]
#[suggestion_verbose(
#[suggestion(
lint_opaque_hidden_inferred_bound_sugg,
style = "verbose",
applicability = "machine-applicable",
code = " + {trait_ref}"
)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_macros/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
/// }
///
/// #[derive(Subdiagnostic)]
/// #[suggestion_verbose(parser::raw_identifier)]
/// #[suggestion(style = "verbose",parser::raw_identifier)]
/// pub struct RawIdentifierSuggestion<'tcx> {
/// #[primary_span]
/// span: Span,
Expand Down
122 changes: 103 additions & 19 deletions compiler/rustc_macros/src/diagnostics/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use syn::{spanned::Spanned, Attribute, Field, Meta, Type, TypeTuple};
use syn::{MetaList, MetaNameValue, NestedMeta, Path};
use synstructure::{BindingInfo, VariantInfo};

use super::error::invalid_nested_attr;
use super::error::{invalid_attr, invalid_nested_attr};

thread_local! {
pub static CODE_IDENT_COUNT: RefCell<u32> = RefCell::new(0);
Expand Down Expand Up @@ -472,32 +472,42 @@ pub(super) fn build_suggestion_code(
}

/// Possible styles for suggestion subdiagnostics.
#[derive(Clone, Copy)]
#[derive(Clone, Copy, PartialEq)]
pub(super) enum SuggestionKind {
/// `#[suggestion]`
Normal,
/// `#[suggestion_short]`
Short,
/// `#[suggestion_hidden]`
Hidden,
/// `#[suggestion_verbose]`
Verbose,
ToolOnly,
}

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),
"normal" => Ok(SuggestionKind::Normal),
"short" => Ok(SuggestionKind::Short),
"hidden" => Ok(SuggestionKind::Hidden),
"verbose" => Ok(SuggestionKind::Verbose),
"tool-only" => Ok(SuggestionKind::ToolOnly),
_ => Err(()),
}
}
}

impl fmt::Display for SuggestionKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SuggestionKind::Normal => write!(f, "normal"),
SuggestionKind::Short => write!(f, "short"),
SuggestionKind::Hidden => write!(f, "hidden"),
SuggestionKind::Verbose => write!(f, "verbose"),
SuggestionKind::ToolOnly => write!(f, "tool-only"),
}
}
}

impl SuggestionKind {
pub fn to_suggestion_style(&self) -> TokenStream {
match self {
Expand All @@ -513,6 +523,19 @@ impl SuggestionKind {
SuggestionKind::Verbose => {
quote! { rustc_errors::SuggestionStyle::ShowAlways }
}
SuggestionKind::ToolOnly => {
quote! { rustc_errors::SuggestionStyle::CompletelyHidden }
}
}
}

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,
}
}
}
Expand Down Expand Up @@ -565,25 +588,49 @@ impl SubdiagnosticKind {
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,
_ => {
// Recover old `#[(multipart_)suggestion_*]` syntaxes
// FIXME(#100717): remove
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 {
invalid_attr(attr, &meta)
.help(format!(
r#"Use `#[suggestion(..., style = "{}")]` instead"#,
suggestion_kind
))
.emit();
}

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 {
invalid_attr(attr, &meta)
.help(format!(
r#"Use `#[multipart_suggestion(..., style = "{}")]` instead"#,
suggestion_kind
))
.emit();
}

SubdiagnosticKind::MultipartSuggestion {
suggestion_kind: SuggestionKind::Normal,
applicability: None,
}
} else {
throw_invalid_attr!(attr, &meta);
}
Expand Down Expand Up @@ -621,6 +668,7 @@ impl SubdiagnosticKind {
};

let mut code = None;
let mut suggestion_kind = None;

let mut nested_iter = nested.into_iter().peekable();

Expand Down Expand Up @@ -682,16 +730,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`, `verbose` and `tool-only`")
.emit();
SuggestionKind::Normal
});

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()
}
_ => {
Expand All @@ -701,19 +770,34 @@ impl SubdiagnosticKind {
}

match kind {
SubdiagnosticKind::Suggestion { ref code_field, ref mut code_init, .. } => {
SubdiagnosticKind::Suggestion {
ref code_field,
ref mut code_init,
suggestion_kind: ref mut kind_field,
..
} => {
if let Some(kind) = suggestion_kind.value() {
*kind_field = kind;
}

*code_init = if let Some(init) = code.value() {
init
} else {
span_err(span, "suggestion without `code = \"...\"`").emit();
quote! { let #code_field = std::iter::empty(); }
};
}
SubdiagnosticKind::MultipartSuggestion {
suggestion_kind: ref mut kind_field, ..
} => {
if let Some(kind) = suggestion_kind.value() {
*kind_field = kind;
}
}
SubdiagnosticKind::Label
| SubdiagnosticKind::Note
| SubdiagnosticKind::Help
| SubdiagnosticKind::Warn
| SubdiagnosticKind::MultipartSuggestion { .. } => {}
| SubdiagnosticKind::Warn => {}
}

Ok(Some((kind, slug)))
Expand Down
Loading

0 comments on commit 69e7055

Please sign in to comment.