add PredicateKint
, because who doesn't like bodging
This commit is contained in:
parent
52d2c7ac94
commit
104cb878e3
@ -19,7 +19,7 @@ use crate::ty::TyKind::*;
|
||||
use crate::ty::{
|
||||
self, query, AdtDef, AdtKind, BindingMode, BoundVar, CanonicalPolyFnSig, Const, ConstVid,
|
||||
DefIdTree, ExistentialPredicate, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy,
|
||||
IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKind,
|
||||
IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateInner, PredicateKint,
|
||||
ProjectionTy, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar,
|
||||
TyVid, TypeAndMut,
|
||||
};
|
||||
@ -79,6 +79,7 @@ pub struct CtxtInterners<'tcx> {
|
||||
region: InternedSet<'tcx, RegionKind>,
|
||||
existential_predicates: InternedSet<'tcx, List<ExistentialPredicate<'tcx>>>,
|
||||
predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
|
||||
predicate_kint: InternedSet<'tcx, PredicateKint<'tcx>>,
|
||||
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
|
||||
projs: InternedSet<'tcx, List<ProjectionKind>>,
|
||||
place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
|
||||
@ -98,11 +99,11 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||
existential_predicates: Default::default(),
|
||||
canonical_var_infos: Default::default(),
|
||||
predicate: Default::default(),
|
||||
predicate_kint: Default::default(),
|
||||
predicates: Default::default(),
|
||||
projs: Default::default(),
|
||||
place_elems: Default::default(),
|
||||
const_: Default::default(),
|
||||
|
||||
chalk_environment_clause_list: Default::default(),
|
||||
}
|
||||
}
|
||||
@ -1616,6 +1617,7 @@ nop_lift! {type_; Ty<'a> => Ty<'tcx>}
|
||||
nop_lift! {region; Region<'a> => Region<'tcx>}
|
||||
nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
|
||||
nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
|
||||
nop_lift! {predicate_kint; &'a PredicateKint<'a> => &'tcx PredicateKint<'tcx>}
|
||||
|
||||
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
|
||||
nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
|
||||
@ -2034,6 +2036,12 @@ impl<'tcx> Borrow<PredicateKind<'tcx>> for Interned<'tcx, PredicateKind<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Borrow<PredicateKint<'tcx>> for Interned<'tcx, PredicateKint<'tcx>> {
|
||||
fn borrow<'a>(&'a self) -> &'a PredicateKint<'tcx> {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! direct_interners {
|
||||
($($name:ident: $method:ident($ty:ty),)+) => {
|
||||
$(impl<'tcx> PartialEq for Interned<'tcx, $ty> {
|
||||
@ -2063,6 +2071,7 @@ macro_rules! direct_interners {
|
||||
direct_interners! {
|
||||
region: mk_region(RegionKind),
|
||||
const_: mk_const(Const<'tcx>),
|
||||
predicate_kint: intern_predicate_kint(PredicateKint<'tcx>),
|
||||
}
|
||||
|
||||
macro_rules! slice_interners {
|
||||
@ -2128,7 +2137,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
#[inline]
|
||||
pub fn mk_ty(&self, st: TyKind<'tcx>) -> Ty<'tcx> {
|
||||
pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> {
|
||||
self.interners.intern_ty(st)
|
||||
}
|
||||
|
||||
|
@ -1063,6 +1063,113 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
|
||||
|
||||
kind.hash_stable(hcx, hasher);
|
||||
}
|
||||
|
||||
pub fn kint(self, tcx: TyCtxt<'tcx>) -> &'tcx PredicateKint<'tcx> {
|
||||
// I am efficient
|
||||
tcx.intern_predicate_kint(match *self.kind() {
|
||||
PredicateKind::Trait(binder, data) => {
|
||||
if let Some(simpl) = binder.no_bound_vars() {
|
||||
PredicateKint::Trait(simpl, data)
|
||||
} else {
|
||||
let inner = tcx
|
||||
.intern_predicate_kint(PredicateKint::Trait(*binder.skip_binder(), data));
|
||||
PredicateKint::ForAll(Binder::bind(inner))
|
||||
}
|
||||
}
|
||||
PredicateKind::RegionOutlives(binder) => {
|
||||
if let Some(simpl) = binder.no_bound_vars() {
|
||||
PredicateKint::RegionOutlives(simpl)
|
||||
} else {
|
||||
let inner = tcx.intern_predicate_kint(PredicateKint::RegionOutlives(
|
||||
*binder.skip_binder(),
|
||||
));
|
||||
PredicateKint::ForAll(Binder::bind(inner))
|
||||
}
|
||||
}
|
||||
PredicateKind::TypeOutlives(binder) => {
|
||||
if let Some(simpl) = binder.no_bound_vars() {
|
||||
PredicateKint::TypeOutlives(simpl)
|
||||
} else {
|
||||
let inner = tcx
|
||||
.intern_predicate_kint(PredicateKint::TypeOutlives(*binder.skip_binder()));
|
||||
PredicateKint::ForAll(Binder::bind(inner))
|
||||
}
|
||||
}
|
||||
PredicateKind::Projection(binder) => {
|
||||
if let Some(simpl) = binder.no_bound_vars() {
|
||||
PredicateKint::Projection(simpl)
|
||||
} else {
|
||||
let inner =
|
||||
tcx.intern_predicate_kint(PredicateKint::Projection(*binder.skip_binder()));
|
||||
PredicateKint::ForAll(Binder::bind(inner))
|
||||
}
|
||||
}
|
||||
PredicateKind::WellFormed(arg) => PredicateKint::WellFormed(arg),
|
||||
PredicateKind::ObjectSafe(def_id) => PredicateKint::ObjectSafe(def_id),
|
||||
PredicateKind::ClosureKind(def_id, substs, kind) => {
|
||||
PredicateKint::ClosureKind(def_id, substs, kind)
|
||||
}
|
||||
PredicateKind::Subtype(binder) => {
|
||||
if let Some(simpl) = binder.no_bound_vars() {
|
||||
PredicateKint::Subtype(simpl)
|
||||
} else {
|
||||
let inner =
|
||||
tcx.intern_predicate_kint(PredicateKint::Subtype(*binder.skip_binder()));
|
||||
PredicateKint::ForAll(Binder::bind(inner))
|
||||
}
|
||||
}
|
||||
PredicateKind::ConstEvaluatable(def, substs) => {
|
||||
PredicateKint::ConstEvaluatable(def, substs)
|
||||
}
|
||||
PredicateKind::ConstEquate(l, r) => PredicateKint::ConstEquate(l, r),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(TypeFoldable)]
|
||||
pub enum PredicateKint<'tcx> {
|
||||
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
|
||||
/// the `Self` type of the trait reference and `A`, `B`, and `C`
|
||||
/// would be the type parameters.
|
||||
///
|
||||
/// A trait predicate will have `Constness::Const` if it originates
|
||||
/// from a bound on a `const fn` without the `?const` opt-out (e.g.,
|
||||
/// `const fn foobar<Foo: Bar>() {}`).
|
||||
Trait(TraitPredicate<'tcx>, Constness),
|
||||
|
||||
/// `where 'a: 'b`
|
||||
RegionOutlives(RegionOutlivesPredicate<'tcx>),
|
||||
|
||||
/// `where T: 'a`
|
||||
TypeOutlives(TypeOutlivesPredicate<'tcx>),
|
||||
|
||||
/// `where <T as TraitRef>::Name == X`, approximately.
|
||||
/// See the `ProjectionPredicate` struct for details.
|
||||
Projection(ProjectionPredicate<'tcx>),
|
||||
|
||||
/// No syntax: `T` well-formed.
|
||||
WellFormed(GenericArg<'tcx>),
|
||||
|
||||
/// Trait must be object-safe.
|
||||
ObjectSafe(DefId),
|
||||
|
||||
/// No direct syntax. May be thought of as `where T: FnFoo<...>`
|
||||
/// for some substitutions `...` and `T` being a closure type.
|
||||
/// Satisfied (or refuted) once we know the closure's kind.
|
||||
ClosureKind(DefId, SubstsRef<'tcx>, ClosureKind),
|
||||
|
||||
/// `T1 <: T2`
|
||||
Subtype(SubtypePredicate<'tcx>),
|
||||
|
||||
/// Constant initializer must evaluate successfully.
|
||||
ConstEvaluatable(DefId, SubstsRef<'tcx>),
|
||||
|
||||
/// Constants must be equal. The first component is the const that is expected.
|
||||
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
|
||||
|
||||
/// `for<'a>: ...`
|
||||
ForAll(Binder<&'tcx PredicateKint<'tcx>>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
@ -1349,6 +1456,76 @@ impl ToPredicate<'tcx> for PredicateKind<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToPredicate<'tcx> for PredicateKint<'tcx> {
|
||||
#[inline(always)]
|
||||
fn to_predicate(&self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
let (predicate, in_binder) = if let PredicateKint::ForAll(binder) = self {
|
||||
(*binder.skip_binder(), true)
|
||||
} else {
|
||||
(self, false)
|
||||
};
|
||||
|
||||
macro_rules! bind {
|
||||
($expr:expr) => {
|
||||
match $expr {
|
||||
expr => {
|
||||
if in_binder {
|
||||
Binder::bind(expr)
|
||||
} else {
|
||||
Binder::dummy(expr)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
match *predicate {
|
||||
PredicateKint::ForAll(_) => bug!("unexpected PredicateKint: {:?}", self),
|
||||
PredicateKint::Trait(data, ct) => PredicateKind::Trait(bind!(data), ct),
|
||||
PredicateKint::RegionOutlives(data) => PredicateKind::RegionOutlives(bind!(data)),
|
||||
PredicateKint::TypeOutlives(data) => PredicateKind::TypeOutlives(bind!(data)),
|
||||
PredicateKint::Projection(data) => PredicateKind::Projection(bind!(data)),
|
||||
PredicateKint::WellFormed(arg) => {
|
||||
if in_binder {
|
||||
bug!("unexpected ForAll: {:?}", self)
|
||||
} else {
|
||||
PredicateKind::WellFormed(arg)
|
||||
}
|
||||
}
|
||||
PredicateKint::ObjectSafe(def_id) => {
|
||||
if in_binder {
|
||||
bug!("unexpected ForAll: {:?}", self)
|
||||
} else {
|
||||
PredicateKind::ObjectSafe(def_id)
|
||||
}
|
||||
}
|
||||
PredicateKint::ClosureKind(def_id, substs, kind) => {
|
||||
if in_binder {
|
||||
bug!("unexpected ForAll: {:?}", self)
|
||||
} else {
|
||||
PredicateKind::ClosureKind(def_id, substs, kind)
|
||||
}
|
||||
}
|
||||
PredicateKint::Subtype(data) => PredicateKind::Subtype(bind!(data)),
|
||||
PredicateKint::ConstEvaluatable(def_id, substs) => {
|
||||
if in_binder {
|
||||
bug!("unexpected ForAll: {:?}", self)
|
||||
} else {
|
||||
PredicateKind::ConstEvaluatable(def_id, substs)
|
||||
}
|
||||
}
|
||||
PredicateKint::ConstEquate(l, r) => {
|
||||
if in_binder {
|
||||
bug!("unexpected ForAll: {:?}", self)
|
||||
} else {
|
||||
PredicateKind::ConstEquate(l, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
.to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
ty::PredicateKind::Trait(
|
||||
|
@ -1028,6 +1028,17 @@ impl<T: TypeVisitor<'tcx>> PredicateVisitor<'tcx> for T {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::PredicateKint<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
let new = ty::PredicateKint::super_fold_with(self, folder);
|
||||
folder.tcx().intern_predicate_kint(new)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
ty::PredicateKint::super_visit_with(self, visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
fold_list(*self, folder, |tcx, v| tcx.intern_predicates(v))
|
||||
|
Loading…
Reference in New Issue
Block a user