Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ impl SingleAttributeParser for SanitizeParser {
const PATH: &[Symbol] = &[sym::sanitize];

// FIXME: still checked in check_attrs.rs
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(CHECKED_LATER);

const TEMPLATE: AttributeTemplate = template!(List: &[
r#"address = "on|off""#,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/crate_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ impl CombineAttributeParser for RegisterToolParser {
const PATH: &[Symbol] = &[sym::register_tool];
type Item = Ident;
const CONVERT: ConvertFn<Self::Item> = |tools, _span| AttributeKind::RegisterTool(tools);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(CHECKED_LATER);
const TEMPLATE: AttributeTemplate = template!(List: &["tool1, tool2, ..."]);

fn extend(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_session::errors::feature_err;
use rustc_span::{Span, Symbol, edition, sym};
use thin_vec::ThinVec;

use super::prelude::{ALL_TARGETS, AllowedTargets};
use super::prelude::{AllowedTargets, CHECKED_LATER};
use super::{AcceptMapping, AttributeParser};
use crate::context::{AcceptContext, FinalizeContext};
use crate::errors::{
Expand Down Expand Up @@ -707,7 +707,7 @@ impl AttributeParser for DocParser {
},
)];
// FIXME: Currently emitted from 2 different places, generating duplicated warnings.
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(CHECKED_LATER);
// const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
// Allow(Target::ExternCrate),
// Allow(Target::Use),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/link_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl CombineAttributeParser for LinkParser {
r#"name = "...", import_name_type = "decorated|noprefix|undecorated""#,
r#"name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated""#,
], "https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute");
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(CHECKED_LATER); //FIXME Still checked fully in `check_attr.rs`

fn extend(
cx: &mut AcceptContext<'_, '_>,
Expand Down Expand Up @@ -528,7 +528,7 @@ impl SingleAttributeParser for LinkSectionParser {
pub(crate) struct ExportStableParser;
impl NoArgsAttributeParser for ExportStableParser {
const PATH: &[Symbol] = &[sym::export_stable];
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(CHECKED_LATER); //FIXME Still checked fully in `check_attr.rs`
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ pub(super) use crate::parser::*;
#[doc(hidden)]
pub(super) use crate::target_checking::Policy::{Allow, Error, Warn};
#[doc(hidden)]
pub(super) use crate::target_checking::{ALL_TARGETS, AllowedTargets};
pub(super) use crate::target_checking::{ALL_TARGETS, AllowedTargets, CHECKED_LATER};
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl CombineAttributeParser for ReprParser {

//FIXME Still checked fully in `check_attr.rs`
//This one is slightly more complicated because the allowed targets depend on the arguments
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(CHECKED_LATER);
}

macro_rules! int_pat {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ pub(crate) struct LangParser;

impl SingleAttributeParser for LangParser {
const PATH: &[Symbol] = &[sym::lang];
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes`
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(CHECKED_LATER); // Targets are checked per lang item in `rustc_passes`
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
Expand Down Expand Up @@ -564,7 +564,7 @@ pub(crate) struct PanicHandlerParser;

impl NoArgsAttributeParser for PanicHandlerParser {
const PATH: &[Symbol] = &[sym::panic_handler];
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Targets are checked per lang item in `rustc_passes`
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(CHECKED_LATER); // Targets are checked per lang item in `rustc_passes`
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::Lang(LangItem::PanicImpl);
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ use super::prelude::*;
pub(crate) struct MayDangleParser;
impl NoArgsAttributeParser for MayDangleParser {
const PATH: &[Symbol] = &[sym::may_dangle];
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); //FIXME Still checked fully in `check_attr.rs`
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(CHECKED_LATER); //FIXME Still checked fully in `check_attr.rs`
const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle;
}
79 changes: 75 additions & 4 deletions compiler/rustc_attr_parsing/src/target_checking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::errors::{
UnsupportedAttributesInWhere,
};
use crate::session_diagnostics::InvalidTarget;
use crate::target_checking::Policy::Allow;
use crate::target_checking::Policy::{Allow, Warn};

#[derive(Debug)]
pub(crate) enum AllowedTargets {
Expand Down Expand Up @@ -394,10 +394,81 @@ fn filter_targets(
added_fake_targets.push(target_group_name);
}

/// This is a list of default targets to which a attribute can be applied
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// This is a list of default targets to which a attribute can be applied
/// This is a list of default targets to which a attribute can be applied
///

Let's not have this big paragraph included in the module level docs :)

/// This is used for attributes that are not parted to the new target checking system yet can use this list as a placeholder.
Copy link
Copy Markdown
Contributor

@fbstj fbstj May 14, 2026

Choose a reason for hiding this comment

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

Suggested change
/// This is used for attributes that are not parted to the new target checking system yet can use this list as a placeholder.
/// This is used for attributes that are not ported to the new target checking system yet and can use this list as a placeholder.

two nits:

  • parted => ported
  • it might be two sentences?

View changes since the review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These attributes don't have target checks during parsing because they need access to hir, not because we haven't gotten around to moving them around.

Unless that's something you're actively planning to change, we shouldn't say "yet".

/// This excludes `Target::MacroCall`, as attributes on macro calls are otherwise not checked for parsed attributes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// This excludes `Target::MacroCall`, as attributes on macro calls are otherwise not checked for parsed attributes.
/// This excludes `Target::MacroCall`, as attributes on macro calls are otherwise not checked for parsed attributes because `check_attr.rs` runs after macro expansion.

or something similar

pub(crate) const CHECKED_LATER: &'static [Policy] = {
use Policy::Allow;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
use Policy::Allow;

Redundant import.

&[
Allow(Target::ExternCrate),
Allow(Target::Use),
Allow(Target::Static),
Allow(Target::Const),
Allow(Target::Fn),
Allow(Target::Closure),
Allow(Target::Mod),
Allow(Target::ForeignMod),
Allow(Target::GlobalAsm),
Allow(Target::TyAlias),
Allow(Target::Enum),
Allow(Target::Variant),
Allow(Target::Struct),
Allow(Target::Field),
Allow(Target::Union),
Allow(Target::Trait),
Allow(Target::TraitAlias),
Allow(Target::Impl { of_trait: false }),
Allow(Target::Impl { of_trait: true }),
Allow(Target::Expression),
Allow(Target::Statement),
Allow(Target::Arm),
Allow(Target::AssocConst),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::AssocTy),
Allow(Target::ForeignFn),
Allow(Target::ForeignStatic),
Allow(Target::ForeignTy),
Allow(Target::MacroDef),
Allow(Target::Param),
Allow(Target::PatField),
Allow(Target::ExprField),
Allow(Target::WherePredicate),
Allow(Target::Crate),
Allow(Target::Delegation { mac: false }),
Allow(Target::Delegation { mac: true }),
Allow(Target::GenericParam {
kind: rustc_hir::target::GenericParamKind::Const,
has_default: false,
}),
Allow(Target::GenericParam {
kind: rustc_hir::target::GenericParamKind::Const,
has_default: true,
}),
Allow(Target::GenericParam {
kind: rustc_hir::target::GenericParamKind::Lifetime,
has_default: false,
}),
Allow(Target::GenericParam {
kind: rustc_hir::target::GenericParamKind::Lifetime,
has_default: true,
}),
Allow(Target::GenericParam {
kind: rustc_hir::target::GenericParamKind::Type,
has_default: false,
}),
Allow(Target::GenericParam {
kind: rustc_hir::target::GenericParamKind::Type,
has_default: true,
}),
Warn(Target::MacroCall),
]
};

/// This is the list of all targets to which a attribute can be applied
/// This is used for:
/// - `rustc_dummy`, which can be applied to all targets
/// - Attributes that are not parted to the new target system yet can use this list as a placeholder
/// This is used for attributes that are actually allowed on all targets, such as `rustc_dummy`
pub(crate) const ALL_TARGETS: &'static [Policy] = {
use Policy::Allow;
&[
Expand Down
55 changes: 55 additions & 0 deletions tests/ui/attributes/macro-call-attr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//@ check-pass
#![feature(sanitize)]
#![feature(register_tool)]
#![feature(export_stable)]
#![feature(lang_items)]
#![feature(dropck_eyepatch)]
Comment on lines +2 to +6
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I propose we just error for all these unstable attributes on macro call positions, no need to bother with a lint or fcw.

#![feature(diagnostic_on_const)]
#![feature(diagnostic_on_move)]
#![feature(diagnostic_on_unknown)]
#![feature(diagnostic_on_unmatch_args)]
#![warn(unused)]

macro_rules! test { () => {} }

#[doc = ""]
//~^ WARN unused doc comment
#[diagnostic::do_not_recommend]
//~^ WARN can only be placed on trait implementations
#[diagnostic::on_const]
//~^ WARN can only be applied to non-const trait implementations
#[diagnostic::on_move]
//~^ WARN can only be applied to enums, structs or unions
#[diagnostic::on_unimplemented]
//~^ WARN can only be applied to trait definitions
#[diagnostic::on_unknown]
//~^ WARN can only be applied to `use` statements
#[diagnostic::on_unmatch_args]
//~^ WARN can only be applied to macro definitions
#[sanitize()]
//~^ WARN attribute cannot be used on macro calls
//~| WARN previously accepted
#[register_tool(test)]
//~^ WARN attribute cannot be used on macro calls
//~| WARN previously accepted
#[link(name = "x")]
//~^ WARN attribute cannot be used on macro calls
//~| WARN previously accepted
#[export_stable]
//~^ WARN attribute cannot be used on macro calls
//~| WARN previously accepted
#[repr(align(64))]
//~^ WARN attribute cannot be used on macro calls
//~| WARN previously accepted
#[lang = "sized"]
//~^ WARN attribute cannot be used on macro calls
//~| WARN previously accepted
#[panic_handler]
//~^ WARN attribute cannot be used on macro calls
//~| WARN previously accepted
#[may_dangle]
//~^ WARN attribute cannot be used on macro calls
//~| WARN previously accepted
test!();

fn main() {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

136 changes: 136 additions & 0 deletions tests/ui/attributes/macro-call-attr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
warning: unused doc comment
--> $DIR/macro-call-attr.rs:15:1
|
LL | #[doc = ""]
| ^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations
|
= help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion
note: the lint level is defined here
--> $DIR/macro-call-attr.rs:11:9
|
LL | #![warn(unused)]
| ^^^^^^
= note: `#[warn(unused_doc_comments)]` implied by `#[warn(unused)]`

warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations
--> $DIR/macro-call-attr.rs:17:1
|
LL | #[diagnostic::do_not_recommend]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | test!();
| ------- not a trait implementation
|
= note: `#[warn(misplaced_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default

warning: `#[diagnostic::on_const]` can only be applied to non-const trait implementations
--> $DIR/macro-call-attr.rs:19:1
|
LL | #[diagnostic::on_const]
| ^^^^^^^^^^^^^^^^^^^^^^^
...
LL | test!();
| ------- not a trait implementation

warning: `#[diagnostic::on_move]` can only be applied to enums, structs or unions
--> $DIR/macro-call-attr.rs:21:1
|
LL | #[diagnostic::on_move]
| ^^^^^^^^^^^^^^^^^^^^^^

warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
--> $DIR/macro-call-attr.rs:23:1
|
LL | #[diagnostic::on_unimplemented]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: `#[diagnostic::on_unknown]` can only be applied to `use` statements
--> $DIR/macro-call-attr.rs:25:1
|
LL | #[diagnostic::on_unknown]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | test!();
| ------- not an import

warning: `#[diagnostic::on_unmatch_args]` can only be applied to macro definitions
--> $DIR/macro-call-attr.rs:27:1
|
LL | #[diagnostic::on_unmatch_args]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: `#[sanitize]` attribute cannot be used on macro calls
--> $DIR/macro-call-attr.rs:29:1
|
LL | #[sanitize()]
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[sanitize]` can be applied to associated consts, associated types, const parameters, const parameters, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, function params, functions, global asms, impl blocks, lifetime parameters, lifetime parameters, macro defs, match arms, modules, pattern fields, statics, struct fields, struct fields, trait aliases, traits, type aliases, type parameters, type parameters, use statements, and where predicates
= note: `#[warn(unused_attributes)]` implied by `#[warn(unused)]`

warning: `#[register_tool]` attribute cannot be used on macro calls
--> $DIR/macro-call-attr.rs:32:1
|
LL | #[register_tool(test)]
| ^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[register_tool]` can be applied to associated consts, associated types, const parameters, const parameters, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, function params, functions, global asms, impl blocks, lifetime parameters, lifetime parameters, macro defs, match arms, modules, pattern fields, statics, struct fields, struct fields, trait aliases, traits, type aliases, type parameters, type parameters, use statements, and where predicates

warning: `#[link]` attribute cannot be used on macro calls
--> $DIR/macro-call-attr.rs:35:1
|
LL | #[link(name = "x")]
| ^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[link]` can be applied to associated consts, associated types, const parameters, const parameters, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, function params, functions, global asms, impl blocks, lifetime parameters, lifetime parameters, macro defs, match arms, modules, pattern fields, statics, struct fields, struct fields, trait aliases, traits, type aliases, type parameters, type parameters, use statements, and where predicates
Copy link
Copy Markdown
Contributor

@mejrs mejrs May 14, 2026

Choose a reason for hiding this comment

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

We shouldn't be saying this huge list of "valid" targets.


warning: `#[export_stable]` attribute cannot be used on macro calls
--> $DIR/macro-call-attr.rs:38:1
|
LL | #[export_stable]
| ^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[export_stable]` can be applied to associated consts, associated types, const parameters, const parameters, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, function params, functions, global asms, impl blocks, lifetime parameters, lifetime parameters, macro defs, match arms, modules, pattern fields, statics, struct fields, struct fields, trait aliases, traits, type aliases, type parameters, type parameters, use statements, and where predicates

warning: `#[repr]` attribute cannot be used on macro calls
--> $DIR/macro-call-attr.rs:41:1
|
LL | #[repr(align(64))]
| ^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[repr]` can be applied to associated consts, associated types, const parameters, const parameters, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, function params, functions, global asms, impl blocks, lifetime parameters, lifetime parameters, macro defs, match arms, modules, pattern fields, statics, struct fields, struct fields, trait aliases, traits, type aliases, type parameters, type parameters, use statements, and where predicates

warning: `#[lang]` attribute cannot be used on macro calls
--> $DIR/macro-call-attr.rs:44:1
|
LL | #[lang = "sized"]
| ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[lang]` can be applied to associated consts, associated types, const parameters, const parameters, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, function params, functions, global asms, impl blocks, lifetime parameters, lifetime parameters, macro defs, match arms, modules, pattern fields, statics, struct fields, struct fields, trait aliases, traits, type aliases, type parameters, type parameters, use statements, and where predicates

warning: `#[panic_handler]` attribute cannot be used on macro calls
--> $DIR/macro-call-attr.rs:47:1
|
LL | #[panic_handler]
| ^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[panic_handler]` can be applied to associated consts, associated types, const parameters, const parameters, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, function params, functions, global asms, impl blocks, lifetime parameters, lifetime parameters, macro defs, match arms, modules, pattern fields, statics, struct fields, struct fields, trait aliases, traits, type aliases, type parameters, type parameters, use statements, and where predicates

warning: `#[may_dangle]` attribute cannot be used on macro calls
--> $DIR/macro-call-attr.rs:50:1
|
LL | #[may_dangle]
| ^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[may_dangle]` can be applied to associated consts, associated types, const parameters, const parameters, constants, crates, data types, enum variants, extern crates, foreign modules, foreign statics, function params, functions, global asms, impl blocks, lifetime parameters, lifetime parameters, macro defs, match arms, modules, pattern fields, statics, struct fields, struct fields, trait aliases, traits, type aliases, type parameters, type parameters, use statements, and where predicates

warning: 15 warnings emitted

Loading