@@ -8,170 +8,190 @@ pub(super) fn handle_needs(
8
8
) -> IgnoreDecision {
9
9
// Note thet we intentionally still put the needs- prefix here to make the file show up when
10
10
// grepping for a directive name, even though we could technically strip that.
11
- let needs = & [
11
+ let needs = & mut [
12
12
Need {
13
13
name : "needs-asm-support" ,
14
- condition : config. has_asm_support ( ) ,
14
+ condition : & mut |_| config. has_asm_support ( ) . then_some ( IgnoreDecision :: Continue ) ,
15
15
ignore_reason : "ignored on targets without inline assembly support" ,
16
16
} ,
17
17
Need {
18
18
name : "needs-sanitizer-support" ,
19
- condition : cache. sanitizer_support ,
19
+ condition : & mut |_| cache. sanitizer_support . then_some ( IgnoreDecision :: Continue ) ,
20
20
ignore_reason : "ignored on targets without sanitizers support" ,
21
21
} ,
22
22
Need {
23
23
name : "needs-sanitizer-address" ,
24
- condition : cache. sanitizer_address ,
24
+ condition : & mut |_| cache. sanitizer_address . then_some ( IgnoreDecision :: Continue ) ,
25
25
ignore_reason : "ignored on targets without address sanitizer" ,
26
26
} ,
27
27
Need {
28
28
name : "needs-sanitizer-cfi" ,
29
- condition : cache. sanitizer_cfi ,
29
+ condition : & mut |_| cache. sanitizer_cfi . then_some ( IgnoreDecision :: Continue ) ,
30
30
ignore_reason : "ignored on targets without CFI sanitizer" ,
31
31
} ,
32
32
Need {
33
33
name : "needs-sanitizer-dataflow" ,
34
- condition : cache. sanitizer_dataflow ,
34
+ condition : & mut |_| cache. sanitizer_dataflow . then_some ( IgnoreDecision :: Continue ) ,
35
35
ignore_reason : "ignored on targets without dataflow sanitizer" ,
36
36
} ,
37
37
Need {
38
38
name : "needs-sanitizer-kcfi" ,
39
- condition : cache. sanitizer_kcfi ,
39
+ condition : & mut |_| cache. sanitizer_kcfi . then_some ( IgnoreDecision :: Continue ) ,
40
40
ignore_reason : "ignored on targets without kernel CFI sanitizer" ,
41
41
} ,
42
42
Need {
43
43
name : "needs-sanitizer-kasan" ,
44
- condition : cache. sanitizer_kasan ,
44
+ condition : & mut |_| cache. sanitizer_kasan . then_some ( IgnoreDecision :: Continue ) ,
45
45
ignore_reason : "ignored on targets without kernel address sanitizer" ,
46
46
} ,
47
47
Need {
48
48
name : "needs-sanitizer-leak" ,
49
- condition : cache. sanitizer_leak ,
49
+ condition : & mut |_| cache. sanitizer_leak . then_some ( IgnoreDecision :: Continue ) ,
50
50
ignore_reason : "ignored on targets without leak sanitizer" ,
51
51
} ,
52
52
Need {
53
53
name : "needs-sanitizer-memory" ,
54
- condition : cache. sanitizer_memory ,
54
+ condition : & mut |_| cache. sanitizer_memory . then_some ( IgnoreDecision :: Continue ) ,
55
55
ignore_reason : "ignored on targets without memory sanitizer" ,
56
56
} ,
57
57
Need {
58
58
name : "needs-sanitizer-thread" ,
59
- condition : cache. sanitizer_thread ,
59
+ condition : & mut |_| cache. sanitizer_thread . then_some ( IgnoreDecision :: Continue ) ,
60
60
ignore_reason : "ignored on targets without thread sanitizer" ,
61
61
} ,
62
62
Need {
63
63
name : "needs-sanitizer-hwaddress" ,
64
- condition : cache. sanitizer_hwaddress ,
64
+ condition : & mut |_| cache. sanitizer_hwaddress . then_some ( IgnoreDecision :: Continue ) ,
65
65
ignore_reason : "ignored on targets without hardware-assisted address sanitizer" ,
66
66
} ,
67
67
Need {
68
68
name : "needs-sanitizer-memtag" ,
69
- condition : cache. sanitizer_memtag ,
69
+ condition : & mut |_| cache. sanitizer_memtag . then_some ( IgnoreDecision :: Continue ) ,
70
70
ignore_reason : "ignored on targets without memory tagging sanitizer" ,
71
71
} ,
72
72
Need {
73
73
name : "needs-sanitizer-shadow-call-stack" ,
74
- condition : cache. sanitizer_shadow_call_stack ,
74
+ condition : & mut |_| {
75
+ cache. sanitizer_shadow_call_stack . then_some ( IgnoreDecision :: Continue )
76
+ } ,
75
77
ignore_reason : "ignored on targets without shadow call stacks" ,
76
78
} ,
77
79
Need {
78
80
name : "needs-sanitizer-safestack" ,
79
- condition : cache. sanitizer_safestack ,
81
+ condition : & mut |_| cache. sanitizer_safestack . then_some ( IgnoreDecision :: Continue ) ,
80
82
ignore_reason : "ignored on targets without SafeStack support" ,
81
83
} ,
82
84
Need {
83
85
name : "needs-enzyme" ,
84
- condition : config. has_enzyme ,
86
+ condition : & mut |_| config. has_enzyme . then_some ( IgnoreDecision :: Continue ) ,
85
87
ignore_reason : "ignored when LLVM Enzyme is disabled" ,
86
88
} ,
87
89
Need {
88
90
name : "needs-run-enabled" ,
89
- condition : config. run_enabled ( ) ,
91
+ condition : & mut |_| config. run_enabled ( ) . then_some ( IgnoreDecision :: Continue ) ,
90
92
ignore_reason : "ignored when running the resulting test binaries is disabled" ,
91
93
} ,
92
94
Need {
93
95
name : "needs-threads" ,
94
- condition : config. has_threads ( ) ,
96
+ condition : & mut |_| config. has_threads ( ) . then_some ( IgnoreDecision :: Continue ) ,
95
97
ignore_reason : "ignored on targets without threading support" ,
96
98
} ,
97
99
Need {
98
100
name : "needs-unwind" ,
99
- condition : config. can_unwind ( ) ,
101
+ condition : & mut |_| config. can_unwind ( ) . then_some ( IgnoreDecision :: Continue ) ,
100
102
ignore_reason : "ignored on targets without unwinding support" ,
101
103
} ,
102
104
Need {
103
105
name : "needs-profiler-runtime" ,
104
- condition : config. profiler_runtime ,
106
+ condition : & mut |_| config. profiler_runtime . then_some ( IgnoreDecision :: Continue ) ,
105
107
ignore_reason : "ignored when the profiler runtime is not available" ,
106
108
} ,
107
109
Need {
108
110
name : "needs-force-clang-based-tests" ,
109
- condition : config. run_clang_based_tests_with . is_some ( ) ,
111
+ condition : & mut |_| {
112
+ config. run_clang_based_tests_with . is_some ( ) . then_some ( IgnoreDecision :: Continue )
113
+ } ,
110
114
ignore_reason : "ignored when RUSTBUILD_FORCE_CLANG_BASED_TESTS is not set" ,
111
115
} ,
112
116
Need {
113
117
name : "needs-xray" ,
114
- condition : cache. xray ,
118
+ condition : & mut |_| cache. xray . then_some ( IgnoreDecision :: Continue ) ,
115
119
ignore_reason : "ignored on targets without xray tracing" ,
116
120
} ,
117
121
Need {
118
122
name : "needs-rust-lld" ,
119
- condition : cache. rust_lld ,
123
+ condition : & mut |_| cache. rust_lld . then_some ( IgnoreDecision :: Continue ) ,
120
124
ignore_reason : "ignored on targets without Rust's LLD" ,
121
125
} ,
122
126
Need {
123
127
name : "needs-dlltool" ,
124
- condition : cache. dlltool ,
128
+ condition : & mut |_| cache. dlltool . then_some ( IgnoreDecision :: Continue ) ,
125
129
ignore_reason : "ignored when dlltool for the current architecture is not present" ,
126
130
} ,
127
131
Need {
128
132
name : "needs-git-hash" ,
129
- condition : config. git_hash ,
133
+ condition : & mut |_| config. git_hash . then_some ( IgnoreDecision :: Continue ) ,
130
134
ignore_reason : "ignored when git hashes have been omitted for building" ,
131
135
} ,
132
136
Need {
133
137
name : "needs-dynamic-linking" ,
134
- condition : config. target_cfg ( ) . dynamic_linking ,
138
+ condition : & mut |_| {
139
+ config. target_cfg ( ) . dynamic_linking . then_some ( IgnoreDecision :: Continue )
140
+ } ,
135
141
ignore_reason : "ignored on targets without dynamic linking" ,
136
142
} ,
137
143
Need {
138
144
name : "needs-relocation-model-pic" ,
139
- condition : config. target_cfg ( ) . relocation_model == "pic" ,
145
+ condition : & mut |_| {
146
+ ( config. target_cfg ( ) . relocation_model == "PIC" ) . then_some ( IgnoreDecision :: Continue )
147
+ } ,
140
148
ignore_reason : "ignored on targets without PIC relocation model" ,
141
149
} ,
142
150
Need {
143
151
name : "needs-deterministic-layouts" ,
144
- condition : !config. rust_randomized_layout ,
152
+ condition : & mut |_| {
153
+ ( !config. rust_randomized_layout ) . then_some ( IgnoreDecision :: Continue )
154
+ } ,
145
155
ignore_reason : "ignored when randomizing layouts" ,
146
156
} ,
147
157
Need {
148
158
name : "needs-wasmtime" ,
149
- condition : config. runner . as_ref ( ) . is_some_and ( |r| r. contains ( "wasmtime" ) ) ,
159
+ condition : & mut |_| {
160
+ config
161
+ . runner
162
+ . as_ref ( )
163
+ . is_some_and ( |r| r. contains ( "wasmtime" ) )
164
+ . then_some ( IgnoreDecision :: Continue )
165
+ } ,
150
166
ignore_reason : "ignored when wasmtime runner is not available" ,
151
167
} ,
152
168
Need {
153
169
name : "needs-symlink" ,
154
- condition : cache. symlinks ,
170
+ condition : & mut |_| cache. symlinks . then_some ( IgnoreDecision :: Continue ) ,
155
171
ignore_reason : "ignored if symlinks are unavailable" ,
156
172
} ,
157
173
Need {
158
174
name : "needs-llvm-zstd" ,
159
- condition : cache. llvm_zstd ,
175
+ condition : & mut |_| cache. llvm_zstd . then_some ( IgnoreDecision :: Continue ) ,
160
176
ignore_reason : "ignored if LLVM wasn't build with zstd for ELF section compression" ,
161
177
} ,
162
178
Need {
163
179
name : "needs-rustc-debug-assertions" ,
164
- condition : config. with_rustc_debug_assertions ,
180
+ condition : & mut |_| {
181
+ config. with_rustc_debug_assertions . then_some ( IgnoreDecision :: Continue )
182
+ } ,
165
183
ignore_reason : "ignored if rustc wasn't built with debug assertions" ,
166
184
} ,
167
185
Need {
168
186
name : "needs-std-debug-assertions" ,
169
- condition : config. with_std_debug_assertions ,
187
+ condition : & mut |_| {
188
+ config. with_std_debug_assertions . then_some ( IgnoreDecision :: Continue )
189
+ } ,
170
190
ignore_reason : "ignored if std wasn't built with debug assertions" ,
171
191
} ,
172
192
] ;
173
193
174
- let ( name, comment) = match ln. split_once ( [ ':' , ' ' ] ) {
194
+ let ( name, mut comment) = match ln. split_once ( [ ':' , ' ' ] ) {
175
195
Some ( ( name, comment) ) => ( name, Some ( comment) ) ,
176
196
None => ( ln, None ) ,
177
197
} ;
@@ -185,34 +205,31 @@ pub(super) fn handle_needs(
185
205
return IgnoreDecision :: Continue ;
186
206
}
187
207
188
- let mut found_valid = false ;
189
- for need in needs {
190
- if need. name == name {
191
- if need. condition {
192
- found_valid = true ;
193
- break ;
208
+ needs
209
+ . iter_mut ( )
210
+ . find_map ( |need| {
211
+ if need. name == name {
212
+ ( need. condition ) ( & mut comment) . or_else ( || {
213
+ Some ( IgnoreDecision :: Ignore {
214
+ reason : if let Some ( comment) = comment {
215
+ format ! ( "{} ({})" , need. ignore_reason, comment. trim( ) )
216
+ } else {
217
+ need. ignore_reason . into ( )
218
+ } ,
219
+ } )
220
+ } )
194
221
} else {
195
- return IgnoreDecision :: Ignore {
196
- reason : if let Some ( comment) = comment {
197
- format ! ( "{} ({})" , need. ignore_reason, comment. trim( ) )
198
- } else {
199
- need. ignore_reason . into ( )
200
- } ,
201
- } ;
222
+ None
202
223
}
203
- }
204
- }
205
-
206
- if found_valid {
207
- IgnoreDecision :: Continue
208
- } else {
209
- IgnoreDecision :: Error { message : format ! ( "invalid needs directive: {name}" ) }
210
- }
224
+ } )
225
+ . unwrap_or_else ( || IgnoreDecision :: Error {
226
+ message : format ! ( "invalid needs directive: {name}" ) ,
227
+ } )
211
228
}
212
229
213
- struct Need {
230
+ struct Need < ' a > {
214
231
name : & ' static str ,
215
- condition : bool ,
232
+ condition : & ' a mut dyn FnMut ( & mut Option < & str > ) -> Option < IgnoreDecision > ,
216
233
ignore_reason : & ' static str ,
217
234
}
218
235
0 commit comments