diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs index f12b0dadeacc1..154d9556fd7ba 100644 --- a/src/bootstrap/build/check.rs +++ b/src/bootstrap/build/check.rs @@ -105,9 +105,18 @@ pub fn compiletest(build: &Build, cmd.arg("--host").arg(compiler.host); cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.config.build)); + let mut flags = format!("-Crpath"); + if build.config.rust_optimize_tests { + flags.push_str(" -O"); + } + if build.config.rust_debuginfo_tests { + flags.push_str(" -g"); + } + + cmd.arg("--host-rustcflags").arg(&flags); + let linkflag = format!("-Lnative={}", build.test_helpers_out(target).display()); - cmd.arg("--host-rustcflags").arg("-Crpath"); - cmd.arg("--target-rustcflags").arg(format!("-Crpath {}", linkflag)); + cmd.arg("--target-rustcflags").arg(format!("{} {}", flags, linkflag)); // FIXME: needs android support cmd.arg("--android-cross-path").arg(""); diff --git a/src/bootstrap/build/config.rs b/src/bootstrap/build/config.rs index 533c1c93d5bc4..3c35b9a95169a 100644 --- a/src/bootstrap/build/config.rs +++ b/src/bootstrap/build/config.rs @@ -59,6 +59,8 @@ pub struct Config { pub rust_rpath: bool, pub rustc_default_linker: Option, pub rustc_default_ar: Option, + pub rust_optimize_tests: bool, + pub rust_debuginfo_tests: bool, pub build: String, pub host: Vec, @@ -136,6 +138,8 @@ struct Rust { channel: Option, musl_root: Option, rpath: Option, + optimize_tests: Option, + debuginfo_tests: Option, } /// TOML representation of how each build target is configured. @@ -154,6 +158,7 @@ impl Config { config.llvm_optimize = true; config.use_jemalloc = true; config.rust_optimize = true; + config.rust_optimize_tests = true; config.submodules = true; config.docs = true; config.rust_rpath = true; @@ -219,6 +224,8 @@ impl Config { set(&mut config.rust_debug_assertions, rust.debug_assertions); set(&mut config.rust_debuginfo, rust.debuginfo); set(&mut config.rust_optimize, rust.optimize); + set(&mut config.rust_optimize_tests, rust.optimize_tests); + set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests); set(&mut config.rust_rpath, rust.rpath); set(&mut config.debug_jemalloc, rust.debug_jemalloc); set(&mut config.use_jemalloc, rust.use_jemalloc); @@ -306,6 +313,8 @@ impl Config { ("JEMALLOC", self.use_jemalloc), ("DEBUG_JEMALLOC", self.debug_jemalloc), ("RPATH", self.rust_rpath), + ("OPTIMIZE_TESTS", self.rust_optimize_tests), + ("DEBUGINFO_TESTS", self.rust_debuginfo_tests), } match key { diff --git a/src/bootstrap/build/mod.rs b/src/bootstrap/build/mod.rs index 3284b5dfe9c07..ebc05c5f61c50 100644 --- a/src/bootstrap/build/mod.rs +++ b/src/bootstrap/build/mod.rs @@ -318,10 +318,18 @@ impl Build { check::compiletest(self, &compiler, target.target, "run-pass", "run-pass"); } + CheckRPassFull { compiler } => { + check::compiletest(self, &compiler, target.target, + "run-pass", "run-pass-fulldeps"); + } CheckCFail { compiler } => { check::compiletest(self, &compiler, target.target, "compile-fail", "compile-fail"); } + CheckCFailFull { compiler } => { + check::compiletest(self, &compiler, target.target, + "compile-fail", "compile-fail-fulldeps") + } CheckPFail { compiler } => { check::compiletest(self, &compiler, target.target, "parse-fail", "parse-fail"); @@ -330,10 +338,34 @@ impl Build { check::compiletest(self, &compiler, target.target, "run-fail", "run-fail"); } + CheckRFailFull { compiler } => { + check::compiletest(self, &compiler, target.target, + "run-fail", "run-fail-fulldeps"); + } CheckPretty { compiler } => { check::compiletest(self, &compiler, target.target, "pretty", "pretty"); } + CheckPrettyRPass { compiler } => { + check::compiletest(self, &compiler, target.target, + "pretty", "run-pass"); + } + CheckPrettyRPassFull { compiler } => { + check::compiletest(self, &compiler, target.target, + "pretty", "run-pass-fulldeps"); + } + CheckPrettyRFail { compiler } => { + check::compiletest(self, &compiler, target.target, + "pretty", "run-fail"); + } + CheckPrettyRFailFull { compiler } => { + check::compiletest(self, &compiler, target.target, + "pretty", "run-fail-fulldeps"); + } + CheckPrettyRPassValgrind { compiler } => { + check::compiletest(self, &compiler, target.target, + "pretty", "run-pass-valgrind"); + } CheckCodegen { compiler } => { check::compiletest(self, &compiler, target.target, "codegen", "codegen"); @@ -370,14 +402,6 @@ impl Build { check::compiletest(self, &compiler, target.target, "run-pass-valgrind", "run-pass-valgrind"); } - CheckRPassFull { compiler } => { - check::compiletest(self, &compiler, target.target, - "run-pass", "run-pass-fulldeps"); - } - CheckCFailFull { compiler } => { - check::compiletest(self, &compiler, target.target, - "compile-fail", "compile-fail-fulldeps") - } CheckDocs { compiler } => { check::docs(self, &compiler); } diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs index 4e53ddef59457..742fd8575bb80 100644 --- a/src/bootstrap/build/step.rs +++ b/src/bootstrap/build/step.rs @@ -106,19 +106,25 @@ macro_rules! targets { (check_cargotest, CheckCargoTest { stage: u32 }), (check_tidy, CheckTidy { stage: u32 }), (check_rpass, CheckRPass { compiler: Compiler<'a> }), + (check_rpass_full, CheckRPassFull { compiler: Compiler<'a> }), + (check_rpass_valgrind, CheckRPassValgrind { compiler: Compiler<'a> }), (check_rfail, CheckRFail { compiler: Compiler<'a> }), + (check_rfail_full, CheckRFailFull { compiler: Compiler<'a> }), (check_cfail, CheckCFail { compiler: Compiler<'a> }), + (check_cfail_full, CheckCFailFull { compiler: Compiler<'a> }), (check_pfail, CheckPFail { compiler: Compiler<'a> }), + (check_pretty, CheckPretty { compiler: Compiler<'a> }), + (check_pretty_rpass, CheckPrettyRPass { compiler: Compiler<'a> }), + (check_pretty_rpass_full, CheckPrettyRPassFull { compiler: Compiler<'a> }), + (check_pretty_rfail, CheckPrettyRFail { compiler: Compiler<'a> }), + (check_pretty_rfail_full, CheckPrettyRFailFull { compiler: Compiler<'a> }), + (check_pretty_rpass_valgrind, CheckPrettyRPassValgrind { compiler: Compiler<'a> }), (check_codegen, CheckCodegen { compiler: Compiler<'a> }), (check_codegen_units, CheckCodegenUnits { compiler: Compiler<'a> }), (check_incremental, CheckIncremental { compiler: Compiler<'a> }), (check_ui, CheckUi { compiler: Compiler<'a> }), (check_debuginfo, CheckDebuginfo { compiler: Compiler<'a> }), (check_rustdoc, CheckRustdoc { compiler: Compiler<'a> }), - (check_pretty, CheckPretty { compiler: Compiler<'a> }), - (check_rpass_valgrind, CheckRPassValgrind { compiler: Compiler<'a> }), - (check_rpass_full, CheckRPassFull { compiler: Compiler<'a> }), - (check_cfail_full, CheckCFailFull { compiler: Compiler<'a> }), (check_docs, CheckDocs { compiler: Compiler<'a> }), (check_error_index, CheckErrorIndex { compiler: Compiler<'a> }), (check_rmake, CheckRMake { compiler: Compiler<'a> }), @@ -378,8 +384,11 @@ impl<'a> Step<'a> { Source::Check { stage, compiler } => { vec![ self.check_rpass(compiler), - self.check_cfail(compiler), + self.check_rpass_full(compiler), self.check_rfail(compiler), + self.check_rfail_full(compiler), + self.check_cfail(compiler), + self.check_cfail_full(compiler), self.check_pfail(compiler), self.check_incremental(compiler), self.check_ui(compiler), @@ -391,9 +400,12 @@ impl<'a> Step<'a> { self.check_debuginfo(compiler), self.check_rustdoc(compiler), self.check_pretty(compiler), + self.check_pretty_rpass(compiler), + self.check_pretty_rpass_full(compiler), + self.check_pretty_rfail(compiler), + self.check_pretty_rfail_full(compiler), + self.check_pretty_rpass_valgrind(compiler), self.check_rpass_valgrind(compiler), - self.check_rpass_full(compiler), - self.check_cfail_full(compiler), self.check_error_index(compiler), self.check_docs(compiler), self.check_rmake(compiler), @@ -412,6 +424,8 @@ impl<'a> Step<'a> { Source::CheckTidy { stage } => { vec![self.tool_tidy(stage)] } + Source::CheckPrettyRPass { compiler } | + Source::CheckPrettyRFail { compiler } | Source::CheckRFail { compiler } | Source::CheckPFail { compiler } | Source::CheckCodegen { compiler } | @@ -438,7 +452,11 @@ impl<'a> Step<'a> { ] } Source::CheckRPassFull { compiler } | + Source::CheckRFailFull { compiler } | Source::CheckCFailFull { compiler } | + Source::CheckPrettyRPassFull { compiler } | + Source::CheckPrettyRFailFull { compiler } | + Source::CheckPrettyRPassValgrind { compiler } | Source::CheckRMake { compiler } => { vec![self.librustc(compiler), self.tool_compiletest(compiler.stage)] diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index a0e6ab1a2d2d0..6f0658423283b 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -122,6 +122,11 @@ # desired in distributions, for example. #rpath = true +# Flag indicating whether tests are compiled with optimizations (the -O flag) or +# with debuginfo (the -g flag) +#optimize-tests = true +#debuginfo-tests = true + # ============================================================================= # Options for specific targets # diff --git a/src/librustc_bitflags/Cargo.toml b/src/librustc_bitflags/Cargo.toml index d1e66dcf9351b..d82a72994ca6f 100644 --- a/src/librustc_bitflags/Cargo.toml +++ b/src/librustc_bitflags/Cargo.toml @@ -6,5 +6,4 @@ version = "0.0.0" [lib] name = "rustc_bitflags" path = "lib.rs" -test = false doctest = false diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 0eacc0907bc25..af4a92221941c 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -143,6 +143,11 @@ impl PMDSource { } } +enum LoadResult { + Previous(ast::CrateNum), + Loaded(loader::Library), +} + impl<'a> CrateReader<'a> { pub fn new(sess: &'a Session, cstore: &'a CStore, @@ -358,12 +363,8 @@ impl<'a> CrateReader<'a> { kind: PathKind, explicitly_linked: bool) -> (ast::CrateNum, Rc, cstore::CrateSource) { - enum LookupResult { - Previous(ast::CrateNum), - Loaded(loader::Library), - } let result = match self.existing_match(name, hash, kind) { - Some(cnum) => LookupResult::Previous(cnum), + Some(cnum) => LoadResult::Previous(cnum), None => { let mut load_ctxt = loader::Context { sess: self.sess, @@ -380,40 +381,59 @@ impl<'a> CrateReader<'a> { rejected_via_kind: vec!(), should_match_name: true, }; - let library = load_ctxt.load_library_crate(); - - // In the case that we're loading a crate, but not matching - // against a hash, we could load a crate which has the same hash - // as an already loaded crate. If this is the case prevent - // duplicates by just using the first crate. - let meta_hash = decoder::get_crate_hash(library.metadata - .as_slice()); - let mut result = LookupResult::Loaded(library); - self.cstore.iter_crate_data(|cnum, data| { - if data.name() == name && meta_hash == data.hash() { - assert!(hash.is_none()); - result = LookupResult::Previous(cnum); - } - }); - result + match self.load(&mut load_ctxt) { + Some(result) => result, + None => load_ctxt.report_load_errs(), + } } }; match result { - LookupResult::Previous(cnum) => { + LoadResult::Previous(cnum) => { let data = self.cstore.get_crate_data(cnum); if explicitly_linked && !data.explicitly_linked.get() { data.explicitly_linked.set(explicitly_linked); } (cnum, data, self.cstore.used_crate_source(cnum)) } - LookupResult::Loaded(library) => { + LoadResult::Loaded(library) => { self.register_crate(root, ident, name, span, library, explicitly_linked) } } } + fn load(&mut self, loader: &mut loader::Context) -> Option { + let library = match loader.maybe_load_library_crate() { + Some(lib) => lib, + None => return None, + }; + + // In the case that we're loading a crate, but not matching + // against a hash, we could load a crate which has the same hash + // as an already loaded crate. If this is the case prevent + // duplicates by just using the first crate. + // + // Note that we only do this for target triple crates, though, as we + // don't want to match a host crate against an equivalent target one + // already loaded. + if loader.triple == self.sess.opts.target_triple { + let meta_hash = decoder::get_crate_hash(library.metadata.as_slice()); + let meta_name = decoder::get_crate_name(library.metadata.as_slice()) + .to_string(); + let mut result = LoadResult::Loaded(library); + self.cstore.iter_crate_data(|cnum, data| { + if data.name() == meta_name && meta_hash == data.hash() { + assert!(loader.hash.is_none()); + result = LoadResult::Previous(cnum); + } + }); + Some(result) + } else { + Some(LoadResult::Loaded(library)) + } + } + fn update_extern_crate(&mut self, cnum: ast::CrateNum, mut extern_crate: ExternCrate) @@ -488,35 +508,46 @@ impl<'a> CrateReader<'a> { rejected_via_kind: vec!(), should_match_name: true, }; - let library = match load_ctxt.maybe_load_library_crate() { - Some(l) => l, - None if is_cross => { - // Try loading from target crates. This will abort later if we - // try to load a plugin registrar function, - target_only = true; - should_link = info.should_link; - - load_ctxt.target = &self.sess.target.target; - load_ctxt.triple = target_triple; - load_ctxt.filesearch = self.sess.target_filesearch(PathKind::Crate); - load_ctxt.load_library_crate() + let library = self.load(&mut load_ctxt).or_else(|| { + if !is_cross { + return None } - None => { load_ctxt.report_load_errs(); }, + // Try loading from target crates. This will abort later if we + // try to load a plugin registrar function, + target_only = true; + should_link = info.should_link; + + load_ctxt.target = &self.sess.target.target; + load_ctxt.triple = target_triple; + load_ctxt.filesearch = self.sess.target_filesearch(PathKind::Crate); + + self.load(&mut load_ctxt) + }); + let library = match library { + Some(l) => l, + None => load_ctxt.report_load_errs(), }; - let dylib = library.dylib.clone(); - let register = should_link && self.existing_match(&info.name, - None, - PathKind::Crate).is_none(); - let metadata = if register { - // Register crate now to avoid double-reading metadata - let (_, cmd, _) = self.register_crate(&None, &info.ident, - &info.name, span, library, - true); - PMDSource::Registered(cmd) - } else { - // Not registering the crate; just hold on to the metadata - PMDSource::Owned(library.metadata) + let (dylib, metadata) = match library { + LoadResult::Previous(cnum) => { + let dylib = self.cstore.opt_used_crate_source(cnum).unwrap().dylib; + let data = self.cstore.get_crate_data(cnum); + (dylib, PMDSource::Registered(data)) + } + LoadResult::Loaded(library) => { + let dylib = library.dylib.clone(); + let metadata = if should_link { + // Register crate now to avoid double-reading metadata + let (_, cmd, _) = self.register_crate(&None, &info.ident, + &info.name, span, + library, true); + PMDSource::Registered(cmd) + } else { + // Not registering the crate; just hold on to the metadata + PMDSource::Owned(library.metadata) + }; + (dylib, metadata) + } }; ExtensionCrate { diff --git a/src/test/run-make/extern-multiple-copies2/Makefile b/src/test/run-make/extern-multiple-copies2/Makefile new file mode 100644 index 0000000000000..567d7e78a57a4 --- /dev/null +++ b/src/test/run-make/extern-multiple-copies2/Makefile @@ -0,0 +1,10 @@ +-include ../tools.mk + +all: + $(RUSTC) foo1.rs + $(RUSTC) foo2.rs + mkdir $(TMPDIR)/foo + cp $(TMPDIR)/libfoo1.rlib $(TMPDIR)/foo/libfoo1.rlib + $(RUSTC) bar.rs \ + --extern foo1=$(TMPDIR)/foo/libfoo1.rlib \ + --extern foo2=$(TMPDIR)/libfoo2.rlib diff --git a/src/test/run-make/extern-multiple-copies2/bar.rs b/src/test/run-make/extern-multiple-copies2/bar.rs new file mode 100644 index 0000000000000..b8ac34aa53e30 --- /dev/null +++ b/src/test/run-make/extern-multiple-copies2/bar.rs @@ -0,0 +1,18 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate foo2; // foo2 first to exhibit the bug +#[macro_use] +extern crate foo1; + +fn main() { + foo2::foo2(foo1::A); +} diff --git a/src/test/run-make/extern-multiple-copies2/foo1.rs b/src/test/run-make/extern-multiple-copies2/foo1.rs new file mode 100644 index 0000000000000..1787772053ba4 --- /dev/null +++ b/src/test/run-make/extern-multiple-copies2/foo1.rs @@ -0,0 +1,17 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +pub struct A; + +pub fn foo1(a: A) { + drop(a); +} diff --git a/src/test/run-make/extern-multiple-copies2/foo2.rs b/src/test/run-make/extern-multiple-copies2/foo2.rs new file mode 100644 index 0000000000000..bad1030438779 --- /dev/null +++ b/src/test/run-make/extern-multiple-copies2/foo2.rs @@ -0,0 +1,18 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +#[macro_use] +extern crate foo1; + +pub fn foo2(a: foo1::A) { + foo1::foo1(a); +}