From 38983ce2e34bd80d547f4e8c57dc83eeecff77e0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 11 Aug 2019 21:24:38 -0700 Subject: [PATCH] Better error messages when `rustc` discovery parsing fails. --- .../compiler/build_context/target_info.rs | 10 +- src/cargo/util/rustc.rs | 7 +- tests/testsuite/cfg.rs | 135 ++++++++++++++++++ 3 files changed, 150 insertions(+), 2 deletions(-) diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index cff55cf6f2c..b5b74fd9024 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -170,7 +170,15 @@ impl TargetInfo { } }; - let cfg = lines.map(Cfg::from_str).collect::>>()?; + let cfg = lines + .map(Cfg::from_str) + .collect::>>() + .chain_err(|| { + format!( + "failed to parse the cfg from `rustc --print=cfg`, got:\n{}", + output + ) + })?; Ok(TargetInfo { crate_type_process, diff --git a/src/cargo/util/rustc.rs b/src/cargo/util/rustc.rs index da47787cd3e..d79b663aa99 100644 --- a/src/cargo/util/rustc.rs +++ b/src/cargo/util/rustc.rs @@ -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() }; diff --git a/tests/testsuite/cfg.rs b/tests/testsuite/cfg.rs index 4f5eb2fa793..81eab7e7b6e 100644 --- a/tests/testsuite/cfg.rs +++ b/tests/testsuite/cfg.rs @@ -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(); +}