Skip to content

Commit 9818bda

Browse files
committed
assert previously implicit invariants in stable_cmp
1 parent 7d12e5f commit 9818bda

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

compiler/rustc_middle/src/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2420,7 +2420,7 @@ impl<'tcx> TyCtxt<'tcx> {
24202420
) -> &'tcx List<ExistentialPredicate<'tcx>> {
24212421
assert!(!eps.is_empty());
24222422
// Do not allow duplicate existential predicates.
2423-
assert!(eps.windows(2).all(|w| w[0].stable_cmp(self, &w[1]) == Ordering::Less));
2423+
assert!(eps.windows(2).all(|w| w[0].stable_cmp(self, w[1]) == Ordering::Less));
24242424
self._intern_existential_predicates(eps)
24252425
}
24262426

compiler/rustc_middle/src/ty/sty.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc_hir::def_id::DefId;
1919
use rustc_index::vec::Idx;
2020
use rustc_macros::HashStable;
2121
use rustc_span::symbol::{kw, Ident, Symbol};
22+
use rustc_span::DUMMY_SP;
2223
use rustc_target::abi::VariantIdx;
2324
use rustc_target::spec::abi;
2425
use std::borrow::Cow;
@@ -672,22 +673,34 @@ pub enum ExistentialPredicate<'tcx> {
672673
impl<'tcx> ExistentialPredicate<'tcx> {
673674
/// Compares via an ordering that will not change if modules are reordered or other changes are
674675
/// made to the tree. In particular, this ordering is preserved across incremental compilations.
675-
pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
676+
pub fn stable_cmp(self, tcx: TyCtxt<'tcx>, other: Self) -> Ordering {
676677
use self::ExistentialPredicate::*;
677678
// Note that we only call this method after checking that the
678679
// given predicates represent a valid trait object.
679680
//
680681
// This means that we have at most one `ExistentialPredicate::Trait`
681682
// and at most one `ExistentialPredicate::Projection` for each associated item.
682-
// We therefore do not have to worry about the ordering for cases which
683-
// are not well formed.
684-
match (*self, *other) {
685-
(Trait(_), Trait(_)) => Ordering::Equal,
686-
(Projection(ref a), Projection(ref b)) => {
683+
match (self, other) {
684+
(Trait(a), Trait(b)) => {
685+
if a != b {
686+
tcx.sess.delay_span_bug(
687+
DUMMY_SP,
688+
&format!("unexpected existential predicates: {:?}, {:?}", a, b),
689+
);
690+
}
691+
Ordering::Equal
692+
}
693+
(Projection(a), Projection(b)) => {
694+
if a.item_def_id == b.item_def_id && a != b {
695+
tcx.sess.delay_span_bug(
696+
DUMMY_SP,
697+
&format!("unexpected existential predicates: {:?}, {:?}", a, b),
698+
);
699+
}
687700
tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id))
688701
}
689-
(AutoTrait(ref a), AutoTrait(ref b)) => {
690-
tcx.trait_def(*a).def_path_hash.cmp(&tcx.trait_def(*b).def_path_hash)
702+
(AutoTrait(a), AutoTrait(b)) => {
703+
tcx.trait_def(a).def_path_hash.cmp(&tcx.trait_def(b).def_path_hash)
691704
}
692705
(Trait(_), _) => Ordering::Less,
693706
(Projection(_), Trait(_)) => Ordering::Greater,

compiler/rustc_typeck/src/astconv/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1192,8 +1192,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11921192
.map(|x| ty::ExistentialPredicate::Projection(x.skip_binder())),
11931193
)
11941194
.collect::<SmallVec<[_; 8]>>();
1195-
v.sort_by(|a, b| a.stable_cmp(tcx, b));
1196-
v.dedup_by(|a, b| a.stable_cmp(tcx, b) == Ordering::Equal);
1195+
v.sort_by(|&a, &b| a.stable_cmp(tcx, b));
1196+
v.dedup_by(|&mut a, &mut b| a.stable_cmp(tcx, b) == Ordering::Equal);
11971197
let existential_predicates = ty::Binder::bind(tcx.mk_existential_predicates(v.into_iter()));
11981198

11991199
// Use explicitly-specified region bound.

0 commit comments

Comments
 (0)