Skip to content

Commit

Permalink
feat: allow multiple suggestions for malformed crate_type attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
Blindspot22 committed Jan 27, 2025
1 parent 9337f7a commit a3070a3
Show file tree
Hide file tree
Showing 14 changed files with 214 additions and 192 deletions.
7 changes: 3 additions & 4 deletions compiler/rustc_builtin_macros/src/cfg_accessible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use rustc_ast as ast;
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
use rustc_feature::AttributeTemplate;
use rustc_parse::validate_attr;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_span::{Span, sym};

use crate::errors;

Expand Down Expand Up @@ -45,9 +44,9 @@ impl MultiItemModifier for Expander {
item: Annotatable,
_is_derive_const: bool,
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
let template = AttributeTemplate { list: Some("path"), ..Default::default() };
let template = AttributeTemplate { list: Some(&["path"]), ..Default::default() };

validate_attr::check_builtin_meta_item(
&ecx.ecfg.features,
&ecx.sess.psess,
meta_item,
ast::AttrStyle::Outer,
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_builtin_macros/src/derive.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use rustc_ast as ast;
use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
use rustc_ast::{GenericParamKind, ItemKind, MetaItemInner, MetaItemKind, StmtKind};
use rustc_expand::base::{
Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier,
};
use rustc_feature::AttributeTemplate;
use rustc_parse::validate_attr;
use rustc_session::Session;
use rustc_span::symbol::{sym, Ident};
use rustc_span::{ErrorGuaranteed, Span};
use rustc_span::{ErrorGuaranteed, Ident, Span, sym};

use crate::cfg_eval::cfg_eval;
use crate::errors;
Expand Down Expand Up @@ -35,10 +34,11 @@ impl MultiItemModifier for Expander {
let (sess, features) = (ecx.sess, ecx.ecfg.features);
let result =
ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| {
let template =
AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
let template = AttributeTemplate {
list: Some(&["Trait1", "Trait2", "..."]),
..Default::default()
};
validate_attr::check_builtin_meta_item(
features,
&sess.psess,
meta_item,
ast::AttrStyle::Outer,
Expand All @@ -50,9 +50,9 @@ impl MultiItemModifier for Expander {
let mut resolutions = match &meta_item.kind {
MetaItemKind::List(list) => {
list.iter()
.filter_map(|nested_meta| match nested_meta {
NestedMetaItem::MetaItem(meta) => Some(meta),
NestedMetaItem::Lit(lit) => {
.filter_map(|meta_item_inner| match meta_item_inner {
MetaItemInner::MetaItem(meta) => Some(meta),
MetaItemInner::Lit(lit) => {
// Reject `#[derive("Debug")]`.
report_unexpected_meta_item_lit(sess, lit);
None
Expand Down
269 changes: 149 additions & 120 deletions compiler/rustc_feature/src/builtin_attrs.rs

Large diffs are not rendered by default.

75 changes: 27 additions & 48 deletions compiler/rustc_parse/src/validate_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,19 @@
use rustc_ast::token::Delimiter;
use rustc_ast::tokenstream::DelimSpan;
use rustc_ast::{
self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemKind,
NestedMetaItem, Safety,
self as ast, AttrArgs, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind, Safety,
};
use rustc_errors::{Applicability, FatalError, PResult};
use rustc_feature::{
AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP,
};
use rustc_feature::{AttributeSafety, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
use rustc_session::errors::report_lit_error;
use rustc_session::lint::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNSAFE_ATTR_OUTSIDE_UNSAFE};
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNSAFE_ATTR_OUTSIDE_UNSAFE};
use rustc_session::parse::ParseSess;
use rustc_span::{sym, BytePos, Span, Symbol};
use rustc_span::{Span, Symbol, sym};

use crate::{errors, parse_in};

pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) {
pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
if attr.is_doc_comment() {
return;
}
Expand All @@ -28,24 +25,24 @@ pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) {

// All non-builtin attributes are considered safe
let safety = attr_info.map(|x| x.safety).unwrap_or(AttributeSafety::Normal);
check_attribute_safety(features, psess, safety, attr);
check_attribute_safety(psess, safety, attr);

// Check input tokens for built-in and key-value attributes.
match attr_info {
// `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => {
match parse_meta(psess, attr) {
// Don't check safety again, we just did that
Ok(meta) => check_builtin_meta_item(
features, psess, &meta, attr.style, *name, *template, false,
),
Ok(meta) => {
check_builtin_meta_item(psess, &meta, attr.style, *name, *template, false)
}
Err(err) => {
err.emit();
}
}
}
_ => {
if let AttrArgs::Eq(..) = attr_item.args {
if let AttrArgs::Eq { .. } = attr_item.args {
// All key-value attributes are restricted to meta-item syntax.
match parse_meta(psess, attr) {
Ok(_) => {}
Expand All @@ -72,7 +69,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met
parse_in(psess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?;
MetaItemKind::List(nmis)
}
AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => {
AttrArgs::Eq { expr, .. } => {
if let ast::ExprKind::Lit(token_lit) = expr.kind {
let res = ast::MetaItemLit::from_token_lit(token_lit, expr.span);
let res = match res {
Expand Down Expand Up @@ -118,7 +115,6 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met
return Err(err);
}
}
AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()),
},
})
}
Expand All @@ -145,7 +141,7 @@ pub(super) fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim

/// Checks that the given meta-item is compatible with this `AttributeTemplate`.
fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaItemKind) -> bool {
let is_one_allowed_subword = |items: &[NestedMetaItem]| match items {
let is_one_allowed_subword = |items: &[MetaItemInner]| match items {
[item] => item.is_word() && template.one_of.iter().any(|&word| item.has_name(word)),
_ => false,
};
Expand All @@ -157,16 +153,7 @@ fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaIte
}
}

pub fn check_attribute_safety(
features: &Features,
psess: &ParseSess,
safety: AttributeSafety,
attr: &Attribute,
) {
if !features.unsafe_attributes {
return;
}

pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr: &Attribute) {
let attr_item = attr.get_normal_item();

if safety == AttributeSafety::Unsafe {
Expand All @@ -177,11 +164,7 @@ pub fn check_attribute_safety(
// wrapping it in `unsafe(...)`. Otherwise, we suggest putting the
// `unsafe(`, `)` right after and right before the opening and closing
// square bracket respectively.
let diag_span = if attr_item.span().can_be_used_for_suggestions() {
attr_item.span()
} else {
attr.span.with_lo(attr.span.lo() + BytePos(2)).with_hi(attr.span.hi() - BytePos(1))
};
let diag_span = attr_item.span();

if attr.span.at_least_rust_2024() {
psess.dcx().emit_err(errors::UnsafeAttrOutsideUnsafe {
Expand All @@ -203,33 +186,28 @@ pub fn check_attribute_safety(
);
}
}
} else {
if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
psess.dcx().emit_err(errors::InvalidAttrUnsafe {
span: unsafe_span,
name: attr_item.path.clone(),
});
}
} else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
psess.dcx().emit_err(errors::InvalidAttrUnsafe {
span: unsafe_span,
name: attr_item.path.clone(),
});
}
}

// Called by `check_builtin_meta_item` and code that manually denies
// `unsafe(...)` in `cfg`
pub fn deny_builtin_meta_unsafety(features: &Features, psess: &ParseSess, meta: &MetaItem) {
pub fn deny_builtin_meta_unsafety(psess: &ParseSess, meta: &MetaItem) {
// This only supports denying unsafety right now - making builtin attributes
// support unsafety will requite us to thread the actual `Attribute` through
// for the nice diagnostics.
if features.unsafe_attributes {
if let Safety::Unsafe(unsafe_span) = meta.unsafety {
psess
.dcx()
.emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, name: meta.path.clone() });
}
if let Safety::Unsafe(unsafe_span) = meta.unsafety {
psess
.dcx()
.emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, name: meta.path.clone() });
}
}

pub fn check_builtin_meta_item(
features: &Features,
psess: &ParseSess,
meta: &MetaItem,
style: ast::AttrStyle,
Expand All @@ -246,7 +224,7 @@ pub fn check_builtin_meta_item(
}

if deny_unsafety {
deny_builtin_meta_unsafety(features, psess, meta);
deny_builtin_meta_unsafety(psess, meta);
}
}

Expand All @@ -270,7 +248,8 @@ fn emit_malformed_attribute(
suggestions.push(format!("#{inner}[{name}]"));
}
if let Some(descr) = template.list {
suggestions.push(format!("#{inner}[{name}({descr})]"));
let descr_formatted = descr.join(", ");
suggestions.push(format!("#{inner}[{name}({descr_formatted})]"));
}
suggestions.extend(template.one_of.iter().map(|&word| format!("#{inner}[{name}({word})]")));
if let Some(descr) = template.name_value_str {
Expand Down
2 changes: 1 addition & 1 deletion library/backtrace
Submodule backtrace updated 48 files
+9 −6 .github/workflows/check-binary-size.yml
+183 −177 .github/workflows/main.yml
+108 −50 Cargo.lock
+12 −29 Cargo.toml
+63 −0 bindings.txt
+0 −55 build.rs
+2 −2 ci/android-ndk.sh
+1 −1 ci/docker/arm-linux-androideabi/Dockerfile
+1 −1 ci/docker/armv7-linux-androideabi/Dockerfile
+1 −1 ci/docker/i686-linux-android/Dockerfile
+7 −7 crates/as-if-std/Cargo.toml
+0 −8 crates/as-if-std/build.rs
+1 −0 crates/cpp_smoke_test/Cargo.toml
+8 −8 src/backtrace/dbghelp32.rs
+11 −11 src/backtrace/dbghelp64.rs
+1 −0 src/backtrace/libunwind.rs
+0 −1 src/backtrace/mod.rs
+114 −17 src/capture.rs
+90 −141 src/dbghelp.rs
+17 −18 src/lib.rs
+3 −4 src/print.rs
+1 −1 src/print/fuchsia.rs
+10 −10 src/symbolize/dbghelp.rs
+62 −43 src/symbolize/gimli.rs
+3 −1 src/symbolize/gimli/coff.rs
+123 −45 src/symbolize/gimli/elf.rs
+5 −3 src/symbolize/gimli/libs_aix.rs
+86 −39 src/symbolize/gimli/libs_dl_iterate_phdr.rs
+6 −4 src/symbolize/gimli/libs_haiku.rs
+5 −3 src/symbolize/gimli/libs_illumos.rs
+2 −1 src/symbolize/gimli/libs_libnx.rs
+2 −1 src/symbolize/gimli/libs_macos.rs
+4 −3 src/symbolize/gimli/libs_windows.rs
+75 −0 src/symbolize/gimli/lru.rs
+5 −2 src/symbolize/gimli/macho.rs
+4 −2 src/symbolize/gimli/mmap_fake.rs
+2 −2 src/symbolize/gimli/mmap_unix.rs
+15 −7 src/symbolize/gimli/mmap_windows.rs
+13 −4 src/symbolize/gimli/parse_running_mmaps_unix.rs
+4 −2 src/symbolize/gimli/xcoff.rs
+3 −3 src/symbolize/mod.rs
+3 −3 src/types.rs
+0 −749 src/windows.rs
+664 −0 src/windows_sys.rs
+3 −3 tests/concurrent-panics.rs
+10 −0 tests/current-exe-mismatch.rs
+12 −5 tests/skip_inner_frames.rs
+29 −27 tests/smoke.rs
2 changes: 1 addition & 1 deletion library/stdarch
Submodule stdarch updated 115 files
2 changes: 1 addition & 1 deletion src/doc/book
Submodule book updated 1009 files
2 changes: 1 addition & 1 deletion src/doc/edition-guide
Submodule edition-guide updated 43 files
+23 −2 .github/workflows/main.yml
+1 −0 book.toml
+34 −16 src/SUMMARY.md
+11 −9 src/editions/creating-a-new-project.md
+37 −4 src/editions/transitioning-an-existing-project-to-a-new-edition.md
+1 −1 src/rust-2021/c-string-literals.md
+47 −0 src/rust-2021/raw-lifetimes.md
+7 −6 src/rust-2021/reserved-syntax.md
+0 −2 src/rust-2024/cargo-inherited-default-features.md
+0 −47 src/rust-2024/cargo-remove-implicit-features.md
+36 −0 src/rust-2024/cargo-resolver.md
+0 −2 src/rust-2024/cargo-table-key-names.md
+3 −0 src/rust-2024/cargo.md
+0 −3 src/rust-2024/gen-keyword.md
+1 −25 src/rust-2024/index.md
+1 −5 src/rust-2024/intoiterator-box-slice.md
+3 −0 src/rust-2024/language.md
+49 −1 src/rust-2024/macro-fragment-specifiers.md
+135 −0 src/rust-2024/match-ergonomics.md
+36 −0 src/rust-2024/missing-macro-fragment-specifiers.md
+3 −8 src/rust-2024/never-type-fallback.md
+76 −0 src/rust-2024/newly-unsafe-functions.md
+21 −11 src/rust-2024/prelude.md
+63 −0 src/rust-2024/reserved-syntax.md
+288 −4 src/rust-2024/rpit-lifetime-capture.md
+80 −0 src/rust-2024/rustdoc-doctests.md
+60 −0 src/rust-2024/rustdoc-nested-includes.md
+3 −0 src/rust-2024/rustdoc.md
+644 −0 src/rust-2024/rustfmt-formatting-fixes.md
+83 −5 src/rust-2024/rustfmt-overflow-delimited-expr.md
+36 −0 src/rust-2024/rustfmt-raw-identifier-sorting.md
+84 −0 src/rust-2024/rustfmt-style-edition.md
+41 −0 src/rust-2024/rustfmt-version-sorting.md
+3 −0 src/rust-2024/rustfmt.md
+3 −0 src/rust-2024/standard-library.md
+0 −44 src/rust-2024/static-mut-reference.md
+53 −0 src/rust-2024/static-mut-references.md
+102 −0 src/rust-2024/temporary-if-let-scope.md
+101 −0 src/rust-2024/temporary-tail-expr-scope.md
+2 −8 src/rust-2024/unsafe-attributes.md
+2 −7 src/rust-2024/unsafe-extern.md
+0 −2 src/rust-2024/unsafe-op-in-unsafe-fn.md
+20 −0 triagebot.toml
2 changes: 1 addition & 1 deletion src/doc/reference
Submodule reference updated 108 files
2 changes: 1 addition & 1 deletion src/doc/rust-by-example
Submodule rust-by-example updated 103 files
2 changes: 1 addition & 1 deletion src/tools/cargo
Submodule cargo updated 1063 files
19 changes: 17 additions & 2 deletions src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct BuiltinAttribute {
#[derive(Clone, Copy)]
pub struct AttributeTemplate {
pub word: bool,
pub list: Option<&'static str>,
pub list: Option<&'static [&'static str]>,
pub name_value_str: Option<&'static str>,
}

Expand Down Expand Up @@ -464,6 +464,9 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
// Used by the `rustc::potential_query_instability` lint to warn methods which
// might not be stable during incremental compilation.
rustc_attr!(rustc_lint_query_instability, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
// Used by the `rustc::untracked_query_information` lint to warn methods which
// might break incremental compilation.
rustc_attr!(rustc_lint_untracked_query_information, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
// Used by the `rustc::untranslatable_diagnostic` and `rustc::diagnostic_outside_of_impl` lints
// to assist in changes to diagnostic APIs.
rustc_attr!(rustc_lint_diagnostics, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
Expand Down Expand Up @@ -629,6 +632,19 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
"the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
),
rustc_attr!(
rustc_intrinsic, Normal, template!(Word), ErrorFollowing,
"the `#[rustc_intrinsic]` attribute is used to declare intrinsics with function bodies",
),
rustc_attr!(
rustc_no_mir_inline, Normal, template!(Word), WarnFollowing,
"#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen"
),
rustc_attr!(
rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing,
"the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies",
),

rustc_attr!(
rustc_deprecated_safe_2024, Normal, template!(Word), WarnFollowing,
"the `#[rustc_safe_intrinsic]` marks functions as unsafe in Rust 2024",
Expand Down Expand Up @@ -679,7 +695,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
template!(List: r#"cfg = "...", module = "...", kind = "...""#), DuplicatesOk,
),
rustc_attr!(TEST, rustc_symbol_name, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_polymorphize_error, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_def_path, Normal, template!(Word), WarnFollowing),
rustc_attr!(TEST, rustc_mir, Normal, template!(List: "arg1, arg2, ..."), DuplicatesOk),
gated!(
Expand Down

0 comments on commit a3070a3

Please sign in to comment.