From 60d4e20ff07ac4546f47f09094c7c04b577f0966 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 5 Dec 2019 16:26:21 -0800 Subject: [PATCH] compiletest: add aux-crate directive --- .../extern-flag-noprelude/Makefile | 11 -- .../extern-flag-noprelude/foo.rs | 3 - src/test/rustdoc/issue-66159.rs | 3 +- .../extern-flag/auxiliary/somedep.rs} | 0 src/test/ui/extern-flag/noprelude-resolves.rs | 11 ++ src/test/ui/extern-flag/noprelude.rs | 7 + src/test/ui/extern-flag/noprelude.stderr | 9 + src/test/ui/privacy/pub-priv-dep/pub-priv1.rs | 5 +- .../ui/privacy/pub-priv-dep/pub-priv1.stderr | 8 +- src/tools/compiletest/src/header.rs | 29 +++- src/tools/compiletest/src/runtest.rs | 159 +++++++++--------- 11 files changed, 129 insertions(+), 116 deletions(-) delete mode 100644 src/test/run-make-fulldeps/extern-flag-noprelude/Makefile delete mode 100644 src/test/run-make-fulldeps/extern-flag-noprelude/foo.rs rename src/test/{run-make-fulldeps/extern-flag-noprelude/dep.rs => ui/extern-flag/auxiliary/somedep.rs} (100%) create mode 100644 src/test/ui/extern-flag/noprelude-resolves.rs create mode 100644 src/test/ui/extern-flag/noprelude.rs create mode 100644 src/test/ui/extern-flag/noprelude.stderr diff --git a/src/test/run-make-fulldeps/extern-flag-noprelude/Makefile b/src/test/run-make-fulldeps/extern-flag-noprelude/Makefile deleted file mode 100644 index 18f9d8bab6004..0000000000000 --- a/src/test/run-make-fulldeps/extern-flag-noprelude/Makefile +++ /dev/null @@ -1,11 +0,0 @@ --include ../tools.mk - -# Test --extern noprelude - -all: - $(RUSTC) dep.rs --crate-name=dep --crate-type=rlib - $(RUSTC) foo.rs --edition=2018 -Zunstable-options \ - --extern noprelude:dep=$(TMPDIR)/libdep.rlib 2>&1 | \ - $(CGREP) -e 'failed to resolve.*`dep`' - $(RUSTC) foo.rs --edition=2018 -Zunstable-options \ - --extern dep=$(TMPDIR)/libdep.rlib diff --git a/src/test/run-make-fulldeps/extern-flag-noprelude/foo.rs b/src/test/run-make-fulldeps/extern-flag-noprelude/foo.rs deleted file mode 100644 index 9bb1b78409f86..0000000000000 --- a/src/test/run-make-fulldeps/extern-flag-noprelude/foo.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - dep::somefun(); -} diff --git a/src/test/rustdoc/issue-66159.rs b/src/test/rustdoc/issue-66159.rs index a69ba61a283d0..003d079a470c0 100644 --- a/src/test/rustdoc/issue-66159.rs +++ b/src/test/rustdoc/issue-66159.rs @@ -1,6 +1,5 @@ -// aux-build:issue-66159-1.rs +// aux-crate:priv:issue_66159_1=issue-66159-1.rs // compile-flags:-Z unstable-options -// extern-private:issue_66159_1 // The issue was an ICE which meant that we never actually generated the docs // so if we have generated the docs, we're okay. diff --git a/src/test/run-make-fulldeps/extern-flag-noprelude/dep.rs b/src/test/ui/extern-flag/auxiliary/somedep.rs similarity index 100% rename from src/test/run-make-fulldeps/extern-flag-noprelude/dep.rs rename to src/test/ui/extern-flag/auxiliary/somedep.rs diff --git a/src/test/ui/extern-flag/noprelude-resolves.rs b/src/test/ui/extern-flag/noprelude-resolves.rs new file mode 100644 index 0000000000000..f69f552b69d8a --- /dev/null +++ b/src/test/ui/extern-flag/noprelude-resolves.rs @@ -0,0 +1,11 @@ +// check-pass +// aux-crate:noprelude:somedep=somedep.rs +// compile-flags: -Zunstable-options +// edition:2018 + +// `extern crate` can be used to add to prelude. +extern crate somedep; + +fn main() { + somedep::somefun(); +} diff --git a/src/test/ui/extern-flag/noprelude.rs b/src/test/ui/extern-flag/noprelude.rs new file mode 100644 index 0000000000000..cdbf34091007e --- /dev/null +++ b/src/test/ui/extern-flag/noprelude.rs @@ -0,0 +1,7 @@ +// aux-crate:noprelude:somedep=somedep.rs +// compile-flags: -Zunstable-options +// edition:2018 + +fn main() { + somedep::somefun(); //~ ERROR failed to resolve +} diff --git a/src/test/ui/extern-flag/noprelude.stderr b/src/test/ui/extern-flag/noprelude.stderr new file mode 100644 index 0000000000000..beb9200dddabc --- /dev/null +++ b/src/test/ui/extern-flag/noprelude.stderr @@ -0,0 +1,9 @@ +error[E0433]: failed to resolve: use of undeclared type or module `somedep` + --> $DIR/noprelude.rs:6:5 + | +LL | somedep::somefun(); + | ^^^^^^^ use of undeclared type or module `somedep` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs index 784615354a95c..feab72b3efa42 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -1,11 +1,10 @@ - // aux-build:priv_dep.rs + // aux-crate:priv:priv_dep=priv_dep.rs // aux-build:pub_dep.rs - // extern-private:priv_dep #![deny(exported_private_dependencies)] // This crate is a private dependency extern crate priv_dep; -// This crate is a public dependenct +// This crate is a public dependency extern crate pub_dep; use priv_dep::{OtherType, OtherTrait}; diff --git a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr index b31efdbd781dc..f21b11f5b32f8 100644 --- a/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/src/test/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -1,23 +1,23 @@ error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:21:5 + --> $DIR/pub-priv1.rs:20:5 | LL | pub field: OtherType, | ^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/pub-priv1.rs:4:9 + --> $DIR/pub-priv1.rs:3:9 | LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:28:5 + --> $DIR/pub-priv1.rs:27:5 | LL | pub fn pub_fn(param: OtherType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:34:1 + --> $DIR/pub-priv1.rs:33:1 | LL | / pub trait MyPubTrait { LL | | type Foo: OtherTrait; diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index ca30e782c5056..46cce6394e617 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -71,6 +71,7 @@ pub struct EarlyProps { pub ignore: Ignore, pub should_fail: bool, pub aux: Vec, + pub aux_crate: Vec<(String, String)>, pub revisions: Vec, } @@ -80,6 +81,7 @@ impl EarlyProps { ignore: Ignore::Run, should_fail: false, aux: Vec::new(), + aux_crate: Vec::new(), revisions: vec![], }; @@ -157,6 +159,10 @@ impl EarlyProps { props.aux.push(s); } + if let Some(ac) = config.parse_aux_crate(ln) { + props.aux_crate.push(ac); + } + if let Some(r) = config.parse_revisions(ln) { props.revisions.extend(r); } @@ -311,10 +317,9 @@ pub struct TestProps { // directory as the test, but for backwards compatibility reasons // we also check the auxiliary directory) pub aux_builds: Vec, - // A list of crates to pass '--extern priv:name=PATH' flags for - // This should be a subset of 'aux_build' - // FIXME: Replace this with a better solution: https://github.com/rust-lang/rust/pull/54020 - pub extern_private: Vec, + // Similar to `aux_builds`, but a list of NAME=somelib.rs of dependencies + // to build and pass with the `--extern` flag. + pub aux_crates: Vec<(String, String)>, // Environment settings to use for compiling pub rustc_env: Vec<(String, String)>, // Environment variables to unset prior to compiling. @@ -387,7 +392,7 @@ impl TestProps { run_flags: None, pp_exact: None, aux_builds: vec![], - extern_private: vec![], + aux_crates: vec![], revisions: vec![], rustc_env: vec![], unset_rustc_env: vec![], @@ -514,8 +519,8 @@ impl TestProps { self.aux_builds.push(ab); } - if let Some(ep) = config.parse_extern_private(ln) { - self.extern_private.push(ep); + if let Some(ac) = config.parse_aux_crate(ln) { + self.aux_crates.push(ac); } if let Some(ee) = config.parse_env(ln, "exec-env") { @@ -713,8 +718,14 @@ impl Config { .map(|r| r.trim().to_string()) } - fn parse_extern_private(&self, line: &str) -> Option { - self.parse_name_value_directive(line, "extern-private") + fn parse_aux_crate(&self, line: &str) -> Option<(String, String)> { + self.parse_name_value_directive(line, "aux-crate").map(|r| { + let mut parts = r.trim().splitn(2, '='); + ( + parts.next().expect("aux-crate name").to_string(), + parts.next().expect("aux-crate value").to_string(), + ) + }) } fn parse_compile_flags(&self, line: &str) -> Option { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index ca68fe3e39b96..480868440b8dc 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1776,93 +1776,16 @@ impl<'test> TestCx<'test> { create_dir_all(&aux_dir).unwrap(); } - // Use a Vec instead of a HashMap to preserve original order - let mut extern_priv = self.props.extern_private.clone(); - - let mut add_extern_priv = |priv_dep: &str, dylib: bool| { - let lib_name = get_lib_name(priv_dep, dylib); - rustc - .arg("--extern") - .arg(format!("priv:{}={}", priv_dep, aux_dir.join(lib_name).to_str().unwrap())); - }; - for rel_ab in &self.props.aux_builds { - let aux_testpaths = self.compute_aux_test_paths(rel_ab); - let aux_props = - self.props - .from_aux_file(&aux_testpaths.file, self.revision, self.config); - let aux_output = TargetLocation::ThisDirectory(self.aux_output_dir_name()); - let aux_cx = TestCx { - config: self.config, - props: &aux_props, - testpaths: &aux_testpaths, - revision: self.revision, - }; - // Create the directory for the stdout/stderr files. - create_dir_all(aux_cx.output_base_dir()).unwrap(); - let mut aux_rustc = aux_cx.make_compile_args(&aux_testpaths.file, aux_output); - - let (dylib, crate_type) = if aux_props.no_prefer_dynamic { - (true, None) - } else if self.config.target.contains("cloudabi") - || self.config.target.contains("emscripten") - || (self.config.target.contains("musl") - && !aux_props.force_host - && !self.config.host.contains("musl")) - || self.config.target.contains("wasm32") - || self.config.target.contains("nvptx") - || self.is_vxworks_pure_static() - { - // We primarily compile all auxiliary libraries as dynamic libraries - // to avoid code size bloat and large binaries as much as possible - // for the test suite (otherwise including libstd statically in all - // executables takes up quite a bit of space). - // - // For targets like MUSL or Emscripten, however, there is no support for - // dynamic libraries so we just go back to building a normal library. Note, - // however, that for MUSL if the library is built with `force_host` then - // it's ok to be a dylib as the host should always support dylibs. - (false, Some("lib")) - } else { - (true, Some("dylib")) - }; - - let trimmed = rel_ab.trim_end_matches(".rs").to_string(); - - // Normally, every 'extern-private' has a corresponding 'aux-build' - // entry. If so, we remove it from our list of private crates, - // and add an '--extern priv:NAME=PATH' flag to rustc - if extern_priv.remove_item(&trimmed).is_some() { - add_extern_priv(&trimmed, dylib); - } - - if let Some(crate_type) = crate_type { - aux_rustc.args(&["--crate-type", crate_type]); - } - - aux_rustc.arg("-L").arg(&aux_dir); - - let auxres = aux_cx.compose_and_run( - aux_rustc, - aux_cx.config.compile_lib_path.to_str().unwrap(), - Some(aux_dir.to_str().unwrap()), - None, - ); - if !auxres.status.success() { - self.fatal_proc_rec( - &format!( - "auxiliary build of {:?} failed to compile: ", - aux_testpaths.file.display() - ), - &auxres, - ); - } + self.build_auxiliary(rel_ab, &aux_dir); } - // Add any '--extern' private entries without a matching - // 'aux-build' - for private_lib in extern_priv { - add_extern_priv(&private_lib, true); + for (aux_name, aux_path) in &self.props.aux_crates { + let is_dylib = self.build_auxiliary(&aux_path, &aux_dir); + let lib_name = get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), + is_dylib); + rustc.arg("--extern") + .arg(format!("{}={}/{}", aux_name, aux_dir.display(), lib_name)); } self.props.unset_rustc_env.clone() @@ -1877,6 +1800,74 @@ impl<'test> TestCx<'test> { ) } + /// Builds an aux dependency. + /// + /// Returns whether or not it is a dylib. + fn build_auxiliary(&self, source_path: &str, aux_dir: &Path) -> bool { + let aux_testpaths = self.compute_aux_test_paths(source_path); + let aux_props = + self.props + .from_aux_file(&aux_testpaths.file, self.revision, self.config); + let aux_output = TargetLocation::ThisDirectory(self.aux_output_dir_name()); + let aux_cx = TestCx { + config: self.config, + props: &aux_props, + testpaths: &aux_testpaths, + revision: self.revision, + }; + // Create the directory for the stdout/stderr files. + create_dir_all(aux_cx.output_base_dir()).unwrap(); + let mut aux_rustc = aux_cx.make_compile_args(&aux_testpaths.file, aux_output); + + let (dylib, crate_type) = if aux_props.no_prefer_dynamic { + (true, None) + } else if self.config.target.contains("cloudabi") + || self.config.target.contains("emscripten") + || (self.config.target.contains("musl") + && !aux_props.force_host + && !self.config.host.contains("musl")) + || self.config.target.contains("wasm32") + || self.config.target.contains("nvptx") + || self.is_vxworks_pure_static() + { + // We primarily compile all auxiliary libraries as dynamic libraries + // to avoid code size bloat and large binaries as much as possible + // for the test suite (otherwise including libstd statically in all + // executables takes up quite a bit of space). + // + // For targets like MUSL or Emscripten, however, there is no support for + // dynamic libraries so we just go back to building a normal library. Note, + // however, that for MUSL if the library is built with `force_host` then + // it's ok to be a dylib as the host should always support dylibs. + (false, Some("lib")) + } else { + (true, Some("dylib")) + }; + + if let Some(crate_type) = crate_type { + aux_rustc.args(&["--crate-type", crate_type]); + } + + aux_rustc.arg("-L").arg(&aux_dir); + + let auxres = aux_cx.compose_and_run( + aux_rustc, + aux_cx.config.compile_lib_path.to_str().unwrap(), + Some(aux_dir.to_str().unwrap()), + None, + ); + if !auxres.status.success() { + self.fatal_proc_rec( + &format!( + "auxiliary build of {:?} failed to compile: ", + aux_testpaths.file.display() + ), + &auxres, + ); + } + dylib + } + fn compose_and_run( &self, mut command: Command,