From bb8b741c32b3b2f32e358b1cfc1111c19cf82306 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 2cbb727078577..8c94bf79dce0d 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -248,6 +248,9 @@ pub enum AttributeKind { span: Span, }, + /// Represents `#[export_stable]`. + ExportStable, + /// Represents `#[ignore]` Ignore { 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 a6ae49d280873..250cb1f178393 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, Ignore { .. } => No, Inline(..) => No, LinkName { .. } => Yes, 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 939f4a6fde705..db66fd5da2333 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; @@ -145,6 +145,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 67b68e77d2b72..47432a3b7ffbb 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -271,6 +271,7 @@ pub fn check_builtin_meta_item( 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 9e4e78c1db68e..bf8dc06c7b7f0 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> { 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 @@ -346,7 +349,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 2f7bf50ead5fd..0b42284f90cde 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:81:1 - | -LL | #[export_stable = 1] - | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]` - error: malformed `coverage` attribute input --> $DIR/malformed-attrs.rs:90:1 | @@ -481,6 +475,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:81: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:86:1 | From 99a9fe1b22edd82697a315e67392bfb35690152d 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 8c94bf79dce0d..4f9ea8be31403 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -251,6 +251,9 @@ pub enum AttributeKind { /// Represents `#[export_stable]`. ExportStable, + /// Represents `#[ffi_const]`. + FfiConst(Span), + /// Represents `#[ignore]` Ignore { 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 250cb1f178393..e69a543d4594b 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, Ignore { .. } => No, Inline(..) => No, LinkName { .. } => Yes, 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 db66fd5da2333..6544278573b5f 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; @@ -146,6 +148,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 ff4544278714f..72bb9e8fac5f4 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -203,6 +203,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 + } _ => {} } } @@ -214,7 +217,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 47432a3b7ffbb..ff5bcdce97b9e 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -272,6 +272,7 @@ pub fn check_builtin_meta_item( 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 bf8dc06c7b7f0..8a59b07a4f32a 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::ExportStable) => { // handled in `check_export` } + &Attribute::Parsed(AttributeKind::FfiConst(attr_span)) => { + self.check_ffi_const(attr_span, target) + } Attribute::Parsed( AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect @@ -304,7 +307,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, ..] => { @@ -1509,7 +1511,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 0b42284f90cde..908b2ba6314a1 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:171:5 - | -LL | #[unsafe(ffi_const = 1)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]` - error: malformed `linkage` attribute input --> $DIR/malformed-attrs.rs:173:5 | @@ -540,6 +534,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:171: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:197:1 | From 5d7771e50d1ed3f4174269c78f06691596e632d3 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 4f9ea8be31403..a004a4ed4d7a7 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -254,6 +254,9 @@ pub enum AttributeKind { /// Represents `#[ffi_const]`. FfiConst(Span), + /// Represents `#[ffi_pure]`. + FfiPure(Span), + /// Represents `#[ignore]` Ignore { 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 e69a543d4594b..5f0f7152f8650 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, Ignore { .. } => No, Inline(..) => No, LinkName { .. } => Yes, 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 6544278573b5f..f40d69c67a85b 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}; @@ -149,6 +149,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 72bb9e8fac5f4..1791df67803c5 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -206,6 +206,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, _ => {} } } @@ -216,7 +217,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 ff5bcdce97b9e..2fc0eca164597 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -273,6 +273,7 @@ pub fn check_builtin_meta_item( 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 8a59b07a4f32a..32e21c99f06fa 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -210,6 +210,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 @@ -306,7 +309,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 908b2ba6314a1..5bcb0c4dc0a4c 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:165:5 - | -LL | #[unsafe(ffi_pure = 1)] - | ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]` - error: malformed `link_ordinal` attribute input --> $DIR/malformed-attrs.rs:167:5 | @@ -534,6 +528,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:165: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:171:5 | From 4f0b0b0f01ef3e5a2445993faf8367a4e17b8df0 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_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 12 +++++------- 7 files changed, 22 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index a004a4ed4d7a7..d3ab368bb20e3 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -335,6 +335,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 5f0f7152f8650..7b4885d86c51a 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -51,6 +51,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 f40d69c67a85b..e6e1978b8db45 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}; @@ -157,6 +158,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 1791df67803c5..85d01d4f93898 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -207,6 +207,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 + } _ => {} } } @@ -223,9 +226,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_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 2fc0eca164597..11424ec3724bf 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -274,6 +274,7 @@ pub fn check_builtin_meta_item( | sym::export_stable | sym::ffi_const | sym::ffi_pure + | sym::rustc_std_internal_symbol | 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 32e21c99f06fa..66166c53336b1 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -242,6 +242,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() { @@ -267,9 +270,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) } @@ -2220,13 +2220,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 }); } } }