Skip to content

take attr style into account in diagnostics #145243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser {
}
}
ArgParser::NameValue(_) => {
let suggestions =
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "inline");
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
.suggestions(cx.attr_style, "inline");
let span = cx.attr_span;
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
return None;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl<S: Stage> AttributeParser<S> for MacroUseParser {
}
}
ArgParser::NameValue(_) => {
let suggestions = MACRO_USE_TEMPLATE.suggestions(false, sym::macro_use);
let suggestions = MACRO_USE_TEMPLATE.suggestions(cx.attr_style, sym::macro_use);
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
num_suggestions: suggestions.len(),
suggestions: DiagArgValue::StrListSepByAnd(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/must_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
Some(value_str)
}
ArgParser::List(_) => {
let suggestions =
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "must_use");
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
.suggestions(cx.attr_style, "must_use");
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
num_suggestions: suggestions.len(),
suggestions: DiagArgValue::StrListSepByAnd(
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_attr_parsing/src/attributes/test_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
ArgParser::NameValue(name_value) => {
let Some(str_value) = name_value.value_as_str() else {
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
.suggestions(false, "ignore");
.suggestions(cx.attr_style, "ignore");
let span = cx.attr_span;
cx.emit_lint(
AttributeLintKind::IllFormedAttributeInput { suggestions },
Expand All @@ -40,8 +40,8 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
Some(str_value)
}
ArgParser::List(_) => {
let suggestions =
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "ignore");
let suggestions = <Self as SingleAttributeParser<S>>::TEMPLATE
.suggestions(cx.attr_style, "ignore");
let span = cx.attr_span;
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
return None;
Expand Down
18 changes: 17 additions & 1 deletion compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::sync::LazyLock;

use itertools::Itertools;
use private::Sealed;
use rustc_ast::{self as ast, LitKind, MetaItemLit, NodeId};
use rustc_ast::{self as ast, AttrStyle, LitKind, MetaItemLit, NodeId};
use rustc_errors::{DiagCtxtHandle, Diagnostic};
use rustc_feature::{AttributeTemplate, Features};
use rustc_hir::attrs::AttributeKind;
Expand Down Expand Up @@ -313,6 +313,7 @@ pub struct AcceptContext<'f, 'sess, S: Stage> {
/// The span of the attribute currently being parsed
pub(crate) attr_span: Span,

pub(crate) attr_style: AttrStyle,
/// The expected structure of the attribute.
///
/// Used in reporting errors to give a hint to users what the attribute *should* look like.
Expand Down Expand Up @@ -394,6 +395,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span))
}),
},
attr_style: self.attr_style,
})
}

Expand All @@ -404,6 +406,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedIntegerLiteral,
attr_style: self.attr_style,
})
}

Expand All @@ -414,6 +417,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedList,
attr_style: self.attr_style,
})
}

Expand All @@ -424,6 +428,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedNoArgs,
attr_style: self.attr_style,
})
}

Expand All @@ -435,6 +440,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedIdentifier,
attr_style: self.attr_style,
})
}

Expand All @@ -447,6 +453,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedNameValue(name),
attr_style: self.attr_style,
})
}

Expand All @@ -458,6 +465,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::DuplicateKey(key),
attr_style: self.attr_style,
})
}

Expand All @@ -470,6 +478,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::UnexpectedLiteral,
attr_style: self.attr_style,
})
}

Expand All @@ -480,6 +489,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedSingleArgument,
attr_style: self.attr_style,
})
}

Expand All @@ -490,6 +500,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
template: self.template.clone(),
attribute: self.attr_path.clone(),
reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument,
attr_style: self.attr_style,
})
}

Expand All @@ -508,6 +519,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
strings: false,
list: false,
},
attr_style: self.attr_style,
})
}

Expand All @@ -526,6 +538,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
strings: false,
list: true,
},
attr_style: self.attr_style,
})
}

Expand All @@ -544,6 +557,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
strings: true,
list: false,
},
attr_style: self.attr_style,
})
}

Expand Down Expand Up @@ -802,6 +816,7 @@ impl<'sess> AttributeParser<'sess, Early> {
},
},
attr_span: attr.span,
attr_style: attr.style,
template,
attr_path: path.get_attribute_path(),
};
Expand Down Expand Up @@ -912,6 +927,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
emit_lint: &mut emit_lint,
},
attr_span: lower_span(attr.span),
attr_style: attr.style,
template: &accept.template,
attr_path: path.get_attribute_path(),
};
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::num::IntErrorKind;

use rustc_ast as ast;
use rustc_ast::{self as ast, AttrStyle};
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
Expand Down Expand Up @@ -579,6 +579,7 @@ pub(crate) enum AttributeParseErrorReason {
pub(crate) struct AttributeParseError {
pub(crate) span: Span,
pub(crate) attr_span: Span,
pub(crate) attr_style: AttrStyle,
pub(crate) template: AttributeTemplate,
pub(crate) attribute: AttrPath,
pub(crate) reason: AttributeParseErrorReason,
Expand Down Expand Up @@ -717,7 +718,8 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError {
if let Some(link) = self.template.docs {
diag.note(format!("for more information, visit <{link}>"));
}
let suggestions = self.template.suggestions(false, &name);
let suggestions = self.template.suggestions(self.attr_style, &name);

diag.span_suggestions(
self.attr_span,
if suggestions.len() == 1 {
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use AttributeDuplicates::*;
use AttributeGate::*;
use AttributeType::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::AttrStyle;
use rustc_hir::attrs::EncodeCrossCrate;
use rustc_span::edition::Edition;
use rustc_span::{Symbol, sym};
Expand Down Expand Up @@ -132,9 +133,12 @@ pub struct AttributeTemplate {
}

impl AttributeTemplate {
pub fn suggestions(&self, inner: bool, name: impl std::fmt::Display) -> Vec<String> {
pub fn suggestions(&self, style: AttrStyle, name: impl std::fmt::Display) -> Vec<String> {
let mut suggestions = vec![];
let inner = if inner { "!" } else { "" };
let inner = match style {
AttrStyle::Outer => "",
AttrStyle::Inner => "!",
};
if self.word {
suggestions.push(format!("#{inner}[{name}]"));
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/attributes/lint_on_root.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// NOTE: this used to panic in debug builds (by a sanity assertion)
// and not emit any lint on release builds. See https://github.com/rust-lang/rust/issues/142891.
#![inline = ""]
//~^ ERROR: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` [ill_formed_attribute_input]
//~^ ERROR: valid forms for the attribute are `#![inline(always)]`, `#![inline(never)]`, and `#![inline]` [ill_formed_attribute_input]
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
//~| ERROR attribute cannot be used on

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/attributes/lint_on_root.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LL | #![inline = ""]
|
= help: `#[inline]` can only be applied to functions

error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]`
error: valid forms for the attribute are `#![inline(always)]`, `#![inline(never)]`, and `#![inline]`
--> $DIR/lint_on_root.rs:3:1
|
LL | #![inline = ""]
Expand All @@ -19,7 +19,7 @@ LL | #![inline = ""]
error: aborting due to 2 previous errors

Future incompatibility report: Future breakage diagnostic:
error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]`
error: valid forms for the attribute are `#![inline(always)]`, `#![inline(never)]`, and `#![inline]`
--> $DIR/lint_on_root.rs:3:1
|
LL | #![inline = ""]
Expand Down
20 changes: 8 additions & 12 deletions tests/ui/attributes/malformed-reprs.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,14 @@ LL | #![repr]
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html#representations>
help: try changing it to one of the following valid forms of the attribute
|
LL - #![repr]
LL + #[repr(<integer type>)]
|
LL - #![repr]
LL + #[repr(C)]
|
LL - #![repr]
LL + #[repr(Rust)]
|
LL - #![repr]
LL + #[repr(align(...))]
|
LL | #![repr(<integer type>)]
| ++++++++++++++++
LL | #![repr(C)]
| +++
LL | #![repr(Rust)]
| ++++++
LL | #![repr(align(...))]
| ++++++++++++
= and 2 other candidates

error[E0589]: invalid `repr(align)` attribute: not a power of two
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/coverage-attr/name-value.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ LL | #![coverage = "off"]
help: try changing it to one of the following valid forms of the attribute
|
LL - #![coverage = "off"]
LL + #[coverage(off)]
LL + #![coverage(off)]
|
LL - #![coverage = "off"]
LL + #[coverage(on)]
LL + #![coverage(on)]
|

error[E0539]: malformed `coverage` attribute input
Expand Down
10 changes: 4 additions & 6 deletions tests/ui/coverage-attr/word-only.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ LL | #![coverage]
|
help: try changing it to one of the following valid forms of the attribute
|
LL - #![coverage]
LL + #[coverage(off)]
|
LL - #![coverage]
LL + #[coverage(on)]
|
LL | #![coverage(off)]
| +++++
LL | #![coverage(on)]
| ++++

error[E0539]: malformed `coverage` attribute input
--> $DIR/word-only.rs:21:1
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/resolve/path-attr-in-const-block.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ LL | #![path = foo!()]
| ^^^^^^^^^^------^
| | |
| | expected a string literal here
| help: must be of the form: `#[path = "file"]`
| help: must be of the form: `#![path = "file"]`
|
= note: for more information, visit <https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute>

Expand Down
Loading