Skip to content

Commit 0153679

Browse files
committed
Auto merge of #6848 - matthiaskrgr:lintcheck_clippyfix, r=llogiq
lintcheck: add --fix mode which tries to apply lint suggestions to th… …e sources and prints a warning if that fails Great for spotting false positives/broken suggestions of applicable lints. There are false positives though because I'm not sure yet how to silence rustc warnings while keeping clippy warnings. Sometimes rustc makes a suggestion that fails to apply and the implementation does not differentiate between clippy and rustc warnings when applying lint suggestions. changelog: none
2 parents 54def1e + 45424c7 commit 0153679

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

clippy_dev/src/lintcheck.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ impl Crate {
229229
target_dir_index: &AtomicUsize,
230230
thread_limit: usize,
231231
total_crates_to_lint: usize,
232+
fix: bool,
232233
) -> Vec<ClippyWarning> {
233234
// advance the atomic index by one
234235
let index = target_dir_index.fetch_add(1, Ordering::SeqCst);
@@ -252,7 +253,18 @@ impl Crate {
252253

253254
let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir");
254255

255-
let mut args = vec!["--", "--message-format=json", "--", "--cap-lints=warn"];
256+
let mut args = if fix {
257+
vec![
258+
"-Zunstable-options",
259+
"--fix",
260+
"-Zunstable-options",
261+
"--allow-no-vcs",
262+
"--",
263+
"--cap-lints=warn",
264+
]
265+
} else {
266+
vec!["--", "--message-format=json", "--", "--cap-lints=warn"]
267+
};
256268

257269
if let Some(options) = &self.options {
258270
for opt in options {
@@ -282,13 +294,31 @@ impl Crate {
282294
);
283295
});
284296
let stdout = String::from_utf8_lossy(&all_output.stdout);
297+
let stderr = String::from_utf8_lossy(&all_output.stderr);
298+
299+
if fix {
300+
if let Some(stderr) = stderr
301+
.lines()
302+
.find(|line| line.contains("failed to automatically apply fixes suggested by rustc to crate"))
303+
{
304+
let subcrate = &stderr[63..];
305+
println!(
306+
"ERROR: failed to apply some suggetion to {} / to (sub)crate {}",
307+
self.name, subcrate
308+
);
309+
}
310+
// fast path, we don't need the warnings anyway
311+
return Vec::new();
312+
}
313+
285314
let output_lines = stdout.lines();
286315
let warnings: Vec<ClippyWarning> = output_lines
287316
.into_iter()
288317
// get all clippy warnings and ICEs
289318
.filter(|line| filter_clippy_warnings(&line))
290319
.map(|json_msg| parse_json_message(json_msg, &self))
291320
.collect();
321+
292322
warnings
293323
}
294324
}
@@ -301,6 +331,8 @@ struct LintcheckConfig {
301331
sources_toml_path: PathBuf,
302332
// we save the clippy lint results here
303333
lintcheck_results_path: PathBuf,
334+
// whether to just run --fix and not collect all the warnings
335+
fix: bool,
304336
}
305337

306338
impl LintcheckConfig {
@@ -342,11 +374,13 @@ impl LintcheckConfig {
342374
// no -j passed, use a single thread
343375
None => 1,
344376
};
377+
let fix: bool = clap_config.is_present("fix");
345378

346379
LintcheckConfig {
347380
max_jobs,
348381
sources_toml_path,
349382
lintcheck_results_path,
383+
fix,
350384
}
351385
}
352386
}
@@ -598,7 +632,7 @@ pub fn run(clap_config: &ArgMatches) {
598632
.into_iter()
599633
.map(|krate| krate.download_and_extract())
600634
.filter(|krate| krate.name == only_one_crate)
601-
.flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &AtomicUsize::new(0), 1, 1))
635+
.flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &AtomicUsize::new(0), 1, 1, config.fix))
602636
.collect()
603637
} else {
604638
if config.max_jobs > 1 {
@@ -621,19 +655,26 @@ pub fn run(clap_config: &ArgMatches) {
621655
crates
622656
.into_par_iter()
623657
.map(|krate| krate.download_and_extract())
624-
.flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, num_cpus, num_crates))
658+
.flat_map(|krate| {
659+
krate.run_clippy_lints(&cargo_clippy_path, &counter, num_cpus, num_crates, config.fix)
660+
})
625661
.collect()
626662
} else {
627663
// run sequential
628664
let num_crates = crates.len();
629665
crates
630666
.into_iter()
631667
.map(|krate| krate.download_and_extract())
632-
.flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, 1, num_crates))
668+
.flat_map(|krate| krate.run_clippy_lints(&cargo_clippy_path, &counter, 1, num_crates, config.fix))
633669
.collect()
634670
}
635671
};
636672

673+
// if we are in --fix mode, don't change the log files, terminate here
674+
if config.fix {
675+
return;
676+
}
677+
637678
// generate some stats
638679
let (stats_formatted, new_stats) = gather_stats(&clippy_warnings);
639680

clippy_dev/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
7777
.short("j")
7878
.long("jobs")
7979
.help("number of threads to use, 0 automatic choice"),
80-
);
80+
)
81+
.arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply"));
8182

8283
let app = App::new("Clippy developer tooling")
8384
.subcommand(

0 commit comments

Comments
 (0)