diff options
| author | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2025-06-18 22:27:35 +0300 |
|---|---|---|
| committer | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2025-06-23 22:48:20 +0300 |
| commit | aa80a2b62cde51fc9796a66dfed013a581bff706 (patch) | |
| tree | fa2f84142c37f4762399cce580233940c5ff594e /compiler/rustc_attr_parsing/src/attributes | |
| parent | 42245d34d22ade32b3f276dcf74deb826841594c (diff) | |
| download | rust-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')
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 }) + } +} |
