about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJana Dönszelmann <jana@donsz.nl>2025-06-13 01:36:52 +0200
committerJana Dönszelmann <jana@donsz.nl>2025-06-23 12:21:43 +0200
commit82cbc3a35e23a804682922d1c04ac51a00b35137 (patch)
tree4fd51ac4a699aff6a1d9bc414e833ae03d3b4473
parent22be76b7e259f27bf3e55eb931f354cd8b69d55f (diff)
downloadrust-82cbc3a35e23a804682922d1c04ac51a00b35137.tar.gz
rust-82cbc3a35e23a804682922d1c04ac51a00b35137.zip
rewrite #[naked] parser
-rw-r--r--compiler/rustc_attr_data_structures/src/attributes.rs3
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs19
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/naked_functions.rs5
-rw-r--r--compiler/rustc_passes/src/check_attr.rs14
-rw-r--r--compiler/rustc_passes/src/liveness.rs3
10 files changed, 44 insertions, 16 deletions
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index c7487847e6f..63db0d0c988 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -244,6 +244,9 @@ pub enum AttributeKind {
         reason: Option<Symbol>,
     },
 
+    /// Represents #[naked]
+    Naked(Span),
+
     /// Represents `#[no_mangle]`
     NoMangle(Span),
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
index ba4e2935004..cf31dd0ace7 100644
--- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -51,12 +51,29 @@ impl<S: Stage> SingleAttributeParser<S> for ColdParser {
         if !args.no_args() {
             cx.expected_no_args(args.span().unwrap_or(cx.attr_span));
             return None;
-        };
+        }
 
         Some(AttributeKind::Cold(cx.attr_span))
     }
 }
 
+pub(crate) struct NakedParser;
+
+impl<S: Stage> SingleAttributeParser<S> for NakedParser {
+    const PATH: &[rustc_span::Symbol] = &[sym::naked];
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
+    const TEMPLATE: AttributeTemplate = template!(Word);
+
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        if !args.no_args() {
+            cx.expected_no_args(args.span().unwrap_or(cx.attr_span));
+            return None;
+        }
+        Some(AttributeKind::Naked(cx.attr_span))
+    }
+}
+
 pub(crate) struct NoMangleParser;
 
 impl<S: Stage> SingleAttributeParser<S> for NoMangleParser {
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index 171995dc9cb..bf289c6aae8 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -15,7 +15,7 @@ use rustc_session::Session;
 use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
 
 use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
-use crate::attributes::codegen_attrs::{ColdParser, NoMangleParser, OptimizeParser};
+use crate::attributes::codegen_attrs::{ColdParser, NakedParser, NoMangleParser, OptimizeParser};
 use crate::attributes::confusables::ConfusablesParser;
 use crate::attributes::deprecation::DeprecationParser;
 use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
@@ -114,6 +114,7 @@ attribute_parsers!(
         Single<InlineParser>,
         Single<MayDangleParser>,
         Single<MustUseParser>,
+        Single<NakedParser>,
         Single<NoMangleParser>,
         Single<OptimizeParser>,
         Single<PubTransparentParser>,
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index b006fdbb658..fbcfcaa706c 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -121,6 +121,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                         .max();
                 }
                 AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
+                AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
                 AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
                 AttributeKind::NoMangle(attr_span) => {
                     if tcx.opt_item_name(did.to_def_id()).is_some() {
@@ -165,7 +166,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
             sym::rustc_allocator_zeroed => {
                 codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
             }
-            sym::naked => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
             sym::rustc_std_internal_symbol => {
                 codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
             }
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 752cc2eff97..3a2dfa8e985 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -4,6 +4,7 @@ use std::ops::ControlFlow;
 use rustc_abi::FieldIdx;
 use rustc_attr_data_structures::AttributeKind;
 use rustc_attr_data_structures::ReprAttr::ReprPacked;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_errors::codes::*;
 use rustc_errors::{EmissionGuarantee, MultiSpan};
@@ -104,7 +105,7 @@ pub fn check_abi_fn_ptr(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ex
 pub fn check_custom_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, fn_sig: FnSig<'_>, fn_sig_span: Span) {
     if fn_sig.abi == ExternAbi::Custom {
         // Function definitions that use `extern "custom"` must be naked functions.
-        if !tcx.has_attr(def_id, sym::naked) {
+        if !find_attr!(tcx.get_all_attrs(def_id), AttributeKind::Naked(_)) {
             tcx.dcx().emit_err(crate::errors::AbiCustomClothedFunction {
                 span: fn_sig_span,
                 naked_span: tcx.def_span(def_id).shrink_to_lo(),
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index bd3ca8317eb..672f3bc67ce 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -7,6 +7,7 @@
 
 use rustc_abi::{FIRST_VARIANT, FieldIdx};
 use rustc_ast::util::parser::ExprPrecedence;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::unord::UnordMap;
@@ -3779,7 +3780,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) -> Ty<'tcx> {
         if let rustc_ast::AsmMacro::NakedAsm = asm.asm_macro {
-            if !self.tcx.has_attr(self.body_id, sym::naked) {
+            if !find_attr!(self.tcx.get_all_attrs(self.body_id), AttributeKind::Naked(..)) {
                 self.tcx.dcx().emit_err(NakedAsmOutsideNakedFn { span });
             }
         }
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 043a687914b..1cc618e2aee 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -42,6 +42,7 @@ mod writeback;
 
 pub use coercion::can_coerce;
 use fn_ctxt::FnCtxt;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::codes::*;
 use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
@@ -55,8 +56,8 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::config;
+use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{Span, sym};
 use tracing::{debug, instrument};
 use typeck_root_ctxt::TypeckRootCtxt;
 
@@ -173,7 +174,7 @@ fn typeck_with_inspect<'tcx>(
                 .map(|(idx, ty)| fcx.normalize(arg_span(idx), ty)),
         );
 
-        if tcx.has_attr(def_id, sym::naked) {
+        if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::Naked(..)) {
             naked_functions::typeck_naked_fn(tcx, def_id, body);
         }
 
diff --git a/compiler/rustc_hir_typeck/src/naked_functions.rs b/compiler/rustc_hir_typeck/src/naked_functions.rs
index 2518d6478e6..d055fa68fc3 100644
--- a/compiler/rustc_hir_typeck/src/naked_functions.rs
+++ b/compiler/rustc_hir_typeck/src/naked_functions.rs
@@ -1,12 +1,13 @@
 //! Checks validity of naked functions.
 
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{ExprKind, HirIdSet, StmtKind};
 use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
-use rustc_span::{Span, sym};
+use rustc_span::Span;
 
 use crate::errors::{
     NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns, ParamsNotAllowed,
@@ -20,7 +21,7 @@ pub(crate) fn typeck_naked_fn<'tcx>(
     def_id: LocalDefId,
     body: &'tcx hir::Body<'tcx>,
 ) {
-    debug_assert!(tcx.has_attr(def_id, sym::naked));
+    debug_assert!(find_attr!(tcx.get_all_attrs(def_id), AttributeKind::Naked(..)));
     check_no_patterns(tcx, body.params);
     check_no_parameters_use(tcx, body);
     check_asm(tcx, def_id, body);
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index ad1a2a04273..1990b46adbb 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -160,6 +160,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 Attribute::Parsed(AttributeKind::Align { align, span: repr_span }) => {
                     self.check_align(span, target, *align, *repr_span)
                 }
+                Attribute::Parsed(AttributeKind::Naked(attr_span)) => {
+                    self.check_naked(hir_id, *attr_span, span, target, attrs)
+                }
                 Attribute::Parsed(
                     AttributeKind::BodyStability { .. }
                     | AttributeKind::ConstStabilityIndirect
@@ -217,7 +220,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         [sym::rustc_std_internal_symbol, ..] => {
                             self.check_rustc_std_internal_symbol(attr, span, target)
                         }
-                        [sym::naked, ..] => self.check_naked(hir_id, attr, span, target, attrs),
                         [sym::rustc_no_implicit_autorefs, ..] => {
                             self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target)
                         }
@@ -623,7 +625,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     fn check_naked(
         &self,
         hir_id: HirId,
-        attr: &Attribute,
+        attr_span: Span,
         span: Span,
         target: Target,
         attrs: &[Attribute],
@@ -659,7 +661,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             sym::link_section,
             sym::linkage,
             sym::no_mangle,
-            sym::naked,
             sym::instruction_set,
             sym::repr,
             sym::align,
@@ -703,13 +704,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             | AttributeKind::NoMangle(..)
                             | AttributeKind::Cold(..)
                             | AttributeKind::MustUse { .. },
+                            | AttributeKind::Naked(..),
                         ) => {
                             continue;
                         }
                         Attribute::Parsed(AttributeKind::Inline(.., span)) => {
                             self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
                                 span: *span,
-                                naked_span: attr.span(),
+                                naked_span: attr_span,
                                 attr: sym::inline.to_string(),
                             });
 
@@ -746,7 +748,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
 
                         self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
                             span: other_attr.span(),
-                            naked_span: attr.span(),
+                            naked_span: attr_span,
                             attr: other_attr_name,
                         });
 
@@ -756,7 +758,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             }
             _ => {
                 self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
-                    attr_span: attr.span(),
+                    attr_span,
                     defn_span: span,
                     on_crate: hir_id == CRATE_HIR_ID,
                 });
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 763d9fda804..125730377ef 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -85,6 +85,7 @@ use std::io;
 use std::io::prelude::*;
 use std::rc::Rc;
 
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
 use rustc_hir::def::*;
@@ -145,7 +146,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     }
 
     // Don't run unused pass for #[naked]
-    if tcx.has_attr(def_id.to_def_id(), sym::naked) {
+    if find_attr!(tcx.get_all_attrs(def_id.to_def_id()), AttributeKind::Naked(..)) {
         return;
     }