about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2018-09-12 12:46:48 +0200
committerMichael Woerister <michaelwoerister@posteo>2018-09-12 12:46:48 +0200
commit3beb762dcf2ff721f2c30534ab6ce6b94c3aebaf (patch)
tree77e88e2794da1982b8583bc1c6103eb0d49d9b9e
parenta2b991b5305b770c7d5288ab3aa231428511c530 (diff)
downloadrust-3beb762dcf2ff721f2c30534ab6ce6b94c3aebaf.tar.gz
rust-3beb762dcf2ff721f2c30534ab6ce6b94c3aebaf.zip
Really make CGU names unique across crates.
-rw-r--r--src/librustc/mir/mono.rs23
-rw-r--r--src/test/codegen-units/partitioning/extern-generic.rs4
-rw-r--r--src/test/codegen-units/partitioning/shared-generics.rs2
-rw-r--r--src/tools/compiletest/Cargo.toml2
-rw-r--r--src/tools/compiletest/src/main.rs1
-rw-r--r--src/tools/compiletest/src/runtest.rs31
6 files changed, 44 insertions, 19 deletions
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index 9d2f62bd030..4d353a36db0 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:
     ///
     /// ```
-    /// <crate-name>.<crate-disambiguator>(-<component>)*[.<special-suffix>]
+    /// <crate-name>.<crate-disambiguator>[-in-<local-crate-id>](-<component>)*[.<special-suffix>]
+    /// <local-crate-id> = <local-crate-name>.<local-crate-disambiguator>
     /// ```
     ///
     /// The '.' before `<special-suffix>` 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 a774376690a..e604d6a92c2 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 880361fac2e..8c261f967ca 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]<u16> @@ shared_generics_aux.volatile[External]
+    //~ MONO_ITEM fn shared_generics_aux::generic_fn[0]<u16> @@ 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 7fec2e003a4..0ee31439358 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 c1d3df79222..a5cf45baa65 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 24b575aae12..2d49c83edb9 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 <crate-name>.<crate-disambiguator> or
+        // the form <crate-name1>.<crate-disambiguator1>-in-<crate-name2>.<crate-disambiguator2>,
+        // 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<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[: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
         }
     }