@@ -1063,6 +1063,113 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
1063
1063
1064
1064
kind. hash_stable ( hcx, hasher) ;
1065
1065
}
1066
+
1067
+ pub fn kint ( self , tcx : TyCtxt < ' tcx > ) -> & ' tcx PredicateKint < ' tcx > {
1068
+ // I am efficient
1069
+ tcx. intern_predicate_kint ( match * self . kind ( ) {
1070
+ PredicateKind :: Trait ( binder, data) => {
1071
+ if let Some ( simpl) = binder. no_bound_vars ( ) {
1072
+ PredicateKint :: Trait ( simpl, data)
1073
+ } else {
1074
+ let inner = tcx
1075
+ . intern_predicate_kint ( PredicateKint :: Trait ( * binder. skip_binder ( ) , data) ) ;
1076
+ PredicateKint :: ForAll ( Binder :: bind ( inner) )
1077
+ }
1078
+ }
1079
+ PredicateKind :: RegionOutlives ( binder) => {
1080
+ if let Some ( simpl) = binder. no_bound_vars ( ) {
1081
+ PredicateKint :: RegionOutlives ( simpl)
1082
+ } else {
1083
+ let inner = tcx. intern_predicate_kint ( PredicateKint :: RegionOutlives (
1084
+ * binder. skip_binder ( ) ,
1085
+ ) ) ;
1086
+ PredicateKint :: ForAll ( Binder :: bind ( inner) )
1087
+ }
1088
+ }
1089
+ PredicateKind :: TypeOutlives ( binder) => {
1090
+ if let Some ( simpl) = binder. no_bound_vars ( ) {
1091
+ PredicateKint :: TypeOutlives ( simpl)
1092
+ } else {
1093
+ let inner = tcx
1094
+ . intern_predicate_kint ( PredicateKint :: TypeOutlives ( * binder. skip_binder ( ) ) ) ;
1095
+ PredicateKint :: ForAll ( Binder :: bind ( inner) )
1096
+ }
1097
+ }
1098
+ PredicateKind :: Projection ( binder) => {
1099
+ if let Some ( simpl) = binder. no_bound_vars ( ) {
1100
+ PredicateKint :: Projection ( simpl)
1101
+ } else {
1102
+ let inner =
1103
+ tcx. intern_predicate_kint ( PredicateKint :: Projection ( * binder. skip_binder ( ) ) ) ;
1104
+ PredicateKint :: ForAll ( Binder :: bind ( inner) )
1105
+ }
1106
+ }
1107
+ PredicateKind :: WellFormed ( arg) => PredicateKint :: WellFormed ( arg) ,
1108
+ PredicateKind :: ObjectSafe ( def_id) => PredicateKint :: ObjectSafe ( def_id) ,
1109
+ PredicateKind :: ClosureKind ( def_id, substs, kind) => {
1110
+ PredicateKint :: ClosureKind ( def_id, substs, kind)
1111
+ }
1112
+ PredicateKind :: Subtype ( binder) => {
1113
+ if let Some ( simpl) = binder. no_bound_vars ( ) {
1114
+ PredicateKint :: Subtype ( simpl)
1115
+ } else {
1116
+ let inner =
1117
+ tcx. intern_predicate_kint ( PredicateKint :: Subtype ( * binder. skip_binder ( ) ) ) ;
1118
+ PredicateKint :: ForAll ( Binder :: bind ( inner) )
1119
+ }
1120
+ }
1121
+ PredicateKind :: ConstEvaluatable ( def, substs) => {
1122
+ PredicateKint :: ConstEvaluatable ( def, substs)
1123
+ }
1124
+ PredicateKind :: ConstEquate ( l, r) => PredicateKint :: ConstEquate ( l, r) ,
1125
+ } )
1126
+ }
1127
+ }
1128
+
1129
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
1130
+ #[ derive( TypeFoldable ) ]
1131
+ pub enum PredicateKint < ' tcx > {
1132
+ /// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
1133
+ /// the `Self` type of the trait reference and `A`, `B`, and `C`
1134
+ /// would be the type parameters.
1135
+ ///
1136
+ /// A trait predicate will have `Constness::Const` if it originates
1137
+ /// from a bound on a `const fn` without the `?const` opt-out (e.g.,
1138
+ /// `const fn foobar<Foo: Bar>() {}`).
1139
+ Trait ( TraitPredicate < ' tcx > , Constness ) ,
1140
+
1141
+ /// `where 'a: 'b`
1142
+ RegionOutlives ( RegionOutlivesPredicate < ' tcx > ) ,
1143
+
1144
+ /// `where T: 'a`
1145
+ TypeOutlives ( TypeOutlivesPredicate < ' tcx > ) ,
1146
+
1147
+ /// `where <T as TraitRef>::Name == X`, approximately.
1148
+ /// See the `ProjectionPredicate` struct for details.
1149
+ Projection ( ProjectionPredicate < ' tcx > ) ,
1150
+
1151
+ /// No syntax: `T` well-formed.
1152
+ WellFormed ( GenericArg < ' tcx > ) ,
1153
+
1154
+ /// Trait must be object-safe.
1155
+ ObjectSafe ( DefId ) ,
1156
+
1157
+ /// No direct syntax. May be thought of as `where T: FnFoo<...>`
1158
+ /// for some substitutions `...` and `T` being a closure type.
1159
+ /// Satisfied (or refuted) once we know the closure's kind.
1160
+ ClosureKind ( DefId , SubstsRef < ' tcx > , ClosureKind ) ,
1161
+
1162
+ /// `T1 <: T2`
1163
+ Subtype ( SubtypePredicate < ' tcx > ) ,
1164
+
1165
+ /// Constant initializer must evaluate successfully.
1166
+ ConstEvaluatable ( DefId , SubstsRef < ' tcx > ) ,
1167
+
1168
+ /// Constants must be equal. The first component is the const that is expected.
1169
+ ConstEquate ( & ' tcx Const < ' tcx > , & ' tcx Const < ' tcx > ) ,
1170
+
1171
+ /// `for<'a>: ...`
1172
+ ForAll ( Binder < & ' tcx PredicateKint < ' tcx > > ) ,
1066
1173
}
1067
1174
1068
1175
#[ derive( Clone , Copy , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
@@ -1349,6 +1456,76 @@ impl ToPredicate<'tcx> for PredicateKind<'tcx> {
1349
1456
}
1350
1457
}
1351
1458
1459
+ impl ToPredicate < ' tcx > for PredicateKint < ' tcx > {
1460
+ #[ inline( always) ]
1461
+ fn to_predicate ( & self , tcx : TyCtxt < ' tcx > ) -> Predicate < ' tcx > {
1462
+ let ( predicate, in_binder) = if let PredicateKint :: ForAll ( binder) = self {
1463
+ ( * binder. skip_binder ( ) , true )
1464
+ } else {
1465
+ ( self , false )
1466
+ } ;
1467
+
1468
+ macro_rules! bind {
1469
+ ( $expr: expr) => {
1470
+ match $expr {
1471
+ expr => {
1472
+ if in_binder {
1473
+ Binder :: bind( expr)
1474
+ } else {
1475
+ Binder :: dummy( expr)
1476
+ }
1477
+ }
1478
+ }
1479
+ } ;
1480
+ }
1481
+
1482
+ match * predicate {
1483
+ PredicateKint :: ForAll ( _) => bug ! ( "unexpected PredicateKint: {:?}" , self ) ,
1484
+ PredicateKint :: Trait ( data, ct) => PredicateKind :: Trait ( bind ! ( data) , ct) ,
1485
+ PredicateKint :: RegionOutlives ( data) => PredicateKind :: RegionOutlives ( bind ! ( data) ) ,
1486
+ PredicateKint :: TypeOutlives ( data) => PredicateKind :: TypeOutlives ( bind ! ( data) ) ,
1487
+ PredicateKint :: Projection ( data) => PredicateKind :: Projection ( bind ! ( data) ) ,
1488
+ PredicateKint :: WellFormed ( arg) => {
1489
+ if in_binder {
1490
+ bug ! ( "unexpected ForAll: {:?}" , self )
1491
+ } else {
1492
+ PredicateKind :: WellFormed ( arg)
1493
+ }
1494
+ }
1495
+ PredicateKint :: ObjectSafe ( def_id) => {
1496
+ if in_binder {
1497
+ bug ! ( "unexpected ForAll: {:?}" , self )
1498
+ } else {
1499
+ PredicateKind :: ObjectSafe ( def_id)
1500
+ }
1501
+ }
1502
+ PredicateKint :: ClosureKind ( def_id, substs, kind) => {
1503
+ if in_binder {
1504
+ bug ! ( "unexpected ForAll: {:?}" , self )
1505
+ } else {
1506
+ PredicateKind :: ClosureKind ( def_id, substs, kind)
1507
+ }
1508
+ }
1509
+ PredicateKint :: Subtype ( data) => PredicateKind :: Subtype ( bind ! ( data) ) ,
1510
+ PredicateKint :: ConstEvaluatable ( def_id, substs) => {
1511
+ if in_binder {
1512
+ bug ! ( "unexpected ForAll: {:?}" , self )
1513
+ } else {
1514
+ PredicateKind :: ConstEvaluatable ( def_id, substs)
1515
+ }
1516
+ }
1517
+ PredicateKint :: ConstEquate ( l, r) => {
1518
+ if in_binder {
1519
+ bug ! ( "unexpected ForAll: {:?}" , self )
1520
+ } else {
1521
+ PredicateKind :: ConstEquate ( l, r)
1522
+ }
1523
+ }
1524
+ }
1525
+ . to_predicate ( tcx)
1526
+ }
1527
+ }
1528
+
1352
1529
impl < ' tcx > ToPredicate < ' tcx > for ConstnessAnd < TraitRef < ' tcx > > {
1353
1530
fn to_predicate ( self , tcx : TyCtxt < ' tcx > ) -> Predicate < ' tcx > {
1354
1531
ty:: PredicateKind :: Trait (
0 commit comments