Skip to content

Commit dc06a36

Browse files
committed
Auto merge of #77351 - jyn514:clippy-sysroot, r=Mark-Simulacrum
Fix `x.py clippy` I don't think this ever worked. Fixes #77309. `--fix` support is a work in progress, but works for a very small subset of `libtest`. This works by using the host `cargo-clippy` driver; it does not use `stage0.txt` at all. To mitigate confusion from this, it gives an error if you don't have `rustc +nightly` as the default rustc in `$PATH`. Additionally, it means that bootstrap can't set `RUSTC`; this makes it no longer possible for clippy to detect the sysroot itself. Instead, bootstrap passes the sysroot to cargo. r? `@ghost`
2 parents 8532e74 + 8d2fa72 commit dc06a36

File tree

3 files changed

+76
-19
lines changed

3 files changed

+76
-19
lines changed

Diff for: src/bootstrap/builder.rs

+42-4
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ impl<'a> Builder<'a> {
371371
tool::CargoMiri,
372372
native::Lld
373373
),
374-
Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => describe!(
374+
Kind::Check | Kind::Clippy { .. } | Kind::Fix | Kind::Format => describe!(
375375
check::Std,
376376
check::Rustc,
377377
check::Rustdoc,
@@ -539,7 +539,7 @@ impl<'a> Builder<'a> {
539539
let (kind, paths) = match build.config.cmd {
540540
Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
541541
Subcommand::Check { ref paths, all_targets: _ } => (Kind::Check, &paths[..]),
542-
Subcommand::Clippy { ref paths } => (Kind::Clippy, &paths[..]),
542+
Subcommand::Clippy { ref paths, .. } => (Kind::Clippy, &paths[..]),
543543
Subcommand::Fix { ref paths } => (Kind::Fix, &paths[..]),
544544
Subcommand::Doc { ref paths, .. } => (Kind::Doc, &paths[..]),
545545
Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
@@ -849,7 +849,41 @@ impl<'a> Builder<'a> {
849849
cargo.args(s.split_whitespace());
850850
}
851851
rustflags.env("RUSTFLAGS_BOOTSTRAP");
852-
rustflags.arg("--cfg=bootstrap");
852+
if cmd == "clippy" {
853+
// clippy overwrites sysroot if we pass it to cargo.
854+
// Pass it directly to clippy instead.
855+
// NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
856+
// so it has no way of knowing the sysroot.
857+
rustflags.arg("--sysroot");
858+
rustflags.arg(
859+
self.sysroot(compiler)
860+
.as_os_str()
861+
.to_str()
862+
.expect("sysroot must be valid UTF-8"),
863+
);
864+
// Only run clippy on a very limited subset of crates (in particular, not build scripts).
865+
cargo.arg("-Zunstable-options");
866+
// Explicitly does *not* set `--cfg=bootstrap`, since we're using a nightly clippy.
867+
let host_version = Command::new("rustc").arg("--version").output().map_err(|_| ());
868+
let output = host_version.and_then(|output| {
869+
if output.status.success() {
870+
Ok(output)
871+
} else {
872+
Err(())
873+
}
874+
}).unwrap_or_else(|_| {
875+
eprintln!(
876+
"error: `x.py clippy` requires a host `rustc` toolchain with the `clippy` component"
877+
);
878+
eprintln!("help: try `rustup component add clippy`");
879+
std::process::exit(1);
880+
});
881+
if !t!(std::str::from_utf8(&output.stdout)).contains("nightly") {
882+
rustflags.arg("--cfg=bootstrap");
883+
}
884+
} else {
885+
rustflags.arg("--cfg=bootstrap");
886+
}
853887
}
854888

855889
if self.config.rust_new_symbol_mangling {
@@ -974,7 +1008,6 @@ impl<'a> Builder<'a> {
9741008
// src/bootstrap/bin/{rustc.rs,rustdoc.rs}
9751009
cargo
9761010
.env("RUSTBUILD_NATIVE_DIR", self.native_dir(target))
977-
.env("RUSTC", self.out.join("bootstrap/debug/rustc"))
9781011
.env("RUSTC_REAL", self.rustc(compiler))
9791012
.env("RUSTC_STAGE", stage.to_string())
9801013
.env("RUSTC_SYSROOT", &sysroot)
@@ -990,6 +1023,11 @@ impl<'a> Builder<'a> {
9901023
)
9911024
.env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir())
9921025
.env("RUSTC_BREAK_ON_ICE", "1");
1026+
// Clippy support is a hack and uses the default `cargo-clippy` in path.
1027+
// Don't override RUSTC so that the `cargo-clippy` in path will be run.
1028+
if cmd != "clippy" {
1029+
cargo.env("RUSTC", self.out.join("bootstrap/debug/rustc"));
1030+
}
9931031

9941032
// Dealing with rpath here is a little special, so let's go into some
9951033
// detail. First off, `-rpath` is a linker option on Unix platforms

Diff for: src/bootstrap/check.rs

+29-14
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,41 @@
11
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
22
3+
use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
34
use crate::cache::Interned;
45
use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo};
56
use crate::config::TargetSelection;
67
use crate::tool::{prepare_tool_cargo, SourceType};
78
use crate::INTERNER;
8-
use crate::{
9-
builder::{Builder, Kind, RunConfig, ShouldRun, Step},
10-
Subcommand,
11-
};
12-
use crate::{Compiler, Mode};
9+
use crate::{Compiler, Mode, Subcommand};
1310
use std::path::PathBuf;
1411

1512
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1613
pub struct Std {
1714
pub target: TargetSelection,
1815
}
1916

20-
fn args(kind: Kind) -> Vec<String> {
21-
match kind {
22-
Kind::Clippy => vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()],
23-
_ => Vec::new(),
17+
/// Returns args for the subcommand itself (not for cargo)
18+
fn args(builder: &Builder<'_>) -> Vec<String> {
19+
fn strings<'a>(arr: &'a [&str]) -> impl Iterator<Item = String> + 'a {
20+
arr.iter().copied().map(String::from)
21+
}
22+
23+
if let Subcommand::Clippy { fix, .. } = builder.config.cmd {
24+
let mut args = vec![];
25+
if fix {
26+
#[rustfmt::skip]
27+
args.extend(strings(&[
28+
"--fix", "-Zunstable-options",
29+
// FIXME: currently, `--fix` gives an error while checking tests for libtest,
30+
// possibly because libtest is not yet built in the sysroot.
31+
// As a workaround, avoid checking tests and benches when passed --fix.
32+
"--lib", "--bins", "--examples",
33+
]));
34+
}
35+
args.extend(strings(&["--", "--cap-lints", "warn"]));
36+
args
37+
} else {
38+
vec![]
2439
}
2540
}
2641

@@ -62,7 +77,7 @@ impl Step for Std {
6277
run_cargo(
6378
builder,
6479
cargo,
65-
args(builder.kind),
80+
args(builder),
6681
&libstd_stamp(builder, compiler, target),
6782
vec![],
6883
true,
@@ -104,7 +119,7 @@ impl Step for Std {
104119
run_cargo(
105120
builder,
106121
cargo,
107-
args(builder.kind),
122+
args(builder),
108123
&libstd_test_stamp(builder, compiler, target),
109124
vec![],
110125
true,
@@ -165,7 +180,7 @@ impl Step for Rustc {
165180
run_cargo(
166181
builder,
167182
cargo,
168-
args(builder.kind),
183+
args(builder),
169184
&librustc_stamp(builder, compiler, target),
170185
vec![],
171186
true,
@@ -220,7 +235,7 @@ impl Step for CodegenBackend {
220235
run_cargo(
221236
builder,
222237
cargo,
223-
args(builder.kind),
238+
args(builder),
224239
&codegen_backend_stamp(builder, compiler, target, backend),
225240
vec![],
226241
true,
@@ -278,7 +293,7 @@ macro_rules! tool_check_step {
278293
run_cargo(
279294
builder,
280295
cargo,
281-
args(builder.kind),
296+
args(builder),
282297
&stamp(builder, compiler, target),
283298
vec![],
284299
true,

Diff for: src/bootstrap/flags.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub enum Subcommand {
5555
paths: Vec<PathBuf>,
5656
},
5757
Clippy {
58+
fix: bool,
5859
paths: Vec<PathBuf>,
5960
},
6061
Fix {
@@ -273,6 +274,9 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
273274
"bench" => {
274275
opts.optmulti("", "test-args", "extra arguments", "ARGS");
275276
}
277+
"clippy" => {
278+
opts.optflag("", "fix", "automatically apply lint suggestions");
279+
}
276280
"doc" => {
277281
opts.optflag("", "open", "open the docs in a browser");
278282
}
@@ -513,7 +517,7 @@ Arguments:
513517
"check" | "c" => {
514518
Subcommand::Check { paths, all_targets: matches.opt_present("all-targets") }
515519
}
516-
"clippy" => Subcommand::Clippy { paths },
520+
"clippy" => Subcommand::Clippy { paths, fix: matches.opt_present("fix") },
517521
"fix" => Subcommand::Fix { paths },
518522
"test" | "t" => Subcommand::Test {
519523
paths,

0 commit comments

Comments
 (0)