Skip to content

Commit

Permalink
Auto merge of #54152 - michaelwoerister:cgu-name-fix, r=alexcrichton
Browse files Browse the repository at this point in the history
Really make CGU names unique across crates.

This will hopefully fix issue #53794.

r? @alexcrichton
  • Loading branch information
bors committed Sep 12, 2018
2 parents 6810f52 + 3beb762 commit 06d2448
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 19 deletions.
23 changes: 20 additions & 3 deletions src/librustc/mir/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions src/test/codegen-units/partitioning/extern-generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
2 changes: 1 addition & 1 deletion src/test/codegen-units/partitioning/shared-generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/tools/compiletest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"] }
1 change: 0 additions & 1 deletion src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
31 changes: 20 additions & 11 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down

0 comments on commit 06d2448

Please sign in to comment.