From e25cf0c04d539ad2cd3e3b8f47dfcc59fb4de77a Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 16 Jun 2025 22:11:41 +0300 Subject: [PATCH 1/4] Port `#[export_stable]` to the new attribute system --- .../rustc_attr_data_structures/src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../src/attributes/link_attrs.rs | 13 +++++++++++-- compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 4 +++- compiler/rustc_passes/src/check_export.rs | 7 ++++--- tests/ui/attributes/malformed-attrs.stderr | 15 +++++++++------ 8 files changed, 34 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index b5934f4e36e89..c8545ecdecb63 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -250,6 +250,9 @@ pub enum AttributeKind { span: Span, }, + /// Represents `#[export_stable]`. + ExportStable, + /// Represents `#[inline]` and `#[rustc_force_inline]`. Inline(InlineAttr, Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 02e95ddcb6fdb..2486e750cca91 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -26,6 +26,7 @@ impl AttributeKind { Deprecation { .. } => Yes, DocComment { .. } => Yes, ExportName { .. } => Yes, + ExportStable => No, Inline(..) => No, LinkName { .. } => Yes, LinkSection { .. } => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index e298053ab7691..935002be314da 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -1,9 +1,11 @@ use rustc_attr_data_structures::AttributeKind; use rustc_attr_data_structures::AttributeKind::{LinkName, LinkSection}; use rustc_feature::{AttributeTemplate, template}; -use rustc_span::{Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::attributes::{ + AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, +}; use crate::context::{AcceptContext, Stage}; use crate::parser::ArgParser; use crate::session_diagnostics::NullOnLinkSection; @@ -57,3 +59,10 @@ impl SingleAttributeParser for LinkSectionParser { Some(LinkSection { name, span: cx.attr_span }) } } + +pub(crate) struct ExportStableParser; +impl NoArgsAttributeParser for ExportStableParser { + const PATH: &[Symbol] = &[sym::export_stable]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 265e1bb6a8cba..c778af2f71d16 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -22,7 +22,7 @@ use crate::attributes::codegen_attrs::{ use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; -use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser}; +use crate::attributes::link_attrs::{ExportStableParser, LinkNameParser, LinkSectionParser}; use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::must_use::MustUseParser; @@ -141,6 +141,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 27355a422d1fe..14fe5c317acd4 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -286,6 +286,7 @@ fn emit_malformed_attribute( if matches!( name, sym::inline + | sym::export_stable | sym::may_dangle | sym::rustc_as_ptr | sym::rustc_pub_transparent diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c5ced4064140e..0c4b184af2144 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -201,6 +201,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span) | AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span), ) => self.check_rustc_layout_scalar_valid_range(*attr_span, span, target), + Attribute::Parsed(AttributeKind::ExportStable) => { + // handled in `check_export` + } Attribute::Parsed( AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect @@ -340,7 +343,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::cfg_attr | sym::cfg_trace | sym::cfg_attr_trace - | sym::export_stable // handled in `check_export` // need to be fixed | sym::cfi_encoding // FIXME(cfi_encoding) | sym::pointee // FIXME(derive_coerce_pointee) diff --git a/compiler/rustc_passes/src/check_export.rs b/compiler/rustc_passes/src/check_export.rs index f8f489d7d0673..b1f4584c2a88a 100644 --- a/compiler/rustc_passes/src/check_export.rs +++ b/compiler/rustc_passes/src/check_export.rs @@ -2,6 +2,7 @@ use std::iter; use std::ops::ControlFlow; use rustc_abi::ExternAbi; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -14,7 +15,7 @@ use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Visibility, }; use rustc_session::config::CrateType; -use rustc_span::{Span, sym}; +use rustc_span::Span; use crate::errors::UnexportableItem; @@ -44,7 +45,7 @@ impl<'tcx> ExportableItemCollector<'tcx> { } fn item_is_exportable(&self, def_id: LocalDefId) -> bool { - let has_attr = self.tcx.has_attr(def_id, sym::export_stable); + let has_attr = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable); if !self.in_exportable_mod && !has_attr { return false; } @@ -80,7 +81,7 @@ impl<'tcx> ExportableItemCollector<'tcx> { fn walk_item_with_mod(&mut self, item: &'tcx hir::Item<'tcx>) { let def_id = item.hir_id().owner.def_id; let old_exportable_mod = self.in_exportable_mod; - if self.tcx.get_attr(def_id, sym::export_stable).is_some() { + if find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable) { self.in_exportable_mod = true; } let old_seen_exportable_in_mod = std::mem::replace(&mut self.seen_exportable_in_mod, false); diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 32b0ddf87ba4f..adace3a75043e 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -40,12 +40,6 @@ error: malformed `crate_name` attribute input LL | #[crate_name] | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` -error: malformed `export_stable` attribute input - --> $DIR/malformed-attrs.rs:80:1 - | -LL | #[export_stable = 1] - | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]` - error: malformed `coverage` attribute input --> $DIR/malformed-attrs.rs:89:1 | @@ -490,6 +484,15 @@ LL | #[target_feature] | expected this to be a list | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]` +error[E0565]: malformed `export_stable` attribute input + --> $DIR/malformed-attrs.rs:80:1 + | +LL | #[export_stable = 1] + | ^^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[export_stable]` + error[E0539]: malformed `link_name` attribute input --> $DIR/malformed-attrs.rs:85:1 | From 1005963ee3932f57839f2cd69690b7080f40f3e6 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:00:30 +0300 Subject: [PATCH 2/4] Port `#[ffi_const]` to the new attribute system --- .../rustc_attr_data_structures/src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../src/attributes/link_attrs.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 5 ++++- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 +++- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 6 ++++-- tests/ui/attributes/malformed-attrs.stderr | 15 +++++++++------ 8 files changed, 32 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index c8545ecdecb63..5e00c9358a282 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -253,6 +253,9 @@ pub enum AttributeKind { /// Represents `#[export_stable]`. ExportStable, + /// Represents `#[ffi_const]`. + FfiConst(Span), + /// Represents `#[inline]` and `#[rustc_force_inline]`. Inline(InlineAttr, Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 2486e750cca91..4db3ec42f2acf 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -27,6 +27,7 @@ impl AttributeKind { DocComment { .. } => Yes, ExportName { .. } => Yes, ExportStable => No, + FfiConst(..) => No, Inline(..) => No, LinkName { .. } => Yes, LinkSection { .. } => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 935002be314da..74283645a5add 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -66,3 +66,10 @@ impl NoArgsAttributeParser for ExportStableParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable; } + +pub(crate) struct FfiConstParser; +impl NoArgsAttributeParser for FfiConstParser { + const PATH: &[Symbol] = &[sym::ffi_const]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiConst; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index c778af2f71d16..b6ec2dc48c63c 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -22,7 +22,9 @@ use crate::attributes::codegen_attrs::{ use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; -use crate::attributes::link_attrs::{ExportStableParser, LinkNameParser, LinkSectionParser}; +use crate::attributes::link_attrs::{ + ExportStableParser, FfiConstParser, LinkNameParser, LinkSectionParser, +}; use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::must_use::MustUseParser; @@ -142,6 +144,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 2713ec07f9759..972e60dc89fac 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -211,6 +211,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER, UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER, }, + AttributeKind::FfiConst(_) => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST + } _ => {} } } @@ -222,7 +225,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { match name { sym::rustc_allocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR, sym::ffi_pure => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE, - sym::ffi_const => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST, sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR, sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 14fe5c317acd4..867549c92ce65 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -287,6 +287,7 @@ fn emit_malformed_attribute( name, sym::inline | sym::export_stable + | sym::ffi_const | sym::may_dangle | sym::rustc_as_ptr | sym::rustc_pub_transparent diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 0c4b184af2144..d9b1df90313ce 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -204,6 +204,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::ExportStable) => { // handled in `check_export` } + &Attribute::Parsed(AttributeKind::FfiConst(attr_span)) => { + self.check_ffi_const(attr_span, target) + } Attribute::Parsed( AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect @@ -298,7 +301,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_has_incoherent_inherent_impls(attr, span, target) } [sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target), - [sym::ffi_const, ..] => self.check_ffi_const(attr.span(), target), [sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target), [sym::link, ..] => self.check_link(hir_id, attr, span, target), [sym::macro_use, ..] | [sym::macro_escape, ..] => { @@ -1503,7 +1505,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.dcx().emit_err(errors::FfiPureInvalidTarget { attr_span }); return; } - if attrs.iter().any(|a| a.has_name(sym::ffi_const)) { + if find_attr!(attrs, AttributeKind::FfiConst(_)) { // `#[ffi_const]` functions cannot be `#[ffi_pure]` self.dcx().emit_err(errors::BothFfiConstAndPure { attr_span }); } diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index adace3a75043e..2a5af9a4a31ab 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -146,12 +146,6 @@ error: malformed `link_ordinal` attribute input LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]` -error: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:170:5 - | -LL | #[unsafe(ffi_const = 1)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]` - error: malformed `linkage` attribute input --> $DIR/malformed-attrs.rs:172:5 | @@ -549,6 +543,15 @@ LL | #[rustc_layout_scalar_valid_range_end] | expected this to be a list | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` +error[E0565]: malformed `ffi_const` attribute input + --> $DIR/malformed-attrs.rs:170:5 + | +LL | #[unsafe(ffi_const = 1)] + | ^^^^^^^^^^^^^^^^^^^---^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[ffi_const]` + error[E0565]: malformed `non_exhaustive` attribute input --> $DIR/malformed-attrs.rs:196:1 | From 59f38b7b030a399f2ac58f3152dd24fae0c9d861 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Tue, 24 Jun 2025 01:10:12 +0300 Subject: [PATCH 3/4] Port `#[ffi_pure]` to the new attribute system --- .../rustc_attr_data_structures/src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../src/attributes/link_attrs.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 2 +- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 4 +++- tests/ui/attributes/malformed-attrs.stderr | 15 +++++++++------ 8 files changed, 27 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 5e00c9358a282..3a238622fab42 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -256,6 +256,9 @@ pub enum AttributeKind { /// Represents `#[ffi_const]`. FfiConst(Span), + /// Represents `#[ffi_pure]`. + FfiPure(Span), + /// Represents `#[inline]` and `#[rustc_force_inline]`. Inline(InlineAttr, Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 4db3ec42f2acf..7e825a5f0cbd0 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -28,6 +28,7 @@ impl AttributeKind { ExportName { .. } => Yes, ExportStable => No, FfiConst(..) => No, + FfiPure(..) => No, Inline(..) => No, LinkName { .. } => Yes, LinkSection { .. } => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 74283645a5add..42d901041d583 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -73,3 +73,10 @@ impl NoArgsAttributeParser for FfiConstParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiConst; } + +pub(crate) struct FfiPureParser; +impl NoArgsAttributeParser for FfiPureParser { + const PATH: &[Symbol] = &[sym::ffi_pure]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index b6ec2dc48c63c..0ccc6695a9bb2 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -23,7 +23,7 @@ use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; use crate::attributes::link_attrs::{ - ExportStableParser, FfiConstParser, LinkNameParser, LinkSectionParser, + ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser, }; use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; @@ -145,6 +145,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 972e60dc89fac..a6b0b2634315f 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -214,6 +214,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { AttributeKind::FfiConst(_) => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST } + AttributeKind::FfiPure(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE, _ => {} } } @@ -224,7 +225,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { match name { sym::rustc_allocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR, - sym::ffi_pure => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE, sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR, sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 867549c92ce65..87763607d0108 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -288,6 +288,7 @@ fn emit_malformed_attribute( sym::inline | sym::export_stable | sym::ffi_const + | sym::ffi_pure | sym::may_dangle | sym::rustc_as_ptr | sym::rustc_pub_transparent diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d9b1df90313ce..2406cc067bcdc 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -207,6 +207,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &Attribute::Parsed(AttributeKind::FfiConst(attr_span)) => { self.check_ffi_const(attr_span, target) } + &Attribute::Parsed(AttributeKind::FfiPure(attr_span)) => { + self.check_ffi_pure(attr_span, attrs, target) + } Attribute::Parsed( AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect @@ -300,7 +303,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_has_incoherent_inherent_impls, ..] => { self.check_has_incoherent_inherent_impls(attr, span, target) } - [sym::ffi_pure, ..] => self.check_ffi_pure(attr.span(), attrs, target), [sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target), [sym::link, ..] => self.check_link(hir_id, attr, span, target), [sym::macro_use, ..] | [sym::macro_escape, ..] => { diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 2a5af9a4a31ab..ed7d5a263b11a 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -134,12 +134,6 @@ error: malformed `fundamental` attribute input LL | #[fundamental()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` -error: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:164:5 - | -LL | #[unsafe(ffi_pure = 1)] - | ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]` - error: malformed `link_ordinal` attribute input --> $DIR/malformed-attrs.rs:166:5 | @@ -543,6 +537,15 @@ LL | #[rustc_layout_scalar_valid_range_end] | expected this to be a list | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` +error[E0565]: malformed `ffi_pure` attribute input + --> $DIR/malformed-attrs.rs:164:5 + | +LL | #[unsafe(ffi_pure = 1)] + | ^^^^^^^^^^^^^^^^^^---^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[ffi_pure]` + error[E0565]: malformed `ffi_const` attribute input --> $DIR/malformed-attrs.rs:170:5 | From 15b33a87463bfb62b11a5f9be0a80b9bfe3bb1ae Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Fri, 4 Jul 2025 15:53:03 +0300 Subject: [PATCH 4/4] Port `#[rustc_std_internal_symbol]` to the new attribute system --- .../rustc_attr_data_structures/src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../rustc_attr_parsing/src/attributes/link_attrs.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 2 ++ compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 6 +++--- compiler/rustc_passes/src/check_attr.rs | 12 +++++------- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 3a238622fab42..323acebc1bdec 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -327,6 +327,9 @@ pub enum AttributeKind { span: Span, }, + /// Represents `#[rustc_std_internal_symbol]`. + StdInternalSymbol(Span), + /// Represents `#[target_feature(enable = "...")]` TargetFeature(ThinVec<(Symbol, Span)>, Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 7e825a5f0cbd0..a01537b356e4c 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -49,6 +49,7 @@ impl AttributeKind { RustcObjectLifetimeDefault => No, SkipDuringMethodDispatch { .. } => No, Stability { .. } => Yes, + StdInternalSymbol(..) => No, TargetFeature(..) => No, TrackCaller(..) => Yes, Used { .. } => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index 42d901041d583..1a66eec870f25 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -80,3 +80,10 @@ impl NoArgsAttributeParser for FfiPureParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure; } + +pub(crate) struct StdInternalSymbolParser; +impl NoArgsAttributeParser for StdInternalSymbolParser { + const PATH: &[Symbol] = &[sym::rustc_std_internal_symbol]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::StdInternalSymbol; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 0ccc6695a9bb2..9a6d2da3cfa5b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -24,6 +24,7 @@ use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; use crate::attributes::link_attrs::{ ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkSectionParser, + StdInternalSymbolParser, }; use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; @@ -153,6 +154,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, // tidy-alphabetical-end ]; diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index a6b0b2634315f..173cbe70d1b25 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -215,6 +215,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST } AttributeKind::FfiPure(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE, + AttributeKind::StdInternalSymbol(_) => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL + } _ => {} } } @@ -231,9 +234,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { sym::rustc_allocator_zeroed => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } - sym::rustc_std_internal_symbol => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL - } sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL, sym::linkage => { if let Some(val) = attr.value_str() { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2406cc067bcdc..01d6d04525d28 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -236,6 +236,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &Attribute::Parsed(AttributeKind::PassByValue(attr_span)) => { self.check_pass_by_value(attr_span, span, target) } + &Attribute::Parsed(AttributeKind::StdInternalSymbol(attr_span)) => { + self.check_rustc_std_internal_symbol(attr_span, span, target) + } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); match attr.path().as_slice() { @@ -261,9 +264,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { ), [sym::no_link, ..] => self.check_no_link(hir_id, attr, span, target), [sym::debugger_visualizer, ..] => self.check_debugger_visualizer(attr, target), - [sym::rustc_std_internal_symbol, ..] => { - self.check_rustc_std_internal_symbol(attr, span, target) - } [sym::rustc_no_implicit_autorefs, ..] => { self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } @@ -2218,13 +2218,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_rustc_std_internal_symbol(&self, attr: &Attribute, span: Span, target: Target) { + fn check_rustc_std_internal_symbol(&self, attr_span: Span, span: Span, target: Target) { match target { Target::Fn | Target::Static | Target::ForeignFn | Target::ForeignStatic => {} _ => { - self.tcx - .dcx() - .emit_err(errors::RustcStdInternalSymbol { attr_span: attr.span(), span }); + self.tcx.dcx().emit_err(errors::RustcStdInternalSymbol { attr_span, span }); } } }