Make sure that projection bounds in ty::TraitObject are sorted in a way that is stable across compilation sessions and crate boundaries.
This commit is contained in:
parent
c87ba3f122
commit
5a881e920e
@ -1303,7 +1303,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
|
@ -1018,10 +1018,6 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
|
||||
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> {
|
||||
|
@ -23,7 +23,7 @@ use std::mem;
|
||||
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};
|
||||
|
||||
@ -440,12 +440,6 @@ pub struct ProjectionTy<'tcx> {
|
||||
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,
|
||||
@ -738,8 +732,17 @@ impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> {
|
||||
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>,
|
||||
|
@ -70,7 +70,11 @@ pub struct TraitDef<'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> {
|
||||
@ -78,7 +82,8 @@ 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,
|
||||
@ -90,6 +95,7 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,12 +385,14 @@ pub fn get_trait_def<'a, 'tcx>(cdata: Cmd,
|
||||
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,
|
||||
|
@ -1290,12 +1290,15 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
}
|
||||
}).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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user