@@ -1063,6 +1063,113 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
10631063
10641064 kind. hash_stable ( hcx, hasher) ;
10651065 }
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 > > ) ,
10661173}
10671174
10681175#[ derive( Clone , Copy , PartialEq , Eq , Hash , RustcEncodable , RustcDecodable ) ]
@@ -1349,6 +1456,76 @@ impl ToPredicate<'tcx> for PredicateKind<'tcx> {
13491456 }
13501457}
13511458
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+
13521529impl < ' tcx > ToPredicate < ' tcx > for ConstnessAnd < TraitRef < ' tcx > > {
13531530 fn to_predicate ( self , tcx : TyCtxt < ' tcx > ) -> Predicate < ' tcx > {
13541531 ty:: PredicateKind :: Trait (
0 commit comments