diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 9d2f62bd03046..4d353a36db02a 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use hir::def_id::{DefId, CrateNum}; +use hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use syntax::ast::NodeId; use syntax::symbol::{Symbol, InternedString}; use ty::{Instance, TyCtxt}; @@ -266,7 +266,8 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> CodegenUnitNameBuilder<'a, 'gcx, 'tcx> { /// This function will build CGU names of the form: /// /// ``` - /// .(-)*[.] + /// .[-in-](-)*[.] + /// = . /// ``` /// /// The '.' before `` makes sure that names with a special @@ -311,9 +312,25 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> CodegenUnitNameBuilder<'a, 'gcx, 'tcx> { // Start out with the crate name and disambiguator let tcx = self.tcx; let crate_prefix = self.cache.entry(cnum).or_insert_with(|| { + // Whenever the cnum is not LOCAL_CRATE we also mix in the + // local crate's ID. Otherwise there can be collisions between CGUs + // instantiating stuff for upstream crates. + let local_crate_id = if cnum != LOCAL_CRATE { + let local_crate_disambiguator = + format!("{}", tcx.crate_disambiguator(LOCAL_CRATE)); + format!("-in-{}.{}", + tcx.crate_name(LOCAL_CRATE), + &local_crate_disambiguator[0 .. 8]) + } else { + String::new() + }; + let crate_disambiguator = format!("{}", tcx.crate_disambiguator(cnum)); // Using a shortened disambiguator of about 40 bits - format!("{}.{}", tcx.crate_name(cnum), &crate_disambiguator[0 .. 8]) + format!("{}.{}{}", + tcx.crate_name(cnum), + &crate_disambiguator[0 .. 8], + local_crate_id) }); write!(cgu_name, "{}", crate_prefix).unwrap(); diff --git a/src/test/codegen-units/partitioning/extern-generic.rs b/src/test/codegen-units/partitioning/extern-generic.rs index a774376690a97..e604d6a92c29c 100644 --- a/src/test/codegen-units/partitioning/extern-generic.rs +++ b/src/test/codegen-units/partitioning/extern-generic.rs @@ -58,5 +58,5 @@ mod mod3 { // Make sure the two generic functions from the extern crate get instantiated // once for the current crate -//~ MONO_ITEM fn cgu_generic_function::foo[0]<&str> @@ cgu_generic_function.volatile[External] -//~ MONO_ITEM fn cgu_generic_function::bar[0]<&str> @@ cgu_generic_function.volatile[External] +//~ MONO_ITEM fn cgu_generic_function::foo[0]<&str> @@ cgu_generic_function-in-extern_generic.volatile[External] +//~ MONO_ITEM fn cgu_generic_function::bar[0]<&str> @@ cgu_generic_function-in-extern_generic.volatile[External] diff --git a/src/test/codegen-units/partitioning/shared-generics.rs b/src/test/codegen-units/partitioning/shared-generics.rs index 880361fac2ee0..8c261f967ca73 100644 --- a/src/test/codegen-units/partitioning/shared-generics.rs +++ b/src/test/codegen-units/partitioning/shared-generics.rs @@ -19,7 +19,7 @@ extern crate shared_generics_aux; //~ MONO_ITEM fn shared_generics::foo[0] pub fn foo() { - //~ MONO_ITEM fn shared_generics_aux::generic_fn[0] @@ shared_generics_aux.volatile[External] + //~ MONO_ITEM fn shared_generics_aux::generic_fn[0] @@ shared_generics_aux-in-shared_generics.volatile[External] let _ = shared_generics_aux::generic_fn(0u16, 1u16); // This should not generate a monomorphization because it's already diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 7fec2e003a445..0ee3143935897 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -14,11 +14,11 @@ serde = "1.0" serde_json = "1.0" serde_derive = "1.0" rustfix = "0.4.1" +lazy_static = "1.0" [target.'cfg(unix)'.dependencies] libc = "0.2" [target.'cfg(windows)'.dependencies] -lazy_static = "1.0" miow = "0.3" winapi = { version = "0.3", features = ["winerror"] } diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index c1d3df79222c5..a5cf45baa653a 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -22,7 +22,6 @@ extern crate libc; extern crate log; extern crate regex; #[macro_use] -#[cfg(windows)] extern crate lazy_static; #[macro_use] extern crate serde_derive; diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 24b575aae12f9..2d49c83edb917 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2355,21 +2355,30 @@ impl<'test> TestCx<'test> { string } + // Given a cgu-name-prefix of the form . or + // the form .-in-., + // remove all crate-disambiguators. fn remove_crate_disambiguator_from_cgu(cgu: &str) -> String { - // The first '.' is the start of the crate disambiguator - let disambiguator_start = cgu.find('.') - .expect("Could not find start of crate disambiguator in CGU spec"); + lazy_static! { + static ref RE: Regex = Regex::new( + r"^[^\.]+(?P\.[[:alnum:]]+)(-in-[^\.]+(?P\.[[:alnum:]]+))?" + ).unwrap(); + } + + let captures = RE.captures(cgu).unwrap_or_else(|| { + panic!("invalid cgu name encountered: {}", cgu) + }); - // The first non-alphanumeric character is the end of the disambiguator - let disambiguator_end = cgu[disambiguator_start + 1 ..] - .find(|c| !char::is_alphanumeric(c)) - .expect("Could not find end of crate disambiguator in CGU spec") - + disambiguator_start + 1; + let mut new_name = cgu.to_owned(); + + if let Some(d2) = captures.name("d2") { + new_name.replace_range(d2.start() .. d2.end(), ""); + } - let mut result = cgu[0 .. disambiguator_start].to_string(); - result.push_str(&cgu[disambiguator_end ..]); + let d1 = captures.name("d1").unwrap(); + new_name.replace_range(d1.start() .. d1.end(), ""); - result + new_name } }