@@ -5,6 +5,7 @@ use rustc_attr_data_structures::{
55 StableSince , UnstableReason , VERSION_PLACEHOLDER ,
66} ;
77use rustc_errors:: ErrorGuaranteed ;
8+ use rustc_feature:: { AttributeTemplate , template} ;
89use rustc_span:: { Span , Symbol , sym} ;
910
1011use super :: util:: parse_version;
@@ -43,26 +44,39 @@ impl StabilityParser {
4344
4445impl < S : Stage > AttributeParser < S > for StabilityParser {
4546 const ATTRIBUTES : AcceptMapping < Self , S > = & [
46- ( & [ sym:: stable] , |this, cx, args| {
47- reject_outside_std ! ( cx) ;
48- if !this. check_duplicate ( cx)
49- && let Some ( ( feature, level) ) = parse_stability ( cx, args)
50- {
51- this. stability = Some ( ( Stability { level, feature } , cx. attr_span ) ) ;
52- }
53- } ) ,
54- ( & [ sym:: unstable] , |this, cx, args| {
55- reject_outside_std ! ( cx) ;
56- if !this. check_duplicate ( cx)
57- && let Some ( ( feature, level) ) = parse_unstability ( cx, args)
58- {
59- this. stability = Some ( ( Stability { level, feature } , cx. attr_span ) ) ;
60- }
61- } ) ,
62- ( & [ sym:: rustc_allowed_through_unstable_modules] , |this, cx, args| {
63- reject_outside_std ! ( cx) ;
64- this. allowed_through_unstable_modules = args. name_value ( ) . and_then ( |i| i. value_as_str ( ) )
65- } ) ,
47+ (
48+ & [ sym:: stable] ,
49+ template ! ( List : r#"feature = "name", since = "version""# ) ,
50+ |this, cx, args| {
51+ reject_outside_std ! ( cx) ;
52+ if !this. check_duplicate ( cx)
53+ && let Some ( ( feature, level) ) = parse_stability ( cx, args)
54+ {
55+ this. stability = Some ( ( Stability { level, feature } , cx. attr_span ) ) ;
56+ }
57+ } ,
58+ ) ,
59+ (
60+ & [ sym:: unstable] ,
61+ template ! ( List : r#"feature = "name", reason = "...", issue = "N""# ) ,
62+ |this, cx, args| {
63+ reject_outside_std ! ( cx) ;
64+ if !this. check_duplicate ( cx)
65+ && let Some ( ( feature, level) ) = parse_unstability ( cx, args)
66+ {
67+ this. stability = Some ( ( Stability { level, feature } , cx. attr_span ) ) ;
68+ }
69+ } ,
70+ ) ,
71+ (
72+ & [ sym:: rustc_allowed_through_unstable_modules] ,
73+ template ! ( NameValueStr : "deprecation message" ) ,
74+ |this, cx, args| {
75+ reject_outside_std ! ( cx) ;
76+ this. allowed_through_unstable_modules =
77+ args. name_value ( ) . and_then ( |i| i. value_as_str ( ) )
78+ } ,
79+ ) ,
6680 ] ;
6781
6882 fn finalize ( mut self , cx : & FinalizeContext < ' _ , ' _ , S > ) -> Option < AttributeKind > {
@@ -96,16 +110,19 @@ pub(crate) struct BodyStabilityParser {
96110}
97111
98112impl < S : Stage > AttributeParser < S > for BodyStabilityParser {
99- const ATTRIBUTES : AcceptMapping < Self , S > =
100- & [ ( & [ sym:: rustc_default_body_unstable] , |this, cx, args| {
113+ const ATTRIBUTES : AcceptMapping < Self , S > = & [ (
114+ & [ sym:: rustc_default_body_unstable] ,
115+ template ! ( List : r#"feature = "name", reason = "...", issue = "N""# ) ,
116+ |this, cx, args| {
101117 reject_outside_std ! ( cx) ;
102118 if this. stability . is_some ( ) {
103119 cx. dcx ( )
104120 . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : cx. attr_span } ) ;
105121 } else if let Some ( ( feature, level) ) = parse_unstability ( cx, args) {
106122 this. stability = Some ( ( DefaultBodyStability { level, feature } , cx. attr_span ) ) ;
107123 }
108- } ) ] ;
124+ } ,
125+ ) ] ;
109126
110127 fn finalize ( self , _cx : & FinalizeContext < ' _ , ' _ , S > ) -> Option < AttributeKind > {
111128 let ( stability, span) = self . stability ?;
@@ -120,6 +137,7 @@ impl<S: Stage> SingleAttributeParser<S> for ConstStabilityIndirectParser {
120137 const PATH : & [ Symbol ] = & [ sym:: rustc_const_stable_indirect] ;
121138 const ATTRIBUTE_ORDER : AttributeOrder = AttributeOrder :: KeepFirst ;
122139 const ON_DUPLICATE : OnDuplicate < S > = OnDuplicate :: Ignore ;
140+ const TEMPLATE : AttributeTemplate = template ! ( Word ) ;
123141
124142 fn convert ( _cx : & mut AcceptContext < ' _ , ' _ , S > , _args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
125143 Some ( AttributeKind :: ConstStabilityIndirect )
@@ -146,7 +164,7 @@ impl ConstStabilityParser {
146164
147165impl < S : Stage > AttributeParser < S > for ConstStabilityParser {
148166 const ATTRIBUTES : AcceptMapping < Self , S > = & [
149- ( & [ sym:: rustc_const_stable] , |this, cx, args| {
167+ ( & [ sym:: rustc_const_stable] , template ! ( List : r#"feature = "name""# ) , |this, cx, args| {
150168 reject_outside_std ! ( cx) ;
151169
152170 if !this. check_duplicate ( cx)
@@ -158,7 +176,7 @@ impl<S: Stage> AttributeParser<S> for ConstStabilityParser {
158176 ) ) ;
159177 }
160178 } ) ,
161- ( & [ sym:: rustc_const_unstable] , |this, cx, args| {
179+ ( & [ sym:: rustc_const_unstable] , template ! ( List : r#"feature = "name""# ) , |this, cx, args| {
162180 reject_outside_std ! ( cx) ;
163181 if !this. check_duplicate ( cx)
164182 && let Some ( ( feature, level) ) = parse_unstability ( cx, args)
@@ -169,7 +187,7 @@ impl<S: Stage> AttributeParser<S> for ConstStabilityParser {
169187 ) ) ;
170188 }
171189 } ) ,
172- ( & [ sym:: rustc_promotable] , |this, cx, _| {
190+ ( & [ sym:: rustc_promotable] , template ! ( Word ) , |this, cx, _| {
173191 reject_outside_std ! ( cx) ;
174192 this. promotable = true ;
175193 } ) ,
0 commit comments