about summary refs log tree commit diff
path: root/compiler/rustc_attr_parsing/src/attributes
diff options
context:
space:
mode:
authorPavel Grigorenko <GrigorenkoPV@ya.ru>2025-06-18 22:27:35 +0300
committerPavel Grigorenko <GrigorenkoPV@ya.ru>2025-06-23 22:48:20 +0300
commitaa80a2b62cde51fc9796a66dfed013a581bff706 (patch)
treefa2f84142c37f4762399cce580233940c5ff594e /compiler/rustc_attr_parsing/src/attributes
parent42245d34d22ade32b3f276dcf74deb826841594c (diff)
downloadrust-aa80a2b62cde51fc9796a66dfed013a581bff706.tar.gz
rust-aa80a2b62cde51fc9796a66dfed013a581bff706.zip
Port `#[rustc_skip_during_method_dispatch]` to the new attribute system
Diffstat (limited to 'compiler/rustc_attr_parsing/src/attributes')
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs14
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs12
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/mod.rs1
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/semantics.rs5
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/stability.rs9
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/traits.rs54
6 files changed, 80 insertions, 15 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
index 24c40c301fe..0fa69c40154 100644
--- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -50,8 +50,8 @@ impl<S: Stage> SingleAttributeParser<S> for ColdParser {
     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));
+        if let Err(span) = args.no_args() {
+            cx.expected_no_args(span);
             return None;
         }
 
@@ -67,8 +67,8 @@ pub(crate) struct NakedParser {
 impl<S: Stage> AttributeParser<S> for NakedParser {
     const ATTRIBUTES: AcceptMapping<Self, S> =
         &[(&[sym::naked], template!(Word), |this, cx, args| {
-            if !args.no_args() {
-                cx.expected_no_args(args.span().unwrap_or(cx.attr_span));
+            if let Err(span) = args.no_args() {
+                cx.expected_no_args(span);
                 return;
             }
 
@@ -175,10 +175,10 @@ impl<S: Stage> SingleAttributeParser<S> for NoMangleParser {
     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));
+        if let Err(span) = args.no_args() {
+            cx.expected_no_args(span);
             return None;
-        };
+        }
 
         Some(AttributeKind::NoMangle(cx.attr_span))
     }
diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
index 4cfd9a82ce8..1c8fc5079da 100644
--- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
@@ -14,8 +14,10 @@ impl<S: Stage> SingleAttributeParser<S> for AsPtrParser {
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
     const TEMPLATE: AttributeTemplate = template!(Word);
 
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
-        // FIXME: check that there's no args (this is currently checked elsewhere)
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        if let Err(span) = args.no_args() {
+            cx.expected_no_args(span);
+        }
         Some(AttributeKind::AsPtr(cx.attr_span))
     }
 }
@@ -27,8 +29,10 @@ impl<S: Stage> SingleAttributeParser<S> for PubTransparentParser {
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
     const TEMPLATE: AttributeTemplate = template!(Word);
 
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
-        // FIXME: check that there's no args (this is currently checked elsewhere)
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        if let Err(span) = args.no_args() {
+            cx.expected_no_args(span);
+        }
         Some(AttributeKind::PubTransparent(cx.attr_span))
     }
 }
diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
index 738d8735b69..ac7e90fd902 100644
--- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
@@ -36,6 +36,7 @@ pub(crate) mod must_use;
 pub(crate) mod repr;
 pub(crate) mod semantics;
 pub(crate) mod stability;
+pub(crate) mod traits;
 pub(crate) mod transparency;
 pub(crate) mod util;
 
diff --git a/compiler/rustc_attr_parsing/src/attributes/semantics.rs b/compiler/rustc_attr_parsing/src/attributes/semantics.rs
index 071574a5612..54f50445fbd 100644
--- a/compiler/rustc_attr_parsing/src/attributes/semantics.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/semantics.rs
@@ -13,7 +13,10 @@ impl<S: Stage> SingleAttributeParser<S> for MayDangleParser {
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
     const TEMPLATE: AttributeTemplate = template!(Word);
 
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        if let Err(span) = args.no_args() {
+            cx.expected_no_args(span);
+        }
         Some(AttributeKind::MayDangle(cx.attr_span))
     }
 }
diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs
index 6871ff4ec9f..37104855623 100644
--- a/compiler/rustc_attr_parsing/src/attributes/stability.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs
@@ -139,7 +139,10 @@ impl<S: Stage> SingleAttributeParser<S> for ConstStabilityIndirectParser {
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;
     const TEMPLATE: AttributeTemplate = template!(Word);
 
-    fn convert(_cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        if let Err(span) = args.no_args() {
+            cx.expected_no_args(span);
+        }
         Some(AttributeKind::ConstStabilityIndirect)
     }
 }
@@ -361,8 +364,8 @@ pub(crate) fn parse_unstability<S: Stage>(
                 };
             }
             Some(sym::soft) => {
-                if !param.args().no_args() {
-                    cx.emit_err(session_diagnostics::SoftNoArgs { span: param.span() });
+                if let Err(span) = args.no_args() {
+                    cx.emit_err(session_diagnostics::SoftNoArgs { span });
                 }
                 is_soft = true;
             }
diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs
new file mode 100644
index 00000000000..83a98c53c7f
--- /dev/null
+++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs
@@ -0,0 +1,54 @@
+use core::mem;
+
+use rustc_attr_data_structures::AttributeKind;
+use rustc_feature::{AttributeTemplate, template};
+use rustc_span::{Symbol, sym};
+
+use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
+use crate::context::{AcceptContext, Stage};
+use crate::parser::ArgParser;
+
+pub(crate) struct SkipDuringMethodDispatchParser;
+
+impl<S: Stage> SingleAttributeParser<S> for SkipDuringMethodDispatchParser {
+    const PATH: &[Symbol] = &[sym::rustc_skip_during_method_dispatch];
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
+
+    const TEMPLATE: AttributeTemplate = template!(List: "array, boxed_slice");
+
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        let mut array = false;
+        let mut boxed_slice = false;
+        let Some(args) = args.list() else {
+            cx.expected_list(cx.attr_span);
+            return None;
+        };
+        if args.is_empty() {
+            cx.expected_at_least_one_argument(args.span);
+            return None;
+        }
+        for arg in args.mixed() {
+            let Some(arg) = arg.meta_item() else {
+                cx.unexpected_literal(arg.span());
+                continue;
+            };
+            if let Err(span) = arg.args().no_args() {
+                cx.expected_no_args(span);
+            }
+            let path = arg.path();
+            let (key, skip): (Symbol, &mut bool) = match path.word_sym() {
+                Some(key @ sym::array) => (key, &mut array),
+                Some(key @ sym::boxed_slice) => (key, &mut boxed_slice),
+                _ => {
+                    cx.expected_specific_argument(path.span(), vec!["array", "boxed_slice"]);
+                    continue;
+                }
+            };
+            if mem::replace(skip, true) {
+                cx.duplicate_key(arg.span(), key);
+            }
+        }
+        Some(AttributeKind::SkipDuringMethodDispatch { array, boxed_slice, span: cx.attr_span })
+    }
+}