Skip to content

Commit 483567e

Browse files
committed
Auto merge of #56595 - ljedrz:x_py_clippy_fix, r=oli-obk
Add clippy and fix commands to x.py Since they are kind of similar in nature, I have used the same approach as for `cargo check`. At least some of the boilerplate could probably be shared, but I'd prefer to gather some feedback before I decide to merge them more aggressively. This works reasonably well for `clippy`; with `-A clippy::all` and some extra `#![feature(rustc_private)]`s almost the whole codebase can be processed. There are some concerns, though: - unlike `check`, in order to be able to traverse all the crates, some of them need to be marked with the `#![feature(rustc_private)]` attribute - `-W clippy::all` breaks on any error. Is there a way to produce errors but not have them break the progress? - I'm not sure how to redirect the errors in a way that would show colors; for now I was able to de-jsonize and print them (something not needed for `check`) `cargo fix` is much more stubborn; it refuses to acknowledge crates like `core` and `std`, so it doesn't progress much at all. Since this is a bit more tricky than I have envisioned, I need some guidance: - is this the right approach or am I doing something very wrong ^^? - why are the extra `rustc_private` features necessary? I was hoping for the same treatment as `check` - are changes in `clippy` and `cargo fix` needed e.g. in order to produce errors in the same manner as `check` or did I miss something? - do we need this level of file granularity (e.g. for futureproofing) or can `check`, `clippy` and `fix` files be condensed? Hopes-to-fix: #53896 Cc @alexcrichton, @zackmdavis
2 parents f492693 + 2f3533b commit 483567e

File tree

5 files changed

+105
-17
lines changed

5 files changed

+105
-17
lines changed

src/bootstrap/builder.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ impl<'a> ShouldRun<'a> {
318318
pub enum Kind {
319319
Build,
320320
Check,
321+
Clippy,
322+
Fix,
321323
Test,
322324
Bench,
323325
Dist,
@@ -359,7 +361,7 @@ impl<'a> Builder<'a> {
359361
tool::Miri,
360362
native::Lld
361363
),
362-
Kind::Check => describe!(
364+
Kind::Check | Kind::Clippy | Kind::Fix => describe!(
363365
check::Std,
364366
check::Test,
365367
check::Rustc,
@@ -520,6 +522,8 @@ impl<'a> Builder<'a> {
520522
let (kind, paths) = match build.config.cmd {
521523
Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
522524
Subcommand::Check { ref paths } => (Kind::Check, &paths[..]),
525+
Subcommand::Clippy { ref paths } => (Kind::Clippy, &paths[..]),
526+
Subcommand::Fix { ref paths } => (Kind::Fix, &paths[..]),
523527
Subcommand::Doc { ref paths } => (Kind::Doc, &paths[..]),
524528
Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
525529
Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
@@ -757,17 +761,17 @@ impl<'a> Builder<'a> {
757761
};
758762

759763
let libstd_stamp = match cmd {
760-
"check" => check::libstd_stamp(self, cmp, target),
764+
"check" | "clippy" | "fix" => check::libstd_stamp(self, cmp, target),
761765
_ => compile::libstd_stamp(self, cmp, target),
762766
};
763767

764768
let libtest_stamp = match cmd {
765-
"check" => check::libtest_stamp(self, cmp, target),
769+
"check" | "clippy" | "fix" => check::libtest_stamp(self, cmp, target),
766770
_ => compile::libstd_stamp(self, cmp, target),
767771
};
768772

769773
let librustc_stamp = match cmd {
770-
"check" => check::librustc_stamp(self, cmp, target),
774+
"check" | "clippy" | "fix" => check::librustc_stamp(self, cmp, target),
771775
_ => compile::librustc_stamp(self, cmp, target),
772776
};
773777

@@ -831,9 +835,9 @@ impl<'a> Builder<'a> {
831835
assert_eq!(target, compiler.host);
832836
}
833837

834-
// Set a flag for `check` so that certain build scripts can do less work
835-
// (e.g., not building/requiring LLVM).
836-
if cmd == "check" {
838+
// Set a flag for `check`/`clippy`/`fix`, so that certain build
839+
// scripts can do less work (e.g. not building/requiring LLVM).
840+
if cmd == "check" || cmd == "clippy" || cmd == "fix" {
837841
cargo.env("RUST_CHECK", "1");
838842
}
839843

@@ -898,6 +902,11 @@ impl<'a> Builder<'a> {
898902
extra_args.push_str(&s);
899903
}
900904

905+
if cmd == "clippy" {
906+
extra_args.push_str("-Zforce-unstable-if-unmarked -Zunstable-options \
907+
--json-rendered=termcolor");
908+
}
909+
901910
if !extra_args.is_empty() {
902911
cargo.env(
903912
"RUSTFLAGS",
@@ -966,7 +975,7 @@ impl<'a> Builder<'a> {
966975
if let Some(ref error_format) = self.config.rustc_error_format {
967976
cargo.env("RUSTC_ERROR_FORMAT", error_format);
968977
}
969-
if cmd != "build" && cmd != "check" && cmd != "rustc" && want_rustdoc {
978+
if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
970979
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
971980
}
972981

src/bootstrap/check.rs

+30-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
//! Implementation of compiling the compiler and standard library, in "check" mode.
1+
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
22
33
use crate::compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env,
44
add_to_sysroot};
5-
use crate::builder::{RunConfig, Builder, ShouldRun, Step};
5+
use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step};
66
use crate::tool::{prepare_tool_cargo, SourceType};
77
use crate::{Compiler, Mode};
88
use crate::cache::{INTERNER, Interned};
@@ -13,6 +13,22 @@ pub struct Std {
1313
pub target: Interned<String>,
1414
}
1515

16+
fn args(kind: Kind) -> Vec<String> {
17+
match kind {
18+
Kind::Clippy => vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()],
19+
_ => Vec::new()
20+
}
21+
}
22+
23+
fn cargo_subcommand(kind: Kind) -> &'static str {
24+
match kind {
25+
Kind::Check => "check",
26+
Kind::Clippy => "clippy",
27+
Kind::Fix => "fix",
28+
_ => unreachable!()
29+
}
30+
}
31+
1632
impl Step for Std {
1733
type Output = ();
1834
const DEFAULT: bool = true;
@@ -31,13 +47,14 @@ impl Step for Std {
3147
let target = self.target;
3248
let compiler = builder.compiler(0, builder.config.build);
3349

34-
let mut cargo = builder.cargo(compiler, Mode::Std, target, "check");
50+
let mut cargo = builder.cargo(compiler, Mode::Std, target, cargo_subcommand(builder.kind));
3551
std_cargo(builder, &compiler, target, &mut cargo);
3652

3753
let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage));
3854
builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
3955
run_cargo(builder,
4056
&mut cargo,
57+
args(builder.kind),
4158
&libstd_stamp(builder, compiler, target),
4259
true);
4360

@@ -78,13 +95,15 @@ impl Step for Rustc {
7895

7996
builder.ensure(Test { target });
8097

81-
let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "check");
98+
let mut cargo = builder.cargo(compiler, Mode::Rustc, target,
99+
cargo_subcommand(builder.kind));
82100
rustc_cargo(builder, &mut cargo);
83101

84102
let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage));
85103
builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
86104
run_cargo(builder,
87105
&mut cargo,
106+
args(builder.kind),
88107
&librustc_stamp(builder, compiler, target),
89108
true);
90109

@@ -127,7 +146,8 @@ impl Step for CodegenBackend {
127146

128147
builder.ensure(Rustc { target });
129148

130-
let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "check");
149+
let mut cargo = builder.cargo(compiler, Mode::Codegen, target,
150+
cargo_subcommand(builder.kind));
131151
cargo.arg("--manifest-path").arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
132152
rustc_cargo_env(builder, &mut cargo);
133153

@@ -136,6 +156,7 @@ impl Step for CodegenBackend {
136156
let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
137157
run_cargo(builder,
138158
&mut cargo,
159+
args(builder.kind),
139160
&codegen_backend_stamp(builder, compiler, target, backend),
140161
true);
141162
}
@@ -166,13 +187,14 @@ impl Step for Test {
166187

167188
builder.ensure(Std { target });
168189

169-
let mut cargo = builder.cargo(compiler, Mode::Test, target, "check");
190+
let mut cargo = builder.cargo(compiler, Mode::Test, target, cargo_subcommand(builder.kind));
170191
test_cargo(builder, &compiler, target, &mut cargo);
171192

172193
let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage));
173194
builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target));
174195
run_cargo(builder,
175196
&mut cargo,
197+
args(builder.kind),
176198
&libtest_stamp(builder, compiler, target),
177199
true);
178200

@@ -212,7 +234,7 @@ impl Step for Rustdoc {
212234
compiler,
213235
Mode::ToolRustc,
214236
target,
215-
"check",
237+
cargo_subcommand(builder.kind),
216238
"src/tools/rustdoc",
217239
SourceType::InTree,
218240
&[]);
@@ -221,6 +243,7 @@ impl Step for Rustdoc {
221243
println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);
222244
run_cargo(builder,
223245
&mut cargo,
246+
args(builder.kind),
224247
&rustdoc_stamp(builder, compiler, target),
225248
true);
226249

src/bootstrap/compile.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ impl Step for Std {
100100
&compiler.host, target));
101101
run_cargo(builder,
102102
&mut cargo,
103+
vec![],
103104
&libstd_stamp(builder, compiler, target),
104105
false);
105106

@@ -425,6 +426,7 @@ impl Step for Test {
425426
&compiler.host, target));
426427
run_cargo(builder,
427428
&mut cargo,
429+
vec![],
428430
&libtest_stamp(builder, compiler, target),
429431
false);
430432

@@ -556,6 +558,7 @@ impl Step for Rustc {
556558
compiler.stage, &compiler.host, target));
557559
run_cargo(builder,
558560
&mut cargo,
561+
vec![],
559562
&librustc_stamp(builder, compiler, target),
560563
false);
561564

@@ -707,6 +710,7 @@ impl Step for CodegenBackend {
707710
let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
708711
let files = run_cargo(builder,
709712
cargo.arg("--features").arg(features),
713+
vec![],
710714
&tmp_stamp,
711715
false);
712716
if builder.config.dry_run {
@@ -1077,6 +1081,7 @@ pub fn add_to_sysroot(
10771081

10781082
pub fn run_cargo(builder: &Builder<'_>,
10791083
cargo: &mut Command,
1084+
tail_args: Vec<String>,
10801085
stamp: &Path,
10811086
is_check: bool)
10821087
-> Vec<PathBuf>
@@ -1099,7 +1104,7 @@ pub fn run_cargo(builder: &Builder<'_>,
10991104
// files we need to probe for later.
11001105
let mut deps = Vec::new();
11011106
let mut toplevel = Vec::new();
1102-
let ok = stream_cargo(builder, cargo, &mut |msg| {
1107+
let ok = stream_cargo(builder, cargo, tail_args, &mut |msg| {
11031108
let (filenames, crate_types) = match msg {
11041109
CargoMessage::CompilerArtifact {
11051110
filenames,
@@ -1108,6 +1113,10 @@ pub fn run_cargo(builder: &Builder<'_>,
11081113
},
11091114
..
11101115
} => (filenames, crate_types),
1116+
CargoMessage::CompilerMessage { message } => {
1117+
eprintln!("{}", message.rendered);
1118+
return;
1119+
}
11111120
_ => return,
11121121
};
11131122
for filename in filenames {
@@ -1235,6 +1244,7 @@ pub fn run_cargo(builder: &Builder<'_>,
12351244
pub fn stream_cargo(
12361245
builder: &Builder<'_>,
12371246
cargo: &mut Command,
1247+
tail_args: Vec<String>,
12381248
cb: &mut dyn FnMut(CargoMessage<'_>),
12391249
) -> bool {
12401250
if builder.config.dry_run {
@@ -1245,6 +1255,10 @@ pub fn stream_cargo(
12451255
cargo.arg("--message-format").arg("json")
12461256
.stdout(Stdio::piped());
12471257

1258+
for arg in tail_args {
1259+
cargo.arg(arg);
1260+
}
1261+
12481262
builder.verbose(&format!("running: {:?}", cargo));
12491263
let mut child = match cargo.spawn() {
12501264
Ok(child) => child,
@@ -1291,5 +1305,13 @@ pub enum CargoMessage<'a> {
12911305
},
12921306
BuildScriptExecuted {
12931307
package_id: Cow<'a, str>,
1308+
},
1309+
CompilerMessage {
1310+
message: ClippyMessage<'a>
12941311
}
12951312
}
1313+
1314+
#[derive(Deserialize)]
1315+
pub struct ClippyMessage<'a> {
1316+
rendered: Cow<'a, str>,
1317+
}

src/bootstrap/flags.rs

+34
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ pub enum Subcommand {
4444
Check {
4545
paths: Vec<PathBuf>,
4646
},
47+
Clippy {
48+
paths: Vec<PathBuf>,
49+
},
50+
Fix {
51+
paths: Vec<PathBuf>,
52+
},
4753
Doc {
4854
paths: Vec<PathBuf>,
4955
},
@@ -90,6 +96,8 @@ Usage: x.py <subcommand> [options] [<paths>...]
9096
Subcommands:
9197
build Compile either the compiler or libraries
9298
check Compile either the compiler or libraries, using cargo check
99+
clippy Run clippy
100+
fix Run cargo fix
93101
test Build and run some test suites
94102
bench Build and run some benchmarks
95103
doc Build documentation
@@ -146,6 +154,8 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`"
146154
let subcommand = args.iter().find(|&s| {
147155
(s == "build")
148156
|| (s == "check")
157+
|| (s == "clippy")
158+
|| (s == "fix")
149159
|| (s == "test")
150160
|| (s == "bench")
151161
|| (s == "doc")
@@ -281,6 +291,28 @@ Arguments:
281291
the compiler.",
282292
);
283293
}
294+
"clippy" => {
295+
subcommand_help.push_str(
296+
"\n
297+
Arguments:
298+
This subcommand accepts a number of paths to directories to the crates
299+
and/or artifacts to run clippy against. For example:
300+
301+
./x.py clippy src/libcore
302+
./x.py clippy src/libcore src/libproc_macro",
303+
);
304+
}
305+
"fix" => {
306+
subcommand_help.push_str(
307+
"\n
308+
Arguments:
309+
This subcommand accepts a number of paths to directories to the crates
310+
and/or artifacts to run `cargo fix` against. For example:
311+
312+
./x.py fix src/libcore
313+
./x.py fix src/libcore src/libproc_macro",
314+
);
315+
}
284316
"test" => {
285317
subcommand_help.push_str(
286318
"\n
@@ -363,6 +395,8 @@ Arguments:
363395
let cmd = match subcommand.as_str() {
364396
"build" => Subcommand::Build { paths },
365397
"check" => Subcommand::Check { paths },
398+
"clippy" => Subcommand::Clippy { paths },
399+
"fix" => Subcommand::Fix { paths },
366400
"test" => Subcommand::Test {
367401
paths,
368402
bless: matches.opt_present("bless"),

src/bootstrap/tool.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl Step for ToolBuild {
7777
let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
7878
builder.info(&format!("Building stage{} tool {} ({})", compiler.stage, tool, target));
7979
let mut duplicates = Vec::new();
80-
let is_expected = compile::stream_cargo(builder, &mut cargo, &mut |msg| {
80+
let is_expected = compile::stream_cargo(builder, &mut cargo, vec![], &mut |msg| {
8181
// Only care about big things like the RLS/Cargo for now
8282
match tool {
8383
| "rls"

0 commit comments

Comments
 (0)