}
pub fn mk_trait(self, mut obj: TraitObject<'tcx>) -> Ty<'tcx> {
- obj.projection_bounds.sort_by(|a, b| a.sort_key().cmp(&b.sort_key()));
+ obj.projection_bounds.sort_by_key(|b| b.sort_key(self));
self.mk_ty(TyTrait(box obj))
}
pub fn item_name(&self) -> Name {
self.0.projection_ty.item_name // safe to skip the binder to access a name
}
-
- pub fn sort_key(&self) -> (DefId, Name) {
- self.0.projection_ty.sort_key()
- }
}
pub trait ToPolyTraitRef<'tcx> {
use std::ops;
use syntax::abi;
use syntax::ast::{self, Name};
-use syntax::parse::token::keywords;
+use syntax::parse::token::{keywords, InternedString};
use serialize::{Decodable, Decoder, Encodable, Encoder};
pub item_name: Name,
}
-impl<'tcx> ProjectionTy<'tcx> {
- pub fn sort_key(&self) -> (DefId, Name) {
- (self.trait_ref.def_id, self.item_name)
- }
-}
-
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct BareFnTy<'tcx> {
pub unsafety: hir::Unsafety,
self.0.item_name // safe to skip the binder to access a name
}
- pub fn sort_key(&self) -> (DefId, Name) {
- (self.0.trait_ref.def_id, self.0.item_name)
+ pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (u64, InternedString) {
+ // We want something here that is stable across crate boundaries.
+ // The DefId isn't but the `deterministic_hash` of the corresponding
+ // DefPath is.
+ let trait_def = tcx.lookup_trait_def(self.0.trait_ref.def_id);
+ let def_path_hash = trait_def.def_path_hash;
+
+ // An `ast::Name` is also not stable (it's just an index into an
+ // interning table), so map to the corresponding `InternedString`.
+ let item_name = self.0.item_name.as_str();
+ (def_path_hash, item_name)
}
pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
pub specialization_graph: RefCell<traits::specialization_graph::Graph>,
/// Various flags
- pub flags: Cell<TraitFlags>
+ pub flags: Cell<TraitFlags>,
+
+ /// The ICH of this trait's DefPath, cached here so it doesn't have to be
+ /// recomputed all the time.
+ pub def_path_hash: u64,
}
impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
paren_sugar: bool,
generics: &'tcx ty::Generics<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
- associated_type_names: Vec<Name>)
+ associated_type_names: Vec<Name>,
+ def_path_hash: u64)
-> TraitDef<'tcx> {
TraitDef {
paren_sugar: paren_sugar,
blanket_impls: RefCell::new(vec![]),
flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS),
specialization_graph: RefCell::new(traits::specialization_graph::Graph::new()),
+ def_path_hash: def_path_hash,
}
}
let unsafety = parse_unsafety(item_doc);
let associated_type_names = parse_associated_type_names(item_doc);
let paren_sugar = parse_paren_sugar(item_doc);
+ let def_path = def_path(cdata, item_id);
ty::TraitDef::new(unsafety,
paren_sugar,
generics,
item_trait_ref(item_doc, tcx, cdata),
- associated_type_names)
+ associated_type_names,
+ def_path.deterministic_hash(tcx))
}
pub fn get_adt_def<'a, 'tcx>(cdata: Cmd,
}
}).collect();
+ let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx);
+
let trait_ref = ty::TraitRef::new(def_id, substs);
let trait_def = ty::TraitDef::new(unsafety,
paren_sugar,
ty_generics,
trait_ref,
- associated_type_names);
+ associated_type_names,
+ def_path_hash);
tcx.intern_trait_def(trait_def)
}