1
- use rustc_feature:: AttributeType ;
1
+ use std:: num:: IntErrorKind ;
2
+
3
+ use rustc_hir:: limit:: Limit ;
2
4
3
5
use 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
+ }
4
38
5
39
pub ( crate ) struct CrateNameParser ;
6
40
@@ -11,8 +45,8 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
11
45
const TEMPLATE : AttributeTemplate = template ! ( NameValueStr : "name" ) ;
12
46
const TYPE : AttributeType = AttributeType :: CrateLevel ;
13
47
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
16
50
const ALLOWED_TARGETS : AllowedTargets = AllowedTargets :: AllowList ( ALL_TARGETS ) ;
17
51
18
52
fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
@@ -34,3 +68,111 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
34
68
} )
35
69
}
36
70
}
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