Skip to content

Commit 025b01e

Browse files
committed
Auto merge of #6759 - yaahallo:cargo-clippy, r=alexcrichton
Cargo clippy resolves rust-lang/rust-clippy#3837
2 parents d04d75b + 842da62 commit 025b01e

File tree

13 files changed

+129
-80
lines changed

13 files changed

+129
-80
lines changed

src/bin/cargo/cli.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
6262
}
6363

6464
if let Some(code) = args.value_of("explain") {
65-
let mut procss = config.rustc(None)?.process();
65+
let mut procss = config.load_global_rustc(None)?.process();
6666
procss.arg("--explain").arg(code).exec()?;
6767
return Ok(());
6868
}

src/bin/cargo/commands/clippy.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use crate::command_prelude::*;
2+
3+
use cargo::ops;
4+
use cargo::util;
5+
6+
pub fn cli() -> App {
7+
subcommand("clippy-preview")
8+
.about("Checks a package to catch common mistakes and improve your Rust code.")
9+
.arg_package_spec(
10+
"Package(s) to check",
11+
"Check all packages in the workspace",
12+
"Exclude packages from the check",
13+
)
14+
.arg_jobs()
15+
.arg_targets_all(
16+
"Check only this package's library",
17+
"Check only the specified binary",
18+
"Check all binaries",
19+
"Check only the specified example",
20+
"Check all examples",
21+
"Check only the specified test target",
22+
"Check all tests",
23+
"Check only the specified bench target",
24+
"Check all benches",
25+
"Check all targets",
26+
)
27+
.arg_release("Check artifacts in release mode, with optimizations")
28+
.arg_features()
29+
.arg_target_triple("Check for the target triple")
30+
.arg_target_dir()
31+
.arg_manifest_path()
32+
.arg_message_format()
33+
.after_help(
34+
"\
35+
If the `--package` argument is given, then SPEC is a package ID specification
36+
which indicates which package should be built. If it is not given, then the
37+
current package is built. For more information on SPEC and its format, see the
38+
`cargo help pkgid` command.
39+
40+
All packages in the workspace are checked if the `--all` flag is supplied. The
41+
`--all` flag is automatically assumed for a virtual manifest.
42+
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
43+
44+
To allow or deny a lint from the command line you can use `cargo clippy --`
45+
with:
46+
47+
-W --warn OPT Set lint warnings
48+
-A --allow OPT Set lint allowed
49+
-D --deny OPT Set lint denied
50+
-F --forbid OPT Set lint forbidden
51+
52+
You can use tool lints to allow or deny lints from your code, eg.:
53+
54+
#[allow(clippy::needless_lifetimes)]
55+
",
56+
)
57+
}
58+
59+
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
60+
let ws = args.workspace(config)?;
61+
62+
let mode = CompileMode::Check { test: false };
63+
let mut compile_opts = args.compile_options(config, mode, Some(&ws))?;
64+
65+
if !config.cli_unstable().unstable_options {
66+
return Err(failure::format_err!(
67+
"`clippy-preview` is unstable, pass `-Z unstable-options` to enable it"
68+
)
69+
.into());
70+
}
71+
72+
let wrapper = util::process("clippy-driver");
73+
compile_opts.build_config.rustc_wrapper = Some(wrapper);
74+
75+
ops::compile(&ws, &compile_opts)?;
76+
Ok(())
77+
}

src/bin/cargo/commands/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub fn builtin() -> Vec<App> {
66
build::cli(),
77
check::cli(),
88
clean::cli(),
9+
clippy::cli(),
910
doc::cli(),
1011
fetch::cli(),
1112
fix::cli(),
@@ -41,6 +42,7 @@ pub fn builtin_exec(cmd: &str) -> Option<fn(&mut Config, &ArgMatches<'_>) -> Cli
4142
"build" => build::exec,
4243
"check" => check::exec,
4344
"clean" => clean::exec,
45+
"clippy-preview" => clippy::exec,
4446
"doc" => doc::exec,
4547
"fetch" => fetch::exec,
4648
"fix" => fix::exec,
@@ -76,6 +78,7 @@ pub mod bench;
7678
pub mod build;
7779
pub mod check;
7880
pub mod clean;
81+
pub mod clippy;
7982
pub mod doc;
8083
pub mod fetch;
8184
pub mod fix;

src/cargo/core/compiler/build_config.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::path::Path;
33

44
use serde::ser;
55

6+
use crate::util::ProcessBuilder;
67
use crate::util::{CargoResult, CargoResultExt, Config, RustfixDiagnosticServer};
78

89
/// Configuration information for a rustc build.
@@ -23,12 +24,8 @@ pub struct BuildConfig {
2324
pub force_rebuild: bool,
2425
/// Output a build plan to stdout instead of actually compiling.
2526
pub build_plan: bool,
26-
/// Use Cargo itself as the wrapper around rustc, only used for `cargo fix`.
27-
pub cargo_as_rustc_wrapper: bool,
28-
/// Extra env vars to inject into rustc commands.
29-
pub extra_rustc_env: Vec<(String, String)>,
30-
/// Extra args to inject into rustc commands.
31-
pub extra_rustc_args: Vec<String>,
27+
/// An optional wrapper, if any, used to wrap rustc invocations
28+
pub rustc_wrapper: Option<ProcessBuilder>,
3229
pub rustfix_diagnostic_server: RefCell<Option<RustfixDiagnosticServer>>,
3330
}
3431

@@ -98,9 +95,7 @@ impl BuildConfig {
9895
message_format: MessageFormat::Human,
9996
force_rebuild: false,
10097
build_plan: false,
101-
cargo_as_rustc_wrapper: false,
102-
extra_rustc_env: Vec::new(),
103-
extra_rustc_args: Vec::new(),
98+
rustc_wrapper: None,
10499
rustfix_diagnostic_server: RefCell::new(None),
105100
})
106101
}

src/cargo/core/compiler/build_context/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
5050
profiles: &'a Profiles,
5151
extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
5252
) -> CargoResult<BuildContext<'a, 'cfg>> {
53-
let rustc = config.rustc(Some(ws))?;
53+
let mut rustc = config.load_global_rustc(Some(ws))?;
54+
if let Some(wrapper) = &build_config.rustc_wrapper {
55+
rustc.set_wrapper(wrapper.clone());
56+
}
57+
5458
let host_config = TargetConfig::new(config, &rustc.host)?;
5559
let target_config = match build_config.requested_target.as_ref() {
5660
Some(triple) => TargetConfig::new(config, triple)?,

src/cargo/core/compiler/compilation.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -75,29 +75,11 @@ pub struct Compilation<'cfg> {
7575

7676
impl<'cfg> Compilation<'cfg> {
7777
pub fn new<'a>(bcx: &BuildContext<'a, 'cfg>) -> CargoResult<Compilation<'cfg>> {
78-
// If we're using cargo as a rustc wrapper then we're in a situation
79-
// like `cargo fix`. For now just disregard the `RUSTC_WRAPPER` env var
80-
// (which is typically set to `sccache` for now). Eventually we'll
81-
// probably want to implement `RUSTC_WRAPPER` for `cargo fix`, but we'll
82-
// leave that open as a bug for now.
83-
let mut rustc = if bcx.build_config.cargo_as_rustc_wrapper {
84-
let mut rustc = bcx.rustc.process_no_wrapper();
85-
let prog = rustc.get_program().to_owned();
86-
rustc.env("RUSTC", prog);
87-
rustc.program(env::current_exe()?);
88-
rustc
89-
} else {
90-
bcx.rustc.process()
91-
};
78+
let mut rustc = bcx.rustc.process();
79+
9280
if bcx.config.extra_verbose() {
9381
rustc.display_env_vars();
9482
}
95-
for (k, v) in bcx.build_config.extra_rustc_env.iter() {
96-
rustc.env(k, v);
97-
}
98-
for arg in bcx.build_config.extra_rustc_args.iter() {
99-
rustc.arg(arg);
100-
}
10183
let srv = bcx.build_config.rustfix_diagnostic_server.borrow();
10284
if let Some(server) = &*srv {
10385
server.configure(&mut rustc);

src/cargo/core/compiler/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@ use log::debug;
2222
use same_file::is_same_file;
2323
use serde::Serialize;
2424

25-
use crate::core::manifest::TargetSourcePath;
26-
use crate::core::profiles::{Lto, PanicStrategy, Profile};
27-
use crate::core::{PackageId, Target};
28-
use crate::util::errors::{CargoResult, CargoResultExt, Internal, ProcessError};
29-
use crate::util::paths;
30-
use crate::util::{self, machine_message, process, Freshness, ProcessBuilder};
31-
use crate::util::{internal, join_paths, profile};
3225
pub use self::build_config::{BuildConfig, CompileMode, MessageFormat};
3326
pub use self::build_context::{BuildContext, FileFlavor, TargetConfig, TargetInfo};
3427
use self::build_plan::BuildPlan;
@@ -39,6 +32,13 @@ use self::job::{Job, Work};
3932
use self::job_queue::JobQueue;
4033
pub use self::layout::is_bad_artifact_name;
4134
use self::output_depinfo::output_depinfo;
35+
use crate::core::manifest::TargetSourcePath;
36+
use crate::core::profiles::{Lto, PanicStrategy, Profile};
37+
use crate::core::{PackageId, Target};
38+
use crate::util::errors::{CargoResult, CargoResultExt, Internal, ProcessError};
39+
use crate::util::paths;
40+
use crate::util::{self, machine_message, process, Freshness, ProcessBuilder};
41+
use crate::util::{internal, join_paths, profile};
4242

4343
/// Indicates whether an object is for the host architcture or the target architecture.
4444
///

src/cargo/ops/cargo_fetch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub fn fetch<'a>(
2121
let jobs = Some(1);
2222
let config = ws.config();
2323
let build_config = BuildConfig::new(config, jobs, &options.target, CompileMode::Build)?;
24-
let rustc = config.rustc(Some(ws))?;
24+
let rustc = config.load_global_rustc(Some(ws))?;
2525
let target_info =
2626
TargetInfo::new(config, &build_config.requested_target, &rustc, Kind::Target)?;
2727
{

src/cargo/ops/fix.rs

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use crate::core::Workspace;
5656
use crate::ops::{self, CompileOptions};
5757
use crate::util::diagnostic_server::{Message, RustfixDiagnosticServer};
5858
use crate::util::errors::CargoResult;
59-
use crate::util::paths;
59+
use crate::util::{self, paths};
6060
use crate::util::{existing_vcs_repo, LockServer, LockServerClient};
6161

6262
const FIX_ENV: &str = "__CARGO_FIX_PLZ";
@@ -81,46 +81,31 @@ pub fn fix(ws: &Workspace<'_>, opts: &mut FixOptions<'_>) -> CargoResult<()> {
8181

8282
// Spin up our lock server, which our subprocesses will use to synchronize fixes.
8383
let lock_server = LockServer::new()?;
84-
opts.compile_opts
85-
.build_config
86-
.extra_rustc_env
87-
.push((FIX_ENV.to_string(), lock_server.addr().to_string()));
84+
let mut wrapper = util::process(env::current_exe()?);
85+
wrapper.env(FIX_ENV, lock_server.addr().to_string());
8886
let _started = lock_server.start()?;
8987

9088
opts.compile_opts.build_config.force_rebuild = true;
9189

9290
if opts.broken_code {
93-
let key = BROKEN_CODE_ENV.to_string();
94-
opts.compile_opts
95-
.build_config
96-
.extra_rustc_env
97-
.push((key, "1".to_string()));
91+
wrapper.env(BROKEN_CODE_ENV, "1");
9892
}
9993

10094
if opts.edition {
101-
let key = EDITION_ENV.to_string();
102-
opts.compile_opts
103-
.build_config
104-
.extra_rustc_env
105-
.push((key, "1".to_string()));
95+
wrapper.env(EDITION_ENV, "1");
10696
} else if let Some(edition) = opts.prepare_for {
107-
opts.compile_opts
108-
.build_config
109-
.extra_rustc_env
110-
.push((PREPARE_FOR_ENV.to_string(), edition.to_string()));
97+
wrapper.env(PREPARE_FOR_ENV, edition);
11198
}
11299
if opts.idioms {
113-
opts.compile_opts
114-
.build_config
115-
.extra_rustc_env
116-
.push((IDIOMS_ENV.to_string(), "1".to_string()));
100+
wrapper.env(IDIOMS_ENV, "1");
117101
}
118-
opts.compile_opts.build_config.cargo_as_rustc_wrapper = true;
102+
119103
*opts
120104
.compile_opts
121105
.build_config
122106
.rustfix_diagnostic_server
123107
.borrow_mut() = Some(RustfixDiagnosticServer::new()?);
108+
opts.compile_opts.build_config.rustc_wrapper = Some(wrapper);
124109

125110
ops::compile(ws, &opts.compile_opts)?;
126111
Ok(())
@@ -207,7 +192,7 @@ pub fn fix_maybe_exec_rustc() -> CargoResult<bool> {
207192

208193
let args = FixArgs::get();
209194
trace!("cargo-fix as rustc got file {:?}", args.file);
210-
let rustc = env::var_os("RUSTC").expect("failed to find RUSTC env var");
195+
let rustc = args.rustc.as_ref().expect("fix wrapper rustc was not set");
211196

212197
// Our goal is to fix only the crates that the end user is interested in.
213198
// That's very likely to only mean the crates in the workspace the user is
@@ -576,6 +561,7 @@ struct FixArgs {
576561
enabled_edition: Option<String>,
577562
other: Vec<OsString>,
578563
primary_package: bool,
564+
rustc: Option<PathBuf>,
579565
}
580566

581567
enum PrepareFor {
@@ -593,7 +579,8 @@ impl Default for PrepareFor {
593579
impl FixArgs {
594580
fn get() -> FixArgs {
595581
let mut ret = FixArgs::default();
596-
for arg in env::args_os().skip(1) {
582+
ret.rustc = env::args_os().nth(1).map(PathBuf::from);
583+
for arg in env::args_os().skip(2) {
597584
let path = PathBuf::from(arg);
598585
if path.extension().and_then(|s| s.to_str()) == Some("rs") && path.exists() {
599586
ret.file = Some(path);

src/cargo/util/config.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use serde::Deserialize;
2020
use serde::{de, de::IntoDeserializer};
2121
use url::Url;
2222

23+
use self::ConfigValue as CV;
2324
use crate::core::profiles::ConfigProfiles;
2425
use crate::core::shell::Verbosity;
2526
use crate::core::{CliUnstable, Shell, SourceId, Workspace};
@@ -30,7 +31,6 @@ use crate::util::Filesystem;
3031
use crate::util::Rustc;
3132
use crate::util::ToUrl;
3233
use crate::util::{paths, validate_package_name};
33-
use self::ConfigValue as CV;
3434

3535
/// Configuration information for cargo. This is not specific to a build, it is information
3636
/// relating to cargo itself.
@@ -191,15 +191,16 @@ impl Config {
191191
}
192192

193193
/// Gets the path to the `rustc` executable.
194-
pub fn rustc(&self, ws: Option<&Workspace<'_>>) -> CargoResult<Rustc> {
194+
pub fn load_global_rustc(&self, ws: Option<&Workspace<'_>>) -> CargoResult<Rustc> {
195195
let cache_location = ws.map(|ws| {
196196
ws.target_dir()
197197
.join(".rustc_info.json")
198198
.into_path_unlocked()
199199
});
200+
let wrapper = self.maybe_get_tool("rustc_wrapper")?;
200201
Rustc::new(
201202
self.get_tool("rustc")?,
202-
self.maybe_get_tool("rustc_wrapper")?,
203+
wrapper,
203204
&self
204205
.home()
205206
.join("bin")
@@ -755,7 +756,7 @@ impl Config {
755756

756757
/// Looks for a path for `tool` in an environment variable or config path, defaulting to `tool`
757758
/// as a path.
758-
fn get_tool(&self, tool: &str) -> CargoResult<PathBuf> {
759+
pub fn get_tool(&self, tool: &str) -> CargoResult<PathBuf> {
759760
self.maybe_get_tool(tool)
760761
.map(|t| t.unwrap_or_else(|| PathBuf::from(tool)))
761762
}
@@ -923,8 +924,7 @@ impl ConfigError {
923924
}
924925
}
925926

926-
impl std::error::Error for ConfigError {
927-
}
927+
impl std::error::Error for ConfigError {}
928928

929929
// Future note: currently, we cannot override `Fail::cause` (due to
930930
// specialization) so we have no way to return the underlying causes. In the

src/cargo/util/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub mod process_builder;
4747
pub mod profile;
4848
mod progress;
4949
mod read2;
50-
mod rustc;
50+
pub mod rustc;
5151
mod sha256;
5252
pub mod to_semver;
5353
pub mod to_url;

src/cargo/util/process_builder.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,7 @@ impl ProcessBuilder {
8080

8181
/// (chainable) Replaces the args list with the given `args`.
8282
pub fn args_replace<T: AsRef<OsStr>>(&mut self, args: &[T]) -> &mut ProcessBuilder {
83-
self.args = args
84-
.iter()
85-
.map(|t| t.as_ref().to_os_string())
86-
.collect();
83+
self.args = args.iter().map(|t| t.as_ref().to_os_string()).collect();
8784
self
8885
}
8986

0 commit comments

Comments
 (0)