From a6a5e4884a6c5be54acd53773e68faf02d79f52f Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 12 May 2016 01:25:20 +0300 Subject: [PATCH] trans: force absolute item paths within symbols. --- src/librustc/ty/item_path.rs | 36 ++++++++++++++++++++++--- src/librustc_trans/back/symbol_names.rs | 11 ++++++-- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 5246c6739d9..ee9983038b1 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -14,12 +14,38 @@ use hir::def_id::{DefId, CRATE_DEF_INDEX}; use ty::{self, Ty, TyCtxt}; use syntax::ast; +use std::cell::Cell; + +thread_local! { + static FORCE_ABSOLUTE: Cell = Cell::new(false) +} + +/// Enforces that item_path_str always returns an absolute path. +/// This is useful when building symbols that contain types, +/// where we want the crate name to be part of the symbol. +pub fn with_forced_absolute_paths R, R>(f: F) -> R { + FORCE_ABSOLUTE.with(|force| { + let old = force.get(); + force.set(true); + let result = f(); + force.set(old); + result + }) +} + impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns a string identifying this def-id. This string is /// suitable for user output. It is relative to the current crate - /// root. + /// root, unless with_forced_absolute_paths was used. pub fn item_path_str(self, def_id: DefId) -> String { - let mut buffer = LocalPathBuffer::new(RootMode::Local); + let mode = FORCE_ABSOLUTE.with(|force| { + if force.get() { + RootMode::Absolute + } else { + RootMode::Local + } + }); + let mut buffer = LocalPathBuffer::new(mode); self.push_item_path(&mut buffer, def_id); buffer.into_string() } @@ -75,7 +101,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { RootMode::Absolute => { // In absolute mode, just write the crate name // unconditionally. - buffer.push(&self.crate_name(cnum)); + if cnum == LOCAL_CRATE { + buffer.push(&self.crate_name(cnum)); + } else { + buffer.push(&self.sess.cstore.original_crate_name(cnum)); + } } } } diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index dffd0beafe5..4c166029c3e 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -120,7 +120,11 @@ pub fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> fn def_path_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_path: &DefPath) -> String { let mut s = String::with_capacity(def_path.data.len() * 16); - s.push_str(&tcx.crate_name(def_path.krate)); + if def_path.krate == cstore::LOCAL_CRATE { + s.push_str(&tcx.crate_name(def_path.krate)); + } else { + s.push_str(&tcx.sess.cstore.original_crate_name(def_path.krate)); + } s.push_str("/"); s.push_str(&tcx.crate_disambiguator(def_path.krate)); @@ -265,7 +269,10 @@ pub fn exported_name<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, let mut buffer = SymbolPathBuffer { names: Vec::with_capacity(def_path.data.len()) }; - ccx.tcx().push_item_path(&mut buffer, def_id); + + item_path::with_forced_absolute_paths(|| { + scx.tcx().push_item_path(&mut buffer, def_id); + }); mangle(buffer.names.into_iter(), Some(&hash[..])) }