@@ -171,9 +171,12 @@ pub(super) fn handle_needs(
171
171
} ,
172
172
] ;
173
173
174
- let ( name, comment) = match ln. split_once ( [ ':' , ' ' ] ) {
175
- Some ( ( name, comment) ) => ( name, Some ( comment) ) ,
176
- None => ( ln, None ) ,
174
+ // Because `needs-atomic` accepts one argument after colon to specify data size, we check whther
175
+ // comment starts with colon.
176
+ let ( name, comment, comment_starts_with_colon) = if let Some ( index) = ln. find ( [ ':' , ' ' ] ) {
177
+ ( & ln[ ..index] , Some ( & ln[ index + 1 ..] ) , ln. as_bytes ( ) [ index] == b':' )
178
+ } else {
179
+ ( ln, None , false )
177
180
} ;
178
181
179
182
if !name. starts_with ( "needs-" ) {
@@ -185,6 +188,69 @@ pub(super) fn handle_needs(
185
188
return IgnoreDecision :: Continue ;
186
189
}
187
190
191
+ // Check here because `needs-atomic` requires parsing comments.
192
+ if name == "needs-atomic" {
193
+ let mut comment = comment;
194
+
195
+ // Parse the comment to specify data size.
196
+ // Just comments not arguments are also accepted.
197
+ // No arguments are handled as (none).
198
+ let size = if !comment_starts_with_colon {
199
+ // Comments starting with spaces are not arguments.
200
+ None
201
+ } else {
202
+ if let Some ( comment_content) = comment {
203
+ if comment_content. trim ( ) . is_empty ( ) {
204
+ None
205
+ } else {
206
+ let ( size, rest) = match comment_content. trim_start ( ) . split_once ( [ ':' , ' ' ] ) {
207
+ Some ( ( size, rest) ) => ( size, Some ( rest) ) ,
208
+ None => ( comment_content. trim ( ) , None ) ,
209
+ } ;
210
+
211
+ if size == "ptr" {
212
+ comment = rest;
213
+ Some ( config. target_cfg ( ) . pointer_width as _ )
214
+ } else if let Ok ( size) = size. parse ( ) {
215
+ if ![ 128 , 64 , 32 , 16 , 8 ] . contains ( & size) {
216
+ // Numeric literals but non data size are disallowed.
217
+ return IgnoreDecision :: Error {
218
+ message : "expected values for `needs-atomic` are: (none), `128`,\
219
+ `16`, `32`, `64`, `8`, and `ptr"
220
+ . into ( ) ,
221
+ } ;
222
+ } else {
223
+ comment = rest;
224
+ Some ( size)
225
+ }
226
+ } else {
227
+ // Comments starting with non-numeric literals are not arguments.
228
+ None
229
+ }
230
+ }
231
+ } else {
232
+ None
233
+ }
234
+ } ;
235
+
236
+ return if config. has_atomic ( size) {
237
+ IgnoreDecision :: Continue
238
+ } else {
239
+ let base = if let Some ( size) = size {
240
+ format ! ( "ignored on targets without {size}-bit atomic operations" )
241
+ } else {
242
+ format ! ( "ignored on targets without atomic operations" )
243
+ } ;
244
+ IgnoreDecision :: Ignore {
245
+ reason : if let Some ( comment) = comment {
246
+ format ! ( "{base}: ({})" , comment. trim( ) )
247
+ } else {
248
+ base
249
+ } ,
250
+ }
251
+ } ;
252
+ }
253
+
188
254
let mut found_valid = false ;
189
255
for need in needs {
190
256
if need. name == name {
0 commit comments