// utility functions
fn metadata_filename(&self) -> &str;
fn metadata_section_name(&self, target: &Target) -> &str;
- fn encode_type<'a>(&self,
- tcx: TyCtxt<'a, 'tcx, 'tcx>,
- ty: Ty<'tcx>,
- def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
- -> Vec<u8>;
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>;
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
// utility functions
fn metadata_filename(&self) -> &str { bug!("metadata_filename") }
fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") }
- fn encode_type<'a>(&self,
- tcx: TyCtxt<'a, 'tcx, 'tcx>,
- ty: Ty<'tcx>,
- def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
- -> Vec<u8> {
- bug!("encode_type")
- }
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
{ vec![] }
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
/// Creates a hash of the type `Ty` which will be the same no matter what crate
/// context it's calculated within. This is used by the `type_id` intrinsic.
pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 {
- let mut hasher = TypeIdHasher {
- tcx: self,
- state: SipHasher::new()
- };
+ let mut hasher = TypeIdHasher::new(self, SipHasher::new());
hasher.visit_ty(ty);
- hasher.state.finish()
+ hasher.finish()
}
/// Returns true if this ADT is a dtorck type.
}
}
-struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
+pub struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a, H> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
- state: SipHasher
+ state: H
}
-impl<'a, 'gcx, 'tcx> TypeIdHasher<'a, 'gcx, 'tcx> {
- fn hash<T: Hash>(&mut self, x: T) {
+impl<'a, 'gcx, 'tcx, H: Hasher> TypeIdHasher<'a, 'gcx, 'tcx, H> {
+ pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, state: H) -> Self {
+ TypeIdHasher {
+ tcx: tcx,
+ state: state
+ }
+ }
+
+ pub fn hash<T: Hash>(&mut self, x: T) {
x.hash(&mut self.state);
}
+ pub fn finish(self) -> u64 {
+ self.state.finish()
+ }
+
fn hash_discriminant_u8<T>(&mut self, x: &T) {
let v = unsafe {
intrinsics::discriminant_value(x)
}
}
-impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> {
+impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, H> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
// Distinguish between the Ty variants uniformly.
self.hash_discriminant_u8(&ty.sty);
{
loader::meta_section_name(target)
}
- fn encode_type<'a>(&self,
- tcx: TyCtxt<'a, 'tcx, 'tcx>,
- ty: Ty<'tcx>,
- def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
- -> Vec<u8>
- {
- encoder::encoded_ty(tcx, ty, def_id_to_string)
- }
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, Option<PathBuf>)>
{
use rustc::util::nodemap::{FnvHashMap, NodeSet};
use rustc_serialize::{Encodable, SpecializedEncoder};
-use std::cell::RefCell;
use std::io::prelude::*;
-use std::io::{Cursor, SeekFrom};
+use std::io::SeekFrom;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use std::u32;
println!(" total bytes: {}", stats.total_bytes);
}
}
-
-// Get the encoded string for a type
-pub fn encoded_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- t: Ty<'tcx>,
- def_id_to_string: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String)
- -> Vec<u8> {
- let mut wr = Cursor::new(Vec::new());
- tyencode::enc_ty(&mut wr, &tyencode::ctxt {
- ds: def_id_to_string,
- tcx: tcx,
- abbrevs: &RefCell::new(FnvHashMap())
- }, t);
- wr.into_inner()
-}
use util::sha2::{Digest, Sha256};
use rustc::middle::weak_lang_items;
-use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::def_id::LOCAL_CRATE;
use rustc::hir::map as hir_map;
-use rustc::ty::{Ty, TyCtxt, TypeFoldable};
+use rustc::ty::{self, Ty, TypeFoldable};
+use rustc::ty::fold::TypeVisitor;
use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
use rustc::ty::subst::Substs;
use rustc::hir::map::definitions::{DefPath, DefPathData};
use syntax::parse::token::{self, InternedString};
use serialize::hex::ToHex;
-pub fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> String {
- let def_path = tcx.def_path(def_id);
- def_path.to_string(tcx)
+use std::hash::Hasher;
+
+struct Sha256Hasher<'a>(&'a mut Sha256);
+
+impl<'a> Hasher for Sha256Hasher<'a> {
+ fn write(&mut self, msg: &[u8]) {
+ self.0.input(msg)
+ }
+
+ fn finish(&self) -> u64 {
+ bug!("Sha256Hasher::finish should not be called");
+ }
}
fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
// values for generic type parameters,
// if any.
- substs: Option<&Substs<'tcx>>)
+ substs: Option<&'tcx Substs<'tcx>>)
-> String {
debug!("get_symbol_hash(def_path={:?}, parameters={:?})",
def_path, substs);
let tcx = scx.tcx();
- return record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
- let mut hash_state = scx.symbol_hasher().borrow_mut();
-
+ let mut hash_state = scx.symbol_hasher().borrow_mut();
+ record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
hash_state.reset();
+ let mut hasher = ty::util::TypeIdHasher::new(tcx, Sha256Hasher(&mut hash_state));
// the main symbol name is not necessarily unique; hash in the
// compiler's internal def-path, guaranteeing each symbol has a
// truly unique path
- hash_state.input_str(&def_path.to_string(tcx));
+ hasher.hash(def_path.to_string(tcx));
// Include the main item-type. Note that, in this case, the
// assertions about `needs_subst` may not hold, but this item-type
// ought to be the same for every reference anyway.
assert!(!item_type.has_erasable_regions());
- let encoded_item_type = tcx.sess.cstore.encode_type(tcx, item_type, def_id_to_string);
- hash_state.input(&encoded_item_type[..]);
+ hasher.visit_ty(item_type);
// also include any type parameters (for generic items)
if let Some(substs) = substs {
- for t in substs.types() {
- assert!(!t.has_erasable_regions());
- assert!(!t.needs_subst());
- let encoded_type = tcx.sess.cstore.encode_type(tcx, t, def_id_to_string);
- hash_state.input(&encoded_type[..]);
- }
+ assert!(!substs.has_erasable_regions());
+ assert!(!substs.needs_subst());
+ substs.visit_with(&mut hasher);
}
-
- format!("h{}", truncated_hash_result(&mut *hash_state))
});
-
fn truncated_hash_result(symbol_hasher: &mut Sha256) -> String {
let output = symbol_hasher.result_bytes();
// 64 bits should be enough to avoid collisions.
output[.. 8].to_hex()
}
+
+ format!("h{}", truncated_hash_result(&mut hash_state))
}
impl<'a, 'tcx> Instance<'tcx> {