Skip to content

Commit 9463863

Browse files
Binders have predicates now
1 parent ccff1b2 commit 9463863

File tree

6 files changed

+73
-35
lines changed

6 files changed

+73
-35
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

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

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

711-
let poly_trait_ref = ty::Binder::bind_with_vars(
711+
let poly_trait_ref = ty::Binder::bind_with_vars_and_predicates(
712712
ty::TraitRef::new(tcx, trait_def_id, generic_args),
713713
bound_vars,
714+
binder_predicates,
714715
);
715716

716717
debug!(?poly_trait_ref, ?assoc_bindings);

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
}

compiler/rustc_infer/src/infer/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,8 @@ impl<'tcx> InferCtxt<'tcx> {
14011401
where
14021402
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
14031403
{
1404+
assert_eq!(value.skip_binder_predicates(), ty::List::empty());
1405+
14041406
if let Some(inner) = value.no_bound_vars() {
14051407
return inner;
14061408
}

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
}

compiler/rustc_middle/src/ty/mod.rs

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

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

@@ -614,8 +614,8 @@ impl<'tcx> Clause<'tcx> {
614614
}
615615
}
616616

617-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
618-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
617+
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
618+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
619619
/// A clause is something that can appear in where bounds or be inferred
620620
/// by implied bounds.
621621
pub enum ClauseKind<'tcx> {
@@ -645,8 +645,8 @@ pub enum ClauseKind<'tcx> {
645645
ConstEvaluatable(ty::Const<'tcx>),
646646
}
647647

648-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
649-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
648+
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
649+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
650650
pub enum PredicateKind<'tcx> {
651651
/// Prove a clause
652652
Clause(ClauseKind<'tcx>),
@@ -690,8 +690,8 @@ pub enum PredicateKind<'tcx> {
690690
AliasRelate(Term<'tcx>, Term<'tcx>, AliasRelationDirection),
691691
}
692692

693-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
694-
#[derive(HashStable, Debug)]
693+
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
694+
#[derive(HashStable, Debug, TyEncodable, TyDecodable)]
695695
pub enum AliasRelationDirection {
696696
Equate,
697697
Subtype,
@@ -826,8 +826,8 @@ impl<'tcx> Clause<'tcx> {
826826
}
827827
}
828828

829-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
830-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
829+
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
830+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
831831
pub struct TraitPredicate<'tcx> {
832832
pub trait_ref: TraitRef<'tcx>,
833833

@@ -885,8 +885,8 @@ pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicat
885885
/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
886886
/// whether the `a` type is the type that we should label as "expected" when
887887
/// presenting user diagnostics.
888-
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
889-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
888+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
889+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
890890
pub struct SubtypePredicate<'tcx> {
891891
pub a_is_expected: bool,
892892
pub a: Ty<'tcx>,
@@ -895,8 +895,8 @@ pub struct SubtypePredicate<'tcx> {
895895
pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
896896

897897
/// Encodes that we have to coerce *from* the `a` type to the `b` type.
898-
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
899-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
898+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
899+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
900900
pub struct CoercePredicate<'tcx> {
901901
pub a: Ty<'tcx>,
902902
pub b: Ty<'tcx>,
@@ -1101,8 +1101,8 @@ impl<'tcx> From<ty::ConstVid<'tcx>> for TermVid<'tcx> {
11011101
/// equality between arbitrary types. Processing an instance of
11021102
/// Form #2 eventually yields one of these `ProjectionPredicate`
11031103
/// instances to normalize the LHS.
1104-
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
1105-
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
1104+
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1105+
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)]
11061106
pub struct ProjectionPredicate<'tcx> {
11071107
pub projection_ty: AliasTy<'tcx>,
11081108
pub term: Term<'tcx>,

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)