Skip to content
Merged
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
10 changes: 4 additions & 6 deletions compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ use crate::session_diagnostics::{
ParsedDescription,
};
use crate::{
AttrSuggestionStyle, AttributeParser, AttributeTemplate, check_cfg, parse_version,
session_diagnostics, template,
AttributeParser, AttributeTemplate, check_cfg, parse_version, session_diagnostics, template,
};

pub const CFG_TEMPLATE: AttributeTemplate = template!(
Expand Down Expand Up @@ -329,12 +328,12 @@ pub fn parse_cfg_attr(
Ok(r) => return Some(r),
Err(e) => {
let suggestions = CFG_ATTR_TEMPLATE.suggestions(
AttrSuggestionStyle::Attribute(cfg_attr.style),
ParsedDescription::Attribute,
cfg_attr.get_normal_item().unsafety,
sym::cfg_attr,
);
e.with_span_suggestions(
cfg_attr.span,
cfg_attr.get_normal_item().span,
"must be of the form",
suggestions,
Applicability::HasPlaceholders,
Expand All @@ -358,15 +357,14 @@ pub fn parse_cfg_attr(

sess.dcx().emit_err(AttributeParseError {
span,
attr_span: cfg_attr.span,
inner_span: cfg_attr.get_normal_item().span,
template: CFG_ATTR_TEMPLATE,
path: AttrPath::from_ast(&cfg_attr.get_normal_item().path, identity),
description: ParsedDescription::Attribute,
reason,
suggestions: session_diagnostics::AttributeParseErrorSuggestions::CreatedByTemplate(
CFG_ATTR_TEMPLATE.suggestions(
AttrSuggestionStyle::Attribute(cfg_attr.style),
ParsedDescription::Attribute,
cfg_attr.get_normal_item().unsafety,
sym::cfg_attr,
),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ impl DocParser {
match args {
ArgParser::NoArgs => {
let suggestions = cx.adcx().suggestions();
let span = cx.attr_span;
let span = cx.inner_span;
cx.emit_lint(
rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
IllFormedAttributeInput::new(&suggestions, None, None),
Expand Down
31 changes: 4 additions & 27 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ use crate::session_diagnostics::{
ParsedDescription, UnusedDuplicate,
};
use crate::target_checking::AllowedTargets;
use crate::{AttrSuggestionStyle, AttributeParser, AttributeTemplate, EmitAttribute};
use crate::{AttributeParser, AttributeTemplate, EmitAttribute};

type GroupType = LazyLock<GroupTypeInner>;

Expand Down Expand Up @@ -920,7 +920,7 @@ impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> {
reason: AttributeParseErrorReason<'_>,
) -> ErrorGuaranteed {
let suggestions = if self.custom_suggestions.is_empty() {
AttributeParseErrorSuggestions::CreatedByTemplate(self.template_suggestions())
AttributeParseErrorSuggestions::CreatedByTemplate(self.suggestions())
} else {
AttributeParseErrorSuggestions::CreatedByParser(mem::take(&mut self.custom_suggestions))
};
Expand All @@ -933,7 +933,6 @@ impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> {

self.emit_err(AttributeParseError {
span,
attr_span: self.attr_span,
inner_span: self.inner_span,
template: *self.template,
path: self.attr_path.clone(),
Expand All @@ -949,19 +948,6 @@ impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> {
self.custom_suggestions.push(Suggestion { msg, sp: span, code });
self
}

pub(crate) fn template_suggestions(&self) -> Vec<String> {
let style = match self.parsed_description {
// If the outer and inner spans are equal, we are parsing an embedded attribute
ParsedDescription::Attribute if self.attr_span == self.inner_span => {
AttrSuggestionStyle::EmbeddedAttribute
}
ParsedDescription::Attribute => AttrSuggestionStyle::Attribute(self.attr_style),
ParsedDescription::Macro => AttrSuggestionStyle::Macro,
};

self.template.suggestions(style, self.attr_safety, &self.attr_path)
}
}

/// Helpers that can be used to generate errors during attribute parsing.
Expand Down Expand Up @@ -1137,7 +1123,7 @@ impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> {
help: Option<String>,
) {
let suggestions = self.suggestions();
let span = self.attr_span;
let span = self.inner_span;
self.emit_lint(
lint,
crate::diagnostics::IllFormedAttributeInput::new(&suggestions, None, help.as_deref()),
Expand All @@ -1146,16 +1132,7 @@ impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> {
}

pub(crate) fn suggestions(&self) -> Vec<String> {
let style = match self.parsed_description {
// If the outer and inner spans are equal, we are parsing an embedded attribute
ParsedDescription::Attribute if self.attr_span == self.inner_span => {
AttrSuggestionStyle::EmbeddedAttribute
}
ParsedDescription::Attribute => AttrSuggestionStyle::Attribute(self.attr_style),
ParsedDescription::Macro => AttrSuggestionStyle::Macro,
};

self.template.suggestions(style, self.attr_safety, &self.attr_path)
self.template.suggestions(self.parsed_description, self.attr_safety, &self.attr_path)
}
/// Error that a string literal was expected.
/// You can optionally give the literal you did find (which you found not to be a string literal)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,4 @@ pub use context::{OmitDoc, ShouldEmit};
pub use interface::{AttributeParser, EmitAttribute};
pub use rustc_parse::parser::Recovery;
pub use session_diagnostics::ParsedDescription;
pub use template::{AttrSuggestionStyle, AttributeTemplate};
pub use template::AttributeTemplate;
3 changes: 1 addition & 2 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,6 @@ pub enum ParsedDescription {

pub(crate) struct AttributeParseError<'a> {
pub(crate) span: Span,
pub(crate) attr_span: Span,
pub(crate) inner_span: Span,
pub(crate) template: AttributeTemplate,
pub(crate) path: AttrPath,
Expand Down Expand Up @@ -604,7 +603,7 @@ impl<'a> AttributeParseError<'a> {
match &self.suggestions {
AttributeParseErrorSuggestions::CreatedByTemplate(suggestions) => {
diag.span_suggestions(
self.attr_span,
self.inner_span,
if suggestions.len() == 1 {
"must be of the form".to_string()
} else {
Expand Down
38 changes: 10 additions & 28 deletions compiler/rustc_attr_parsing/src/template.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use rustc_ast::ast::Safety;
use rustc_hir::AttrStyle;
use rustc_span::Symbol;

use crate::ParsedDescription;

/// A template to suggest the correct syntax of an attribute.
///
/// This is not used to *check* attributes. The attribute's parser is responsible for that.
Expand All @@ -22,30 +23,16 @@ pub struct AttributeTemplate {
pub docs: Option<&'static str>,
}

pub enum AttrSuggestionStyle {
/// The suggestion is styled for a normal attribute.
/// The `AttrStyle` determines whether this is an inner or outer attribute.
Attribute(AttrStyle),
/// The suggestion is styled for an attribute embedded into another attribute.
/// For example, attributes inside `#[cfg_attr(true, attr(...)]`.
EmbeddedAttribute,
/// The suggestion is styled for macros that are parsed with attribute parsers.
/// For example, the `cfg!(predicate)` macro.
Macro,
}

impl AttributeTemplate {
pub fn suggestions(
&self,
style: AttrSuggestionStyle,
description: ParsedDescription,
safety: Safety,
name: impl std::fmt::Display,
) -> Vec<String> {
let (start, macro_call, end) = match style {
AttrSuggestionStyle::Attribute(AttrStyle::Outer) => ("#[", "", "]"),
AttrSuggestionStyle::Attribute(AttrStyle::Inner) => ("#![", "", "]"),
AttrSuggestionStyle::Macro => ("", "!", ""),
AttrSuggestionStyle::EmbeddedAttribute => ("", "", ""),
let macro_call = match description {
ParsedDescription::Macro => "!",
ParsedDescription::Attribute => "",
};

let mut suggestions = vec![];
Expand All @@ -57,25 +44,20 @@ impl AttributeTemplate {

if self.word {
debug_assert!(macro_call.is_empty(), "Macro suggestions use list style");
suggestions.push(format!("{start}{safety_start}{name}{safety_end}{end}"));
suggestions.push(format!("{safety_start}{name}{safety_end}"));
}
if let Some(descr) = self.list {
for descr in descr {
suggestions.push(format!(
"{start}{safety_start}{name}{macro_call}({descr}){safety_end}{end}"
));
suggestions.push(format!("{safety_start}{name}{macro_call}({descr}){safety_end}"));
}
}
suggestions.extend(
self.one_of
.iter()
.map(|&word| format!("{start}{safety_start}{name}({word}){safety_end}{end}")),
self.one_of.iter().map(|&word| format!("{safety_start}{name}({word}){safety_end}")),
);
if let Some(descr) = self.name_value_str {
debug_assert!(macro_call.is_empty(), "Macro suggestions use list style");
for descr in descr {
suggestions
.push(format!("{start}{safety_start}{name} = \"{descr}\"{safety_end}{end}"));
suggestions.push(format!("{safety_start}{name} = \"{descr}\"{safety_end}"));
}
}
suggestions.sort();
Expand Down
6 changes: 3 additions & 3 deletions tests/rustdoc-ui/lints/invalid-doc-attr-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ note: the lint level is defined here
LL | #![deny(invalid_doc_attributes)]
| ^^^^^^^^^^^^^^^^^^^^^^

error: valid forms for the attribute are `#![doc = "string"]`, `#![doc(alias)]`, `#![doc(attribute)]`, `#![doc(auto_cfg)]`, `#![doc(cfg)]`, `#![doc(fake_variadic)]`, `#![doc(hidden)]`, `#![doc(html_favicon_url)]`, `#![doc(html_logo_url)]`, `#![doc(html_no_source)]`, `#![doc(html_playground_url)]`, `#![doc(html_root_url)]`, `#![doc(include)]`, `#![doc(inline)]`, `#![doc(issue_tracker_base_url)]`, `#![doc(keyword)]`, `#![doc(masked)]`, `#![doc(no_default_passes)]`, `#![doc(no_inline)]`, `#![doc(notable_trait)]`, `#![doc(passes)]`, `#![doc(plugins)]`, `#![doc(rust_logo)]`, `#![doc(search_unbox)]`, `#![doc(spotlight)]`, and `#![doc(test)]`
--> $DIR/invalid-doc-attr-2.rs:6:1
error: valid forms for the attribute are `doc = "string"`, `doc(alias)`, `doc(attribute)`, `doc(auto_cfg)`, `doc(cfg)`, `doc(fake_variadic)`, `doc(hidden)`, `doc(html_favicon_url)`, `doc(html_logo_url)`, `doc(html_no_source)`, `doc(html_playground_url)`, `doc(html_root_url)`, `doc(include)`, `doc(inline)`, `doc(issue_tracker_base_url)`, `doc(keyword)`, `doc(masked)`, `doc(no_default_passes)`, `doc(no_inline)`, `doc(notable_trait)`, `doc(passes)`, `doc(plugins)`, `doc(rust_logo)`, `doc(search_unbox)`, `doc(spotlight)`, and `doc(test)`
--> $DIR/invalid-doc-attr-2.rs:6:4
|
LL | #![doc]
| ^^^^^^^
| ^^^

error: aborting due to 2 previous errors

48 changes: 24 additions & 24 deletions tests/ui/attributes/args-checked.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ LL | #[inline(always = 5)]
help: try changing it to one of the following valid forms of the attribute
|
LL - #[inline(always = 5)]
LL + #[inline(always)]
LL + #[inline]
|
LL - #[inline(always = 5)]
LL + #[inline(never)]
LL + #[inline(always)]
|
LL - #[inline(always = 5)]
LL + #[inline]
LL + #[inline(never)]
|

error[E0539]: malformed `inline` attribute input
Expand All @@ -59,13 +59,13 @@ LL | #[inline(always(x, y, z))]
help: try changing it to one of the following valid forms of the attribute
|
LL - #[inline(always(x, y, z))]
LL + #[inline(always)]
LL + #[inline]
|
LL - #[inline(always(x, y, z))]
LL + #[inline(never)]
LL + #[inline(always)]
|
LL - #[inline(always(x, y, z))]
LL + #[inline]
LL + #[inline(never)]
|

error[E0539]: malformed `instruction_set` attribute input
Expand Down Expand Up @@ -241,13 +241,13 @@ LL | #[used(always = 5)]
help: try changing it to one of the following valid forms of the attribute
|
LL - #[used(always = 5)]
LL + #[used(compiler)]
LL + #[used]
|
LL - #[used(always = 5)]
LL + #[used(linker)]
LL + #[used(compiler)]
|
LL - #[used(always = 5)]
LL + #[used]
LL + #[used(linker)]
|

error[E0539]: malformed `used` attribute input
Expand All @@ -261,13 +261,13 @@ LL | #[used(always(x, y, z))]
help: try changing it to one of the following valid forms of the attribute
|
LL - #[used(always(x, y, z))]
LL + #[used(compiler)]
LL + #[used]
|
LL - #[used(always(x, y, z))]
LL + #[used(linker)]
LL + #[used(compiler)]
|
LL - #[used(always(x, y, z))]
LL + #[used]
LL + #[used(linker)]
|

error[E0565]: malformed `rustc_must_implement_one_of` attribute input
Expand Down Expand Up @@ -314,21 +314,21 @@ LL | #[rustc_dump_layout(debug(x, y, z))]
| |
| didn't expect a literal here

error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]`
--> $DIR/args-checked.rs:37:1
error: valid forms for the attribute are `macro_export` and `macro_export(local_inner_macros)`
--> $DIR/args-checked.rs:37:3
|
LL | #[macro_export(local_inner_macros = 5)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
= note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default

error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]`
--> $DIR/args-checked.rs:40:1
error: valid forms for the attribute are `macro_export` and `macro_export(local_inner_macros)`
--> $DIR/args-checked.rs:40:3
|
LL | #[macro_export(local_inner_macros(x, y, z))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
Expand All @@ -338,22 +338,22 @@ error: aborting due to 23 previous errors
Some errors have detailed explanations: E0539, E0565.
For more information about an error, try `rustc --explain E0539`.
Future incompatibility report: Future breakage diagnostic:
error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]`
--> $DIR/args-checked.rs:37:1
error: valid forms for the attribute are `macro_export` and `macro_export(local_inner_macros)`
--> $DIR/args-checked.rs:37:3
|
LL | #[macro_export(local_inner_macros = 5)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
= note: `#[deny(invalid_macro_export_arguments)]` (part of `#[deny(future_incompatible)]`) on by default

Future breakage diagnostic:
error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]`
--> $DIR/args-checked.rs:40:1
error: valid forms for the attribute are `macro_export` and `macro_export(local_inner_macros)`
--> $DIR/args-checked.rs:40:3
|
LL | #[macro_export(local_inner_macros(x, y, z))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/attributes/attribute-on-wrong-item-inline-repr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ LL | #[inline(XYZ)]
help: try changing it to one of the following valid forms of the attribute
|
LL - #[inline(XYZ)]
LL + #[inline(always)]
LL + #[inline]
|
LL - #[inline(XYZ)]
LL + #[inline(never)]
LL + #[inline(always)]
|
LL - #[inline(XYZ)]
LL + #[inline]
LL + #[inline(never)]
|

error: the `inline` attribute cannot be used on statements
Expand Down Expand Up @@ -75,13 +75,13 @@ LL | #[inline(ABC)]
help: try changing it to one of the following valid forms of the attribute
|
LL - #[inline(ABC)]
LL + #[inline(always)]
LL + #[inline]
|
LL - #[inline(ABC)]
LL + #[inline(never)]
LL + #[inline(always)]
|
LL - #[inline(ABC)]
LL + #[inline]
LL + #[inline(never)]
|

error: the `inline` attribute cannot be used on expressions
Expand Down
Loading
Loading