Skip to content

Commit 93b8719

Browse files
Binders have predicates now
1 parent 53cc20f commit 93b8719

File tree

6 files changed

+73
-35
lines changed

6 files changed

+73
-35
lines changed

Diff for: compiler/rustc_hir_analysis/src/astconv/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
687687
args: &GenericArgs<'_>,
688688
infer_args: bool,
689689
self_ty: Ty<'tcx>,
690-
_binder_predicates: &'tcx ty::List<ty::Clause<'tcx>>,
690+
binder_predicates: &'tcx ty::List<ty::Clause<'tcx>>,
691691
only_self_bounds: OnlySelfBounds,
692692
) -> GenericArgCountResult {
693693
let (generic_args, arg_count) = self.create_args_for_ast_path(
@@ -707,9 +707,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
707707

708708
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
709709

710-
let poly_trait_ref = ty::Binder::bind_with_vars(
710+
let poly_trait_ref = ty::Binder::bind_with_vars_and_predicates(
711711
ty::TraitRef::new(tcx, trait_def_id, generic_args),
712712
bound_vars,
713+
binder_predicates,
713714
);
714715

715716
debug!(?poly_trait_ref, ?assoc_bindings);

Diff for: compiler/rustc_infer/src/infer/higher_ranked/mod.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
}

Diff for: compiler/rustc_infer/src/infer/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,8 @@ impl<'tcx> InferCtxt<'tcx> {
14461446
where
14471447
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
14481448
{
1449+
assert_eq!(value.skip_binder_predicates(), ty::List::empty());
1450+
14491451
if let Some(inner) = value.no_bound_vars() {
14501452
return inner;
14511453
}

Diff for: compiler/rustc_infer/src/infer/nll_relate/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ where
263263
where
264264
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
265265
{
266+
assert_eq!(binder.skip_binder_predicates(), ty::List::empty());
267+
266268
if let Some(inner) = binder.no_bound_vars() {
267269
return inner;
268270
}
@@ -311,6 +313,8 @@ where
311313
where
312314
T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
313315
{
316+
assert_eq!(binder.skip_binder_predicates(), ty::List::empty());
317+
314318
if let Some(inner) = binder.no_bound_vars() {
315319
return inner;
316320
}

Diff for: compiler/rustc_middle/src/ty/mod.rs

+17-17
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ pub enum ImplSubject<'tcx> {
244244
Inherent(Ty<'tcx>),
245245
}
246246

247-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)]
248-
#[derive(TypeFoldable, TypeVisitable)]
247+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
248+
#[derive(HashStable, TypeFoldable, TypeVisitable, TyEncodable, TyDecodable)]
249249
pub enum ImplPolarity {
250250
/// `impl Trait for Type`
251251
Positive,
@@ -573,7 +573,7 @@ impl rustc_errors::IntoDiagnosticArg for Clause<'_> {
573573
/// A subset of predicates which can be assumed by the trait solver. They show up in
574574
/// an item's where clauses, hence the name `Clause`, and may either be user-written
575575
/// (such as traits) or may be inserted during lowering.
576-
#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable)]
576+
#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
577577
#[rustc_pass_by_value]
578578
pub struct Clause<'tcx>(Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>);
579579

@@ -626,8 +626,8 @@ impl<'tcx> Clause<'tcx> {
626626
}
627627
}
628628

629-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
630-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
629+
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
630+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
631631
/// A clause is something that can appear in where bounds or be inferred
632632
/// by implied bounds.
633633
pub enum ClauseKind<'tcx> {
@@ -657,8 +657,8 @@ pub enum ClauseKind<'tcx> {
657657
ConstEvaluatable(ty::Const<'tcx>),
658658
}
659659

660-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
661-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
660+
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
661+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
662662
pub enum PredicateKind<'tcx> {
663663
/// Prove a clause
664664
Clause(ClauseKind<'tcx>),
@@ -702,8 +702,8 @@ pub enum PredicateKind<'tcx> {
702702
AliasRelate(Term<'tcx>, Term<'tcx>, AliasRelationDirection),
703703
}
704704

705-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
706-
#[derive(HashStable, Debug)]
705+
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
706+
#[derive(HashStable, Debug, TyEncodable, TyDecodable)]
707707
pub enum AliasRelationDirection {
708708
Equate,
709709
Subtype,
@@ -838,8 +838,8 @@ impl<'tcx> Clause<'tcx> {
838838
}
839839
}
840840

841-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
842-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
841+
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
842+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
843843
pub struct TraitPredicate<'tcx> {
844844
pub trait_ref: TraitRef<'tcx>,
845845

@@ -897,8 +897,8 @@ pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicat
897897
/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
898898
/// whether the `a` type is the type that we should label as "expected" when
899899
/// presenting user diagnostics.
900-
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
901-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
900+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
901+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
902902
pub struct SubtypePredicate<'tcx> {
903903
pub a_is_expected: bool,
904904
pub a: Ty<'tcx>,
@@ -907,8 +907,8 @@ pub struct SubtypePredicate<'tcx> {
907907
pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
908908

909909
/// Encodes that we have to coerce *from* the `a` type to the `b` type.
910-
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
911-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
910+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
911+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
912912
pub struct CoercePredicate<'tcx> {
913913
pub a: Ty<'tcx>,
914914
pub b: Ty<'tcx>,
@@ -1113,8 +1113,8 @@ impl<'tcx> From<ty::ConstVid<'tcx>> for TermVid<'tcx> {
11131113
/// equality between arbitrary types. Processing an instance of
11141114
/// Form #2 eventually yields one of these `ProjectionPredicate`
11151115
/// instances to normalize the LHS.
1116-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
1117-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
1116+
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1117+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
11181118
pub struct ProjectionPredicate<'tcx> {
11191119
pub projection_ty: AliasTy<'tcx>,
11201120
pub term: Term<'tcx>,

Diff for: compiler/rustc_middle/src/ty/sty.rs

+45-16
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,7 @@ impl BoundVariableKind {
10001000
pub struct Binder<'tcx, T> {
10011001
value: T,
10021002
bound_vars: &'tcx List<BoundVariableKind>,
1003+
bound_predicates: &'tcx List<ty::Clause<'tcx>>,
10031004
}
10041005

10051006
impl<'tcx, T> Binder<'tcx, T>
@@ -1016,19 +1017,36 @@ where
10161017
!value.has_escaping_bound_vars(),
10171018
"`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
10181019
);
1019-
Binder { value, bound_vars: ty::List::empty() }
1020+
Binder { value, bound_vars: ty::List::empty(), bound_predicates: ty::List::empty() }
10201021
}
10211022

10221023
pub fn bind_with_vars(value: T, bound_vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
10231024
if cfg!(debug_assertions) {
10241025
let mut validator = ValidateBoundVars::new(bound_vars);
10251026
value.visit_with(&mut validator);
10261027
}
1027-
Binder { value, bound_vars }
1028+
Binder { value, bound_vars, bound_predicates: ty::List::empty() }
1029+
}
1030+
1031+
pub fn bind_with_vars_and_predicates(
1032+
value: T,
1033+
bound_vars: &'tcx List<BoundVariableKind>,
1034+
bound_predicates: &'tcx List<ty::Clause<'tcx>>,
1035+
) -> Binder<'tcx, T> {
1036+
if cfg!(debug_assertions) {
1037+
let mut validator = ValidateBoundVars::new(bound_vars);
1038+
value.visit_with(&mut validator);
1039+
bound_predicates.visit_with(&mut validator);
1040+
}
1041+
Binder { value, bound_vars, bound_predicates }
10281042
}
10291043
}
10301044

10311045
impl<'tcx, T> Binder<'tcx, T> {
1046+
pub fn skip_binder_predicates(self) -> &'tcx List<ty::Clause<'tcx>> {
1047+
self.bound_predicates
1048+
}
1049+
10321050
/// Skips the binder and returns the "bound" value. This is a
10331051
/// risky thing to do because it's easy to get confused about
10341052
/// De Bruijn indices and the like. It is usually better to
@@ -1054,22 +1072,30 @@ impl<'tcx, T> Binder<'tcx, T> {
10541072
}
10551073

10561074
pub fn as_ref(&self) -> Binder<'tcx, &T> {
1057-
Binder { value: &self.value, bound_vars: self.bound_vars }
1075+
Binder {
1076+
value: &self.value,
1077+
bound_vars: self.bound_vars,
1078+
bound_predicates: self.bound_predicates,
1079+
}
10581080
}
10591081

10601082
pub fn as_deref(&self) -> Binder<'tcx, &T::Target>
10611083
where
10621084
T: Deref,
10631085
{
1064-
Binder { value: &self.value, bound_vars: self.bound_vars }
1086+
Binder {
1087+
value: &self.value,
1088+
bound_vars: self.bound_vars,
1089+
bound_predicates: self.bound_predicates,
1090+
}
10651091
}
10661092

10671093
pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
10681094
where
10691095
F: FnOnce(&T) -> U,
10701096
{
10711097
let value = f(&self.value);
1072-
Binder { value, bound_vars: self.bound_vars }
1098+
Binder { value, bound_vars: self.bound_vars, bound_predicates: self.bound_predicates }
10731099
}
10741100

10751101
pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
@@ -1083,13 +1109,13 @@ impl<'tcx, T> Binder<'tcx, T> {
10831109
where
10841110
F: FnOnce(T) -> U,
10851111
{
1086-
let Binder { value, bound_vars } = self;
1112+
let Binder { value, bound_vars, bound_predicates } = self;
10871113
let value = f(value);
10881114
if cfg!(debug_assertions) {
10891115
let mut validator = ValidateBoundVars::new(bound_vars);
10901116
value.visit_with(&mut validator);
10911117
}
1092-
Binder { value, bound_vars }
1118+
Binder { value, bound_vars, bound_predicates }
10931119
}
10941120

10951121
pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
@@ -1099,13 +1125,13 @@ impl<'tcx, T> Binder<'tcx, T> {
10991125
where
11001126
F: FnOnce(T) -> Result<U, E>,
11011127
{
1102-
let Binder { value, bound_vars } = self;
1128+
let Binder { value, bound_vars, bound_predicates } = self;
11031129
let value = f(value)?;
11041130
if cfg!(debug_assertions) {
11051131
let mut validator = ValidateBoundVars::new(bound_vars);
11061132
value.visit_with(&mut validator);
11071133
}
1108-
Ok(Binder { value, bound_vars })
1134+
Ok(Binder { value, bound_vars, bound_predicates })
11091135
}
11101136

11111137
/// Wraps a `value` in a binder, using the same bound variables as the
@@ -1121,7 +1147,7 @@ impl<'tcx, T> Binder<'tcx, T> {
11211147
where
11221148
U: TypeVisitable<TyCtxt<'tcx>>,
11231149
{
1124-
Binder::bind_with_vars(value, self.bound_vars)
1150+
Binder::bind_with_vars_and_predicates(value, self.bound_vars, self.bound_predicates)
11251151
}
11261152

11271153
/// Unwraps and returns the value within, but only if it contains
@@ -1151,23 +1177,26 @@ impl<'tcx, T> Binder<'tcx, T> {
11511177
where
11521178
F: FnOnce(T) -> (U, V),
11531179
{
1154-
let Binder { value, bound_vars } = self;
1180+
let Binder { value, bound_vars, bound_predicates } = self;
11551181
let (u, v) = f(value);
1156-
(Binder { value: u, bound_vars }, Binder { value: v, bound_vars })
1182+
(
1183+
Binder { value: u, bound_vars, bound_predicates },
1184+
Binder { value: v, bound_vars, bound_predicates },
1185+
)
11571186
}
11581187
}
11591188

11601189
impl<'tcx, T> Binder<'tcx, Option<T>> {
11611190
pub fn transpose(self) -> Option<Binder<'tcx, T>> {
1162-
let Binder { value, bound_vars } = self;
1163-
value.map(|value| Binder { value, bound_vars })
1191+
let Binder { value, bound_vars, bound_predicates } = self;
1192+
value.map(|value| Binder { value, bound_vars, bound_predicates })
11641193
}
11651194
}
11661195

11671196
impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
11681197
pub fn iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>> {
1169-
let Binder { value, bound_vars } = self;
1170-
value.into_iter().map(|value| Binder { value, bound_vars })
1198+
let Binder { value, bound_vars, bound_predicates } = self;
1199+
value.into_iter().map(|value| Binder { value, bound_vars, bound_predicates })
11711200
}
11721201
}
11731202

0 commit comments

Comments
 (0)