Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow compiletest to pass down --extern flags #54020

Closed
wants to merge 14 commits into from
7 changes: 0 additions & 7 deletions src/test/run-make-fulldeps/use-suggestions-rust-2018/Makefile

This file was deleted.

Expand Up @@ -8,6 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn main() {
let x = Baz{};
}
#![crate_type="lib"]

pub struct Yellow;
19 changes: 19 additions & 0 deletions src/test/ui/issue-53737.rs
@@ -0,0 +1,19 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-crate:myfoo=baz.rs
// edition:2018


use myfoo::Yellow;

fn main() {
let x = Yellow{};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we port the extern prelude test to use this?

What about your existing tests for suggestions?

Expand Up @@ -12,6 +12,6 @@

pub mod foo {
pub mod bar {
pub struct Baz;
pub struct Bazz;
}
}
17 changes: 17 additions & 0 deletions src/test/ui/rust-2018/use-suggestions-extern-prelude.rs
@@ -0,0 +1,17 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// edition:2018
// aux-crate:netted=ep-nested-lib.rs

fn main() {
let _x = Bazz{};
//~^ ERROR cannot find struct, variant or union type `Bazz` in this scope
}
13 changes: 13 additions & 0 deletions src/test/ui/rust-2018/use-suggestions-extern-prelude.stderr
@@ -0,0 +1,13 @@
error[E0422]: cannot find struct, variant or union type `Bazz` in this scope
--> $DIR/use-suggestions-extern-prelude.rs:15:14
|
LL | let _x = Bazz{};
| ^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
|
LL | use netted::foo::bar::Bazz;
|

error: aborting due to previous error

For more information about this error, try `rustc --explain E0422`.
71 changes: 63 additions & 8 deletions src/tools/compiletest/src/header.rs
Expand Up @@ -77,6 +77,7 @@ pub struct EarlyProps {
pub ignore: Ignore,
pub should_fail: bool,
pub aux: Vec<String>,
pub aux_crate: Vec<KeyValue>,
pub revisions: Vec<String>,
}

Expand All @@ -86,6 +87,7 @@ impl EarlyProps {
ignore: Ignore::Run,
should_fail: false,
aux: Vec::new(),
aux_crate: Vec::new(),
revisions: vec![],
};

Expand Down Expand Up @@ -137,6 +139,10 @@ impl EarlyProps {
props.aux.push(s);
}

if let Some(s) = config.parse_aux_crate(ln) {
props.aux_crate.push(s);
}

if let Some(r) = config.parse_revisions(ln) {
props.revisions.extend(r);
}
Expand Down Expand Up @@ -268,6 +274,8 @@ pub struct TestProps {
// directory as the test, but for backwards compatibility reasons
// we also check the auxiliary directory)
pub aux_builds: Vec<String>,
// crates that should be compiled and exposed as the given alias
pub aux_crates: Vec<KeyValue>,
// Environment settings to use for compiling
pub rustc_env: Vec<(String, String)>,
// Environment settings to use during execution
Expand Down Expand Up @@ -327,6 +335,7 @@ impl TestProps {
run_flags: None,
pp_exact: None,
aux_builds: vec![],
aux_crates: vec![],
revisions: vec![],
rustc_env: vec![],
exec_env: vec![],
Expand Down Expand Up @@ -442,6 +451,10 @@ impl TestProps {
self.aux_builds.push(ab);
}

if let Some(ab) = config.parse_aux_crate(ln) {
self.aux_crates.push(ab);
}

if let Some(ee) = config.parse_env(ln, "exec-env") {
self.exec_env.push(ee);
}
Expand Down Expand Up @@ -576,6 +589,10 @@ impl Config {
self.parse_name_value_directive(line, "aux-build")
}

fn parse_aux_crate(&self, line: &str) -> Option<KeyValue> {
self.parse_name_kv_directive(line, "aux-crate")
}

fn parse_compile_flags(&self, line: &str) -> Option<String> {
self.parse_name_value_directive(line, "compile-flags")
}
Expand Down Expand Up @@ -772,14 +789,11 @@ impl Config {
}

pub fn parse_name_value_directive(&self, line: &str, directive: &str) -> Option<String> {
let colon = directive.len();
if line.starts_with(directive) && line.as_bytes().get(colon) == Some(&b':') {
let value = line[(colon + 1)..].to_owned();
debug!("{}: {}", directive, value);
Some(expand_variables(value, self))
} else {
None
}
internal_parse_name_value_directive(line, directive).map(|v| expand_variables(v, self))
}

pub fn parse_name_kv_directive(&self, line: &str, directive: &str) -> Option<KeyValue> {
internal_parse_name_kv_directive(line, directive)
}

pub fn find_rust_src_root(&self) -> Option<PathBuf> {
Expand Down Expand Up @@ -816,6 +830,47 @@ pub fn lldb_version_to_int(version_string: &str) -> isize {
version_string.parse().expect(&error_string)
}

#[test]
fn test_parse_name_value_directive() {
assert_eq!(Some("foo.rs".to_owned()),
internal_parse_name_value_directive("aux-build:foo.rs", "aux-build"));
assert_eq!(None, internal_parse_name_value_directive("faux-build:foo.rs", "aux-build"));
}

#[derive(Clone, Debug, PartialEq)]
pub struct KeyValue {
pub key: String,
pub value: String,
}

#[test]
fn test_parse_name_kv_directive() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woah tests. Totally not idiomatic for compiletest. 😛

let value = internal_parse_name_kv_directive("crate-aux-build:baz=foo.rs", "crate-aux-build");
assert_eq!(Some(KeyValue{key:"baz".to_owned(), value:"foo.rs".to_owned()}), value);
}

fn internal_parse_name_kv_directive(line: &str, directive: &str) -> Option<KeyValue> {
if let Some(value) = internal_parse_name_value_directive(line, directive) {
let parts = value.split("=").collect::<Vec<&str>>();
if parts.len() == 2 {
let (k,v) = (parts[0], parts[1]);
return Some(KeyValue{key:k.to_string(),value:v.to_string()});
}
}
None
}

fn internal_parse_name_value_directive(line: &str, directive: &str) -> Option<String> {
let colon = directive.len();
if line.starts_with(directive) && line.as_bytes().get(colon) == Some(&b':') {
let value = line[(colon + 1)..].to_owned();
debug!("{}: {}", directive, value);
Some(value)
} else {
None
}
}

fn expand_variables(mut value: String, config: &Config) -> String {
const CWD: &'static str = "{{cwd}}";
const SRC_BASE: &'static str = "{{src-base}}";
Expand Down
130 changes: 75 additions & 55 deletions src/tools/compiletest/src/runtest.rs
Expand Up @@ -36,6 +36,7 @@ use std::io::{self, BufReader};
use std::path::{Path, PathBuf};
use std::process::{Child, Command, ExitStatus, Output, Stdio};
use std::str;
use std::env::consts::DLL_EXTENSION;

use extract_gdb_version;
use is_android_gdb_target;
Expand Down Expand Up @@ -1563,66 +1564,25 @@ impl<'test> TestCx<'test> {
}

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 crate_type = if aux_props.no_prefer_dynamic {
None
} else if self.config.target.contains("cloudabi")
|| self.config.target.contains("emscripten")
|| (self.config.target.contains("musl") && !aux_props.force_host)
|| self.config.target.contains("wasm32")
{
// 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.
Some("lib")
} else {
Some("dylib")
};
build_auxiliary(self, rel_ab, &aux_dir);
}

if let Some(crate_type) = crate_type {
aux_rustc.args(&["--crate-type", crate_type]);
}
for rel_ab in &self.props.aux_crates {
build_auxiliary(self, &rel_ab.value, &aux_dir);
}

aux_rustc.arg("-L").arg(&aux_dir);
rustc.envs(self.props.rustc_env.clone());

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,
);
}
for aux_crate in &self.props.aux_crates {
rustc.arg("--extern");
rustc.arg(format!("{}={}/lib{}",
aux_crate.key,
aux_dir.display(),
aux_crate.value.replace(".rs", &format!(".{}", DLL_EXTENSION))
.replace("-","_")
));
}

rustc.envs(self.props.rustc_env.clone());
self.compose_and_run(
rustc,
self.config.compile_lib_path.to_str().unwrap(),
Expand Down Expand Up @@ -3249,6 +3209,66 @@ impl<'test> TestCx<'test> {
}
}

fn build_auxiliary(test_cx: &TestCx, rel_ab: &str, aux_dir: &Path) {
let aux_testpaths = test_cx.compute_aux_test_paths(rel_ab);
let aux_props =
test_cx.props
.from_aux_file(&aux_testpaths.file, test_cx.revision, test_cx.config);
let aux_output = TargetLocation::ThisDirectory(test_cx.aux_output_dir_name());
let aux_cx = TestCx {
config: test_cx.config,
props: &aux_props,
testpaths: &aux_testpaths,
revision: test_cx.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 crate_type = if aux_props.no_prefer_dynamic {
None
} else if test_cx.config.target.contains("cloudabi")
|| test_cx.config.target.contains("emscripten")
|| (test_cx.config.target.contains("musl") && !aux_props.force_host)
|| test_cx.config.target.contains("wasm32")
{
// 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.
Some("lib")
} else {
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() {
test_cx.fatal_proc_rec(
&format!(
"auxiliary build of {:?} failed to compile: ",
aux_testpaths.file.display()
),
&auxres,
);
}
}

struct ProcArgs {
prog: String,
args: Vec<String>,
Expand Down