Skip to content

Commit 3c71263

Browse files
committed
NoArgsAttributeParser
1 parent 2801f9a commit 3c71263

File tree

8 files changed

+98
-112
lines changed

8 files changed

+98
-112
lines changed

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use rustc_feature::{AttributeTemplate, template};
33
use rustc_session::parse::feature_err;
44
use rustc_span::{Span, Symbol, sym};
55

6-
use super::{AcceptMapping, AttributeOrder, AttributeParser, OnDuplicate, SingleAttributeParser};
6+
use super::{
7+
AcceptMapping, AttributeOrder, AttributeParser, NoArgsAttributeParser, OnDuplicate,
8+
SingleAttributeParser,
9+
};
710
use crate::context::{AcceptContext, FinalizeContext, Stage};
811
use crate::parser::ArgParser;
912
use crate::session_diagnostics::NakedFunctionIncompatibleAttribute;
@@ -43,19 +46,12 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
4346

4447
pub(crate) struct ColdParser;
4548

46-
impl<S: Stage> SingleAttributeParser<S> for ColdParser {
49+
impl<S: Stage> NoArgsAttributeParser<S> for ColdParser {
4750
const PATH: &[Symbol] = &[sym::cold];
48-
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
4951
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
50-
const TEMPLATE: AttributeTemplate = template!(Word);
51-
52-
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
53-
if let Err(span) = args.no_args() {
54-
cx.expected_no_args(span);
55-
return None;
56-
}
5752

58-
Some(AttributeKind::Cold(cx.attr_span))
53+
fn create(span: Span) -> AttributeKind {
54+
AttributeKind::Cold(span)
5955
}
6056
}
6157

@@ -167,37 +163,21 @@ impl<S: Stage> AttributeParser<S> for NakedParser {
167163
}
168164

169165
pub(crate) struct TrackCallerParser;
170-
171-
impl<S: Stage> SingleAttributeParser<S> for TrackCallerParser {
166+
impl<S: Stage> NoArgsAttributeParser<S> for TrackCallerParser {
172167
const PATH: &[Symbol] = &[sym::track_caller];
173-
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
174168
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
175-
const TEMPLATE: AttributeTemplate = template!(Word);
176169

177-
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
178-
if let Err(span) = args.no_args() {
179-
cx.expected_no_args(span);
180-
return None;
181-
}
182-
183-
Some(AttributeKind::TrackCaller(cx.attr_span))
170+
fn create(span: Span) -> AttributeKind {
171+
AttributeKind::TrackCaller(span)
184172
}
185173
}
186174

187175
pub(crate) struct NoMangleParser;
188-
189-
impl<S: Stage> SingleAttributeParser<S> for NoMangleParser {
190-
const PATH: &[rustc_span::Symbol] = &[sym::no_mangle];
191-
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
176+
impl<S: Stage> NoArgsAttributeParser<S> for NoMangleParser {
177+
const PATH: &[Symbol] = &[sym::no_mangle];
192178
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
193-
const TEMPLATE: AttributeTemplate = template!(Word);
194-
195-
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
196-
if let Err(span) = args.no_args() {
197-
cx.expected_no_args(span);
198-
return None;
199-
}
200179

201-
Some(AttributeKind::NoMangle(cx.attr_span))
180+
fn create(span: Span) -> AttributeKind {
181+
AttributeKind::NoMangle(span)
202182
}
203183
}
Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,25 @@
11
use rustc_attr_data_structures::AttributeKind;
2-
use rustc_feature::{AttributeTemplate, template};
3-
use rustc_span::{Symbol, sym};
2+
use rustc_span::{Span, Symbol, sym};
43

5-
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
6-
use crate::context::{AcceptContext, Stage};
7-
use crate::parser::ArgParser;
4+
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
5+
use crate::context::Stage;
86

97
pub(crate) struct AsPtrParser;
10-
11-
impl<S: Stage> SingleAttributeParser<S> for AsPtrParser {
8+
impl<S: Stage> NoArgsAttributeParser<S> for AsPtrParser {
129
const PATH: &[Symbol] = &[sym::rustc_as_ptr];
13-
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
1410
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
15-
const TEMPLATE: AttributeTemplate = template!(Word);
1611

17-
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
18-
if let Err(span) = args.no_args() {
19-
cx.expected_no_args(span);
20-
}
21-
Some(AttributeKind::AsPtr(cx.attr_span))
12+
fn create(span: Span) -> AttributeKind {
13+
AttributeKind::AsPtr(span)
2214
}
2315
}
2416

2517
pub(crate) struct PubTransparentParser;
26-
impl<S: Stage> SingleAttributeParser<S> for PubTransparentParser {
18+
impl<S: Stage> NoArgsAttributeParser<S> for PubTransparentParser {
2719
const PATH: &[Symbol] = &[sym::rustc_pub_transparent];
28-
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
2920
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
30-
const TEMPLATE: AttributeTemplate = template!(Word);
3121

32-
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
33-
if let Err(span) = args.no_args() {
34-
cx.expected_no_args(span);
35-
}
36-
Some(AttributeKind::PubTransparent(cx.attr_span))
22+
fn create(span: Span) -> AttributeKind {
23+
AttributeKind::PubTransparent(span)
3724
}
3825
}
Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
11
use rustc_attr_data_structures::AttributeKind;
2-
use rustc_feature::{AttributeTemplate, template};
3-
use rustc_span::{Symbol, sym};
2+
use rustc_span::{Span, Symbol, sym};
43

5-
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
6-
use crate::context::{AcceptContext, Stage};
7-
use crate::parser::ArgParser;
4+
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
5+
use crate::context::Stage;
86

97
pub(crate) struct LoopMatchParser;
10-
impl<S: Stage> SingleAttributeParser<S> for LoopMatchParser {
8+
impl<S: Stage> NoArgsAttributeParser<S> for LoopMatchParser {
119
const PATH: &[Symbol] = &[sym::loop_match];
12-
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
1310
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
14-
const TEMPLATE: AttributeTemplate = template!(Word);
1511

16-
fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
17-
Some(AttributeKind::LoopMatch(cx.attr_span))
12+
fn create(span: Span) -> AttributeKind {
13+
AttributeKind::LoopMatch(span)
1814
}
1915
}
2016

2117
pub(crate) struct ConstContinueParser;
22-
impl<S: Stage> SingleAttributeParser<S> for ConstContinueParser {
18+
impl<S: Stage> NoArgsAttributeParser<S> for ConstContinueParser {
2319
const PATH: &[Symbol] = &[sym::const_continue];
24-
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
2520
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
26-
const TEMPLATE: AttributeTemplate = template!(Word);
2721

28-
fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
29-
Some(AttributeKind::ConstContinue(cx.attr_span))
22+
fn create(span: Span) -> AttributeKind {
23+
AttributeKind::ConstContinue(span)
3024
}
3125
}

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use std::marker::PhantomData;
1818

1919
use rustc_attr_data_structures::AttributeKind;
20-
use rustc_feature::AttributeTemplate;
20+
use rustc_feature::{AttributeTemplate, template};
2121
use rustc_span::{Span, Symbol};
2222
use thin_vec::ThinVec;
2323

@@ -227,6 +227,41 @@ pub(crate) enum AttributeOrder {
227227
KeepLast,
228228
}
229229

230+
/// An even simpler version of [`SingleAttributeParser`]:
231+
/// now automatically check that there are no arguments provided to the attribute.
232+
///
233+
/// [`WithoutArgs<T> where T: NoArgsAttributeParser`](WithoutArgs) implements [`SingleAttributeParser`].
234+
//
235+
pub(crate) trait NoArgsAttributeParser<S: Stage>: 'static {
236+
const PATH: &[Symbol];
237+
const ON_DUPLICATE: OnDuplicate<S>;
238+
239+
/// Create the [`AttributeKind`] given attribute's [`Span`].
240+
fn create(span: Span) -> AttributeKind;
241+
}
242+
243+
pub(crate) struct WithoutArgs<T: NoArgsAttributeParser<S>, S: Stage>(PhantomData<(S, T)>);
244+
245+
impl<T: NoArgsAttributeParser<S>, S: Stage> Default for WithoutArgs<T, S> {
246+
fn default() -> Self {
247+
Self(Default::default())
248+
}
249+
}
250+
251+
impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for WithoutArgs<T, S> {
252+
const PATH: &[Symbol] = T::PATH;
253+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
254+
const ON_DUPLICATE: OnDuplicate<S> = T::ON_DUPLICATE;
255+
const TEMPLATE: AttributeTemplate = template!(Word);
256+
257+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
258+
if let Err(span) = args.no_args() {
259+
cx.expected_no_args(span);
260+
}
261+
Some(T::create(cx.attr_span))
262+
}
263+
}
264+
230265
type ConvertFn<E> = fn(ThinVec<E>) -> AttributeKind;
231266

232267
/// Alternative to [`AttributeParser`] that automatically handles state management.
Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
use rustc_attr_data_structures::AttributeKind;
2-
use rustc_feature::{AttributeTemplate, template};
3-
use rustc_span::{Symbol, sym};
2+
use rustc_span::{Span, Symbol, sym};
43

5-
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
6-
use crate::context::{AcceptContext, Stage};
7-
use crate::parser::ArgParser;
4+
use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
5+
use crate::context::Stage;
86

97
pub(crate) struct MayDangleParser;
10-
impl<S: Stage> SingleAttributeParser<S> for MayDangleParser {
8+
impl<S: Stage> NoArgsAttributeParser<S> for MayDangleParser {
119
const PATH: &[Symbol] = &[sym::may_dangle];
12-
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
1310
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
14-
const TEMPLATE: AttributeTemplate = template!(Word);
1511

16-
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
17-
if let Err(span) = args.no_args() {
18-
cx.expected_no_args(span);
19-
}
20-
Some(AttributeKind::MayDangle(cx.attr_span))
12+
fn create(span: Span) -> AttributeKind {
13+
AttributeKind::MayDangle(span)
2114
}
2215
}

compiler/rustc_attr_parsing/src/attributes/stability.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ use rustc_attr_data_structures::{
55
StableSince, UnstableReason, VERSION_PLACEHOLDER,
66
};
77
use rustc_errors::ErrorGuaranteed;
8-
use rustc_feature::{AttributeTemplate, template};
8+
use rustc_feature::template;
99
use rustc_span::{Ident, Span, Symbol, sym};
1010

1111
use super::util::parse_version;
12-
use super::{AcceptMapping, AttributeOrder, AttributeParser, OnDuplicate, SingleAttributeParser};
12+
use super::{AcceptMapping, AttributeParser, OnDuplicate};
13+
use crate::attributes::NoArgsAttributeParser;
1314
use crate::context::{AcceptContext, FinalizeContext, Stage};
1415
use crate::parser::{ArgParser, MetaItemParser};
1516
use crate::session_diagnostics::{self, UnsupportedLiteralReason};
@@ -132,18 +133,12 @@ impl<S: Stage> AttributeParser<S> for BodyStabilityParser {
132133
}
133134

134135
pub(crate) struct ConstStabilityIndirectParser;
135-
// FIXME(jdonszelmann): single word attribute group when we have these
136-
impl<S: Stage> SingleAttributeParser<S> for ConstStabilityIndirectParser {
136+
impl<S: Stage> NoArgsAttributeParser<S> for ConstStabilityIndirectParser {
137137
const PATH: &[Symbol] = &[sym::rustc_const_stable_indirect];
138-
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
139138
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;
140-
const TEMPLATE: AttributeTemplate = template!(Word);
141139

142-
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
143-
if let Err(span) = args.no_args() {
144-
cx.expected_no_args(span);
145-
}
146-
Some(AttributeKind::ConstStabilityIndirect)
140+
fn create(_: Span) -> AttributeKind {
141+
AttributeKind::ConstStabilityIndirect
147142
}
148143
}
149144

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::attributes::stability::{
3131
};
3232
use crate::attributes::traits::SkipDuringMethodDispatchParser;
3333
use crate::attributes::transparency::TransparencyParser;
34-
use crate::attributes::{AttributeParser as _, Combine, Single};
34+
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
3535
use crate::parser::{ArgParser, MetaItemParser, PathParser};
3636
use crate::session_diagnostics::{AttributeParseError, AttributeParseErrorReason, UnknownMetaItem};
3737

@@ -52,13 +52,15 @@ macro_rules! attribute_parsers {
5252
use super::*;
5353
type Combine<T> = super::Combine<T, Early>;
5454
type Single<T> = super::Single<T, Early>;
55+
type WithoutArgs<T> = super::WithoutArgs<T, Early>;
5556

5657
attribute_parsers!(@[Early] pub(crate) static $name = [$($names),*];);
5758
}
5859
mod late {
5960
use super::*;
6061
type Combine<T> = super::Combine<T, Late>;
6162
type Single<T> = super::Single<T, Late>;
63+
type WithoutArgs<T> = super::WithoutArgs<T, Late>;
6264

6365
attribute_parsers!(@[Late] pub(crate) static $name = [$($names),*];);
6466
}
@@ -112,22 +114,22 @@ attribute_parsers!(
112114
// tidy-alphabetical-end
113115

114116
// tidy-alphabetical-start
115-
Single<AsPtrParser>,
116-
Single<ColdParser>,
117-
Single<ConstContinueParser>,
118-
Single<ConstStabilityIndirectParser>,
119117
Single<DeprecationParser>,
120118
Single<InlineParser>,
121-
Single<LoopMatchParser>,
122-
Single<MayDangleParser>,
123119
Single<MustUseParser>,
124-
Single<NoMangleParser>,
125120
Single<OptimizeParser>,
126-
Single<PubTransparentParser>,
127121
Single<RustcForceInlineParser>,
128122
Single<SkipDuringMethodDispatchParser>,
129-
Single<TrackCallerParser>,
130123
Single<TransparencyParser>,
124+
Single<WithoutArgs<AsPtrParser>>,
125+
Single<WithoutArgs<ColdParser>>,
126+
Single<WithoutArgs<ConstContinueParser>>,
127+
Single<WithoutArgs<ConstStabilityIndirectParser>>,
128+
Single<WithoutArgs<LoopMatchParser>>,
129+
Single<WithoutArgs<MayDangleParser>>,
130+
Single<WithoutArgs<NoMangleParser>>,
131+
Single<WithoutArgs<PubTransparentParser>>,
132+
Single<WithoutArgs<TrackCallerParser>>,
131133
// tidy-alphabetical-end
132134
];
133135
);

tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,12 @@ LL | #![link_section = "1800"]
403403
|
404404
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
405405

406+
warning: `#[must_use]` has no effect when applied to a module
407+
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
408+
|
409+
LL | #![must_use]
410+
| ^^^^^^^^^^^^
411+
406412
warning: attribute should be applied to a function definition
407413
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
408414
|
@@ -411,12 +417,6 @@ LL | #![cold]
411417
|
412418
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
413419

414-
warning: `#[must_use]` has no effect when applied to a module
415-
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
416-
|
417-
LL | #![must_use]
418-
| ^^^^^^^^^^^^
419-
420420
warning: `#[macro_use]` only has an effect on `extern crate` and modules
421421
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:5
422422
|

0 commit comments

Comments
 (0)