rustc_codegen_utils: remove symbol name dumping/checking harness, and mw impl.
This commit is contained in:
parent
6386a31c5b
commit
9cf35bfbe7
16
Cargo.lock
16
Cargo.lock
|
@ -2699,7 +2699,6 @@ dependencies = [
|
||||||
"rustc_metadata 0.0.0",
|
"rustc_metadata 0.0.0",
|
||||||
"rustc_mir 0.0.0",
|
"rustc_mir 0.0.0",
|
||||||
"rustc_target 0.0.0",
|
"rustc_target 0.0.0",
|
||||||
"std-mangle-rs 0.1.0 (git+https://github.com/michaelwoerister/std-mangle-rs?rev=e884304cfcb2f636db4d59ca8ad8fa95b983281c)",
|
|
||||||
"syntax 0.0.0",
|
"syntax 0.0.0",
|
||||||
"syntax_pos 0.0.0",
|
"syntax_pos 0.0.0",
|
||||||
]
|
]
|
||||||
|
@ -3336,14 +3335,6 @@ dependencies = [
|
||||||
"unwind 0.0.0",
|
"unwind 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "std-mangle-rs"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "git+https://github.com/michaelwoerister/std-mangle-rs?rev=e884304cfcb2f636db4d59ca8ad8fa95b983281c#e884304cfcb2f636db4d59ca8ad8fa95b983281c"
|
|
||||||
dependencies = [
|
|
||||||
"unic-idna-punycode 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "string_cache"
|
name = "string_cache"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
|
@ -3858,11 +3849,6 @@ name = "ucd-util"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unic-idna-punycode"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unicase"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
|
@ -4368,7 +4354,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db"
|
"checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db"
|
||||||
"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
|
"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
|
||||||
"checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa"
|
"checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa"
|
||||||
"checksum std-mangle-rs 0.1.0 (git+https://github.com/michaelwoerister/std-mangle-rs?rev=e884304cfcb2f636db4d59ca8ad8fa95b983281c)" = "<none>"
|
|
||||||
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
|
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
|
||||||
"checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
|
"checksum string_cache_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
|
||||||
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
||||||
|
@ -4412,7 +4397,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||||
"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
|
"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
|
||||||
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
||||||
"checksum unic-idna-punycode 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b0366615c248bc56ea5ceafe6f71a682f6591e653b1ce61814999302617b8c0"
|
|
||||||
"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6"
|
"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6"
|
||||||
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||||
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
|
"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
|
||||||
|
|
|
@ -23,7 +23,3 @@ rustc_target = { path = "../librustc_target" }
|
||||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||||
rustc_metadata = { path = "../librustc_metadata" }
|
rustc_metadata = { path = "../librustc_metadata" }
|
||||||
rustc_mir = { path = "../librustc_mir" }
|
rustc_mir = { path = "../librustc_mir" }
|
||||||
|
|
||||||
[dependencies.std-mangle-rs]
|
|
||||||
git = "https://github.com/michaelwoerister/std-mangle-rs"
|
|
||||||
rev = "e884304cfcb2f636db4d59ca8ad8fa95b983281c"
|
|
||||||
|
|
|
@ -100,9 +100,7 @@ use syntax_pos::symbol::InternedString;
|
||||||
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
mod dump;
|
|
||||||
mod legacy;
|
mod legacy;
|
||||||
mod mw;
|
|
||||||
mod v0;
|
mod v0;
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers<'_>) {
|
pub fn provide(providers: &mut Providers<'_>) {
|
||||||
|
@ -221,19 +219,9 @@ fn symbol_name(tcx: TyCtxt<'_, 'tcx, 'tcx>, instance: Instance<'tcx>) -> Interne
|
||||||
};
|
};
|
||||||
|
|
||||||
let mangled = match mangling_version {
|
let mangled = match mangling_version {
|
||||||
SymbolManglingVersion::Legacy => legacy::mangle(tcx, instance, instantiating_crate, false),
|
SymbolManglingVersion::Legacy => legacy::mangle(tcx, instance, instantiating_crate),
|
||||||
SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate, true),
|
SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate),
|
||||||
};
|
};
|
||||||
|
|
||||||
let r = InternedString::intern(&mangled);
|
InternedString::intern(&mangled)
|
||||||
|
|
||||||
dump::record(
|
|
||||||
tcx,
|
|
||||||
instance,
|
|
||||||
instantiating_crate,
|
|
||||||
mangling_version,
|
|
||||||
mangled,
|
|
||||||
);
|
|
||||||
|
|
||||||
r
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,558 +0,0 @@
|
||||||
use rustc::hir::def_id::{CrateNum, DefId};
|
|
||||||
use rustc::hir::map::{DefPathData, DisambiguatedDefPathData};
|
|
||||||
use rustc::session::config::SymbolManglingVersion;
|
|
||||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
|
||||||
use rustc::ty::print::{PrettyPrinter, Printer, Print};
|
|
||||||
use rustc::ty::subst::{Kind, Subst, UnpackedKind};
|
|
||||||
use rustc_mir::monomorphize::Instance;
|
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::fmt::{self, Write as FmtWrite};
|
|
||||||
use std::fs::{self, File};
|
|
||||||
use std::io::Write;
|
|
||||||
use std::ops::Range;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::time::SystemTime;
|
|
||||||
|
|
||||||
use crate::symbol_names::{legacy, mw, v0};
|
|
||||||
|
|
||||||
thread_local!(static OUT_DIR: Option<PathBuf> = {
|
|
||||||
std::env::var_os("RUST_SYMBOL_DUMP_DIR").map(PathBuf::from)
|
|
||||||
});
|
|
||||||
thread_local!(static OUTPUT: RefCell<Option<File>> = RefCell::new(None));
|
|
||||||
|
|
||||||
pub fn record(
|
|
||||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
|
||||||
instance: Instance<'tcx>,
|
|
||||||
instantiating_crate: Option<CrateNum>,
|
|
||||||
mangling_version: SymbolManglingVersion,
|
|
||||||
mangled: String,
|
|
||||||
) {
|
|
||||||
let header = "legacy+generics,legacy,mw,mw+compression,v0,v0+compression";
|
|
||||||
|
|
||||||
// Reuse the already-mangled symbol name that is used by codegen.
|
|
||||||
let (legacy_mangling, v0_mangling_plus_compression) = match mangling_version {
|
|
||||||
SymbolManglingVersion::Legacy =>
|
|
||||||
(mangled, v0::mangle(tcx, instance, instantiating_crate, true)),
|
|
||||||
SymbolManglingVersion::V0 =>
|
|
||||||
(legacy::mangle(tcx, instance, instantiating_crate, false), mangled),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Always attempt all the choices of mangling.
|
|
||||||
let legacy_mangling_plus_generics =
|
|
||||||
legacy::mangle(tcx, instance, instantiating_crate, true);
|
|
||||||
|
|
||||||
let (mw_mangling, mw_mangling_plus_compression) =
|
|
||||||
mw::mangle(tcx, instance, instantiating_crate)
|
|
||||||
.unwrap_or((String::new(), String::new()));
|
|
||||||
|
|
||||||
let v0_mangling = v0::mangle(tcx, instance, instantiating_crate, false);
|
|
||||||
|
|
||||||
OUTPUT.with(|out| {
|
|
||||||
let mut out = out.borrow_mut();
|
|
||||||
if out.is_none() {
|
|
||||||
OUT_DIR.with(|out_dir| {
|
|
||||||
if let Some(out_dir) = out_dir {
|
|
||||||
let mut opts = fs::OpenOptions::new();
|
|
||||||
opts.write(true).create_new(true);
|
|
||||||
|
|
||||||
let mut time = SystemTime::now()
|
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
|
||||||
.map(|d| d.as_secs())
|
|
||||||
.unwrap_or(0);
|
|
||||||
let mut file = loop {
|
|
||||||
let file_path = out_dir.join(format!("{}-{}.{}.csv",
|
|
||||||
tcx.crate_name,
|
|
||||||
tcx.sess.local_crate_disambiguator(),
|
|
||||||
time,
|
|
||||||
));
|
|
||||||
|
|
||||||
match opts.open(&file_path) {
|
|
||||||
Ok(file) => break file,
|
|
||||||
Err(e) => {
|
|
||||||
if e.kind() == std::io::ErrorKind::AlreadyExists {
|
|
||||||
time += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bug!("can't open symbol dump file `{}`: {:?}",
|
|
||||||
file_path.display(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
writeln!(file, "{}", header).unwrap();
|
|
||||||
*out = Some(file);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(out) = out.as_mut() {
|
|
||||||
writeln!(out, "{},{},{},{},{},{}",
|
|
||||||
legacy_mangling_plus_generics,
|
|
||||||
legacy_mangling,
|
|
||||||
mw_mangling,
|
|
||||||
mw_mangling_plus_compression,
|
|
||||||
v0_mangling,
|
|
||||||
v0_mangling_plus_compression,
|
|
||||||
).unwrap();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let def_id = instance.def_id();
|
|
||||||
// FIXME(eddyb) this should ideally not be needed.
|
|
||||||
let substs =
|
|
||||||
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), instance.substs);
|
|
||||||
|
|
||||||
// Build the expected output of demangling, via `ty::print`.
|
|
||||||
let make_expected_demangling = |alternate| {
|
|
||||||
let cx = DemanglingPrinter {
|
|
||||||
tcx,
|
|
||||||
out: String::new(),
|
|
||||||
alternate,
|
|
||||||
in_value: true,
|
|
||||||
binders: vec![],
|
|
||||||
};
|
|
||||||
if instance.is_vtable_shim() {
|
|
||||||
cx.path_append_ns(
|
|
||||||
|cx| cx.print_def_path(def_id, substs),
|
|
||||||
'S',
|
|
||||||
0,
|
|
||||||
"",
|
|
||||||
).unwrap().out
|
|
||||||
} else {
|
|
||||||
cx.print_def_path(def_id, substs).unwrap().out
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let expected_demangling_alt = make_expected_demangling(true);
|
|
||||||
let expected_demangling = make_expected_demangling(false);
|
|
||||||
|
|
||||||
for mangling in &[&v0_mangling, &v0_mangling_plus_compression] {
|
|
||||||
match rustc_demangle::try_demangle(mangling) {
|
|
||||||
Ok(demangling) => {
|
|
||||||
let demangling_alt = format!("{:#}", demangling);
|
|
||||||
if demangling_alt.contains('?') {
|
|
||||||
bug!("demangle(alt) printing failed for {:?}\n{:?}", mangling, demangling_alt);
|
|
||||||
}
|
|
||||||
assert_eq!(demangling_alt, expected_demangling_alt);
|
|
||||||
|
|
||||||
let demangling = format!("{}", demangling);
|
|
||||||
if demangling.contains('?') {
|
|
||||||
bug!("demangle printing failed for {:?}\n{:?}", mangling, demangling);
|
|
||||||
}
|
|
||||||
assert_eq!(demangling, expected_demangling);
|
|
||||||
}
|
|
||||||
Err(_) => bug!("try_demangle failed for {:?}", mangling),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BinderLevel {
|
|
||||||
lifetime_depths: Range<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Our expectation of the output of demangling,
|
|
||||||
// relying on `ty::print` / `PrettyPrinter`.
|
|
||||||
struct DemanglingPrinter<'a, 'tcx> {
|
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
out: String,
|
|
||||||
|
|
||||||
/// Equivalent to `rustc-demangle`'s `{:#}` printing.
|
|
||||||
alternate: bool,
|
|
||||||
|
|
||||||
in_value: bool,
|
|
||||||
binders: Vec<BinderLevel>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Write for DemanglingPrinter<'_, '_> {
|
|
||||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
|
||||||
self.out.write_str(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DemanglingPrinter<'_, '_> {
|
|
||||||
fn path_append_ns(
|
|
||||||
mut self,
|
|
||||||
print_prefix: impl FnOnce(Self) -> Result<Self, fmt::Error>,
|
|
||||||
ns: char,
|
|
||||||
disambiguator: u64,
|
|
||||||
name: &str,
|
|
||||||
) -> Result<Self, fmt::Error> {
|
|
||||||
self = print_prefix(self)?;
|
|
||||||
|
|
||||||
if let 'A'..='Z' = ns {
|
|
||||||
self.write_str("::{")?;
|
|
||||||
match ns {
|
|
||||||
'C' => self.write_str("closure")?,
|
|
||||||
'S' => self.write_str("shim")?,
|
|
||||||
_ => write!(self, "{}", ns)?,
|
|
||||||
}
|
|
||||||
if !name.is_empty() {
|
|
||||||
write!(self, ":{}", name)?;
|
|
||||||
}
|
|
||||||
write!(self, "#{}", disambiguator)?;
|
|
||||||
self.write_str("}")?;
|
|
||||||
} else {
|
|
||||||
if !name.is_empty() {
|
|
||||||
self.write_str("::")?;
|
|
||||||
self.write_str(&name)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_lifetime_at_depth(&mut self, depth: u64) -> Result<(), fmt::Error> {
|
|
||||||
if depth < 26 {
|
|
||||||
write!(self, "'{}", (b'a' + depth as u8) as char)
|
|
||||||
} else {
|
|
||||||
write!(self, "'_{}", depth)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Printer<'tcx, 'tcx> for DemanglingPrinter<'_, 'tcx> {
|
|
||||||
type Error = fmt::Error;
|
|
||||||
|
|
||||||
type Path = Self;
|
|
||||||
type Region = Self;
|
|
||||||
type Type = Self;
|
|
||||||
type DynExistential = Self;
|
|
||||||
type Const = Self;
|
|
||||||
|
|
||||||
fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
|
|
||||||
self.tcx
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_impl_path(
|
|
||||||
self,
|
|
||||||
impl_def_id: DefId,
|
|
||||||
substs: &'tcx [Kind<'tcx>],
|
|
||||||
mut self_ty: Ty<'tcx>,
|
|
||||||
mut impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
let mut param_env = self.tcx.param_env(impl_def_id)
|
|
||||||
.with_reveal_all();
|
|
||||||
if !substs.is_empty() {
|
|
||||||
param_env = param_env.subst(self.tcx, substs);
|
|
||||||
}
|
|
||||||
|
|
||||||
match &mut impl_trait_ref {
|
|
||||||
Some(impl_trait_ref) => {
|
|
||||||
assert_eq!(impl_trait_ref.self_ty(), self_ty);
|
|
||||||
*impl_trait_ref =
|
|
||||||
self.tcx.normalize_erasing_regions(param_env, *impl_trait_ref);
|
|
||||||
self_ty = impl_trait_ref.self_ty();
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self_ty = self.tcx.normalize_erasing_regions(param_env, self_ty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.path_qualified(self_ty, impl_trait_ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_region(
|
|
||||||
mut self,
|
|
||||||
region: ty::Region<'_>,
|
|
||||||
) -> Result<Self::Region, Self::Error> {
|
|
||||||
match *region {
|
|
||||||
ty::ReErased => write!(self, "'_")?,
|
|
||||||
|
|
||||||
ty::ReLateBound(debruijn, ty::BrAnon(i)) => {
|
|
||||||
let binder = &self.binders[self.binders.len() - 1 - debruijn.index()];
|
|
||||||
let depth = binder.lifetime_depths.start + i;
|
|
||||||
self.print_lifetime_at_depth(depth as u64)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => bug!("symbol_names::dump: non-erased region `{:?}`", region),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_type(
|
|
||||||
mut self,
|
|
||||||
ty: Ty<'tcx>,
|
|
||||||
) -> Result<Self::Type, Self::Error> {
|
|
||||||
match ty.sty {
|
|
||||||
// Mangled as paths (unlike `pretty_print_type`).
|
|
||||||
ty::FnDef(def_id, substs) |
|
|
||||||
ty::Opaque(def_id, substs) |
|
|
||||||
ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) |
|
|
||||||
ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) |
|
|
||||||
ty::Closure(def_id, ty::ClosureSubsts { substs }) |
|
|
||||||
ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
|
|
||||||
self.print_def_path(def_id, substs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mangled as placeholders.
|
|
||||||
ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) |
|
|
||||||
ty::Infer(_) | ty::Error => {
|
|
||||||
write!(self, "_")?;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Demangled with explicit type for constants (`len` here).
|
|
||||||
ty::Array(ty, len) if !self.alternate => {
|
|
||||||
write!(self, "[")?;
|
|
||||||
self = ty.print(self)?;
|
|
||||||
write!(self, "; ")?;
|
|
||||||
if let Some(n) = len.assert_usize(self.tcx()) {
|
|
||||||
write!(self, "{}", n)?;
|
|
||||||
} else {
|
|
||||||
self = len.print(self)?;
|
|
||||||
}
|
|
||||||
write!(self, ": usize]")?;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Demangled without anyparens.
|
|
||||||
ty::Dynamic(data, r) => {
|
|
||||||
let print_r = self.region_should_not_be_omitted(r);
|
|
||||||
write!(self, "dyn ")?;
|
|
||||||
self = data.print(self)?;
|
|
||||||
if print_r {
|
|
||||||
write!(self, " + ")?;
|
|
||||||
self = r.print(self)?;
|
|
||||||
}
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => self.pretty_print_type(ty),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_dyn_existential(
|
|
||||||
mut self,
|
|
||||||
predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
|
|
||||||
) -> Result<Self::DynExistential, Self::Error> {
|
|
||||||
// Generate the main trait ref, including associated types.
|
|
||||||
let mut first = true;
|
|
||||||
|
|
||||||
if let Some(principal) = predicates.principal() {
|
|
||||||
self = self.print_def_path(principal.def_id, &[])?;
|
|
||||||
|
|
||||||
// Use a type that can't appear in defaults of type parameters.
|
|
||||||
let dummy_self = self.tcx().mk_ty_infer(ty::FreshTy(0));
|
|
||||||
let principal = principal.with_self_ty(self.tcx(), dummy_self);
|
|
||||||
|
|
||||||
let args = self.generic_args_to_print(
|
|
||||||
self.tcx().generics_of(principal.def_id),
|
|
||||||
principal.substs,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Don't print any regions if they're all erased.
|
|
||||||
let print_regions = args.iter().any(|arg| {
|
|
||||||
match arg.unpack() {
|
|
||||||
UnpackedKind::Lifetime(r) => *r != ty::ReErased,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let mut args = args.iter().cloned().filter(|arg| {
|
|
||||||
match arg.unpack() {
|
|
||||||
UnpackedKind::Lifetime(_) => print_regions,
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let mut projections = predicates.projection_bounds();
|
|
||||||
|
|
||||||
let arg0 = args.next();
|
|
||||||
let projection0 = projections.next();
|
|
||||||
if arg0.is_some() || projection0.is_some() {
|
|
||||||
let args = arg0.into_iter().chain(args);
|
|
||||||
let projections = projection0.into_iter().chain(projections);
|
|
||||||
|
|
||||||
self = self.generic_delimiters(|mut cx| {
|
|
||||||
cx = cx.comma_sep(args)?;
|
|
||||||
if arg0.is_some() && projection0.is_some() {
|
|
||||||
write!(cx, ", ")?;
|
|
||||||
}
|
|
||||||
cx.comma_sep(projections)
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for def_id in predicates.auto_traits() {
|
|
||||||
if !first {
|
|
||||||
write!(self, " + ")?;
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
|
|
||||||
self = self.print_def_path(def_id, &[])?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_const(
|
|
||||||
mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<Self::Const, Self::Error> {
|
|
||||||
if let ty::Uint(_) = ct.ty.sty {
|
|
||||||
if let Some(bits) = ct.assert_bits(self.tcx, ty::ParamEnv::empty().and(ct.ty)) {
|
|
||||||
write!(self, "{}", bits)?;
|
|
||||||
} else {
|
|
||||||
write!(self, "_")?;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
write!(self, "_")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.alternate {
|
|
||||||
write!(self, ": ")?;
|
|
||||||
self = ct.ty.print(self)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn path_crate(
|
|
||||||
mut self,
|
|
||||||
cnum: CrateNum,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
self.write_str(&self.tcx.original_crate_name(cnum).as_str())?;
|
|
||||||
let fingerprint = self.tcx.crate_disambiguator(cnum).to_fingerprint();
|
|
||||||
if !self.alternate {
|
|
||||||
write!(self, "[{:x}]", fingerprint.to_smaller_hash())?;
|
|
||||||
}
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
fn path_qualified(
|
|
||||||
self,
|
|
||||||
self_ty: Ty<'tcx>,
|
|
||||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
self.generic_delimiters(|mut cx| {
|
|
||||||
cx = self_ty.print(cx)?;
|
|
||||||
if let Some(trait_ref) = trait_ref {
|
|
||||||
write!(cx, " as ")?;
|
|
||||||
cx = trait_ref.print(cx)?;
|
|
||||||
}
|
|
||||||
Ok(cx)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn path_append_impl(
|
|
||||||
self,
|
|
||||||
_print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
|
|
||||||
_disambiguated_data: &DisambiguatedDefPathData,
|
|
||||||
_self_ty: Ty<'tcx>,
|
|
||||||
_trait_ref: Option<ty::TraitRef<'tcx>>,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
fn path_append(
|
|
||||||
self,
|
|
||||||
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
|
|
||||||
disambiguated_data: &DisambiguatedDefPathData,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
let ns = match disambiguated_data.data {
|
|
||||||
DefPathData::ClosureExpr => 'C',
|
|
||||||
_ => '_',
|
|
||||||
};
|
|
||||||
|
|
||||||
let name = disambiguated_data.data.get_opt_name().map(|s| s.as_str());
|
|
||||||
let name = name.as_ref().map_or("", |s| &s[..]);
|
|
||||||
|
|
||||||
self.path_append_ns(
|
|
||||||
print_prefix,
|
|
||||||
ns,
|
|
||||||
disambiguated_data.disambiguator as u64,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn path_generic_args(
|
|
||||||
mut self,
|
|
||||||
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
|
|
||||||
args: &[Kind<'tcx>],
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
self = print_prefix(self)?;
|
|
||||||
|
|
||||||
// Don't print any regions if they're all erased.
|
|
||||||
let print_regions = args.iter().any(|arg| {
|
|
||||||
match arg.unpack() {
|
|
||||||
UnpackedKind::Lifetime(r) => *r != ty::ReErased,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let args = args.iter().cloned().filter(|arg| {
|
|
||||||
match arg.unpack() {
|
|
||||||
UnpackedKind::Lifetime(_) => print_regions,
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if args.clone().next().is_some() {
|
|
||||||
if self.in_value {
|
|
||||||
write!(self, "::")?;
|
|
||||||
}
|
|
||||||
self.generic_delimiters(|cx| cx.comma_sep(args))
|
|
||||||
} else {
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PrettyPrinter<'tcx, 'tcx> for DemanglingPrinter<'_, 'tcx> {
|
|
||||||
fn region_should_not_be_omitted(
|
|
||||||
&self,
|
|
||||||
region: ty::Region<'_>,
|
|
||||||
) -> bool {
|
|
||||||
*region != ty::ReErased
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generic_delimiters(
|
|
||||||
mut self,
|
|
||||||
f: impl FnOnce(Self) -> Result<Self, Self::Error>,
|
|
||||||
) -> Result<Self, Self::Error> {
|
|
||||||
write!(self, "<")?;
|
|
||||||
let was_in_value = ::std::mem::replace(&mut self.in_value, false);
|
|
||||||
self = f(self)?;
|
|
||||||
self.in_value = was_in_value;
|
|
||||||
write!(self, ">")?;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn in_binder<T>(
|
|
||||||
mut self,
|
|
||||||
value: &ty::Binder<T>,
|
|
||||||
) -> Result<Self, Self::Error>
|
|
||||||
where T: Print<'tcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>
|
|
||||||
{
|
|
||||||
let regions = if value.has_late_bound_regions() {
|
|
||||||
self.tcx.collect_referenced_late_bound_regions(value)
|
|
||||||
} else {
|
|
||||||
Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut lifetime_depths =
|
|
||||||
self.binders.last().map(|b| b.lifetime_depths.end).map_or(0..0, |i| i..i);
|
|
||||||
|
|
||||||
let lifetimes = regions.into_iter().map(|br| {
|
|
||||||
match br {
|
|
||||||
ty::BrAnon(i) => i + 1,
|
|
||||||
_ => bug!("symbol_names: non-anonymized region `{:?}` in `{:?}`", br, value),
|
|
||||||
}
|
|
||||||
}).max().unwrap_or(0);
|
|
||||||
|
|
||||||
lifetime_depths.end += lifetimes;
|
|
||||||
|
|
||||||
if lifetimes > 0 {
|
|
||||||
write!(self, "for<")?;
|
|
||||||
for i in lifetime_depths.clone() {
|
|
||||||
if i > lifetime_depths.start {
|
|
||||||
write!(self, ", ")?;
|
|
||||||
}
|
|
||||||
self.print_lifetime_at_depth(i as u64)?;
|
|
||||||
}
|
|
||||||
write!(self, "> ")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.binders.push(BinderLevel { lifetime_depths });
|
|
||||||
self = value.skip_binder().print(self)?;
|
|
||||||
self.binders.pop();
|
|
||||||
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,7 +18,6 @@ pub(super) fn mangle(
|
||||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
instantiating_crate: Option<CrateNum>,
|
instantiating_crate: Option<CrateNum>,
|
||||||
include_generic_args: bool,
|
|
||||||
) -> String {
|
) -> String {
|
||||||
let def_id = instance.def_id();
|
let def_id = instance.def_id();
|
||||||
|
|
||||||
|
@ -57,17 +56,11 @@ pub(super) fn mangle(
|
||||||
|
|
||||||
let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate);
|
let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate);
|
||||||
|
|
||||||
let substs = if include_generic_args {
|
|
||||||
// FIXME(eddyb) this should ideally not be needed.
|
|
||||||
&tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), instance.substs)[..]
|
|
||||||
} else {
|
|
||||||
&[]
|
|
||||||
};
|
|
||||||
let mut printer = SymbolPrinter {
|
let mut printer = SymbolPrinter {
|
||||||
tcx,
|
tcx,
|
||||||
path: SymbolPath::new(),
|
path: SymbolPath::new(),
|
||||||
keep_within_component: false,
|
keep_within_component: false,
|
||||||
}.print_def_path(def_id, substs).unwrap();
|
}.print_def_path(def_id, &[]).unwrap();
|
||||||
|
|
||||||
if instance.is_vtable_shim() {
|
if instance.is_vtable_shim() {
|
||||||
let _ = printer.write_str("{{vtable-shim}}");
|
let _ = printer.write_str("{{vtable-shim}}");
|
||||||
|
|
|
@ -1,421 +0,0 @@
|
||||||
use std_mangle_rs::ast;
|
|
||||||
|
|
||||||
use rustc::hir;
|
|
||||||
use rustc::hir::def_id::{CrateNum, DefId};
|
|
||||||
use rustc::hir::map::{DefPathData, DisambiguatedDefPathData};
|
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
|
||||||
use rustc::ty::print::{Printer, Print};
|
|
||||||
use rustc::ty::subst::{Kind, UnpackedKind};
|
|
||||||
use rustc_mir::monomorphize::Instance;
|
|
||||||
use rustc_target::spec::abi::Abi;
|
|
||||||
use syntax::ast::{IntTy, UintTy, FloatTy};
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub(super) struct Unsupported;
|
|
||||||
|
|
||||||
pub(super) fn mangle(
|
|
||||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
|
||||||
instance: Instance<'tcx>,
|
|
||||||
instantiating_crate: Option<CrateNum>,
|
|
||||||
) -> Result<(String, String), Unsupported> {
|
|
||||||
if instance.is_vtable_shim() {
|
|
||||||
return Err(Unsupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
let symbol = ast::Symbol {
|
|
||||||
version: None,
|
|
||||||
path: SymbolPrinter { tcx }
|
|
||||||
.print_def_path(instance.def_id(), instance.substs)?,
|
|
||||||
instantiating_crate: match instantiating_crate {
|
|
||||||
Some(instantiating_crate) => Some(
|
|
||||||
SymbolPrinter { tcx }
|
|
||||||
.path_crate(instantiating_crate)?
|
|
||||||
),
|
|
||||||
None => None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let _ = symbol;
|
|
||||||
unimplemented!("missing compressor/mangler for mw symbol mangling");
|
|
||||||
|
|
||||||
/*let mut uncompressed = String::new();
|
|
||||||
symbol.mangle(&mut uncompressed);
|
|
||||||
|
|
||||||
let (compressed_symbol, _) = std_mangle_rs::compress::compress_ext(&symbol);
|
|
||||||
let mut compressed = String::new();
|
|
||||||
compressed_symbol.mangle(&mut compressed);
|
|
||||||
|
|
||||||
Ok((uncompressed, compressed))*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
struct SymbolPrinter<'a, 'tcx> {
|
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> {
|
|
||||||
type Error = Unsupported;
|
|
||||||
|
|
||||||
type Path = ast::Path;
|
|
||||||
type Region = ast::Lifetime;
|
|
||||||
type Type = ast::Type;
|
|
||||||
type DynExistential = ast::DynBounds;
|
|
||||||
type Const = ast::Const;
|
|
||||||
|
|
||||||
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
|
|
||||||
self.tcx
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_impl_path(
|
|
||||||
self,
|
|
||||||
impl_def_id: DefId,
|
|
||||||
_substs: &[Kind<'tcx>],
|
|
||||||
self_ty: Ty<'tcx>,
|
|
||||||
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
let key = self.tcx.def_key(impl_def_id);
|
|
||||||
let parent_def_id = DefId { index: key.parent.unwrap(), ..impl_def_id };
|
|
||||||
|
|
||||||
self.path_append_impl(
|
|
||||||
|cx| cx.print_def_path(parent_def_id, &[]),
|
|
||||||
&key.disambiguated_data,
|
|
||||||
self_ty,
|
|
||||||
impl_trait_ref,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_region(
|
|
||||||
self,
|
|
||||||
region: ty::Region<'_>,
|
|
||||||
) -> Result<Self::Region, Self::Error> {
|
|
||||||
let i = match *region {
|
|
||||||
ty::ReErased => 0,
|
|
||||||
|
|
||||||
// FIXME(eddyb) copy the implementation over to here.
|
|
||||||
ty::ReLateBound(_, ty::BrAnon(_)) => {
|
|
||||||
return Err(Unsupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => bug!("mw: non-erased region `{:?}`", region),
|
|
||||||
};
|
|
||||||
Ok(ast::Lifetime {
|
|
||||||
debruijn_index: ast::Base62Number(i),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_type(
|
|
||||||
self,
|
|
||||||
ty: Ty<'tcx>,
|
|
||||||
) -> Result<Self::Type, Self::Error> {
|
|
||||||
macro_rules! basic {
|
|
||||||
($name:ident) => (ast::Type::BasicType(ast::BasicType::$name))
|
|
||||||
}
|
|
||||||
Ok(match ty.sty {
|
|
||||||
ty::Bool => basic!(Bool),
|
|
||||||
ty::Char => basic!(Char),
|
|
||||||
ty::Str => basic!(Str),
|
|
||||||
ty::Tuple(_) if ty.is_unit() => basic!(Unit),
|
|
||||||
ty::Int(IntTy::I8) => basic!(I8),
|
|
||||||
ty::Int(IntTy::I16) => basic!(I16),
|
|
||||||
ty::Int(IntTy::I32) => basic!(I32),
|
|
||||||
ty::Int(IntTy::I64) => basic!(I64),
|
|
||||||
ty::Int(IntTy::I128) => basic!(I128),
|
|
||||||
ty::Int(IntTy::Isize) => basic!(Isize),
|
|
||||||
ty::Uint(UintTy::U8) => basic!(U8),
|
|
||||||
ty::Uint(UintTy::U16) => basic!(U16),
|
|
||||||
ty::Uint(UintTy::U32) => basic!(U32),
|
|
||||||
ty::Uint(UintTy::U64) => basic!(U64),
|
|
||||||
ty::Uint(UintTy::U128) => basic!(U128),
|
|
||||||
ty::Uint(UintTy::Usize) => basic!(Usize),
|
|
||||||
ty::Float(FloatTy::F32) => basic!(F32),
|
|
||||||
ty::Float(FloatTy::F64) => basic!(F64),
|
|
||||||
ty::Never => basic!(Never),
|
|
||||||
|
|
||||||
// Placeholders (should be demangled as `_`).
|
|
||||||
ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) |
|
|
||||||
ty::Infer(_) | ty::Error => basic!(Placeholder),
|
|
||||||
|
|
||||||
ty::Ref(r, ty, mutbl) => {
|
|
||||||
let lt = if *r != ty::ReErased {
|
|
||||||
Some(r.print(self)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let ty = Arc::new(ty.print(self)?);
|
|
||||||
match mutbl {
|
|
||||||
hir::MutImmutable => ast::Type::Ref(lt, ty),
|
|
||||||
hir::MutMutable => ast::Type::RefMut(lt, ty),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::RawPtr(ty::TypeAndMut { ty, mutbl: hir::MutImmutable }) => {
|
|
||||||
ast::Type::RawPtrConst(Arc::new(ty.print(self)?))
|
|
||||||
}
|
|
||||||
ty::RawPtr(ty::TypeAndMut { ty, mutbl: hir::MutMutable }) => {
|
|
||||||
ast::Type::RawPtrMut(Arc::new(ty.print(self)?))
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Array(ty, len) => {
|
|
||||||
ast::Type::Array(Arc::new(ty.print(self)?), Arc::new(len.print(self)?))
|
|
||||||
}
|
|
||||||
ty::Slice(ty) => ast::Type::Slice(Arc::new(ty.print(self)?)),
|
|
||||||
|
|
||||||
ty::Tuple(tys) => {
|
|
||||||
let tys = tys.iter()
|
|
||||||
.map(|k| k.expect_ty().print(self))
|
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
|
||||||
ast::Type::Tuple(tys)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mangle all nominal types as paths.
|
|
||||||
ty::Adt(&ty::AdtDef { did: def_id, .. }, substs) |
|
|
||||||
ty::FnDef(def_id, substs) |
|
|
||||||
ty::Opaque(def_id, substs) |
|
|
||||||
ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) |
|
|
||||||
ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) |
|
|
||||||
ty::Closure(def_id, ty::ClosureSubsts { substs }) |
|
|
||||||
ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
|
|
||||||
ast::Type::Named(Arc::new(self.print_def_path(def_id, substs)?))
|
|
||||||
}
|
|
||||||
ty::Foreign(def_id) => {
|
|
||||||
ast::Type::Named(Arc::new(self.print_def_path(def_id, &[])?))
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::FnPtr(sig) => {
|
|
||||||
let mut param_types = sig.inputs().skip_binder().iter()
|
|
||||||
.map(|ty| ty.print(self))
|
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
|
||||||
if sig.c_variadic() {
|
|
||||||
param_types.push(basic!(Ellipsis));
|
|
||||||
}
|
|
||||||
let return_type = sig.output().skip_binder().print(self)?;
|
|
||||||
ast::Type::Fn(Arc::new(ast::FnSig {
|
|
||||||
binder: ast::Binder {
|
|
||||||
// FIXME(eddyb) needs to be implemented, see `print_region`.
|
|
||||||
count: ast::Base62Number(0),
|
|
||||||
},
|
|
||||||
is_unsafe: sig.unsafety() == hir::Unsafety::Unsafe,
|
|
||||||
abi: match sig.abi() {
|
|
||||||
Abi::Rust => None,
|
|
||||||
Abi::C => Some(ast::Abi::C),
|
|
||||||
abi => Some(ast::Abi::Named(ast::UIdent(abi.name().replace('-', "_")))),
|
|
||||||
},
|
|
||||||
param_types,
|
|
||||||
return_type,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Dynamic(predicates, r) => {
|
|
||||||
let bounds = Arc::new(self.print_dyn_existential(predicates.skip_binder())?);
|
|
||||||
let lt = r.print(self)?;
|
|
||||||
ast::Type::DynTrait(bounds, lt)
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::GeneratorWitness(_) => {
|
|
||||||
bug!("mw: unexpected `GeneratorWitness`")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_dyn_existential(
|
|
||||||
self,
|
|
||||||
predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
|
|
||||||
) -> Result<Self::DynExistential, Self::Error> {
|
|
||||||
let mut traits = vec![];
|
|
||||||
for predicate in predicates {
|
|
||||||
match *predicate {
|
|
||||||
ty::ExistentialPredicate::Trait(trait_ref) => {
|
|
||||||
// Use a type that can't appear in defaults of type parameters.
|
|
||||||
let dummy_self = self.tcx.mk_infer(ty::FreshTy(0));
|
|
||||||
let trait_ref = trait_ref.with_self_ty(self.tcx, dummy_self);
|
|
||||||
traits.push(ast::DynTrait {
|
|
||||||
path: self.print_def_path(trait_ref.def_id, trait_ref.substs)?,
|
|
||||||
assoc_type_bindings: vec![],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ty::ExistentialPredicate::Projection(projection) => {
|
|
||||||
let name = self.tcx.associated_item(projection.item_def_id).ident;
|
|
||||||
traits.last_mut().unwrap().assoc_type_bindings.push(ast::DynTraitAssocBinding {
|
|
||||||
ident: ast::UIdent(name.to_string()),
|
|
||||||
ty: projection.ty.print(self)?,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ty::ExistentialPredicate::AutoTrait(def_id) => {
|
|
||||||
traits.push(ast::DynTrait {
|
|
||||||
path: self.print_def_path(def_id, &[])?,
|
|
||||||
assoc_type_bindings: vec![],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(ast::DynBounds {
|
|
||||||
binder: ast::Binder {
|
|
||||||
// FIXME(eddyb) needs to be implemented, see `print_region`.
|
|
||||||
count: ast::Base62Number(0),
|
|
||||||
},
|
|
||||||
traits,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_const(
|
|
||||||
self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<Self::Const, Self::Error> {
|
|
||||||
match ct.ty.sty {
|
|
||||||
ty::Uint(_) => {}
|
|
||||||
_ => {
|
|
||||||
bug!("mw: unsupported constant of type `{}` ({:?})",
|
|
||||||
ct.ty, ct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let ty = ct.ty.print(self)?;
|
|
||||||
|
|
||||||
if let Some(bits) = ct.assert_bits(self.tcx, ty::ParamEnv::empty().and(ct.ty)) {
|
|
||||||
if bits as u64 as u128 != bits {
|
|
||||||
return Err(Unsupported);
|
|
||||||
}
|
|
||||||
Ok(ast::Const::Value(ty, bits as u64))
|
|
||||||
} else {
|
|
||||||
// NOTE(eddyb) despite having the path, we need to
|
|
||||||
// encode a placeholder, as the path could refer
|
|
||||||
// back to e.g. an `impl` using the constant.
|
|
||||||
Ok(ast::Const::Placeholder(ty))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn path_crate(
|
|
||||||
self,
|
|
||||||
cnum: CrateNum,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
let fingerprint = self.tcx.crate_disambiguator(cnum).to_fingerprint();
|
|
||||||
Ok(ast::Path::CrateRoot {
|
|
||||||
id: ast::Ident {
|
|
||||||
dis: ast::Base62Number(fingerprint.to_smaller_hash()),
|
|
||||||
u_ident: ast::UIdent(self.tcx.original_crate_name(cnum).to_string()),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn path_qualified(
|
|
||||||
self,
|
|
||||||
self_ty: Ty<'tcx>,
|
|
||||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
assert!(trait_ref.is_some());
|
|
||||||
let trait_ref = trait_ref.unwrap();
|
|
||||||
|
|
||||||
// This is a default method in the trait declaration.
|
|
||||||
Ok(ast::Path::TraitDef {
|
|
||||||
self_type: self_ty.print(self)?,
|
|
||||||
trait_name: Arc::new(self.print_def_path(trait_ref.def_id, trait_ref.substs)?),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn path_append_impl(
|
|
||||||
self,
|
|
||||||
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
|
|
||||||
disambiguated_data: &DisambiguatedDefPathData,
|
|
||||||
self_ty: Ty<'tcx>,
|
|
||||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
let impl_path = ast::ImplPath {
|
|
||||||
dis: Some(ast::Base62Number(disambiguated_data.disambiguator as u64)),
|
|
||||||
path: Arc::new(print_prefix(self)?),
|
|
||||||
};
|
|
||||||
let self_type = self_ty.print(self)?;
|
|
||||||
match trait_ref {
|
|
||||||
Some(trait_ref) => Ok(ast::Path::TraitImpl {
|
|
||||||
impl_path,
|
|
||||||
self_type,
|
|
||||||
trait_name: Arc::new(self.print_def_path(trait_ref.def_id, trait_ref.substs)?),
|
|
||||||
}),
|
|
||||||
None => Ok(ast::Path::InherentImpl {
|
|
||||||
impl_path,
|
|
||||||
self_type,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn path_append(
|
|
||||||
self,
|
|
||||||
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
|
|
||||||
disambiguated_data: &DisambiguatedDefPathData,
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
let inner = Arc::new(print_prefix(self)?);
|
|
||||||
|
|
||||||
let name = disambiguated_data.data.get_opt_name().map(|s| s.as_str());
|
|
||||||
let name = name.as_ref().map_or("", |s| &s[..]);
|
|
||||||
let ns = match disambiguated_data.data {
|
|
||||||
DefPathData::ClosureExpr => ast::Namespace(b'C'),
|
|
||||||
|
|
||||||
// Lowercase a-z are unspecified disambiguation categories.
|
|
||||||
_ => {
|
|
||||||
let discriminant = unsafe {
|
|
||||||
::std::intrinsics::discriminant_value(&disambiguated_data.data)
|
|
||||||
};
|
|
||||||
assert!(discriminant < 26);
|
|
||||||
|
|
||||||
// Mix in the name to avoid making it too predictable.
|
|
||||||
let mut d = (discriminant ^ 0x55) % 26;
|
|
||||||
for (i, b) in name.bytes().enumerate() {
|
|
||||||
d = (d + i as u64 + b as u64) % 26;
|
|
||||||
}
|
|
||||||
|
|
||||||
ast::Namespace(b'a' + d as u8)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(ast::Path::Nested {
|
|
||||||
ns,
|
|
||||||
inner,
|
|
||||||
ident: ast::Ident {
|
|
||||||
dis: ast::Base62Number(disambiguated_data.disambiguator as u64),
|
|
||||||
u_ident: ast::UIdent(name.to_string()),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fn path_generic_args(
|
|
||||||
self,
|
|
||||||
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
|
|
||||||
args: &[Kind<'tcx>],
|
|
||||||
) -> Result<Self::Path, Self::Error> {
|
|
||||||
let prefix = print_prefix(self)?;
|
|
||||||
|
|
||||||
// Don't print any regions if they're all erased.
|
|
||||||
let print_regions = args.iter().any(|arg| {
|
|
||||||
match arg.unpack() {
|
|
||||||
UnpackedKind::Lifetime(r) => *r != ty::ReErased,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let args = args.iter().cloned().filter(|arg| {
|
|
||||||
match arg.unpack() {
|
|
||||||
UnpackedKind::Lifetime(_) => print_regions,
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if args.clone().next().is_none() {
|
|
||||||
return Ok(prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
let args = args.map(|arg| {
|
|
||||||
Ok(match arg.unpack() {
|
|
||||||
UnpackedKind::Lifetime(lt) => {
|
|
||||||
ast::GenericArg::Lifetime(lt.print(self)?)
|
|
||||||
}
|
|
||||||
UnpackedKind::Type(ty) => {
|
|
||||||
ast::GenericArg::Type(ty.print(self)?)
|
|
||||||
}
|
|
||||||
UnpackedKind::Const(ct) => {
|
|
||||||
ast::GenericArg::Const(ct.print(self)?)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}).collect::<Result<Vec<_>, _>>()?;
|
|
||||||
|
|
||||||
Ok(ast::Path::Generic {
|
|
||||||
inner: Arc::new(prefix),
|
|
||||||
args,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,7 +17,6 @@ pub(super) fn mangle(
|
||||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
instantiating_crate: Option<CrateNum>,
|
instantiating_crate: Option<CrateNum>,
|
||||||
compress: bool,
|
|
||||||
) -> String {
|
) -> String {
|
||||||
let def_id = instance.def_id();
|
let def_id = instance.def_id();
|
||||||
// FIXME(eddyb) this should ideally not be needed.
|
// FIXME(eddyb) this should ideally not be needed.
|
||||||
|
@ -27,17 +26,13 @@ pub(super) fn mangle(
|
||||||
let prefix = "_R";
|
let prefix = "_R";
|
||||||
let mut cx = SymbolMangler {
|
let mut cx = SymbolMangler {
|
||||||
tcx,
|
tcx,
|
||||||
compress: if compress {
|
compress: Some(Box::new(CompressionCaches {
|
||||||
Some(Box::new(CompressionCaches {
|
start_offset: prefix.len(),
|
||||||
start_offset: prefix.len(),
|
|
||||||
|
|
||||||
paths: FxHashMap::default(),
|
paths: FxHashMap::default(),
|
||||||
types: FxHashMap::default(),
|
types: FxHashMap::default(),
|
||||||
consts: FxHashMap::default(),
|
consts: FxHashMap::default(),
|
||||||
}))
|
})),
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
binders: vec![],
|
binders: vec![],
|
||||||
out: String::from(prefix),
|
out: String::from(prefix),
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,10 +6,6 @@ use std::path::Path;
|
||||||
/// List of whitelisted sources for packages.
|
/// List of whitelisted sources for packages.
|
||||||
const WHITELISTED_SOURCES: &[&str] = &[
|
const WHITELISTED_SOURCES: &[&str] = &[
|
||||||
"\"registry+https://github.com/rust-lang/crates.io-index\"",
|
"\"registry+https://github.com/rust-lang/crates.io-index\"",
|
||||||
|
|
||||||
"\"git+https://github.com/michaelwoerister/std-mangle-rs?\
|
|
||||||
rev=e884304cfcb2f636db4d59ca8ad8fa95b983281c#\
|
|
||||||
e884304cfcb2f636db4d59ca8ad8fa95b983281c\"",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Checks for external package sources.
|
/// Checks for external package sources.
|
||||||
|
|
Loading…
Reference in New Issue