1- use rustc_feature:: AttributeType ;
1+ use std:: num:: IntErrorKind ;
2+
3+ use rustc_hir:: limit:: Limit ;
24
35use super :: prelude:: * ;
6+ use crate :: session_diagnostics:: LimitInvalid ;
7+
8+ impl < S : Stage > AcceptContext < ' _ , ' _ , S > {
9+ fn parse_limit_int ( & self , nv : & NameValueParser ) -> Option < Limit > {
10+ let Some ( limit) = nv. value_as_str ( ) else {
11+ self . expected_string_literal ( nv. value_span , Some ( nv. value_as_lit ( ) ) ) ;
12+ return None ;
13+ } ;
14+
15+ let error_str = match limit. as_str ( ) . parse ( ) {
16+ Ok ( i) => return Some ( Limit :: new ( i) ) ,
17+ Err ( e) => match e. kind ( ) {
18+ IntErrorKind :: PosOverflow => "`limit` is too large" ,
19+ IntErrorKind :: Empty => "`limit` must be a non-negative integer" ,
20+ IntErrorKind :: InvalidDigit => "not a valid integer" ,
21+ IntErrorKind :: NegOverflow => {
22+ panic ! (
23+ "`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead"
24+ )
25+ }
26+ IntErrorKind :: Zero => {
27+ panic ! ( "zero is a valid `limit` so should have returned Ok() when parsing" )
28+ }
29+ kind => panic ! ( "unimplemented IntErrorKind variant: {:?}" , kind) ,
30+ } ,
31+ } ;
32+
33+ self . emit_err ( LimitInvalid { span : self . attr_span , value_span : nv. value_span , error_str } ) ;
34+
35+ None
36+ }
37+ }
438
539pub ( crate ) struct CrateNameParser ;
640
@@ -11,8 +45,8 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
1145 const TEMPLATE : AttributeTemplate = template ! ( NameValueStr : "name" ) ;
1246 const TYPE : AttributeType = AttributeType :: CrateLevel ;
1347
14- // FIXME: crate name is allowed on all targets and ignored,
15- // even though it should only be valid on crates of course
48+ // because it's a crate-level attribute, we already warn about it.
49+ // Putting target limitations here would give duplicate warnings
1650 const ALLOWED_TARGETS : AllowedTargets = AllowedTargets :: AllowList ( ALL_TARGETS ) ;
1751
1852 fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
@@ -34,3 +68,111 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
3468 } )
3569 }
3670}
71+
72+ pub ( crate ) struct RecursionLimitParser ;
73+
74+ impl < S : Stage > SingleAttributeParser < S > for RecursionLimitParser {
75+ const PATH : & [ Symbol ] = & [ sym:: recursion_limit] ;
76+ const ATTRIBUTE_ORDER : AttributeOrder = AttributeOrder :: KeepOutermost ;
77+ const ON_DUPLICATE : OnDuplicate < S > = OnDuplicate :: WarnButFutureError ;
78+ const TEMPLATE : AttributeTemplate = template ! ( NameValueStr : "N" , "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute" ) ;
79+ const TYPE : AttributeType = AttributeType :: CrateLevel ;
80+
81+ // because it's a crate-level attribute, we already warn about it.
82+ // Putting target limitations here would give duplicate warnings
83+ const ALLOWED_TARGETS : AllowedTargets = AllowedTargets :: AllowList ( ALL_TARGETS ) ;
84+
85+ fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
86+ let ArgParser :: NameValue ( nv) = args else {
87+ cx. expected_name_value ( cx. attr_span , None ) ;
88+ return None ;
89+ } ;
90+
91+ Some ( AttributeKind :: RecursionLimit {
92+ limit : cx. parse_limit_int ( nv) ?,
93+ attr_span : cx. attr_span ,
94+ limit_span : nv. value_span ,
95+ } )
96+ }
97+ }
98+
99+ pub ( crate ) struct MoveSizeLimitParser ;
100+
101+ impl < S : Stage > SingleAttributeParser < S > for MoveSizeLimitParser {
102+ const PATH : & [ Symbol ] = & [ sym:: move_size_limit] ;
103+ const ATTRIBUTE_ORDER : AttributeOrder = AttributeOrder :: KeepOutermost ;
104+ const ON_DUPLICATE : OnDuplicate < S > = OnDuplicate :: Error ;
105+ const TEMPLATE : AttributeTemplate = template ! ( NameValueStr : "N" ) ;
106+ const TYPE : AttributeType = AttributeType :: CrateLevel ;
107+
108+ // because it's a crate-level attribute, we already warn about it.
109+ // Putting target limitations here would give duplicate warnings
110+ const ALLOWED_TARGETS : AllowedTargets = AllowedTargets :: AllowList ( ALL_TARGETS ) ;
111+
112+ fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
113+ let ArgParser :: NameValue ( nv) = args else {
114+ cx. expected_name_value ( cx. attr_span , None ) ;
115+ return None ;
116+ } ;
117+
118+ Some ( AttributeKind :: MoveSizeLimit {
119+ limit : cx. parse_limit_int ( nv) ?,
120+ attr_span : cx. attr_span ,
121+ limit_span : nv. value_span ,
122+ } )
123+ }
124+ }
125+
126+ pub ( crate ) struct TypeLengthLimitParser ;
127+
128+ impl < S : Stage > SingleAttributeParser < S > for TypeLengthLimitParser {
129+ const PATH : & [ Symbol ] = & [ sym:: type_length_limit] ;
130+ const ATTRIBUTE_ORDER : AttributeOrder = AttributeOrder :: KeepOutermost ;
131+ const ON_DUPLICATE : OnDuplicate < S > = OnDuplicate :: WarnButFutureError ;
132+ const TEMPLATE : AttributeTemplate = template ! ( NameValueStr : "N" ) ;
133+ const TYPE : AttributeType = AttributeType :: CrateLevel ;
134+
135+ // because it's a crate-level attribute, we already warn about it.
136+ // Putting target limitations here would give duplicate warnings
137+ const ALLOWED_TARGETS : AllowedTargets = AllowedTargets :: AllowList ( ALL_TARGETS ) ;
138+
139+ fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
140+ let ArgParser :: NameValue ( nv) = args else {
141+ cx. expected_name_value ( cx. attr_span , None ) ;
142+ return None ;
143+ } ;
144+
145+ Some ( AttributeKind :: TypeLengthLimit {
146+ limit : cx. parse_limit_int ( nv) ?,
147+ attr_span : cx. attr_span ,
148+ limit_span : nv. value_span ,
149+ } )
150+ }
151+ }
152+
153+ pub ( crate ) struct PatternComplexityLimitParser ;
154+
155+ impl < S : Stage > SingleAttributeParser < S > for PatternComplexityLimitParser {
156+ const PATH : & [ Symbol ] = & [ sym:: pattern_complexity_limit] ;
157+ const ATTRIBUTE_ORDER : AttributeOrder = AttributeOrder :: KeepOutermost ;
158+ const ON_DUPLICATE : OnDuplicate < S > = OnDuplicate :: Error ;
159+ const TEMPLATE : AttributeTemplate = template ! ( NameValueStr : "N" ) ;
160+ const TYPE : AttributeType = AttributeType :: CrateLevel ;
161+
162+ // because it's a crate-level attribute, we already warn about it.
163+ // Putting target limitations here would give duplicate warnings
164+ const ALLOWED_TARGETS : AllowedTargets = AllowedTargets :: AllowList ( ALL_TARGETS ) ;
165+
166+ fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
167+ let ArgParser :: NameValue ( nv) = args else {
168+ cx. expected_name_value ( cx. attr_span , None ) ;
169+ return None ;
170+ } ;
171+
172+ Some ( AttributeKind :: PatternComplexityLimit {
173+ limit : cx. parse_limit_int ( nv) ?,
174+ attr_span : cx. attr_span ,
175+ limit_span : nv. value_span ,
176+ } )
177+ }
178+ }
0 commit comments