Skip to content

Commit 9fd4a82

Browse files
Binders have predicates now
1 parent aa6737a commit 9fd4a82

File tree

9 files changed

+94
-43
lines changed

9 files changed

+94
-43
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
707707
self_ty: Ty<'tcx>,
708708
bounds: &mut Bounds<'tcx>,
709709
speculative: bool,
710-
_binder_predicates: &'tcx ty::List<ty::Clause<'tcx>>,
710+
binder_predicates: &'tcx ty::List<ty::Clause<'tcx>>,
711711
only_self_bounds: OnlySelfBounds,
712712
) -> GenericArgCountResult {
713713
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
@@ -734,9 +734,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
734734

735735
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
736736

737-
let poly_trait_ref = ty::Binder::bind_with_vars(
737+
let poly_trait_ref = ty::Binder::bind_with_vars_and_predicates(
738738
ty::TraitRef::new(tcx, trait_def_id, generic_args),
739739
bound_vars,
740+
binder_predicates,
740741
);
741742

742743
debug!(?poly_trait_ref, ?assoc_bindings);

compiler/rustc_infer/src/infer/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,8 @@ impl<'tcx> InferCtxt<'tcx> {
14701470
where
14711471
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
14721472
{
1473+
assert_eq!(value.skip_binder_predicates(), ty::List::empty());
1474+
14731475
if let Some(inner) = value.no_bound_vars() {
14741476
return inner;
14751477
}

compiler/rustc_infer/src/infer/relate/higher_ranked.rs

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ impl<'tcx> InferCtxt<'tcx> {
7474
where
7575
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
7676
{
77+
assert_eq!(binder.skip_binder_predicates(), ty::List::empty());
78+
7779
if let Some(inner) = binder.no_bound_vars() {
7880
return inner;
7981
}

compiler/rustc_infer/src/infer/relate/nll.rs

+4
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ where
266266
where
267267
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
268268
{
269+
assert_eq!(binder.skip_binder_predicates(), ty::List::empty());
270+
269271
if let Some(inner) = binder.no_bound_vars() {
270272
return inner;
271273
}
@@ -314,6 +316,8 @@ where
314316
where
315317
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
316318
{
319+
assert_eq!(binder.skip_binder_predicates(), ty::List::empty());
320+
317321
if let Some(inner) = binder.no_bound_vars() {
318322
return inner;
319323
}

compiler/rustc_middle/src/ty/context.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,7 @@ nop_lift! {predicate; Clause<'a> => Clause<'tcx>}
13841384
nop_list_lift! {type_lists; Ty<'a> => Ty<'tcx>}
13851385
nop_list_lift! {poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>}
13861386
nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
1387+
nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>}
13871388

13881389
// This is the impl for `&'a GenericArgs<'a>`.
13891390
nop_list_lift! {args; GenericArg<'a> => GenericArg<'tcx>}

compiler/rustc_middle/src/ty/mod.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,8 @@ pub enum ImplSubject<'tcx> {
234234
Inherent(Ty<'tcx>),
235235
}
236236

237-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)]
238-
#[derive(TypeFoldable, TypeVisitable)]
237+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
238+
#[derive(HashStable, TypeFoldable, TypeVisitable, TyEncodable, TyDecodable)]
239239
pub enum ImplPolarity {
240240
/// `impl Trait for Type`
241241
Positive,
@@ -491,7 +491,7 @@ impl EarlyParamRegion {
491491
/// predicate which is emitted when a type is coerced to a trait object.
492492
///
493493
/// Use this rather than `PredicateKind`, whenever possible.
494-
#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable)]
494+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
495495
#[rustc_pass_by_value]
496496
pub struct Predicate<'tcx>(
497497
Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
@@ -591,7 +591,7 @@ impl rustc_errors::IntoDiagnosticArg for Clause<'_> {
591591
/// A subset of predicates which can be assumed by the trait solver. They show up in
592592
/// an item's where clauses, hence the name `Clause`, and may either be user-written
593593
/// (such as traits) or may be inserted during lowering.
594-
#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable)]
594+
#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
595595
#[rustc_pass_by_value]
596596
pub struct Clause<'tcx>(Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>);
597597

@@ -764,8 +764,8 @@ impl<'tcx> Clause<'tcx> {
764764
}
765765
}
766766

767-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
768-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
767+
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
768+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
769769
pub struct TraitPredicate<'tcx> {
770770
pub trait_ref: TraitRef<'tcx>,
771771

@@ -823,8 +823,8 @@ pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicat
823823
/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
824824
/// whether the `a` type is the type that we should label as "expected" when
825825
/// presenting user diagnostics.
826-
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
827-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
826+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
827+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
828828
pub struct SubtypePredicate<'tcx> {
829829
pub a_is_expected: bool,
830830
pub a: Ty<'tcx>,
@@ -833,8 +833,8 @@ pub struct SubtypePredicate<'tcx> {
833833
pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
834834

835835
/// Encodes that we have to coerce *from* the `a` type to the `b` type.
836-
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
837-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
836+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
837+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
838838
pub struct CoercePredicate<'tcx> {
839839
pub a: Ty<'tcx>,
840840
pub b: Ty<'tcx>,
@@ -1039,8 +1039,8 @@ impl From<ty::ConstVid> for TermVid {
10391039
/// equality between arbitrary types. Processing an instance of
10401040
/// Form #2 eventually yields one of these `ProjectionPredicate`
10411041
/// instances to normalize the LHS.
1042-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
1043-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
1042+
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1043+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
10441044
pub struct ProjectionPredicate<'tcx> {
10451045
pub projection_ty: AliasTy<'tcx>,
10461046
pub term: Term<'tcx>,
@@ -1102,8 +1102,8 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
11021102

11031103
/// Used by the new solver. Unlike a `ProjectionPredicate` this can only be
11041104
/// proven by actually normalizing `alias`.
1105-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
1106-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
1105+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1106+
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
11071107
pub struct NormalizesTo<'tcx> {
11081108
pub alias: AliasTy<'tcx>,
11091109
pub term: Term<'tcx>,

compiler/rustc_middle/src/ty/sty.rs

+45-16
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,7 @@ impl BoundVariableKind {
991991
pub struct Binder<'tcx, T> {
992992
value: T,
993993
bound_vars: &'tcx List<BoundVariableKind>,
994+
bound_predicates: &'tcx List<ty::Clause<'tcx>>,
994995
}
995996

996997
impl<'tcx, T> Binder<'tcx, T>
@@ -1007,19 +1008,36 @@ where
10071008
!value.has_escaping_bound_vars(),
10081009
"`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
10091010
);
1010-
Binder { value, bound_vars: ty::List::empty() }
1011+
Binder { value, bound_vars: ty::List::empty(), bound_predicates: ty::List::empty() }
10111012
}
10121013

10131014
pub fn bind_with_vars(value: T, bound_vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
10141015
if cfg!(debug_assertions) {
10151016
let mut validator = ValidateBoundVars::new(bound_vars);
10161017
value.visit_with(&mut validator);
10171018
}
1018-
Binder { value, bound_vars }
1019+
Binder { value, bound_vars, bound_predicates: ty::List::empty() }
1020+
}
1021+
1022+
pub fn bind_with_vars_and_predicates(
1023+
value: T,
1024+
bound_vars: &'tcx List<BoundVariableKind>,
1025+
bound_predicates: &'tcx List<ty::Clause<'tcx>>,
1026+
) -> Binder<'tcx, T> {
1027+
if cfg!(debug_assertions) {
1028+
let mut validator = ValidateBoundVars::new(bound_vars);
1029+
value.visit_with(&mut validator);
1030+
bound_predicates.visit_with(&mut validator);
1031+
}
1032+
Binder { value, bound_vars, bound_predicates }
10191033
}
10201034
}
10211035

10221036
impl<'tcx, T> Binder<'tcx, T> {
1037+
pub fn skip_binder_predicates(self) -> &'tcx List<ty::Clause<'tcx>> {
1038+
self.bound_predicates
1039+
}
1040+
10231041
/// Skips the binder and returns the "bound" value. This is a
10241042
/// risky thing to do because it's easy to get confused about
10251043
/// De Bruijn indices and the like. It is usually better to
@@ -1045,22 +1063,30 @@ impl<'tcx, T> Binder<'tcx, T> {
10451063
}
10461064

10471065
pub fn as_ref(&self) -> Binder<'tcx, &T> {
1048-
Binder { value: &self.value, bound_vars: self.bound_vars }
1066+
Binder {
1067+
value: &self.value,
1068+
bound_vars: self.bound_vars,
1069+
bound_predicates: self.bound_predicates,
1070+
}
10491071
}
10501072

10511073
pub fn as_deref(&self) -> Binder<'tcx, &T::Target>
10521074
where
10531075
T: Deref,
10541076
{
1055-
Binder { value: &self.value, bound_vars: self.bound_vars }
1077+
Binder {
1078+
value: &self.value,
1079+
bound_vars: self.bound_vars,
1080+
bound_predicates: self.bound_predicates,
1081+
}
10561082
}
10571083

10581084
pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
10591085
where
10601086
F: FnOnce(&T) -> U,
10611087
{
10621088
let value = f(&self.value);
1063-
Binder { value, bound_vars: self.bound_vars }
1089+
Binder { value, bound_vars: self.bound_vars, bound_predicates: self.bound_predicates }
10641090
}
10651091

10661092
pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
@@ -1074,13 +1100,13 @@ impl<'tcx, T> Binder<'tcx, T> {
10741100
where
10751101
F: FnOnce(T) -> U,
10761102
{
1077-
let Binder { value, bound_vars } = self;
1103+
let Binder { value, bound_vars, bound_predicates } = self;
10781104
let value = f(value);
10791105
if cfg!(debug_assertions) {
10801106
let mut validator = ValidateBoundVars::new(bound_vars);
10811107
value.visit_with(&mut validator);
10821108
}
1083-
Binder { value, bound_vars }
1109+
Binder { value, bound_vars, bound_predicates }
10841110
}
10851111

10861112
pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
@@ -1090,13 +1116,13 @@ impl<'tcx, T> Binder<'tcx, T> {
10901116
where
10911117
F: FnOnce(T) -> Result<U, E>,
10921118
{
1093-
let Binder { value, bound_vars } = self;
1119+
let Binder { value, bound_vars, bound_predicates } = self;
10941120
let value = f(value)?;
10951121
if cfg!(debug_assertions) {
10961122
let mut validator = ValidateBoundVars::new(bound_vars);
10971123
value.visit_with(&mut validator);
10981124
}
1099-
Ok(Binder { value, bound_vars })
1125+
Ok(Binder { value, bound_vars, bound_predicates })
11001126
}
11011127

11021128
/// Wraps a `value` in a binder, using the same bound variables as the
@@ -1112,7 +1138,7 @@ impl<'tcx, T> Binder<'tcx, T> {
11121138
where
11131139
U: TypeVisitable<TyCtxt<'tcx>>,
11141140
{
1115-
Binder::bind_with_vars(value, self.bound_vars)
1141+
Binder::bind_with_vars_and_predicates(value, self.bound_vars, self.bound_predicates)
11161142
}
11171143

11181144
/// Unwraps and returns the value within, but only if it contains
@@ -1142,23 +1168,26 @@ impl<'tcx, T> Binder<'tcx, T> {
11421168
where
11431169
F: FnOnce(T) -> (U, V),
11441170
{
1145-
let Binder { value, bound_vars } = self;
1171+
let Binder { value, bound_vars, bound_predicates } = self;
11461172
let (u, v) = f(value);
1147-
(Binder { value: u, bound_vars }, Binder { value: v, bound_vars })
1173+
(
1174+
Binder { value: u, bound_vars, bound_predicates },
1175+
Binder { value: v, bound_vars, bound_predicates },
1176+
)
11481177
}
11491178
}
11501179

11511180
impl<'tcx, T> Binder<'tcx, Option<T>> {
11521181
pub fn transpose(self) -> Option<Binder<'tcx, T>> {
1153-
let Binder { value, bound_vars } = self;
1154-
value.map(|value| Binder { value, bound_vars })
1182+
let Binder { value, bound_vars, bound_predicates } = self;
1183+
value.map(|value| Binder { value, bound_vars, bound_predicates })
11551184
}
11561185
}
11571186

11581187
impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
11591188
pub fn iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>> {
1160-
let Binder { value, bound_vars } = self;
1161-
value.into_iter().map(|value| Binder { value, bound_vars })
1189+
let Binder { value, bound_vars, bound_predicates } = self;
1190+
value.into_iter().map(|value| Binder { value, bound_vars, bound_predicates })
11621191
}
11631192
}
11641193

compiler/rustc_type_ir/src/interner.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@ pub trait Interner: Sized {
7070
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
7171

7272
// Predicates
73-
type Predicate: Copy + Debug + Hash + Eq;
74-
type TraitPredicate: Copy + Debug + Hash + Eq;
75-
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
76-
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
77-
type ProjectionPredicate: Copy + Debug + Hash + Eq;
78-
type NormalizesTo: Copy + Debug + Hash + Eq;
79-
type SubtypePredicate: Copy + Debug + Hash + Eq;
80-
type CoercePredicate: Copy + Debug + Hash + Eq;
81-
type ClosureKind: Copy + Debug + Hash + Eq;
73+
type Predicate: Copy + Debug + Hash + Ord;
74+
type TraitPredicate: Copy + Debug + Hash + Ord;
75+
type RegionOutlivesPredicate: Copy + Debug + Hash + Ord;
76+
type TypeOutlivesPredicate: Copy + Debug + Hash + Ord;
77+
type ProjectionPredicate: Copy + Debug + Hash + Ord;
78+
type NormalizesTo: Copy + Debug + Hash + Ord;
79+
type SubtypePredicate: Copy + Debug + Hash + Ord;
80+
type CoercePredicate: Copy + Debug + Hash + Ord;
81+
type ClosureKind: Copy + Debug + Hash + Ord;
8282

8383
fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
8484

compiler/rustc_type_ir/src/predicate_kind.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@ use crate::Interner;
88
/// A clause is something that can appear in where bounds or be inferred
99
/// by implied bounds.
1010
#[derive(derivative::Derivative)]
11-
#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))]
11+
#[derivative(
12+
Clone(bound = ""),
13+
Copy(bound = ""),
14+
Hash(bound = ""),
15+
PartialOrd(bound = ""),
16+
PartialOrd = "feature_allow_slow_enum",
17+
Ord(bound = ""),
18+
Ord = "feature_allow_slow_enum"
19+
)]
1220
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
1321
pub enum ClauseKind<I: Interner> {
1422
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
@@ -113,7 +121,11 @@ where
113121
Copy(bound = ""),
114122
Hash(bound = ""),
115123
PartialEq(bound = ""),
116-
Eq(bound = "")
124+
Eq(bound = ""),
125+
PartialOrd(bound = ""),
126+
PartialOrd = "feature_allow_slow_enum",
127+
Ord(bound = ""),
128+
Ord = "feature_allow_slow_enum"
117129
)]
118130
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
119131
pub enum PredicateKind<I: Interner> {

0 commit comments

Comments
 (0)