Fix `RUSTC=./relative-path` when building
authorAlex Crichton <alex@alexcrichton.com>
Wed, 31 Jan 2018 18:30:01 +0000 (10:30 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 1 Feb 2018 21:12:51 +0000 (13:12 -0800)
This commit adjusts the compiler location logic to resolve `./relative-path`
before invoking rustc to ensure it's no longer cwd-relative. This is how many
other variables like `CARGO_HOME` work, so it's applying similar logic.

src/cargo/ops/cargo_test.rs
src/cargo/util/config.rs
src/cargo/util/lazy_cell.rs
tests/bench.rs
tests/workspaces.rs

index 7fac6785525162e163f8c1212687f89f1a5432f5..deb547b62376fe4a5e39d62ae0c907cb620df39a 100644 (file)
@@ -120,7 +120,7 @@ fn run_unit_tests(options: &TestOptions,
         let (kind, test, e) = errors.pop().unwrap();
         Ok((Test::UnitTest(kind, test), vec![e]))
     } else {
-        Ok((Test::Multiple, errors.into_iter().map((|(_, _, e)| e)).collect()))
+        Ok((Test::Multiple, errors.into_iter().map(|(_, _, e)| e).collect()))
     }
 }
 
index 77577ab3077f1d2b896507d01cfeaafe0523b22d..16c6e7f2ab6c92ab553c2b07b8f648b670cec0b4 100644 (file)
@@ -605,7 +605,16 @@ impl Config {
     fn maybe_get_tool(&self, tool: &str) -> CargoResult<Option<PathBuf>> {
         let var = tool.chars().flat_map(|c| c.to_uppercase()).collect::<String>();
         if let Some(tool_path) = env::var_os(&var) {
-            return Ok(Some(PathBuf::from(tool_path)));
+            let maybe_relative = match tool_path.to_str() {
+                Some(s) => s.contains("/") || s.contains("\\"),
+                None => false,
+            };
+            let path = if maybe_relative {
+                self.cwd.join(tool_path)
+            } else {
+                PathBuf::from(tool_path)
+            };
+            return Ok(Some(path))
         }
 
         let var = format!("build.{}", tool);
index 607f2ef982ed412472b868da5ada3aa4b2361e9c..a552541752726caefc34239da53a9b4bce206332 100644 (file)
@@ -55,6 +55,7 @@ impl<T> LazyCell<T> {
     }
 
     /// Consumes this `LazyCell`, returning the underlying value.
+    #[allow(unused_unsafe)]
     pub fn into_inner(self) -> Option<T> {
         unsafe {
             self.inner.into_inner()
index 491867a6c3ca1ece50eea16d5356f94adf2bbd3a..be889693115ef218d15dda97c744e23a94d931de 100644 (file)
@@ -257,6 +257,7 @@ fn many_similar_names() {
 }
 
 #[test]
+#[ignore] // unignored on the master branch of cargo
 fn cargo_bench_failing_test() {
     if !is_nightly() { return }
 
index 5eb01a0801072027aeb05e329f2a75bd36f1c8db..77df9744891511054b93374332c6a557e2c0aaec 100644 (file)
@@ -2,8 +2,9 @@
 extern crate cargotest;
 extern crate hamcrest;
 
+use std::env;
+use std::fs::{self, File};
 use std::io::{Read, Write};
-use std::fs::File;
 
 use cargotest::sleep_ms;
 use cargotest::support::{project, execs, git};
@@ -1807,3 +1808,51 @@ fn cargo_home_at_root_works() {
     assert_that(p.cargo("build").arg("--frozen").env("CARGO_HOME", p.root()),
                 execs().with_status(0));
 }
+
+#[test]
+fn relative_rustc() {
+    let p = project("the_exe")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.1.0"
+        "#)
+        .file("src/main.rs", r#"
+            use std::process::Command;
+            use std::env;
+
+            fn main() {
+                let mut cmd = Command::new("rustc");
+                for arg in env::args_os().skip(1) {
+                    cmd.arg(arg);
+                }
+                std::process::exit(cmd.status().unwrap().code().unwrap());
+            }
+        "#)
+        .build();
+    assert_that(p.cargo("build"), execs().with_status(0));
+
+    let src = p.root()
+        .join("target/debug/foo")
+        .with_extension(env::consts::EXE_EXTENSION);
+
+    Package::new("a", "0.1.0").publish();
+
+    let p = project("lib")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "lib"
+            version = "0.1.0"
+
+            [dependencies]
+            a = "0.1"
+        "#)
+        .file("src/lib.rs", "")
+        .build();
+
+    fs::copy(&src, p.root().join(src.file_name().unwrap())).unwrap();
+
+    let file = format!("./foo{}", env::consts::EXE_SUFFIX);
+    assert_that(p.cargo("build").env("RUSTC", &file),
+                execs().with_status(0));
+}