1212//! - [`CombineAttributeParser`](crate::attributes::CombineAttributeParser): makes it easy to implement an attribute which should combine the
1313//! contents of attributes, if an attribute appear multiple times in a list
1414//!
15+ //! By default, attributes are allowed anywhere. When adding an attribute that should only be used
16+ //! at the crate root, consider setting the `TYPE` in the parser trait to
17+ //! [`AttributeType::CrateOnly`].
18+ //!
1519//! Attributes should be added to `crate::context::ATTRIBUTE_PARSERS` to be parsed.
1620
1721use std:: marker:: PhantomData ;
1822
19- use rustc_feature:: { AttributeTemplate , template} ;
23+ use rustc_feature:: { AttributeTemplate , AttributeType , template} ;
2024use rustc_hir:: attrs:: AttributeKind ;
2125use rustc_span:: { Span , Symbol } ;
2226use thin_vec:: ThinVec ;
@@ -88,6 +92,8 @@ pub(crate) trait AttributeParser<S: Stage>: Default + 'static {
8892
8993 const ALLOWED_TARGETS : AllowedTargets ;
9094
95+ const TYPE : AttributeType = AttributeType :: Normal ;
96+
9197 /// The parser has gotten a chance to accept the attributes on an item,
9298 /// here it can produce an attribute.
9399 ///
@@ -129,6 +135,8 @@ pub(crate) trait SingleAttributeParser<S: Stage>: 'static {
129135 /// The template this attribute parser should implement. Used for diagnostics.
130136 const TEMPLATE : AttributeTemplate ;
131137
138+ const TYPE : AttributeType = AttributeType :: Normal ;
139+
132140 /// Converts a single syntactical attribute to a single semantic attribute, or [`AttributeKind`]
133141 fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > ;
134142}
@@ -175,6 +183,8 @@ impl<T: SingleAttributeParser<S>, S: Stage> AttributeParser<S> for Single<T, S>
175183 ) ] ;
176184 const ALLOWED_TARGETS : AllowedTargets = T :: ALLOWED_TARGETS ;
177185
186+ const TYPE : AttributeType = T :: TYPE ;
187+
178188 fn finalize ( self , _cx : & FinalizeContext < ' _ , ' _ , S > ) -> Option < AttributeKind > {
179189 Some ( self . 1 ?. 0 )
180190 }
@@ -259,6 +269,7 @@ pub(crate) trait NoArgsAttributeParser<S: Stage>: 'static {
259269 const PATH : & [ Symbol ] ;
260270 const ON_DUPLICATE : OnDuplicate < S > ;
261271 const ALLOWED_TARGETS : AllowedTargets ;
272+ const TYPE : AttributeType = AttributeType :: Normal ;
262273
263274 /// Create the [`AttributeKind`] given attribute's [`Span`].
264275 const CREATE : fn ( Span ) -> AttributeKind ;
@@ -278,6 +289,7 @@ impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for Without
278289 const ON_DUPLICATE : OnDuplicate < S > = T :: ON_DUPLICATE ;
279290 const ALLOWED_TARGETS : AllowedTargets = T :: ALLOWED_TARGETS ;
280291 const TEMPLATE : AttributeTemplate = template ! ( Word ) ;
292+ const TYPE : AttributeType = T :: TYPE ;
281293
282294 fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
283295 if let Err ( span) = args. no_args ( ) {
@@ -311,6 +323,8 @@ pub(crate) trait CombineAttributeParser<S: Stage>: 'static {
311323 /// The template this attribute parser should implement. Used for diagnostics.
312324 const TEMPLATE : AttributeTemplate ;
313325
326+ const TYPE : AttributeType = AttributeType :: Normal ;
327+
314328 /// Converts a single syntactical attribute to a number of elements of the semantic attribute, or [`AttributeKind`]
315329 fn extend < ' c > (
316330 cx : & ' c mut AcceptContext < ' _ , ' _ , S > ,
@@ -346,6 +360,7 @@ impl<T: CombineAttributeParser<S>, S: Stage> AttributeParser<S> for Combine<T, S
346360 group. items . extend ( T :: extend ( cx, args) )
347361 } ) ] ;
348362 const ALLOWED_TARGETS : AllowedTargets = T :: ALLOWED_TARGETS ;
363+ const TYPE : AttributeType = T :: TYPE ;
349364
350365 fn finalize ( self , _cx : & FinalizeContext < ' _ , ' _ , S > ) -> Option < AttributeKind > {
351366 if let Some ( first_span) = self . first_span {
0 commit comments