6
6
// positives.
7
7
8
8
#![ feature( iter_collect_into) ]
9
+ #![ feature( let_chains) ]
9
10
#![ warn(
10
11
trivial_casts,
11
12
trivial_numeric_casts,
@@ -87,8 +88,6 @@ impl Crate {
87
88
) ;
88
89
}
89
90
90
- let shared_target_dir = clippy_project_root ( ) . join ( "target/lintcheck/shared_target_dir" ) ;
91
-
92
91
let cargo_home = env ! ( "CARGO_HOME" ) ;
93
92
94
93
// `src/lib.rs` -> `target/lintcheck/sources/crate-1.2.3/src/lib.rs`
@@ -132,7 +131,7 @@ impl Crate {
132
131
// The wrapper is set to `lintcheck` itself so we can force enable linting and ignore certain crates
133
132
// (see `crate::driver`)
134
133
let status = cmd
135
- . env ( "CARGO_TARGET_DIR" , shared_target_dir. join ( "recursive" ) )
134
+ . env ( "CARGO_TARGET_DIR" , shared_target_dir ( "recursive" ) )
136
135
. env ( "RUSTC_WRAPPER" , env:: current_exe ( ) . unwrap ( ) )
137
136
// Pass the absolute path so `crate::driver` can find `clippy-driver`, as it's executed in various
138
137
// different working directories
@@ -150,9 +149,10 @@ impl Crate {
150
149
cmd. arg ( "--message-format=json" ) ;
151
150
}
152
151
152
+ let shared_target_dir = shared_target_dir ( & format ! ( "_{thread_index:?}" ) ) ;
153
153
let all_output = cmd
154
154
// use the looping index to create individual target dirs
155
- . env ( "CARGO_TARGET_DIR" , shared_target_dir. join ( format ! ( "_{thread_index:?}" ) ) )
155
+ . env ( "CARGO_TARGET_DIR" , shared_target_dir. as_os_str ( ) )
156
156
// Roughly equivalent to `cargo clippy`/`cargo clippy --fix`
157
157
. env ( "RUSTC_WORKSPACE_WRAPPER" , clippy_driver_path)
158
158
. output ( )
@@ -186,7 +186,10 @@ impl Crate {
186
186
// get all clippy warnings and ICEs
187
187
let mut entries: Vec < ClippyCheckOutput > = Message :: parse_stream ( stdout. as_bytes ( ) )
188
188
. filter_map ( |msg| match msg {
189
- Ok ( Message :: CompilerMessage ( message) ) => ClippyWarning :: new ( message. message , & self . base_url ) ,
189
+ Ok ( Message :: CompilerMessage ( message) ) => ClippyWarning :: new (
190
+ normalize_diag ( message. message , shared_target_dir. to_str ( ) . unwrap ( ) ) ,
191
+ & self . base_url ,
192
+ ) ,
190
193
_ => None ,
191
194
} )
192
195
. map ( ClippyCheckOutput :: ClippyWarning )
@@ -202,6 +205,31 @@ impl Crate {
202
205
}
203
206
}
204
207
208
+ /// The target directory can sometimes be stored in the file name of spans.
209
+ /// This is problematic since the directory in constructed from the thread
210
+ /// ID and also used in our CI to determine if two lint emissions are the
211
+ /// same or not. This function simply normalizes the `_<thread_id>` to `_*`.
212
+ fn normalize_diag (
213
+ mut message : cargo_metadata:: diagnostic:: Diagnostic ,
214
+ thread_target_dir : & str ,
215
+ ) -> cargo_metadata:: diagnostic:: Diagnostic {
216
+ let mut dir_found = false ;
217
+ message
218
+ . spans
219
+ . iter_mut ( )
220
+ . filter ( |span| span. file_name . starts_with ( thread_target_dir) )
221
+ . for_each ( |span| {
222
+ dir_found = true ;
223
+ span. file_name
224
+ . replace_range ( 0 ..thread_target_dir. len ( ) , shared_target_dir ( "_*" ) . to_str ( ) . unwrap ( ) ) ;
225
+ } ) ;
226
+
227
+ if dir_found && let Some ( rendered) = & mut message. rendered {
228
+ * rendered = rendered. replace ( thread_target_dir, shared_target_dir ( "_*" ) . to_str ( ) . unwrap ( ) ) ;
229
+ }
230
+ message
231
+ }
232
+
205
233
/// Builds clippy inside the repo to make sure we have a clippy executable we can use.
206
234
fn build_clippy ( ) -> String {
207
235
let output = Command :: new ( "cargo" )
@@ -388,6 +416,15 @@ fn clippy_project_root() -> &'static Path {
388
416
Path :: new ( env ! ( "CARGO_MANIFEST_DIR" ) ) . parent ( ) . unwrap ( )
389
417
}
390
418
419
+ /// The qualifier can be used to separate different threads from another. By
420
+ /// default it should be set to `_<thread_id>`
421
+ #[ must_use]
422
+ fn shared_target_dir ( qualifier : & str ) -> PathBuf {
423
+ clippy_project_root ( )
424
+ . join ( "target/lintcheck/shared_target_dir" )
425
+ . join ( qualifier)
426
+ }
427
+
391
428
#[ test]
392
429
fn lintcheck_test ( ) {
393
430
let args = [
0 commit comments