Skip to content

Commit ff96fa1

Browse files
committed
Pass --cap-lints=allow instead of -Awarnings
This commit adds support to Cargo to pass `--cap-lints allow` to all upstream dependencies instead of `-A warings`. This should serve the same purpose of suppressing warnings in upstream dependencies as well as preventing widespread breakage whenever a change to a lint is introduced in the compiler.
1 parent fec382d commit ff96fa1

File tree

11 files changed

+170
-70
lines changed

11 files changed

+170
-70
lines changed

src/cargo/ops/cargo_compile.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ pub fn compile_pkg<'a>(package: &Package,
126126
let override_ids = try!(source_ids_from_config(config, package.root()));
127127

128128
let (packages, resolve_with_overrides, sources) = {
129-
let rustc_host = config.rustc_host().to_string();
130129
let mut registry = PackageRegistry::new(config);
131130
if let Some(source) = source {
132131
registry.preload(package.package_id().source_id(), source);
@@ -146,13 +145,14 @@ pub fn compile_pkg<'a>(package: &Package,
146145

147146
try!(registry.add_overrides(override_ids));
148147

149-
let platform = target.as_ref().map(|e| &e[..]).or(Some(&rustc_host[..]));
148+
let platform = target.as_ref().unwrap_or(&config.rustc_info().host);
150149

151-
let method = Method::Required{
150+
let method = Method::Required {
152151
dev_deps: true, // TODO: remove this option?
153152
features: &features,
154153
uses_default_features: !no_default_features,
155-
target_platform: platform};
154+
target_platform: Some(&platform[..]),
155+
};
156156

157157
let resolved_with_overrides =
158158
try!(ops::resolve_with_previous(&mut registry, package, method,
@@ -397,7 +397,7 @@ fn scrape_build_config(config: &Config,
397397
requested_target: target.clone(),
398398
..Default::default()
399399
};
400-
base.host = try!(scrape_target_config(config, config.rustc_host()));
400+
base.host = try!(scrape_target_config(config, &config.rustc_info().host));
401401
base.target = match target.as_ref() {
402402
Some(triple) => try!(scrape_target_config(config, &triple)),
403403
None => base.host.clone(),

src/cargo/ops/cargo_rustc/context.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
7070
} else {
7171
try!(Context::filename_parts(None, config))
7272
};
73-
let target_triple = target.unwrap_or(config.rustc_host()).to_string();
73+
let target_triple = target.unwrap_or_else(|| {
74+
&config.rustc_info().host[..]
75+
}).to_string();
7476
let engine = build_config.exec_engine.as_ref().cloned().unwrap_or({
7577
Arc::new(Box::new(ProcessEngine))
7678
});
@@ -244,9 +246,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
244246
/// otherwise it corresponds to the target platform.
245247
fn dylib(&self, kind: Kind) -> CargoResult<(&str, &str)> {
246248
let (triple, pair) = if kind == Kind::Host {
247-
(self.config.rustc_host(), &self.host_dylib)
249+
(&self.config.rustc_info().host, &self.host_dylib)
248250
} else {
249-
(&self.target_triple[..], &self.target_dylib)
251+
(&self.target_triple, &self.target_dylib)
250252
};
251253
match *pair {
252254
None => return Err(human(format!("dylib outputs are not supported \

src/cargo/ops/cargo_rustc/custom_build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ pub fn prepare(pkg: &Package, target: &Target, req: Platform,
6363
.env("CARGO_MANIFEST_DIR", pkg.root())
6464
.env("NUM_JOBS", &cx.jobs().to_string())
6565
.env("TARGET", &match kind {
66-
Kind::Host => cx.config.rustc_host(),
66+
Kind::Host => &cx.config.rustc_info().host[..],
6767
Kind::Target => cx.target_triple(),
6868
})
6969
.env("DEBUG", &profile.debuginfo.to_string())
7070
.env("OPT_LEVEL", &profile.opt_level.to_string())
7171
.env("PROFILE", if cx.build_config.release {"release"} else {"debug"})
72-
.env("HOST", &cx.config.rustc_host());
72+
.env("HOST", &cx.config.rustc_info().host);
7373

7474
// Be sure to pass along all enabled features for this package, this is the
7575
// last piece of statically known information that we have.

src/cargo/ops/cargo_rustc/fingerprint.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ fn calculate<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
165165
v.sort();
166166
v
167167
});
168-
let extra = util::short_hash(&(cx.config.rustc_version(), target, &features,
169-
profile));
168+
let extra = util::short_hash(&(&cx.config.rustc_info().verbose_version,
169+
target, &features, profile));
170170
debug!("extra {:?} {:?} {:?} = {}", target, profile, features, extra);
171171

172172
// Next, recursively calculate the fingerprint for all of our dependencies.

src/cargo/ops/cargo_rustc/mod.rs

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::env;
33
use std::ffi::OsString;
44
use std::fs;
55
use std::io::prelude::*;
6-
use std::path::{self, Path, PathBuf};
6+
use std::path::{self, PathBuf};
77
use std::sync::Arc;
88

99
use core::{SourceMap, Package, PackageId, PackageSet, Target, Resolve};
@@ -52,29 +52,6 @@ pub struct TargetConfig {
5252
pub overrides: HashMap<String, BuildOutput>,
5353
}
5454

55-
/// Run `rustc` to figure out what its current version string is.
56-
///
57-
/// The second element of the tuple returned is the target triple that rustc
58-
/// is a host for.
59-
pub fn rustc_version<P: AsRef<Path>>(rustc: P) -> CargoResult<(String, String)> {
60-
let output = try!(try!(util::process(rustc.as_ref()))
61-
.arg("-vV")
62-
.exec_with_output());
63-
let output = try!(String::from_utf8(output.stdout).map_err(|_| {
64-
internal("rustc -v didn't return utf8 output")
65-
}));
66-
let triple = {
67-
let triple = output.lines().filter(|l| {
68-
l.starts_with("host: ")
69-
}).map(|l| &l[6..]).next();
70-
let triple = try!(triple.chain_error(|| {
71-
internal("rustc -v didn't have a line for `host:`")
72-
}));
73-
triple.to_string()
74-
};
75-
Ok((output, triple))
76-
}
77-
7855
// Returns a mapping of the root package plus its immediate dependencies to
7956
// where the compiled libraries are all located.
8057
pub fn compile_targets<'a, 'cfg: 'a>(targets: &[(&'a Target, &'a Profile)],
@@ -336,10 +313,14 @@ fn rustc(package: &Package, target: &Target, profile: &Profile,
336313
return rustcs.into_iter().map(|(mut rustc, kind)| {
337314
let name = package.name().to_string();
338315
let is_path_source = package.package_id().source_id().is_path();
339-
let show_warnings = package.package_id() == cx.resolve.root() ||
340-
is_path_source;
341-
if !show_warnings {
342-
rustc.arg("-Awarnings");
316+
let allow_warnings = package.package_id() == cx.resolve.root() ||
317+
is_path_source;
318+
if !allow_warnings {
319+
if cx.config.rustc_info().cap_lints {
320+
rustc.arg("--cap-lints").arg("allow");
321+
} else {
322+
rustc.arg("-Awarnings");
323+
}
343324
}
344325
let has_custom_args = profile.rustc_args.is_some();
345326
let exec_engine = cx.exec_engine.clone();

src/cargo/ops/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pub use self::cargo_clean::{clean, CleanOptions};
22
pub use self::cargo_compile::{compile, compile_pkg, CompileOptions};
33
pub use self::cargo_compile::{CompileFilter, CompileMode};
44
pub use self::cargo_read_manifest::{read_manifest,read_package,read_packages};
5-
pub use self::cargo_rustc::{compile_targets, Compilation, Layout, Kind, rustc_version};
5+
pub use self::cargo_rustc::{compile_targets, Compilation, Layout, Kind};
66
pub use self::cargo_rustc::{Context, LayoutProxy};
77
pub use self::cargo_rustc::Platform;
88
pub use self::cargo_rustc::{BuildOutput, BuildConfig, TargetConfig};

src/cargo/util/config.rs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use std::path::{Path, PathBuf};
1212
use rustc_serialize::{Encodable,Encoder};
1313
use toml;
1414
use core::{MultiShell, Package};
15-
use ops;
16-
use util::{CargoResult, ChainError, internal, human};
15+
use util::{CargoResult, ChainError, Rustc, internal, human};
1716

1817
use util::toml as cargo_toml;
1918

@@ -22,9 +21,7 @@ use self::ConfigValue as CV;
2221
pub struct Config {
2322
home_path: PathBuf,
2423
shell: RefCell<MultiShell>,
25-
rustc_version: String,
26-
/// The current host and default target of rustc
27-
rustc_host: String,
24+
rustc_info: Rustc,
2825
values: RefCell<HashMap<String, ConfigValue>>,
2926
values_loaded: Cell<bool>,
3027
cwd: PathBuf,
@@ -45,8 +42,7 @@ impl Config {
4542
This probably means that $HOME was not set.")
4643
})),
4744
shell: RefCell::new(shell),
48-
rustc_version: String::new(),
49-
rustc_host: String::new(),
45+
rustc_info: Rustc::blank(),
5046
cwd: cwd,
5147
values: RefCell::new(HashMap::new()),
5248
values_loaded: Cell::new(false),
@@ -92,11 +88,7 @@ impl Config {
9288

9389
pub fn rustdoc(&self) -> &Path { &self.rustdoc }
9490

95-
/// Return the output of `rustc -v verbose`
96-
pub fn rustc_version(&self) -> &str { &self.rustc_version }
97-
98-
/// Return the host platform and default target of rustc
99-
pub fn rustc_host(&self) -> &str { &self.rustc_host }
91+
pub fn rustc_info(&self) -> &Rustc { &self.rustc_info }
10092

10193
pub fn values(&self) -> CargoResult<Ref<HashMap<String, ConfigValue>>> {
10294
if !self.values_loaded.get() {
@@ -219,9 +211,7 @@ impl Config {
219211
}
220212

221213
fn scrape_rustc_version(&mut self) -> CargoResult<()> {
222-
let (rustc_version, rustc_host) = try!(ops::rustc_version(&self.rustc));
223-
self.rustc_version = rustc_version;
224-
self.rustc_host = rustc_host;
214+
self.rustc_info = try!(Rustc::new(&self.rustc));
225215
Ok(())
226216
}
227217

src/cargo/util/mod.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
pub use self::config::Config;
2-
pub use self::process_builder::{process, ProcessBuilder};
2+
pub use self::dependency_queue::Dependency;
3+
pub use self::dependency_queue::{DependencyQueue, Fresh, Dirty, Freshness};
34
pub use self::errors::{CargoResult, CargoError, ChainError, CliResult};
45
pub use self::errors::{CliError, ProcessError};
5-
pub use self::errors::{process_error, internal_error, internal, human};
66
pub use self::errors::{Human, caused_human};
7+
pub use self::errors::{process_error, internal_error, internal, human};
8+
pub use self::graph::Graph;
9+
pub use self::hex::{to_hex, short_hash};
10+
pub use self::lev_distance::{lev_distance};
711
pub use self::paths::{join_paths, path2bytes, bytes2path, dylib_path};
812
pub use self::paths::{normalize_path, dylib_path_envvar, without_prefix};
9-
pub use self::lev_distance::{lev_distance};
10-
pub use self::hex::{to_hex, short_hash};
11-
pub use self::dependency_queue::{DependencyQueue, Fresh, Dirty, Freshness};
12-
pub use self::dependency_queue::Dependency;
13-
pub use self::graph::Graph;
14-
pub use self::to_url::ToUrl;
13+
pub use self::process_builder::{process, ProcessBuilder};
14+
pub use self::rustc::Rustc;
15+
pub use self::sha256::Sha256;
1516
pub use self::to_semver::ToSemver;
17+
pub use self::to_url::ToUrl;
1618
pub use self::vcs::{GitRepo, HgRepo};
17-
pub use self::sha256::Sha256;
1819

1920
pub mod config;
2021
pub mod errors;
@@ -32,3 +33,4 @@ mod dependency_queue;
3233
mod sha256;
3334
mod shell_escape;
3435
mod vcs;
36+
mod rustc;

src/cargo/util/rustc.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use std::path::Path;
2+
3+
use util::{self, CargoResult, internal, ChainError};
4+
5+
pub struct Rustc {
6+
pub verbose_version: String,
7+
pub host: String,
8+
pub cap_lints: bool,
9+
}
10+
11+
impl Rustc {
12+
/// Run the compiler at `path` to learn varioues pieces of information about
13+
/// it.
14+
///
15+
/// If successful this function returns a description of the compiler along
16+
/// with a list of its capabilities.
17+
pub fn new<P: AsRef<Path>>(path: P) -> CargoResult<Rustc> {
18+
let mut cmd = try!(util::process(path.as_ref()));
19+
cmd.arg("-vV");
20+
21+
let mut ret = Rustc::blank();
22+
let mut first = cmd.clone();
23+
first.arg("--cap-lints").arg("allow");
24+
let output = match first.exec_with_output() {
25+
Ok(output) => { ret.cap_lints = true; output }
26+
Err(..) => try!(cmd.exec_with_output()),
27+
};
28+
ret.verbose_version = try!(String::from_utf8(output.stdout).map_err(|_| {
29+
internal("rustc -v didn't return utf8 output")
30+
}));
31+
ret.host = {
32+
let triple = ret.verbose_version.lines().filter(|l| {
33+
l.starts_with("host: ")
34+
}).map(|l| &l[6..]).next();
35+
let triple = try!(triple.chain_error(|| {
36+
internal("rustc -v didn't have a line for `host:`")
37+
}));
38+
triple.to_string()
39+
};
40+
Ok(ret)
41+
}
42+
43+
pub fn blank() -> Rustc {
44+
Rustc {
45+
verbose_version: String::new(),
46+
host: String::new(),
47+
cap_lints: false,
48+
}
49+
}
50+
}

tests/test_cargo_compile_git_deps.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,3 +1654,73 @@ test!(doctest_same_name {
16541654
assert_that(p.cargo_process("test").arg("-v"),
16551655
execs().with_status(0));
16561656
});
1657+
1658+
test!(lints_are_suppressed {
1659+
let a = git::new("a", |p| {
1660+
p.file("Cargo.toml", r#"
1661+
[project]
1662+
name = "a"
1663+
version = "0.5.0"
1664+
authors = []
1665+
"#)
1666+
.file("src/lib.rs", "
1667+
use std::option;
1668+
")
1669+
}).unwrap();
1670+
1671+
let p = project("foo")
1672+
.file("Cargo.toml", &format!(r#"
1673+
[package]
1674+
name = "foo"
1675+
version = "0.0.1"
1676+
authors = []
1677+
1678+
[dependencies]
1679+
a = {{ git = '{}' }}
1680+
"#, a.url()))
1681+
.file("src/lib.rs", "");
1682+
1683+
assert_that(p.cargo_process("build"),
1684+
execs().with_status(0).with_stdout(&format!("\
1685+
{updating} git repository `[..]`
1686+
{compiling} a v0.5.0 ([..])
1687+
{compiling} foo v0.0.1 ([..])
1688+
", compiling = COMPILING, updating = UPDATING)));
1689+
});
1690+
1691+
test!(denied_lints_are_allowed {
1692+
let enabled = super::RUSTC.with(|r| r.cap_lints);
1693+
if !enabled { return }
1694+
1695+
let a = git::new("a", |p| {
1696+
p.file("Cargo.toml", r#"
1697+
[project]
1698+
name = "a"
1699+
version = "0.5.0"
1700+
authors = []
1701+
"#)
1702+
.file("src/lib.rs", "
1703+
#![deny(warnings)]
1704+
use std::option;
1705+
")
1706+
}).unwrap();
1707+
1708+
let p = project("foo")
1709+
.file("Cargo.toml", &format!(r#"
1710+
[package]
1711+
name = "foo"
1712+
version = "0.0.1"
1713+
authors = []
1714+
1715+
[dependencies]
1716+
a = {{ git = '{}' }}
1717+
"#, a.url()))
1718+
.file("src/lib.rs", "");
1719+
1720+
assert_that(p.cargo_process("build"),
1721+
execs().with_status(0).with_stdout(&format!("\
1722+
{updating} git repository `[..]`
1723+
{compiling} a v0.5.0 ([..])
1724+
{compiling} foo v0.0.1 ([..])
1725+
", compiling = COMPILING, updating = UPDATING)));
1726+
});

0 commit comments

Comments
 (0)