diff options
| author | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2025-06-19 02:05:47 +0300 |
|---|---|---|
| committer | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2025-06-30 23:19:04 +0300 |
| commit | 187babc35f07153e2853ee9b6984f56aa158abc5 (patch) | |
| tree | f1415133c4d9d5ed2bba6cedc54771fe9591af1b /compiler/rustc_attr_parsing/src | |
| parent | c65dccabacdfd6c8a7f7439eba13422fdd89b91e (diff) | |
| download | rust-187babc35f07153e2853ee9b6984f56aa158abc5.tar.gz rust-187babc35f07153e2853ee9b6984f56aa158abc5.zip | |
NoArgsAttributeParser
Diffstat (limited to 'compiler/rustc_attr_parsing/src')
7 files changed, 92 insertions, 106 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index 7c412d4fa89..360c28dafab 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -3,7 +3,10 @@ use rustc_feature::{AttributeTemplate, template}; use rustc_session::parse::feature_err; use rustc_span::{Span, Symbol, sym}; -use super::{AcceptMapping, AttributeOrder, AttributeParser, OnDuplicate, SingleAttributeParser}; +use super::{ + AcceptMapping, AttributeOrder, AttributeParser, NoArgsAttributeParser, OnDuplicate, + SingleAttributeParser, +}; use crate::context::{AcceptContext, FinalizeContext, Stage}; use crate::parser::ArgParser; use crate::session_diagnostics::{NakedFunctionIncompatibleAttribute, NullOnExport}; @@ -43,19 +46,12 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser { pub(crate) struct ColdParser; -impl<S: Stage> SingleAttributeParser<S> for ColdParser { +impl<S: Stage> NoArgsAttributeParser<S> for ColdParser { const PATH: &[Symbol] = &[sym::cold]; - 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 let Err(span) = args.no_args() { - cx.expected_no_args(span); - return None; - } - Some(AttributeKind::Cold(cx.attr_span)) + fn create(span: Span) -> AttributeKind { + AttributeKind::Cold(span) } } @@ -194,38 +190,22 @@ impl<S: Stage> AttributeParser<S> for NakedParser { } pub(crate) struct TrackCallerParser; - -impl<S: Stage> SingleAttributeParser<S> for TrackCallerParser { +impl<S: Stage> NoArgsAttributeParser<S> for TrackCallerParser { const PATH: &[Symbol] = &[sym::track_caller]; - 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 let Err(span) = args.no_args() { - cx.expected_no_args(span); - return None; - } - - Some(AttributeKind::TrackCaller(cx.attr_span)) + fn create(span: Span) -> AttributeKind { + AttributeKind::TrackCaller(span) } } pub(crate) struct NoMangleParser; - -impl<S: Stage> SingleAttributeParser<S> for NoMangleParser { - const PATH: &[rustc_span::Symbol] = &[sym::no_mangle]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast; +impl<S: Stage> NoArgsAttributeParser<S> for NoMangleParser { + const PATH: &[Symbol] = &[sym::no_mangle]; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; - const TEMPLATE: AttributeTemplate = template!(Word); - - fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { - if let Err(span) = args.no_args() { - cx.expected_no_args(span); - return None; - } - Some(AttributeKind::NoMangle(cx.attr_span)) + fn create(span: Span) -> AttributeKind { + AttributeKind::NoMangle(span) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 1c8fc5079da..0dfcf3cb899 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -1,38 +1,25 @@ use rustc_attr_data_structures::AttributeKind; -use rustc_feature::{AttributeTemplate, template}; -use rustc_span::{Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; -use crate::context::{AcceptContext, Stage}; -use crate::parser::ArgParser; +use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; +use crate::context::Stage; pub(crate) struct AsPtrParser; - -impl<S: Stage> SingleAttributeParser<S> for AsPtrParser { +impl<S: Stage> NoArgsAttributeParser<S> for AsPtrParser { const PATH: &[Symbol] = &[sym::rustc_as_ptr]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; - const TEMPLATE: AttributeTemplate = template!(Word); - 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)) + fn create(span: Span) -> AttributeKind { + AttributeKind::AsPtr(span) } } pub(crate) struct PubTransparentParser; -impl<S: Stage> SingleAttributeParser<S> for PubTransparentParser { +impl<S: Stage> NoArgsAttributeParser<S> for PubTransparentParser { const PATH: &[Symbol] = &[sym::rustc_pub_transparent]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; - const TEMPLATE: AttributeTemplate = template!(Word); - 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)) + fn create(span: Span) -> AttributeKind { + AttributeKind::PubTransparent(span) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/loop_match.rs b/compiler/rustc_attr_parsing/src/attributes/loop_match.rs index f6c7ac5e3a3..1a5368c092f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/loop_match.rs +++ b/compiler/rustc_attr_parsing/src/attributes/loop_match.rs @@ -1,31 +1,25 @@ use rustc_attr_data_structures::AttributeKind; -use rustc_feature::{AttributeTemplate, template}; -use rustc_span::{Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; -use crate::context::{AcceptContext, Stage}; -use crate::parser::ArgParser; +use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; +use crate::context::Stage; pub(crate) struct LoopMatchParser; -impl<S: Stage> SingleAttributeParser<S> for LoopMatchParser { +impl<S: Stage> NoArgsAttributeParser<S> for LoopMatchParser { const PATH: &[Symbol] = &[sym::loop_match]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; - const TEMPLATE: AttributeTemplate = template!(Word); - fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> { - Some(AttributeKind::LoopMatch(cx.attr_span)) + fn create(span: Span) -> AttributeKind { + AttributeKind::LoopMatch(span) } } pub(crate) struct ConstContinueParser; -impl<S: Stage> SingleAttributeParser<S> for ConstContinueParser { +impl<S: Stage> NoArgsAttributeParser<S> for ConstContinueParser { const PATH: &[Symbol] = &[sym::const_continue]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; - const TEMPLATE: AttributeTemplate = template!(Word); - fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> { - Some(AttributeKind::ConstContinue(cx.attr_span)) + fn create(span: Span) -> AttributeKind { + AttributeKind::ConstContinue(span) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 584dadadcf7..abddc75ab8b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -17,7 +17,7 @@ use std::marker::PhantomData; use rustc_attr_data_structures::AttributeKind; -use rustc_feature::AttributeTemplate; +use rustc_feature::{AttributeTemplate, template}; use rustc_span::{Span, Symbol}; use thin_vec::ThinVec; @@ -228,6 +228,41 @@ pub(crate) enum AttributeOrder { KeepLast, } +/// An even simpler version of [`SingleAttributeParser`]: +/// now automatically check that there are no arguments provided to the attribute. +/// +/// [`WithoutArgs<T> where T: NoArgsAttributeParser`](WithoutArgs) implements [`SingleAttributeParser`]. +// +pub(crate) trait NoArgsAttributeParser<S: Stage>: 'static { + const PATH: &[Symbol]; + const ON_DUPLICATE: OnDuplicate<S>; + + /// Create the [`AttributeKind`] given attribute's [`Span`]. + fn create(span: Span) -> AttributeKind; +} + +pub(crate) struct WithoutArgs<T: NoArgsAttributeParser<S>, S: Stage>(PhantomData<(S, T)>); + +impl<T: NoArgsAttributeParser<S>, S: Stage> Default for WithoutArgs<T, S> { + fn default() -> Self { + Self(Default::default()) + } +} + +impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for WithoutArgs<T, S> { + const PATH: &[Symbol] = T::PATH; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast; + const ON_DUPLICATE: OnDuplicate<S> = T::ON_DUPLICATE; + const TEMPLATE: AttributeTemplate = template!(Word); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { + if let Err(span) = args.no_args() { + cx.expected_no_args(span); + } + Some(T::create(cx.attr_span)) + } +} + type ConvertFn<E> = fn(ThinVec<E>) -> AttributeKind; /// Alternative to [`AttributeParser`] that automatically handles state management. diff --git a/compiler/rustc_attr_parsing/src/attributes/semantics.rs b/compiler/rustc_attr_parsing/src/attributes/semantics.rs index 54f50445fbd..c5e2bf6862f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/semantics.rs +++ b/compiler/rustc_attr_parsing/src/attributes/semantics.rs @@ -1,22 +1,15 @@ use rustc_attr_data_structures::AttributeKind; -use rustc_feature::{AttributeTemplate, template}; -use rustc_span::{Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; -use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; -use crate::context::{AcceptContext, Stage}; -use crate::parser::ArgParser; +use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; +use crate::context::Stage; pub(crate) struct MayDangleParser; -impl<S: Stage> SingleAttributeParser<S> for MayDangleParser { +impl<S: Stage> NoArgsAttributeParser<S> for MayDangleParser { const PATH: &[Symbol] = &[sym::may_dangle]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; - const TEMPLATE: AttributeTemplate = template!(Word); - 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)) + fn create(span: Span) -> AttributeKind { + AttributeKind::MayDangle(span) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs index 37104855623..ffe60f59cc4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/stability.rs +++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs @@ -5,11 +5,12 @@ use rustc_attr_data_structures::{ StableSince, UnstableReason, VERSION_PLACEHOLDER, }; use rustc_errors::ErrorGuaranteed; -use rustc_feature::{AttributeTemplate, template}; +use rustc_feature::template; use rustc_span::{Ident, Span, Symbol, sym}; use super::util::parse_version; -use super::{AcceptMapping, AttributeOrder, AttributeParser, OnDuplicate, SingleAttributeParser}; +use super::{AcceptMapping, AttributeParser, OnDuplicate}; +use crate::attributes::NoArgsAttributeParser; use crate::context::{AcceptContext, FinalizeContext, Stage}; use crate::parser::{ArgParser, MetaItemParser}; use crate::session_diagnostics::{self, UnsupportedLiteralReason}; @@ -132,18 +133,12 @@ impl<S: Stage> AttributeParser<S> for BodyStabilityParser { } pub(crate) struct ConstStabilityIndirectParser; -// FIXME(jdonszelmann): single word attribute group when we have these -impl<S: Stage> SingleAttributeParser<S> for ConstStabilityIndirectParser { +impl<S: Stage> NoArgsAttributeParser<S> for ConstStabilityIndirectParser { const PATH: &[Symbol] = &[sym::rustc_const_stable_indirect]; - const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore; - const TEMPLATE: AttributeTemplate = template!(Word); - 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) + fn create(_: Span) -> AttributeKind { + AttributeKind::ConstStabilityIndirect } } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index eee6d860550..4b960a07dd7 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -33,7 +33,7 @@ use crate::attributes::stability::{ }; use crate::attributes::traits::SkipDuringMethodDispatchParser; use crate::attributes::transparency::TransparencyParser; -use crate::attributes::{AttributeParser as _, Combine, Single}; +use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; use crate::parser::{ArgParser, MetaItemParser, PathParser}; use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem}; @@ -54,6 +54,7 @@ macro_rules! attribute_parsers { use super::*; type Combine<T> = super::Combine<T, Early>; type Single<T> = super::Single<T, Early>; + type WithoutArgs<T> = super::WithoutArgs<T, Early>; attribute_parsers!(@[Early] pub(crate) static $name = [$($names),*];); } @@ -61,6 +62,7 @@ macro_rules! attribute_parsers { use super::*; type Combine<T> = super::Combine<T, Late>; type Single<T> = super::Single<T, Late>; + type WithoutArgs<T> = super::WithoutArgs<T, Late>; attribute_parsers!(@[Late] pub(crate) static $name = [$($names),*];); } @@ -115,25 +117,25 @@ attribute_parsers!( // tidy-alphabetical-end // tidy-alphabetical-start - Single<AsPtrParser>, - Single<ColdParser>, - Single<ConstContinueParser>, - Single<ConstStabilityIndirectParser>, Single<DeprecationParser>, Single<ExportNameParser>, Single<InlineParser>, Single<LinkNameParser>, Single<LinkSectionParser>, - Single<LoopMatchParser>, - Single<MayDangleParser>, Single<MustUseParser>, - Single<NoMangleParser>, Single<OptimizeParser>, - Single<PubTransparentParser>, Single<RustcForceInlineParser>, Single<SkipDuringMethodDispatchParser>, - Single<TrackCallerParser>, Single<TransparencyParser>, + Single<WithoutArgs<AsPtrParser>>, + Single<WithoutArgs<ColdParser>>, + Single<WithoutArgs<ConstContinueParser>>, + Single<WithoutArgs<ConstStabilityIndirectParser>>, + Single<WithoutArgs<LoopMatchParser>>, + Single<WithoutArgs<MayDangleParser>>, + Single<WithoutArgs<NoMangleParser>>, + Single<WithoutArgs<PubTransparentParser>>, + Single<WithoutArgs<TrackCallerParser>>, // tidy-alphabetical-end ]; ); |
