Skip to content
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
9 changes: 5 additions & 4 deletions compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use rustc_ast::token::Delimiter;
use rustc_ast::tokenstream::DelimSpan;
use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, NodeId, ast, token};
use rustc_errors::{Applicability, PResult};
use rustc_feature::{AttributeTemplate, Features, template};
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate, Features, template};
use rustc_hir::attrs::CfgEntry;
use rustc_hir::{AttrPath, RustcVersion};
use rustc_parse::parser::{ForceCollect, Parser};
Expand Down Expand Up @@ -324,8 +324,8 @@ pub fn parse_cfg_attr(
}) {
Ok(r) => return Some(r),
Err(e) => {
let suggestions =
CFG_ATTR_TEMPLATE.suggestions(Some(cfg_attr.style), sym::cfg_attr);
let suggestions = CFG_ATTR_TEMPLATE
.suggestions(AttrSuggestionStyle::Attribute(cfg_attr.style), sym::cfg_attr);
e.with_span_suggestions(
cfg_attr.span,
"must be of the form",
Expand Down Expand Up @@ -356,7 +356,8 @@ pub fn parse_cfg_attr(
path: AttrPath::from_ast(&cfg_attr.get_normal_item().path),
description: ParsedDescription::Attribute,
reason,
suggestions: CFG_ATTR_TEMPLATE.suggestions(Some(cfg_attr.style), sym::cfg_attr),
suggestions: CFG_ATTR_TEMPLATE
.suggestions(AttrSuggestionStyle::Attribute(cfg_attr.style), sym::cfg_attr),
});
}
}
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::sync::LazyLock;
use private::Sealed;
use rustc_ast::{AttrStyle, CRATE_NODE_ID, MetaItemLit, NodeId};
use rustc_errors::{Diag, Diagnostic, Level};
use rustc_feature::AttributeTemplate;
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId};
Expand Down Expand Up @@ -638,9 +638,15 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
}

pub(crate) fn suggestions(&self) -> Vec<String> {
// If the outer and inner spans are equal, we are parsing an attribute from `cfg_attr`,
// So don't display an attribute style in the suggestions
let style = (self.attr_span != self.inner_span).then_some(self.attr_style);
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_path)
}
}
Expand Down
31 changes: 24 additions & 7 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,28 +132,45 @@ 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,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I invented the term "Embedded Attribute" here, feel free to bikeshed a better name

/// 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: Option<AttrStyle>,
style: AttrSuggestionStyle,
name: impl std::fmt::Display,
) -> Vec<String> {
let mut suggestions = vec![];
let (start, end) = match style {
Some(AttrStyle::Outer) => ("#[", "]"),
Some(AttrStyle::Inner) => ("#![", "]"),
None => ("", ""),
let (start, macro_call, end) = match style {
AttrSuggestionStyle::Attribute(AttrStyle::Outer) => ("#[", "", "]"),
AttrSuggestionStyle::Attribute(AttrStyle::Inner) => ("#![", "", "]"),
AttrSuggestionStyle::Macro => ("", "!", ""),
AttrSuggestionStyle::EmbeddedAttribute => ("", "", ""),
};

let mut suggestions = vec![];

if self.word {
debug_assert!(macro_call.is_empty(), "Macro suggestions use list style");
suggestions.push(format!("{start}{name}{end}"));
}
if let Some(descr) = self.list {
for descr in descr {
suggestions.push(format!("{start}{name}({descr}){end}"));
suggestions.push(format!("{start}{name}{macro_call}({descr}){end}"));
}
}
suggestions.extend(self.one_of.iter().map(|&word| format!("{start}{name}({word}){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}{name} = \"{descr}\"{end}"));
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_feature/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZero<u

pub use accepted::ACCEPTED_LANG_FEATURES;
pub use builtin_attrs::{
AttributeDuplicates, AttributeGate, AttributeSafety, AttributeTemplate, AttributeType,
BUILTIN_ATTRIBUTE_MAP, BUILTIN_ATTRIBUTES, BuiltinAttribute, GatedCfg, encode_cross_crate,
find_gated_cfg, is_builtin_attr_name, is_stable_diagnostic_attribute, is_valid_for_get_attr,
AttrSuggestionStyle, AttributeDuplicates, AttributeGate, AttributeSafety, AttributeTemplate,
AttributeType, BUILTIN_ATTRIBUTE_MAP, BUILTIN_ATTRIBUTES, BuiltinAttribute, GatedCfg,
encode_cross_crate, find_gated_cfg, is_builtin_attr_name, is_stable_diagnostic_attribute,
is_valid_for_get_attr,
};
pub use removed::REMOVED_LANG_FEATURES;
pub use unstable::{
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/macros/cfg.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ LL | cfg!(123);
| ^^^^^---^
| | |
| | expected a valid identifier here
| help: must be of the form: `cfg(predicate)`
| help: must be of the form: `cfg!(predicate)`
|
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>

Expand All @@ -22,7 +22,7 @@ LL | cfg!(foo = 123);
| ^^^^^^^^^^^---^
| | |
| | expected a string literal here
| help: must be of the form: `cfg(predicate)`
| help: must be of the form: `cfg!(predicate)`
|
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/span/E0805.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | if cfg!(not()) { }
| ^^^^^^^^--^
| | |
| | expected a single argument here
| help: must be of the form: `cfg(predicate)`
| help: must be of the form: `cfg!(predicate)`
|
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>

Expand Down
Loading