Skip to content

Commit 104cb87

Browse files
committed
add PredicateKint, because who doesn't like bodging
1 parent 52d2c7a commit 104cb87

File tree

3 files changed

+200
-3
lines changed

3 files changed

+200
-3
lines changed

src/librustc_middle/ty/context.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::ty::TyKind::*;
1919
use crate::ty::{
2020
self, query, AdtDef, AdtKind, BindingMode, BoundVar, CanonicalPolyFnSig, Const, ConstVid,
2121
DefIdTree, ExistentialPredicate, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy,
22-
IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind,
22+
IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKint,
2323
ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar,
2424
TyVid, TypeAndMut,
2525
};
@@ -79,6 +79,7 @@ pub struct CtxtInterners<'tcx> {
7979
region: InternedSet<'tcx, RegionKind>,
8080
existential_predicates: InternedSet<'tcx, List<ExistentialPredicate<'tcx>>>,
8181
predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
82+
predicate_kint: InternedSet<'tcx, PredicateKint<'tcx>>,
8283
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
8384
projs: InternedSet<'tcx, List<ProjectionKind>>,
8485
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
@@ -98,11 +99,11 @@ impl<'tcx> CtxtInterners<'tcx> {
9899
existential_predicates: Default::default(),
99100
canonical_var_infos: Default::default(),
100101
predicate: Default::default(),
102+
predicate_kint: Default::default(),
101103
predicates: Default::default(),
102104
projs: Default::default(),
103105
place_elems: Default::default(),
104106
const_: Default::default(),
105-
106107
chalk_environment_clause_list: Default::default(),
107108
}
108109
}
@@ -1616,6 +1617,7 @@ nop_lift! {type_; Ty<'a> => Ty<'tcx>}
16161617
nop_lift! {region; Region<'a> => Region<'tcx>}
16171618
nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
16181619
nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
1620+
nop_lift! {predicate_kint; &'a PredicateKint<'a> => &'tcx PredicateKint<'tcx>}
16191621

16201622
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
16211623
nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
@@ -2034,6 +2036,12 @@ impl<'tcx> Borrow<PredicateKind<'tcx>> for Interned<'tcx, PredicateKind<'tcx>> {
20342036
}
20352037
}
20362038

2039+
impl<'tcx> Borrow<PredicateKint<'tcx>> for Interned<'tcx, PredicateKint<'tcx>> {
2040+
fn borrow<'a>(&'a self) -> &'a PredicateKint<'tcx> {
2041+
&self.0
2042+
}
2043+
}
2044+
20372045
macro_rules! direct_interners {
20382046
($($name:ident: $method:ident($ty:ty),)+) => {
20392047
$(impl<'tcx> PartialEq for Interned<'tcx, $ty> {
@@ -2063,6 +2071,7 @@ macro_rules! direct_interners {
20632071
direct_interners! {
20642072
region: mk_region(RegionKind),
20652073
const_: mk_const(Const<'tcx>),
2074+
predicate_kint: intern_predicate_kint(PredicateKint<'tcx>),
20662075
}
20672076

20682077
macro_rules! slice_interners {
@@ -2128,7 +2137,7 @@ impl<'tcx> TyCtxt<'tcx> {
21282137

21292138
#[allow(rustc::usage_of_ty_tykind)]
21302139
#[inline]
2131-
pub fn mk_ty(&self, st: TyKind<'tcx>) -> Ty<'tcx> {
2140+
pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> {
21322141
self.interners.intern_ty(st)
21332142
}
21342143

src/librustc_middle/ty/mod.rs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
13521529
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
13531530
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
13541531
ty::PredicateKind::Trait(

src/librustc_middle/ty/structural_impls.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,17 @@ impl<T: TypeVisitor<'tcx>> PredicateVisitor<'tcx> for T {
10281028
}
10291029
}
10301030

1031+
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::PredicateKint<'tcx> {
1032+
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
1033+
let new = ty::PredicateKint::super_fold_with(self, folder);
1034+
folder.tcx().intern_predicate_kint(new)
1035+
}
1036+
1037+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1038+
ty::PredicateKint::super_visit_with(self, visitor)
1039+
}
1040+
}
1041+
10311042
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
10321043
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
10331044
fold_list(*self, folder, |tcx, v| tcx.intern_predicates(v))

0 commit comments

Comments
 (0)