@@ -171,9 +171,12 @@ pub(super) fn handle_needs(
171171 } ,
172172 ] ;
173173
174- let ( name, comment) = match ln. split_once ( [ ':' , ' ' ] ) {
175- Some ( ( name, comment) ) => ( name, Some ( comment) ) ,
176- None => ( ln, None ) ,
174+ // Because `needs-target-has-atomic` accepts comma separated arguments following a colon to
175+ // specify data sizes, we check whether 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 )
177180 } ;
178181
179182 if !name. starts_with ( "needs-" ) {
@@ -185,6 +188,11 @@ pub(super) fn handle_needs(
185188 return IgnoreDecision :: Continue ;
186189 }
187190
191+ // Check here because `needs-target-has-atomic` requires parsing comments.
192+ if name == "needs-target-has-atomic" {
193+ return handle_needs_target_has_atomic ( comment_starts_with_colon, comment, config) ;
194+ }
195+
188196 let mut found_valid = false ;
189197 for need in needs {
190198 if need. name == name {
@@ -210,6 +218,42 @@ pub(super) fn handle_needs(
210218 }
211219}
212220
221+ fn handle_needs_target_has_atomic (
222+ comment_starts_with_colon : bool ,
223+ comment : Option < & str > ,
224+ config : & Config ,
225+ ) -> IgnoreDecision {
226+ // `needs-target-has-atomic` requires comma-separated data sizes following a collon.
227+ if !comment_starts_with_colon || comment. is_none ( ) {
228+ return IgnoreDecision :: Error {
229+ message : "`needs-target-has-atomic` requires data sizes for atomic operations" . into ( ) ,
230+ } ;
231+ }
232+ let comment = comment. unwrap ( ) ;
233+
234+ // Parse the comment to specify data sizes.
235+ for size in comment. split ( ',' ) . map ( |size| size. trim ( ) ) {
236+ if ![ "ptr" , "128" , "64" , "32" , "16" , "8" ] . contains ( & size) {
237+ return IgnoreDecision :: Error {
238+ message : "expected values for `needs-target-has-atomic` are: `128`, `16`, \\
239+ `32`, `64`, `8`, and `ptr`"
240+ . into ( ) ,
241+ } ;
242+ }
243+ if !config. has_atomic ( size) {
244+ return IgnoreDecision :: Ignore {
245+ reason : if size == "ptr" {
246+ "ignored on targets without ptr-size atomic operations" . into ( )
247+ } else {
248+ format ! ( "ignored on targets without {size}-bit atomic operations" )
249+ } ,
250+ } ;
251+ }
252+ }
253+
254+ IgnoreDecision :: Continue
255+ }
256+
213257struct Need {
214258 name : & ' static str ,
215259 condition : bool ,
0 commit comments