Skip to content

Commit

Permalink
Better error messages when rustc discovery parsing fails.
Browse files Browse the repository at this point in the history
  • Loading branch information
ehuss committed Aug 12, 2019
1 parent e853aa9 commit 38983ce
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 2 deletions.
10 changes: 9 additions & 1 deletion src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,15 @@ impl TargetInfo {
}
};

let cfg = lines.map(Cfg::from_str).collect::<CargoResult<Vec<_>>>()?;
let cfg = lines
.map(Cfg::from_str)
.collect::<CargoResult<Vec<_>>>()
.chain_err(|| {
format!(
"failed to parse the cfg from `rustc --print=cfg`, got:\n{}",
output
)
})?;

Ok(TargetInfo {
crate_type_process,
Expand Down
7 changes: 6 additions & 1 deletion src/cargo/util/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ impl Rustc {
.lines()
.find(|l| l.starts_with("host: "))
.map(|l| &l[6..])
.ok_or_else(|| internal("rustc -v didn't have a line for `host:`"))?;
.ok_or_else(|| {
failure::format_err!(
"`rustc -vV` didn't have a line for `host:`, got:\n{}",
verbose_version
)
})?;
triple.to_string()
};

Expand Down
135 changes: 135 additions & 0 deletions tests/testsuite/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,138 @@ fn cfg_looks_at_rustflags_for_target() {
.env("RUSTFLAGS", "--cfg with_b")
.run();
}

#[cargo_test]
fn bad_cfg_discovery() {
// Check error messages when `rustc -v` and `rustc --print=*` parsing fails.
//
// This is a `rustc` replacement which behaves differently based on an
// environment variable.
let p = project()
.at("compiler")
.file("Cargo.toml", &basic_manifest("compiler", "0.1.0"))
.file(
"src/main.rs",
r#"
fn run_rustc() -> String {
let mut cmd = std::process::Command::new("rustc");
for arg in std::env::args_os().skip(1) {
cmd.arg(arg);
}
String::from_utf8(cmd.output().unwrap().stdout).unwrap()
}
fn main() {
let mode = std::env::var("FUNKY_MODE").unwrap();
if mode == "bad-version" {
println!("foo");
return;
}
if std::env::args_os().any(|a| a == "-vV") {
print!("{}", run_rustc());
return;
}
if mode == "no-crate-types" {
return;
}
if mode == "bad-crate-type" {
println!("foo");
return;
}
let output = run_rustc();
let mut lines = output.lines();
let sysroot = loop {
let line = lines.next().unwrap();
if line.contains("___") {
println!("{}", line);
} else {
break line;
}
};
if mode == "no-sysroot" {
return;
}
println!("{}", sysroot);
if mode != "bad-cfg" {
panic!("unexpected");
}
println!("123");
}
"#,
)
.build();
p.cargo("build").run();
let funky_rustc = p.bin("compiler");

let p = project().file("src/lib.rs", "").build();

p.cargo("build")
.env("RUSTC", &funky_rustc)
.env("FUNKY_MODE", "bad-version")
.with_status(101)
.with_stderr(
"\
[ERROR] `rustc -vV` didn't have a line for `host:`, got:
foo
",
)
.run();

p.cargo("build")
.env("RUSTC", &funky_rustc)
.env("FUNKY_MODE", "no-crate-types")
.with_status(101)
.with_stderr(
"\
[ERROR] malformed output when learning about crate-type bin information
command was: `[..]compiler[..] --crate-name ___ [..]`
(no output received)
",
)
.run();

p.cargo("build")
.env("RUSTC", &funky_rustc)
.env("FUNKY_MODE", "no-sysroot")
.with_status(101)
.with_stderr(
"\
[ERROR] output of --print=sysroot missing when learning about target-specific information from rustc
command was: `[..]compiler[..]--crate-type [..]`
--- stdout
[..]___[..]
[..]___[..]
[..]___[..]
[..]___[..]
[..]___[..]
[..]___[..]
",
)
.run();

p.cargo("build")
.env("RUSTC", &funky_rustc)
.env("FUNKY_MODE", "bad-cfg")
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse the cfg from `rustc --print=cfg`, got:
[..]___[..]
[..]___[..]
[..]___[..]
[..]___[..]
[..]___[..]
[..]___[..]
[..]
123
Caused by:
unexpected character in cfg `1`, expected parens, a comma, an identifier, or a string
",
)
.run();
}

0 comments on commit 38983ce

Please sign in to comment.