Skip to content

Commit 26898a0

Browse files
committed
rustc_codegen_utils: add new mangling scheme implementation.
1 parent e95d059 commit 26898a0

File tree

5 files changed

+745
-44
lines changed

5 files changed

+745
-44
lines changed

Cargo.lock

+7
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,11 @@ dependencies = [
18771877
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
18781878
]
18791879

1880+
[[package]]
1881+
name = "punycode"
1882+
version = "0.4.0"
1883+
source = "registry+https://github.com/rust-lang/crates.io-index"
1884+
18801885
[[package]]
18811886
name = "quick-error"
18821887
version = "1.2.2"
@@ -2524,6 +2529,7 @@ version = "0.0.0"
25242529
dependencies = [
25252530
"flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
25262531
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
2532+
"punycode 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
25272533
"rustc 0.0.0",
25282534
"rustc_data_structures 0.0.0",
25292535
"rustc_incremental 0.0.0",
@@ -3939,6 +3945,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
39393945
"checksum proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "926d0604475349f463fe44130aae73f2294b5309ab2ca0310b998bd334ef191f"
39403946
"checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
39413947
"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
3948+
"checksum punycode 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ddd112cca70a4d30883b2d21568a1d376ff8be4758649f64f973c6845128ad3"
39423949
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
39433950
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
39443951
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"

src/librustc_codegen_utils/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ test = false
1212
[dependencies]
1313
flate2 = "1.0"
1414
log = "0.4"
15+
punycode = "0.4.0"
1516

1617
syntax = { path = "../libsyntax" }
1718
syntax_pos = { path = "../libsyntax_pos" }

src/librustc_codegen_utils/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
#![feature(arbitrary_self_types)]
1010
#![feature(box_patterns)]
1111
#![feature(box_syntax)]
12+
#![feature(core_intrinsics)]
1213
#![feature(custom_attribute)]
1314
#![feature(in_band_lifetimes)]
15+
#![feature(never_type)]
1416
#![feature(nll)]
1517
#![allow(unused_attributes)]
1618
#![feature(rustc_diagnostic_macros)]
@@ -20,6 +22,7 @@
2022
extern crate flate2;
2123
#[macro_use]
2224
extern crate log;
25+
extern crate punycode;
2326

2427
#[macro_use]
2528
extern crate rustc;

src/librustc_codegen_utils/symbol_names.rs

+59-44
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ use syntax_pos::symbol::Symbol;
106106
use std::fmt::{self, Write};
107107
use std::mem::{self, discriminant};
108108

109+
mod new;
110+
109111
pub fn provide(providers: &mut Providers) {
110112
*providers = Providers {
111113
def_symbol_name,
@@ -118,9 +120,6 @@ pub fn provide(providers: &mut Providers) {
118120
fn get_symbol_hash<'a, 'tcx>(
119121
tcx: TyCtxt<'a, 'tcx, 'tcx>,
120122

121-
// the DefId of the item this name is for
122-
def_id: DefId,
123-
124123
// instance this name will be for
125124
instance: Instance<'tcx>,
126125

@@ -129,11 +128,9 @@ fn get_symbol_hash<'a, 'tcx>(
129128
// included in the hash as a kind of
130129
// safeguard.
131130
item_type: Ty<'tcx>,
132-
133-
// values for generic type parameters,
134-
// if any.
135-
substs: &'tcx Substs<'tcx>,
136131
) -> u64 {
132+
let def_id = instance.def_id();
133+
let substs = instance.substs;
137134
debug!(
138135
"get_symbol_hash(def_id={:?}, parameters={:?})",
139136
def_id, substs
@@ -170,42 +167,7 @@ fn get_symbol_hash<'a, 'tcx>(
170167
assert!(!substs.needs_subst());
171168
substs.hash_stable(&mut hcx, &mut hasher);
172169

173-
let is_generic = substs.types().next().is_some();
174-
let avoid_cross_crate_conflicts =
175-
// If this is an instance of a generic function, we also hash in
176-
// the ID of the instantiating crate. This avoids symbol conflicts
177-
// in case the same instances is emitted in two crates of the same
178-
// project.
179-
is_generic ||
180-
181-
// If we're dealing with an instance of a function that's inlined from
182-
// another crate but we're marking it as globally shared to our
183-
// compliation (aka we're not making an internal copy in each of our
184-
// codegen units) then this symbol may become an exported (but hidden
185-
// visibility) symbol. This means that multiple crates may do the same
186-
// and we want to be sure to avoid any symbol conflicts here.
187-
match MonoItem::Fn(instance).instantiation_mode(tcx) {
188-
InstantiationMode::GloballyShared { may_conflict: true } => true,
189-
_ => false,
190-
};
191-
192-
if avoid_cross_crate_conflicts {
193-
let instantiating_crate = if is_generic {
194-
if !def_id.is_local() && tcx.sess.opts.share_generics() {
195-
// If we are re-using a monomorphization from another crate,
196-
// we have to compute the symbol hash accordingly.
197-
let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id);
198-
199-
upstream_monomorphizations
200-
.and_then(|monos| monos.get(&substs).cloned())
201-
.unwrap_or(LOCAL_CRATE)
202-
} else {
203-
LOCAL_CRATE
204-
}
205-
} else {
206-
LOCAL_CRATE
207-
};
208-
170+
if let Some(instantiating_crate) = instantiating_crate(tcx, instance) {
209171
(&tcx.original_crate_name(instantiating_crate).as_str()[..])
210172
.hash_stable(&mut hcx, &mut hasher);
211173
(&tcx.crate_disambiguator(instantiating_crate)).hash_stable(&mut hcx, &mut hasher);
@@ -220,6 +182,53 @@ fn get_symbol_hash<'a, 'tcx>(
220182
hasher.finish()
221183
}
222184

185+
fn instantiating_crate(
186+
tcx: TyCtxt<'_, 'tcx, 'tcx>,
187+
instance: Instance<'tcx>,
188+
) -> Option<CrateNum> {
189+
let def_id = instance.def_id();
190+
let substs = instance.substs;
191+
192+
let is_generic = substs.types().next().is_some();
193+
let avoid_cross_crate_conflicts =
194+
// If this is an instance of a generic function, we also hash in
195+
// the ID of the instantiating crate. This avoids symbol conflicts
196+
// in case the same instances is emitted in two crates of the same
197+
// project.
198+
is_generic ||
199+
200+
// If we're dealing with an instance of a function that's inlined from
201+
// another crate but we're marking it as globally shared to our
202+
// compliation (aka we're not making an internal copy in each of our
203+
// codegen units) then this symbol may become an exported (but hidden
204+
// visibility) symbol. This means that multiple crates may do the same
205+
// and we want to be sure to avoid any symbol conflicts here.
206+
match MonoItem::Fn(instance).instantiation_mode(tcx) {
207+
InstantiationMode::GloballyShared { may_conflict: true } => true,
208+
_ => false,
209+
};
210+
211+
if avoid_cross_crate_conflicts {
212+
Some(if is_generic {
213+
if !def_id.is_local() && tcx.sess.opts.share_generics() {
214+
// If we are re-using a monomorphization from another crate,
215+
// we have to compute the symbol hash accordingly.
216+
let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id);
217+
218+
upstream_monomorphizations
219+
.and_then(|monos| monos.get(&substs).cloned())
220+
.unwrap_or(LOCAL_CRATE)
221+
} else {
222+
LOCAL_CRATE
223+
}
224+
} else {
225+
LOCAL_CRATE
226+
})
227+
} else {
228+
None
229+
}
230+
}
231+
223232
fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
224233
SymbolPrinter {
225234
tcx,
@@ -282,6 +291,12 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
282291
return tcx.item_name(def_id).to_string();
283292
}
284293

294+
compute_mangled_symbol_name(tcx, instance)
295+
}
296+
297+
fn compute_mangled_symbol_name(tcx: TyCtxt<'_, 'tcx, 'tcx>, instance: Instance<'tcx>) -> String {
298+
let def_id = instance.def_id();
299+
285300
// We want to compute the "type" of this item. Unfortunately, some
286301
// kinds of items (e.g., closures) don't have an entry in the
287302
// item-type array. So walk back up the find the closest parent
@@ -315,7 +330,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance
315330
// and should not matter anyhow.
316331
let instance_ty = tcx.erase_regions(&instance_ty);
317332

318-
let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs);
333+
let hash = get_symbol_hash(tcx, instance, instance_ty);
319334

320335
let mut buf = SymbolPath::from_interned(tcx.def_symbol_name(def_id));
321336

0 commit comments

Comments
 (0)