]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #41447 - alexcrichton:sccache-everywhere, r=brson
authorbors <bors@rust-lang.org>
Thu, 27 Apr 2017 16:38:19 +0000 (16:38 +0000)
committerbors <bors@rust-lang.org>
Thu, 27 Apr 2017 16:38:19 +0000 (16:38 +0000)
appveyor: Use Ninja/sccache on MSVC

Now that the final bug fixes have been merged into sccache we can start
leveraging sccache on the MSVC builders on AppVeyor instead of relying on the
ad-hoc caching strategy of trigger files and whatnot.

16 files changed:
src/librustc/dep_graph/dep_node.rs
src/librustc/ty/maps.rs
src/librustc/ty/mod.rs
src/librustc_driver/driver.rs
src/librustc_trans/back/symbol_export.rs
src/librustc_trans/back/symbol_names.rs
src/librustc_trans/base.rs
src/librustc_trans/callee.rs
src/librustc_trans/consts.rs
src/librustc_trans/context.rs
src/librustc_trans/lib.rs
src/librustc_trans/partitioning.rs
src/librustc_trans/symbol_cache.rs [deleted file]
src/librustc_trans/symbol_map.rs [deleted file]
src/librustc_trans/symbol_names_test.rs
src/librustc_trans/trans_item.rs

index 33133f6834b9ab70a32a3e45de54c27929363d35..31e6a3106a438890a49d7f960e6b6aad12b1caaf 100644 (file)
@@ -99,6 +99,7 @@ pub enum DepNode<D: Clone + Debug> {
     TypeckTables(D),
     UsedTraitImports(D),
     ConstEval(D),
+    SymbolName(D),
 
     // The set of impls for a given trait. Ultimately, it would be
     // nice to get more fine-grained here (e.g., to include a
@@ -236,6 +237,7 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
             TypeckTables(ref d) => op(d).map(TypeckTables),
             UsedTraitImports(ref d) => op(d).map(UsedTraitImports),
             ConstEval(ref d) => op(d).map(ConstEval),
+            SymbolName(ref d) => op(d).map(SymbolName),
             TraitImpls(ref d) => op(d).map(TraitImpls),
             TraitItems(ref d) => op(d).map(TraitItems),
             ReprHints(ref d) => op(d).map(ReprHints),
index 1407e57dc2a6a7e48f56b027aaa34ca24462dd8d..c80ae87d941ffa96dcc308acfc8d49c85ad364dd 100644 (file)
@@ -24,6 +24,7 @@
 use std::ops::Deref;
 use std::rc::Rc;
 use syntax_pos::{Span, DUMMY_SP};
+use syntax::symbol::Symbol;
 
 trait Key {
     fn map_crate(&self) -> CrateNum;
@@ -40,6 +41,16 @@ fn default_span(&self, tcx: TyCtxt) -> Span {
     }
 }
 
+impl<'tcx> Key for ty::Instance<'tcx> {
+    fn map_crate(&self) -> CrateNum {
+        LOCAL_CRATE
+    }
+
+    fn default_span(&self, tcx: TyCtxt) -> Span {
+        tcx.def_span(self.def_id())
+    }
+}
+
 impl Key for CrateNum {
     fn map_crate(&self) -> CrateNum {
         *self
@@ -108,13 +119,18 @@ fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
     }
 }
 
-
 impl<'tcx> Value<'tcx> for ty::DtorckConstraint<'tcx> {
     fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
         Self::empty()
     }
 }
 
+impl<'tcx> Value<'tcx> for ty::SymbolName {
+    fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
+        ty::SymbolName { name: Symbol::intern("<error>").as_str() }
+    }
+}
+
 pub struct CycleError<'a, 'tcx: 'a> {
     span: Span,
     cycle: RefMut<'a, [(Span, Query<'tcx>)]>,
@@ -242,6 +258,12 @@ fn describe(tcx: TyCtxt, (def_id, _): (DefId, &'tcx Substs<'tcx>)) -> String {
     }
 }
 
+impl<'tcx> QueryDescription for queries::symbol_name<'tcx> {
+    fn describe(_tcx: TyCtxt, instance: ty::Instance<'tcx>) -> String {
+        format!("computing the symbol for `{}`", instance)
+    }
+}
+
 macro_rules! define_maps {
     (<$tcx:tt>
      $($(#[$attr:meta])*
@@ -513,7 +535,10 @@ fn default() -> Self {
 
     pub reachable_set: reachability_dep_node(CrateNum) -> Rc<NodeSet>,
 
-    pub mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>
+    pub mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>,
+
+    pub def_symbol_name: SymbolName(DefId) -> ty::SymbolName,
+    pub symbol_name: symbol_name_dep_node(ty::Instance<'tcx>) -> ty::SymbolName
 }
 
 fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
@@ -532,6 +557,12 @@ fn mir_shim_dep_node(instance: ty::InstanceDef) -> DepNode<DefId> {
     instance.dep_node()
 }
 
+fn symbol_name_dep_node(instance: ty::Instance) -> DepNode<DefId> {
+    // symbol_name uses the substs only to traverse them to find the
+    // hash, and that does not create any new dep-nodes.
+    DepNode::SymbolName(instance.def.def_id())
+}
+
 fn typeck_item_bodies_dep_node(_: CrateNum) -> DepNode<DefId> {
     DepNode::TypeckBodiesKrate
 }
index 9a8c91f5820dcfac4377bcb540bce5eeebe138f7..de207df7d15eb0baf3aed24a42d7b84a2838843b 100644 (file)
@@ -38,6 +38,7 @@
 use std::cell::{Cell, RefCell, Ref};
 use std::collections::BTreeMap;
 use std::cmp;
+use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::iter::FromIterator;
 use std::ops::Deref;
@@ -2745,3 +2746,22 @@ fn dedup<'a>(&mut self) {
         self.dtorck_types.retain(|&val| dtorck_types.replace(val).is_none());
     }
 }
+
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct SymbolName {
+    // FIXME: we don't rely on interning or equality here - better have
+    // this be a `&'tcx str`.
+    pub name: InternedString
+}
+
+impl Deref for SymbolName {
+    type Target = str;
+
+    fn deref(&self) -> &str { &self.name }
+}
+
+impl fmt::Display for SymbolName {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&self.name, fmt)
+    }
+}
index 438f482fa55c7bfbd90be456920f77f3edfbbbfd..dab2a0758a2176df55fce2128f6ddefc127800a8 100644 (file)
@@ -225,8 +225,6 @@ macro_rules! controller_entry_point {
         sess.code_stats.borrow().print_type_sizes();
     }
 
-    if ::std::env::var("SKIP_LLVM").is_ok() { ::std::process::exit(0); }
-
     let phase5_result = phase_5_run_llvm_passes(sess, &trans, &outputs);
 
     controller_entry_point!(after_llvm,
@@ -895,6 +893,7 @@ macro_rules! try_with_f {
     mir::provide(&mut local_providers);
     reachable::provide(&mut local_providers);
     rustc_privacy::provide(&mut local_providers);
+    trans::provide(&mut local_providers);
     typeck::provide(&mut local_providers);
     ty::provide(&mut local_providers);
     reachable::provide(&mut local_providers);
@@ -902,6 +901,7 @@ macro_rules! try_with_f {
 
     let mut extern_providers = ty::maps::Providers::default();
     cstore::provide(&mut extern_providers);
+    trans::provide(&mut extern_providers);
     ty::provide_extern(&mut extern_providers);
     // FIXME(eddyb) get rid of this once we replace const_eval with miri.
     rustc_const_eval::provide(&mut extern_providers);
index 221c52141a8323de0193f3d2a926599df704a5b9..ddd86c4679934d79493a9d20e2755e6d0fd1b164 100644 (file)
 
 use context::SharedCrateContext;
 use monomorphize::Instance;
-use symbol_map::SymbolMap;
-use back::symbol_names::symbol_name;
 use util::nodemap::FxHashMap;
 use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
 use rustc::session::config;
 use rustc::ty::TyCtxt;
 use syntax::attr;
-use trans_item::TransItem;
 
 /// The SymbolExportLevel of a symbols specifies from which kinds of crates
 /// the symbol will be exported. `C` symbols will be exported from any
@@ -36,16 +33,13 @@ pub struct ExportedSymbols {
 }
 
 impl ExportedSymbols {
-
     pub fn empty() -> ExportedSymbols {
         ExportedSymbols {
             exports: FxHashMap(),
         }
     }
 
-    pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
-                                  symbol_map: &SymbolMap<'tcx>)
-                                  -> ExportedSymbols {
+    pub fn compute<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>) -> ExportedSymbols {
         let mut local_crate: Vec<_> = scx
             .exported_symbols()
             .iter()
@@ -53,10 +47,10 @@ pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                 scx.tcx().hir.local_def_id(node_id)
             })
             .map(|def_id| {
-                let name = symbol_for_def_id(scx.tcx(), def_id, symbol_map);
+                let name = scx.tcx().symbol_name(Instance::mono(scx.tcx(), def_id));
                 let export_level = export_level(scx, def_id);
                 debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level);
-                (name, export_level)
+                (str::to_owned(&name), export_level)
             })
             .collect();
 
@@ -108,7 +102,7 @@ pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                 .exported_symbols(cnum)
                 .iter()
                 .map(|&def_id| {
-                    let name = symbol_name(Instance::mono(scx.tcx(), def_id), scx.tcx());
+                    let name = scx.tcx().symbol_name(Instance::mono(scx.tcx(), def_id));
                     let export_level = if special_runtime_crate {
                         // We can probably do better here by just ensuring that
                         // it has hidden visibility rather than public
@@ -117,9 +111,9 @@ pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                         //
                         // In general though we won't link right if these
                         // symbols are stripped, and LTO currently strips them.
-                        if name == "rust_eh_personality" ||
-                           name == "rust_eh_register_frames" ||
-                           name == "rust_eh_unregister_frames" {
+                        if &*name == "rust_eh_personality" ||
+                           &*name == "rust_eh_register_frames" ||
+                           &*name == "rust_eh_unregister_frames" {
                             SymbolExportLevel::C
                         } else {
                             SymbolExportLevel::Rust
@@ -128,7 +122,7 @@ pub fn compute_from<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
                         export_level(scx, def_id)
                     };
                     debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level);
-                    (name, export_level)
+                    (str::to_owned(&name), export_level)
                 })
                 .collect();
 
@@ -213,22 +207,3 @@ pub fn is_below_threshold(level: SymbolExportLevel,
         level == SymbolExportLevel::C
     }
 }
-
-fn symbol_for_def_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                               def_id: DefId,
-                               symbol_map: &SymbolMap<'tcx>)
-                               -> String {
-    // Just try to look things up in the symbol map. If nothing's there, we
-    // recompute.
-    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-        if let Some(sym) = symbol_map.get(TransItem::Static(node_id)) {
-            return sym.to_owned();
-        }
-    }
-
-    let instance = Instance::mono(tcx, def_id);
-
-    symbol_map.get(TransItem::Fn(instance))
-              .map(str::to_owned)
-              .unwrap_or_else(|| symbol_name(instance, tcx))
-}
index a96128fcf2f5305a06afb2105fd28baff96aba7b..aef9140ba4556cf9b14f927daaf13d12bbadc4a7 100644 (file)
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::ty::fold::TypeVisitor;
 use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
+use rustc::ty::maps::Providers;
 use rustc::ty::subst::Substs;
 use rustc::hir::map::definitions::DefPathData;
 use rustc::util::common::record_time;
 
 use syntax::attr;
+use syntax_pos::symbol::Symbol;
 
 use std::fmt::Write;
 
+pub fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        def_symbol_name,
+        symbol_name,
+        ..*providers
+    };
+}
+
 fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
                              // the DefId of the item this name is for
@@ -127,7 +137,7 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              // values for generic type parameters,
                              // if any.
                              substs: Option<&'tcx Substs<'tcx>>)
-                             -> String {
+                             -> u64 {
     debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs);
 
     let mut hasher = ty::util::TypeIdHasher::<u64>::new(tcx);
@@ -162,11 +172,28 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     });
 
     // 64 bits should be enough to avoid collisions.
-    format!("h{:016x}", hasher.finish())
+    hasher.finish()
+}
+
+fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
+                             -> ty::SymbolName
+{
+    let mut buffer = SymbolPathBuffer::new();
+    item_path::with_forced_absolute_paths(|| {
+        tcx.push_item_path(&mut buffer, def_id);
+    });
+    buffer.into_interned()
 }
 
-pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
-                             tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
+fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
+                         -> ty::SymbolName
+{
+    ty::SymbolName { name: Symbol::intern(&compute_symbol_name(tcx, instance)).as_str() }
+}
+
+fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>)
+    -> String
+{
     let def_id = instance.def_id();
     let substs = instance.substs;
 
@@ -253,11 +280,7 @@ pub fn symbol_name<'a, 'tcx>(instance: Instance<'tcx>,
 
     let hash = get_symbol_hash(tcx, Some(def_id), instance_ty, Some(substs));
 
-    let mut buffer = SymbolPathBuffer::new();
-    item_path::with_forced_absolute_paths(|| {
-        tcx.push_item_path(&mut buffer, def_id);
-    });
-    buffer.finish(&hash)
+    SymbolPathBuffer::from_interned(tcx.def_symbol_name(def_id)).finish(hash)
 }
 
 // Follow C++ namespace-mangling style, see
@@ -288,10 +311,22 @@ fn new() -> Self {
         result
     }
 
-    fn finish(mut self, hash: &str) -> String {
-        // end name-sequence
-        self.push(hash);
-        self.result.push('E');
+    fn from_interned(symbol: ty::SymbolName) -> Self {
+        let mut result = SymbolPathBuffer {
+            result: String::with_capacity(64),
+            temp_buf: String::with_capacity(16)
+        };
+        result.result.push_str(&symbol.name);
+        result
+    }
+
+    fn into_interned(self) -> ty::SymbolName {
+        ty::SymbolName { name: Symbol::intern(&self.result).as_str() }
+    }
+
+    fn finish(mut self, hash: u64) -> String {
+        // E = end name-sequence
+        let _ = write!(self.result, "17h{:016x}E", hash);
         self.result
     }
 }
@@ -320,7 +355,7 @@ pub fn exported_name_from_type_and_prefix<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let hash = get_symbol_hash(tcx, None, t, None);
     let mut buffer = SymbolPathBuffer::new();
     buffer.push(prefix);
-    buffer.finish(&hash)
+    buffer.finish(hash)
 }
 
 // Name sanitation. LLVM will happily accept identifiers with weird names, but
index e8cca7bc74f1a7d0050284ce24d21ca8760a5246..56ff5ebb069ea4a5f044a912fda677f656d726c1 100644 (file)
@@ -65,8 +65,6 @@
 use mir;
 use monomorphize::{self, Instance};
 use partitioning::{self, PartitioningStrategy, CodegenUnit};
-use symbol_cache::SymbolCache;
-use symbol_map::SymbolMap;
 use symbol_names_test;
 use trans_item::{TransItem, DefPathBasedNames};
 use type_::Type;
@@ -804,7 +802,6 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
                                  scx: &SharedCrateContext<'a, 'tcx>,
                                  translation_items: &FxHashSet<TransItem<'tcx>>,
                                  llvm_modules: &[ModuleLlvm],
-                                 symbol_map: &SymbolMap<'tcx>,
                                  exported_symbols: &ExportedSymbols) {
     let export_threshold =
         symbol_export::crates_export_threshold(&sess.crate_types.borrow());
@@ -856,7 +853,7 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
             let mut linkage_fixed_explicitly = FxHashSet();
 
             for trans_item in translation_items {
-                let symbol_name = symbol_map.get_or_compute(scx, *trans_item);
+                let symbol_name = str::to_owned(&trans_item.symbol_name(tcx));
                 if trans_item.explicit_linkage(tcx).is_some() {
                     linkage_fixed_explicitly.insert(symbol_name.clone());
                 }
@@ -1110,7 +1107,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     // Run the translation item collector and partition the collected items into
     // codegen units.
-    let (translation_items, codegen_units, symbol_map) =
+    let (translation_items, codegen_units) =
         collect_and_partition_translation_items(&shared_ccx);
 
     let mut all_stats = Stats::default();
@@ -1139,8 +1136,7 @@ fn module_translation<'a, 'tcx>(
 
         let cgu_name = String::from(cgu.name());
         let cgu_id = cgu.work_product_id();
-        let symbol_cache = SymbolCache::new(scx.tcx());
-        let symbol_name_hash = cgu.compute_symbol_name_hash(scx, &symbol_cache);
+        let symbol_name_hash = cgu.compute_symbol_name_hash(scx);
 
         // Check whether there is a previous work-product we can
         // re-use.  Not only must the file exist, and the inputs not
@@ -1175,11 +1171,11 @@ fn module_translation<'a, 'tcx>(
         }
 
         // Instantiate translation items without filling out definitions yet...
-        let lcx = LocalCrateContext::new(scx, cgu, &symbol_cache);
+        let lcx = LocalCrateContext::new(scx, cgu);
         let module = {
             let ccx = CrateContext::new(scx, &lcx);
             let trans_items = ccx.codegen_unit()
-                                 .items_in_deterministic_order(ccx.tcx(), &symbol_cache);
+                                 .items_in_deterministic_order(ccx.tcx());
             for &(trans_item, linkage) in &trans_items {
                 trans_item.predefine(&ccx, linkage);
             }
@@ -1271,8 +1267,7 @@ fn module_translation<'a, 'tcx>(
 
     let sess = shared_ccx.sess();
 
-    let exported_symbols = ExportedSymbols::compute_from(&shared_ccx,
-                                                         &symbol_map);
+    let exported_symbols = ExportedSymbols::compute(&shared_ccx);
 
     // Get the list of llvm modules we created. We'll do a few wacky
     // transforms on them now.
@@ -1292,7 +1287,6 @@ fn module_translation<'a, 'tcx>(
                             &shared_ccx,
                             &translation_items,
                             &llvm_modules,
-                            &symbol_map,
                             &exported_symbols);
     });
 
@@ -1518,10 +1512,57 @@ enum Fields<'a> {
     }
 }
 
+#[inline(never)] // give this a place in the profiler
+fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_items: I)
+    where I: Iterator<Item=&'a TransItem<'tcx>>
+{
+    let mut symbols: Vec<_> = trans_items.map(|trans_item| {
+        (trans_item, trans_item.symbol_name(tcx))
+    }).collect();
+
+    (&mut symbols[..]).sort_by(|&(_, ref sym1), &(_, ref sym2)|{
+        sym1.cmp(sym2)
+    });
+
+    for pair in (&symbols[..]).windows(2) {
+        let sym1 = &pair[0].1;
+        let sym2 = &pair[1].1;
+
+        if *sym1 == *sym2 {
+            let trans_item1 = pair[0].0;
+            let trans_item2 = pair[1].0;
+
+            let span1 = trans_item1.local_span(tcx);
+            let span2 = trans_item2.local_span(tcx);
+
+            // Deterministically select one of the spans for error reporting
+            let span = match (span1, span2) {
+                (Some(span1), Some(span2)) => {
+                    Some(if span1.lo.0 > span2.lo.0 {
+                        span1
+                    } else {
+                        span2
+                    })
+                }
+                (Some(span), None) |
+                (None, Some(span)) => Some(span),
+                _ => None
+            };
+
+            let error_message = format!("symbol `{}` is already defined", sym1);
+
+            if let Some(span) = span {
+                tcx.sess.span_fatal(span, &error_message)
+            } else {
+                tcx.sess.fatal(&error_message)
+            }
+        }
+    }
+}
+
 fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>)
                                                      -> (FxHashSet<TransItem<'tcx>>,
-                                                         Vec<CodegenUnit<'tcx>>,
-                                                         SymbolMap<'tcx>) {
+                                                         Vec<CodegenUnit<'tcx>>) {
     let time_passes = scx.sess().time_passes();
 
     let collection_mode = match scx.sess().opts.debugging_opts.print_trans_items {
@@ -1549,7 +1590,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
             collector::collect_crate_translation_items(&scx, collection_mode)
     });
 
-    let symbol_map = SymbolMap::build(scx, items.iter().cloned());
+    assert_symbols_are_distinct(scx.tcx(), items.iter());
 
     let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
         PartitioningStrategy::PerModule
@@ -1622,5 +1663,5 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
         }
     }
 
-    (translation_items, codegen_units, symbol_map)
+    (translation_items, codegen_units)
 }
index 78e0a524ef2dc833b4912f9393833d78c1f9c0be..dc788dc4b48342026eab14e1611ed38b2f6dbc39 100644 (file)
@@ -23,7 +23,6 @@
 use rustc::hir::def_id::DefId;
 use rustc::ty::TypeFoldable;
 use rustc::ty::subst::Substs;
-use trans_item::TransItem;
 use type_of;
 
 /// Translates a reference to a fn/method item, monomorphizing and
@@ -50,7 +49,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         return llfn;
     }
 
-    let sym = ccx.symbol_cache().get(TransItem::Fn(instance));
+    let sym = tcx.symbol_name(instance);
     debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym);
 
     // This is subtle and surprising, but sometimes we have to bitcast
index 3d614cfbcbf3c5c5f961a0d8b5b361c2df6274e2..6afb340107d6661aa1c3a5ad517319757942f887 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-use back::symbol_names;
 use llvm;
 use llvm::{SetUnnamedAddr};
 use llvm::{ValueRef, True};
@@ -93,8 +91,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
             hir_map::NodeItem(&hir::Item {
                 ref attrs, span, node: hir::ItemStatic(..), ..
             }) => {
-                let sym = ccx.symbol_cache()
-                             .get(TransItem::Static(id));
+                let sym = TransItem::Static(id).symbol_name(ccx.tcx());
 
                 let defined_in_current_codegen_unit = ccx.codegen_unit()
                                                          .items()
@@ -113,7 +110,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
             hir_map::NodeForeignItem(&hir::ForeignItem {
                 ref attrs, span, node: hir::ForeignItemStatic(..), ..
             }) => {
-                let sym = symbol_names::symbol_name(instance, ccx.tcx());
+                let sym = ccx.tcx().symbol_name(instance);
                 let g = if let Some(name) =
                         attr::first_attr_value_str_by_name(&attrs, "linkage") {
                     // If this is a static with a linkage specified, then we need to handle
@@ -173,7 +170,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
 
         g
     } else {
-        let sym = symbol_names::symbol_name(instance, ccx.tcx());
+        let sym = ccx.tcx().symbol_name(instance);
 
         // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
         // FIXME(nagisa): investigate whether it can be changed into define_global
index bef22cf304dcb938f962c7e58c50429617807efb..90cda2f5cad3d582378141b12184d4e5ea05b4a3 100644 (file)
@@ -29,7 +29,6 @@
 use session::config::NoDebugInfo;
 use session::Session;
 use session::config;
-use symbol_cache::SymbolCache;
 use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
 
 use std::ffi::{CStr, CString};
@@ -37,6 +36,7 @@
 use std::ptr;
 use std::iter;
 use std::str;
+use std::marker::PhantomData;
 use syntax::ast;
 use syntax::symbol::InternedString;
 use syntax_pos::DUMMY_SP;
@@ -94,7 +94,6 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
     llcx: ContextRef,
     stats: Stats,
     codegen_unit: CodegenUnit<'tcx>,
-    needs_unwind_cleanup_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
     /// Cache instances of monomorphic and polymorphic items
     instances: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>,
     /// Cache generated vtables
@@ -125,11 +124,6 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
     /// Mapping from static definitions to their DefId's.
     statics: RefCell<FxHashMap<ValueRef, DefId>>,
 
-    impl_method_cache: RefCell<FxHashMap<(DefId, ast::Name), DefId>>,
-
-    /// Cache of closure wrappers for bare fn's.
-    closure_bare_wrapper_cache: RefCell<FxHashMap<ValueRef, ValueRef>>,
-
     /// List of globals for static variables which need to be passed to the
     /// LLVM function ReplaceAllUsesWith (RAUW) when translation is complete.
     /// (We have to make sure we don't invalidate any ValueRefs referring
@@ -141,15 +135,11 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
     used_statics: RefCell<Vec<ValueRef>>,
 
     lltypes: RefCell<FxHashMap<Ty<'tcx>, Type>>,
-    llsizingtypes: RefCell<FxHashMap<Ty<'tcx>, Type>>,
     type_hashcodes: RefCell<FxHashMap<Ty<'tcx>, String>>,
     int_type: Type,
     opaque_vec_type: Type,
     str_slice_type: Type,
 
-    /// Holds the LLVM values for closure IDs.
-    closure_vals: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>,
-
     dbg_cx: Option<debuginfo::CrateDebugContext<'tcx>>,
 
     eh_personality: Cell<Option<ValueRef>>,
@@ -164,7 +154,8 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
     /// A counter that is used for generating local symbol names
     local_gen_sym_counter: Cell<usize>,
 
-    symbol_cache: &'a SymbolCache<'a, 'tcx>,
+    /// A placeholder so we can add lifetimes
+    placeholder: PhantomData<&'a ()>,
 }
 
 /// A CrateContext value binds together one LocalCrateContext with the
@@ -366,8 +357,7 @@ pub fn use_dll_storage_attrs(&self) -> bool {
 
 impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
     pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
-               codegen_unit: CodegenUnit<'tcx>,
-               symbol_cache: &'a SymbolCache<'a, 'tcx>)
+               codegen_unit: CodegenUnit<'tcx>)
                -> LocalCrateContext<'a, 'tcx> {
         unsafe {
             // Append ".rs" to LLVM module identifier.
@@ -396,7 +386,6 @@ pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
                 llcx: llcx,
                 stats: Stats::default(),
                 codegen_unit: codegen_unit,
-                needs_unwind_cleanup_cache: RefCell::new(FxHashMap()),
                 instances: RefCell::new(FxHashMap()),
                 vtables: RefCell::new(FxHashMap()),
                 const_cstr_cache: RefCell::new(FxHashMap()),
@@ -405,17 +394,13 @@ pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
                 const_values: RefCell::new(FxHashMap()),
                 extern_const_values: RefCell::new(DefIdMap()),
                 statics: RefCell::new(FxHashMap()),
-                impl_method_cache: RefCell::new(FxHashMap()),
-                closure_bare_wrapper_cache: RefCell::new(FxHashMap()),
                 statics_to_rauw: RefCell::new(Vec::new()),
                 used_statics: RefCell::new(Vec::new()),
                 lltypes: RefCell::new(FxHashMap()),
-                llsizingtypes: RefCell::new(FxHashMap()),
                 type_hashcodes: RefCell::new(FxHashMap()),
                 int_type: Type::from_ref(ptr::null_mut()),
                 opaque_vec_type: Type::from_ref(ptr::null_mut()),
                 str_slice_type: Type::from_ref(ptr::null_mut()),
-                closure_vals: RefCell::new(FxHashMap()),
                 dbg_cx: dbg_cx,
                 eh_personality: Cell::new(None),
                 eh_unwind_resume: Cell::new(None),
@@ -423,7 +408,7 @@ pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
                 intrinsics: RefCell::new(FxHashMap()),
                 type_of_depth: Cell::new(0),
                 local_gen_sym_counter: Cell::new(0),
-                symbol_cache: symbol_cache,
+                placeholder: PhantomData,
             };
 
             let (int_type, opaque_vec_type, str_slice_ty, mut local_ccx) = {
@@ -515,10 +500,6 @@ pub fn td(&self) -> llvm::TargetDataRef {
         unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
     }
 
-    pub fn needs_unwind_cleanup_cache(&self) -> &RefCell<FxHashMap<Ty<'tcx>, bool>> {
-        &self.local().needs_unwind_cleanup_cache
-    }
-
     pub fn instances<'a>(&'a self) -> &'a RefCell<FxHashMap<Instance<'tcx>, ValueRef>> {
         &self.local().instances
     }
@@ -554,15 +535,6 @@ pub fn statics<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, DefId>> {
         &self.local().statics
     }
 
-    pub fn impl_method_cache<'a>(&'a self)
-            -> &'a RefCell<FxHashMap<(DefId, ast::Name), DefId>> {
-        &self.local().impl_method_cache
-    }
-
-    pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, ValueRef>> {
-        &self.local().closure_bare_wrapper_cache
-    }
-
     pub fn statics_to_rauw<'a>(&'a self) -> &'a RefCell<Vec<(ValueRef, ValueRef)>> {
         &self.local().statics_to_rauw
     }
@@ -575,10 +547,6 @@ pub fn lltypes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, Type>> {
         &self.local().lltypes
     }
 
-    pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, Type>> {
-        &self.local().llsizingtypes
-    }
-
     pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, String>> {
         &self.local().type_hashcodes
     }
@@ -599,10 +567,6 @@ pub fn str_slice_type(&self) -> Type {
         self.local().str_slice_type
     }
 
-    pub fn closure_vals<'a>(&'a self) -> &'a RefCell<FxHashMap<Instance<'tcx>, ValueRef>> {
-        &self.local().closure_vals
-    }
-
     pub fn dbg_cx<'a>(&'a self) -> &'a Option<debuginfo::CrateDebugContext<'tcx>> {
         &self.local().dbg_cx
     }
@@ -644,10 +608,6 @@ pub fn use_dll_storage_attrs(&self) -> bool {
         self.shared.use_dll_storage_attrs()
     }
 
-    pub fn symbol_cache(&self) -> &'b SymbolCache<'b, 'tcx> {
-        self.local().symbol_cache
-    }
-
     /// Given the def-id of some item that has no type parameters, make
     /// a suitable "empty substs" for it.
     pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
index d5fc2ee5e25e07e141bd8edc246a6c5bf54467e9..111c2547721663decc75b17ae753e0576c5c204f 100644 (file)
@@ -67,6 +67,7 @@
 pub use rustc::util;
 
 pub use base::trans_crate;
+pub use back::symbol_names::provide;
 
 pub mod back {
     pub use rustc::hir::svh;
@@ -125,8 +126,6 @@ pub mod back {
 mod mir;
 mod monomorphize;
 mod partitioning;
-mod symbol_cache;
-mod symbol_map;
 mod symbol_names_test;
 mod trans_item;
 mod tvec;
index 6b89d11cfb68f161e9356ba6934a46e943f306bc..2c76cdeb48cdf7cda90d2699399560d1f5a19057 100644 (file)
 use rustc::ty::{self, TyCtxt};
 use rustc::ty::item_path::characteristic_def_id_of_type;
 use rustc_incremental::IchHasher;
-use std::cmp::Ordering;
 use std::hash::Hash;
 use std::sync::Arc;
-use symbol_cache::SymbolCache;
 use syntax::ast::NodeId;
 use syntax::symbol::{Symbol, InternedString};
 use trans_item::{TransItem, InstantiationMode};
@@ -175,14 +173,13 @@ pub fn work_product_dep_node(&self) -> DepNode<DefId> {
     }
 
     pub fn compute_symbol_name_hash<'a>(&self,
-                                        scx: &SharedCrateContext<'a, 'tcx>,
-                                        symbol_cache: &SymbolCache<'a, 'tcx>)
+                                        scx: &SharedCrateContext<'a, 'tcx>)
                                         -> u64 {
         let mut state = IchHasher::new();
         let exported_symbols = scx.exported_symbols();
-        let all_items = self.items_in_deterministic_order(scx.tcx(), symbol_cache);
+        let all_items = self.items_in_deterministic_order(scx.tcx());
         for (item, _) in all_items {
-            let symbol_name = symbol_cache.get(item);
+            let symbol_name = item.symbol_name(scx.tcx());
             symbol_name.len().hash(&mut state);
             symbol_name.hash(&mut state);
             let exported = match item {
@@ -203,53 +200,30 @@ pub fn compute_symbol_name_hash<'a>(&self,
     }
 
     pub fn items_in_deterministic_order<'a>(&self,
-                                            tcx: TyCtxt,
-                                            symbol_cache: &SymbolCache<'a, 'tcx>)
+                                            tcx: TyCtxt<'a, 'tcx, 'tcx>)
                                             -> Vec<(TransItem<'tcx>, llvm::Linkage)> {
-        let mut items: Vec<(TransItem<'tcx>, llvm::Linkage)> =
-            self.items.iter().map(|(item, linkage)| (*item, *linkage)).collect();
-
         // The codegen tests rely on items being process in the same order as
         // they appear in the file, so for local items, we sort by node_id first
-        items.sort_by(|&(trans_item1, _), &(trans_item2, _)| {
-            let node_id1 = local_node_id(tcx, trans_item1);
-            let node_id2 = local_node_id(tcx, trans_item2);
-
-            match (node_id1, node_id2) {
-                (None, None) => {
-                    let symbol_name1 = symbol_cache.get(trans_item1);
-                    let symbol_name2 = symbol_cache.get(trans_item2);
-                    symbol_name1.cmp(&symbol_name2)
-                }
-                // In the following two cases we can avoid looking up the symbol
-                (None, Some(_)) => Ordering::Less,
-                (Some(_), None) => Ordering::Greater,
-                (Some(node_id1), Some(node_id2)) => {
-                    let ordering = node_id1.cmp(&node_id2);
-
-                    if ordering != Ordering::Equal {
-                        return ordering;
-                    }
-
-                    let symbol_name1 = symbol_cache.get(trans_item1);
-                    let symbol_name2 = symbol_cache.get(trans_item2);
-                    symbol_name1.cmp(&symbol_name2)
-                }
-            }
-        });
-
-        return items;
+        #[derive(PartialEq, Eq, PartialOrd, Ord)]
+        pub struct ItemSortKey(Option<NodeId>, ty::SymbolName);
 
-        fn local_node_id(tcx: TyCtxt, trans_item: TransItem) -> Option<NodeId> {
-            match trans_item {
+        fn item_sort_key<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                   item: TransItem<'tcx>) -> ItemSortKey {
+            ItemSortKey(match item {
                 TransItem::Fn(instance) => {
                     tcx.hir.as_local_node_id(instance.def_id())
                 }
                 TransItem::Static(node_id) | TransItem::GlobalAsm(node_id) => {
                     Some(node_id)
                 }
-            }
+            }, item.symbol_name(tcx))
         }
+
+        let items: Vec<_> = self.items.iter().map(|(&i, &l)| (i, l)).collect();
+        let mut items : Vec<_> = items.iter()
+            .map(|il| (il, item_sort_key(tcx, il.0))).collect();
+        items.sort_by(|&(_, ref key1), &(_, ref key2)| key1.cmp(key2));
+        items.into_iter().map(|(&item_linkage, _)| item_linkage).collect()
     }
 }
 
@@ -537,12 +511,11 @@ fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 {
     if cfg!(debug_assertions) {
         debug!("{}", label);
-        let symbol_cache = SymbolCache::new(tcx);
         for cgu in cgus {
             debug!("CodegenUnit {}:", cgu.name);
 
             for (trans_item, linkage) in &cgu.items {
-                let symbol_name = symbol_cache.get(*trans_item);
+                let symbol_name = trans_item.symbol_name(tcx);
                 let symbol_hash_start = symbol_name.rfind('h');
                 let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..])
                                                    .unwrap_or("<no hash>");
diff --git a/src/librustc_trans/symbol_cache.rs b/src/librustc_trans/symbol_cache.rs
deleted file mode 100644 (file)
index ddc1ef5..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use rustc::ty::TyCtxt;
-use std::cell::RefCell;
-use syntax_pos::symbol::{InternedString, Symbol};
-use trans_item::TransItem;
-use util::nodemap::FxHashMap;
-
-// In the SymbolCache we collect the symbol names of translation items
-// and cache them for later reference. This is just a performance
-// optimization and the cache is populated lazilly; symbol names of
-// translation items are deterministic and fully defined by the item.
-// Thus they can always be recomputed if needed.
-
-pub struct SymbolCache<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    index: RefCell<FxHashMap<TransItem<'tcx>, Symbol>>,
-}
-
-impl<'a, 'tcx> SymbolCache<'a, 'tcx> {
-    pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
-        SymbolCache {
-            tcx: tcx,
-            index: RefCell::new(FxHashMap())
-        }
-    }
-
-    pub fn get(&self, trans_item: TransItem<'tcx>) -> InternedString {
-        let mut index = self.index.borrow_mut();
-        index.entry(trans_item)
-             .or_insert_with(|| Symbol::intern(&trans_item.compute_symbol_name(self.tcx)))
-             .as_str()
-    }
-}
diff --git a/src/librustc_trans/symbol_map.rs b/src/librustc_trans/symbol_map.rs
deleted file mode 100644 (file)
index 9d3e628..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use context::SharedCrateContext;
-use monomorphize::Instance;
-use rustc::ty::TyCtxt;
-use std::borrow::Cow;
-use syntax::codemap::Span;
-use trans_item::TransItem;
-use util::nodemap::FxHashMap;
-
-// In the SymbolMap we collect the symbol names of all translation items of
-// the current crate. This map exists as a performance optimization. Symbol
-// names of translation items are deterministic and fully defined by the item.
-// Thus they could also always be recomputed if needed.
-
-pub struct SymbolMap<'tcx> {
-    index: FxHashMap<TransItem<'tcx>, (usize, usize)>,
-    arena: String,
-}
-
-impl<'tcx> SymbolMap<'tcx> {
-
-    pub fn build<'a, I>(scx: &SharedCrateContext<'a, 'tcx>,
-                        trans_items: I)
-                        -> SymbolMap<'tcx>
-        where I: Iterator<Item=TransItem<'tcx>>
-    {
-        // Check for duplicate symbol names
-        let tcx = scx.tcx();
-        let mut symbols: Vec<_> = trans_items.map(|trans_item| {
-            (trans_item, trans_item.compute_symbol_name(tcx))
-        }).collect();
-
-        (&mut symbols[..]).sort_by(|&(_, ref sym1), &(_, ref sym2)|{
-            sym1.cmp(sym2)
-        });
-
-        for pair in (&symbols[..]).windows(2) {
-            let sym1 = &pair[0].1;
-            let sym2 = &pair[1].1;
-
-            if *sym1 == *sym2 {
-                let trans_item1 = pair[0].0;
-                let trans_item2 = pair[1].0;
-
-                let span1 = get_span(scx.tcx(), trans_item1);
-                let span2 = get_span(scx.tcx(), trans_item2);
-
-                // Deterministically select one of the spans for error reporting
-                let span = match (span1, span2) {
-                    (Some(span1), Some(span2)) => {
-                        Some(if span1.lo.0 > span2.lo.0 {
-                            span1
-                        } else {
-                            span2
-                        })
-                    }
-                    (Some(span), None) |
-                    (None, Some(span)) => Some(span),
-                    _ => None
-                };
-
-                let error_message = format!("symbol `{}` is already defined", sym1);
-
-                if let Some(span) = span {
-                    scx.sess().span_fatal(span, &error_message)
-                } else {
-                    scx.sess().fatal(&error_message)
-                }
-            }
-        }
-
-        let mut symbol_map = SymbolMap {
-            index: FxHashMap(),
-            arena: String::with_capacity(1024),
-        };
-
-        for (trans_item, symbol) in symbols {
-            let start_index = symbol_map.arena.len();
-            symbol_map.arena.push_str(&symbol[..]);
-            let end_index = symbol_map.arena.len();
-            let prev_entry = symbol_map.index.insert(trans_item,
-                                                     (start_index, end_index));
-            if prev_entry.is_some() {
-                bug!("TransItem encountered twice?")
-            }
-        }
-
-        fn get_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              trans_item: TransItem<'tcx>) -> Option<Span> {
-            match trans_item {
-                TransItem::Fn(Instance { def, .. }) => {
-                    tcx.hir.as_local_node_id(def.def_id())
-                }
-                TransItem::Static(node_id) |
-                TransItem::GlobalAsm(node_id) => {
-                    Some(node_id)
-                }
-            }.map(|node_id| {
-                tcx.hir.span(node_id)
-            })
-        }
-
-        symbol_map
-    }
-
-    pub fn get(&self, trans_item: TransItem<'tcx>) -> Option<&str> {
-        self.index.get(&trans_item).map(|&(start_index, end_index)| {
-            &self.arena[start_index .. end_index]
-        })
-    }
-
-    pub fn get_or_compute<'map, 'scx>(&'map self,
-                                      scx: &SharedCrateContext<'scx, 'tcx>,
-                                      trans_item: TransItem<'tcx>)
-                                      -> Cow<'map, str> {
-        if let Some(sym) = self.get(trans_item) {
-            Cow::from(sym)
-        } else {
-            Cow::from(trans_item.compute_symbol_name(scx.tcx()))
-        }
-    }
-}
index fd817cb94c1c1db1251d73e7ea84c6832a300d47..d96757be9f3a5e046f9ba0f1522e4d36bfe7e879 100644 (file)
@@ -14,7 +14,6 @@
 //! item-path. This is used for unit testing the code that generates
 //! paths etc in all kinds of annoying scenarios.
 
-use back::symbol_names;
 use rustc::hir;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::ty::TyCtxt;
@@ -52,7 +51,7 @@ fn process_attrs(&mut self,
             if attr.check_name(SYMBOL_NAME) {
                 // for now, can only use on monomorphic names
                 let instance = Instance::mono(tcx, def_id);
-                let name = symbol_names::symbol_name(instance, self.tcx);
+                let name = self.tcx.symbol_name(instance);
                 tcx.sess.span_err(attr.span, &format!("symbol-name({})", name));
             } else if attr.check_name(ITEM_PATH) {
                 let path = tcx.item_path_str(def_id);
index d8e139dc505b6129764db5f8990224352f5058f6..392ee71d52b44c751d44523928293f9549aa53fb 100644 (file)
@@ -30,8 +30,9 @@
 use rustc::ty::subst::Substs;
 use syntax::ast::{self, NodeId};
 use syntax::attr;
+use syntax_pos::Span;
+use syntax_pos::symbol::Symbol;
 use type_of;
-use back::symbol_names;
 use std::fmt::Write;
 use std::iter;
 
@@ -118,7 +119,7 @@ pub fn predefine(&self,
                self.to_raw_string(),
                ccx.codegen_unit().name());
 
-        let symbol_name = ccx.symbol_cache().get(*self);
+        let symbol_name = self.symbol_name(ccx.tcx());
 
         debug!("symbol {}", &symbol_name);
 
@@ -184,20 +185,34 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
         ccx.instances().borrow_mut().insert(instance, lldecl);
     }
 
-    pub fn compute_symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
+    pub fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName {
         match *self {
-            TransItem::Fn(instance) => symbol_names::symbol_name(instance, tcx),
+            TransItem::Fn(instance) => tcx.symbol_name(instance),
             TransItem::Static(node_id) => {
                 let def_id = tcx.hir.local_def_id(node_id);
-                symbol_names::symbol_name(Instance::mono(tcx, def_id), tcx)
+                tcx.symbol_name(Instance::mono(tcx, def_id))
             }
             TransItem::GlobalAsm(node_id) => {
                 let def_id = tcx.hir.local_def_id(node_id);
-                format!("global_asm_{:?}", def_id)
+                ty::SymbolName {
+                    name: Symbol::intern(&format!("global_asm_{:?}", def_id)).as_str()
+                }
             }
         }
     }
 
+    pub fn local_span(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Span> {
+        match *self {
+            TransItem::Fn(Instance { def, .. }) => {
+                tcx.hir.as_local_node_id(def.def_id())
+            }
+            TransItem::Static(node_id) |
+            TransItem::GlobalAsm(node_id) => {
+                Some(node_id)
+            }
+        }.map(|node_id| tcx.hir.span(node_id))
+    }
+
     pub fn instantiation_mode(&self,
                               tcx: TyCtxt<'a, 'tcx, 'tcx>)
                               -> InstantiationMode {