Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
assert previously implicit invariants in stable_cmp
  • Loading branch information
lcnr committed Sep 18, 2020
commit 9818bda28897745da792817fd41d0cd70efbcacb
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2420,7 +2420,7 @@ impl<'tcx> TyCtxt<'tcx> {
) -> &'tcx List<ExistentialPredicate<'tcx>> {
assert!(!eps.is_empty());
// Do not allow duplicate existential predicates.
assert!(eps.windows(2).all(|w| w[0].stable_cmp(self, &w[1]) == Ordering::Less));
assert!(eps.windows(2).all(|w| w[0].stable_cmp(self, w[1]) == Ordering::Less));
self._intern_existential_predicates(eps)
}

Expand Down
29 changes: 21 additions & 8 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustc_hir::def_id::DefId;
use rustc_index::vec::Idx;
use rustc_macros::HashStable;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::DUMMY_SP;
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi;
use std::borrow::Cow;
Expand Down Expand Up @@ -672,22 +673,34 @@ pub enum ExistentialPredicate<'tcx> {
impl<'tcx> ExistentialPredicate<'tcx> {
/// Compares via an ordering that will not change if modules are reordered or other changes are
/// made to the tree. In particular, this ordering is preserved across incremental compilations.
pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
pub fn stable_cmp(self, tcx: TyCtxt<'tcx>, other: Self) -> Ordering {
use self::ExistentialPredicate::*;
// Note that we only call this method after checking that the
// given predicates represent a valid trait object.
//
// This means that we have at most one `ExistentialPredicate::Trait`
// and at most one `ExistentialPredicate::Projection` for each associated item.
// We therefore do not have to worry about the ordering for cases which
// are not well formed.
match (*self, *other) {
(Trait(_), Trait(_)) => Ordering::Equal,
(Projection(ref a), Projection(ref b)) => {
match (self, other) {
(Trait(a), Trait(b)) => {
if a != b {
tcx.sess.delay_span_bug(
DUMMY_SP,
&format!("unexpected existential predicates: {:?}, {:?}", a, b),
);
}
Ordering::Equal
}
(Projection(a), Projection(b)) => {
if a.item_def_id == b.item_def_id && a != b {
tcx.sess.delay_span_bug(
DUMMY_SP,
&format!("unexpected existential predicates: {:?}, {:?}", a, b),
);
}
tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id))
}
(AutoTrait(ref a), AutoTrait(ref b)) => {
tcx.trait_def(*a).def_path_hash.cmp(&tcx.trait_def(*b).def_path_hash)
(AutoTrait(a), AutoTrait(b)) => {
tcx.trait_def(a).def_path_hash.cmp(&tcx.trait_def(b).def_path_hash)
}
(Trait(_), _) => Ordering::Less,
(Projection(_), Trait(_)) => Ordering::Greater,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1192,8 +1192,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.map(|x| ty::ExistentialPredicate::Projection(x.skip_binder())),
)
.collect::<SmallVec<[_; 8]>>();
v.sort_by(|a, b| a.stable_cmp(tcx, b));
v.dedup_by(|a, b| a.stable_cmp(tcx, b) == Ordering::Equal);
v.sort_by(|&a, &b| a.stable_cmp(tcx, b));
v.dedup_by(|&mut a, &mut b| a.stable_cmp(tcx, b) == Ordering::Equal);
let existential_predicates = ty::Binder::bind(tcx.mk_existential_predicates(v.into_iter()));

// Use explicitly-specified region bound.
Expand Down