mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Uplift ClauseKind and PredicateKind
This commit is contained in:
parent
249624b504
commit
573f475853
@ -230,9 +230,9 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D>
|
||||
assert!(pos >= SHORTHAND_OFFSET);
|
||||
let shorthand = pos - SHORTHAND_OFFSET;
|
||||
|
||||
decoder.with_position(shorthand, ty::PredicateKind::decode)
|
||||
decoder.with_position(shorthand, <ty::PredicateKind<'tcx> as Decodable<D>>::decode)
|
||||
} else {
|
||||
ty::PredicateKind::decode(decoder)
|
||||
<ty::PredicateKind<'tcx> as Decodable<D>>::decode(decoder)
|
||||
},
|
||||
bound_vars,
|
||||
)
|
||||
|
@ -84,10 +84,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type AdtDef = ty::AdtDef<'tcx>;
|
||||
type GenericArgs = ty::GenericArgsRef<'tcx>;
|
||||
type GenericArg = ty::GenericArg<'tcx>;
|
||||
type Term = ty::Term<'tcx>;
|
||||
|
||||
type Binder<T> = Binder<'tcx, T>;
|
||||
type Predicate = Predicate<'tcx>;
|
||||
type PredicateKind = ty::PredicateKind<'tcx>;
|
||||
type TypeAndMut = TypeAndMut<'tcx>;
|
||||
|
||||
type Ty = Ty<'tcx>;
|
||||
type Tys = &'tcx List<Ty<'tcx>>;
|
||||
type AliasTy = ty::AliasTy<'tcx>;
|
||||
@ -95,10 +96,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type BoundTy = ty::BoundTy;
|
||||
type PlaceholderTy = ty::PlaceholderType;
|
||||
type InferTy = InferTy;
|
||||
|
||||
type ErrorGuaranteed = ErrorGuaranteed;
|
||||
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
|
||||
type PolyFnSig = PolyFnSig<'tcx>;
|
||||
type AllocId = crate::mir::interpret::AllocId;
|
||||
|
||||
type Const = ty::Const<'tcx>;
|
||||
type InferConst = ty::InferConst<'tcx>;
|
||||
type AliasConst = ty::UnevaluatedConst<'tcx>;
|
||||
@ -107,6 +110,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type BoundConst = ty::BoundVar;
|
||||
type ValueConst = ty::ValTree<'tcx>;
|
||||
type ExprConst = ty::Expr<'tcx>;
|
||||
|
||||
type Region = Region<'tcx>;
|
||||
type EarlyBoundRegion = ty::EarlyBoundRegion;
|
||||
type BoundRegion = ty::BoundRegion;
|
||||
@ -114,6 +118,15 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type InferRegion = ty::RegionVid;
|
||||
type PlaceholderRegion = ty::PlaceholderRegion;
|
||||
|
||||
type Predicate = Predicate<'tcx>;
|
||||
type TraitPredicate = ty::TraitPredicate<'tcx>;
|
||||
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
|
||||
type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>;
|
||||
type ProjectionPredicate = ty::ProjectionPredicate<'tcx>;
|
||||
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
|
||||
type CoercePredicate = ty::CoercePredicate<'tcx>;
|
||||
type ClosureKind = ty::ClosureKind;
|
||||
|
||||
fn ty_and_mut_to_parts(
|
||||
TypeAndMut { ty, mutbl }: TypeAndMut<'tcx>,
|
||||
) -> (Self::Ty, ty::Mutability) {
|
||||
|
@ -97,12 +97,12 @@ pub use self::rvalue_scopes::RvalueScopes;
|
||||
pub use self::sty::BoundRegionKind::*;
|
||||
pub use self::sty::{
|
||||
AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar,
|
||||
BoundVariableKind, CanonicalPolyFnSig, ClosureArgs, ClosureArgsParts, ConstKind, ConstVid,
|
||||
CoroutineArgs, CoroutineArgsParts, EarlyBoundRegion, EffectVid, ExistentialPredicate,
|
||||
BoundVariableKind, CanonicalPolyFnSig, ClauseKind, ClosureArgs, ClosureArgsParts, ConstKind,
|
||||
ConstVid, CoroutineArgs, CoroutineArgsParts, EarlyBoundRegion, EffectVid, ExistentialPredicate,
|
||||
ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig, InlineConstArgs,
|
||||
InlineConstArgsParts, ParamConst, ParamTy, PolyExistentialPredicate, PolyExistentialProjection,
|
||||
PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, Region, RegionKind, RegionVid,
|
||||
TraitRef, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo,
|
||||
PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, PredicateKind, Region,
|
||||
RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo,
|
||||
};
|
||||
pub use self::trait_def::TraitDef;
|
||||
pub use self::typeck_results::{
|
||||
@ -626,98 +626,6 @@ impl<'tcx> Clause<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
/// A clause is something that can appear in where bounds or be inferred
|
||||
/// by implied bounds.
|
||||
pub enum ClauseKind<'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.
|
||||
Trait(TraitPredicate<'tcx>),
|
||||
|
||||
/// `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>),
|
||||
|
||||
/// Ensures that a const generic argument to a parameter `const N: u8`
|
||||
/// is of type `u8`.
|
||||
ConstArgHasType(Const<'tcx>, Ty<'tcx>),
|
||||
|
||||
/// No syntax: `T` well-formed.
|
||||
WellFormed(GenericArg<'tcx>),
|
||||
|
||||
/// Constant initializer must evaluate successfully.
|
||||
ConstEvaluatable(ty::Const<'tcx>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub enum PredicateKind<'tcx> {
|
||||
/// Prove a clause
|
||||
Clause(ClauseKind<'tcx>),
|
||||
|
||||
/// Trait must be object-safe.
|
||||
ObjectSafe(DefId),
|
||||
|
||||
/// No direct syntax. May be thought of as `where T: FnFoo<...>`
|
||||
/// for some generic args `...` and `T` being a closure type.
|
||||
/// Satisfied (or refuted) once we know the closure's kind.
|
||||
ClosureKind(DefId, GenericArgsRef<'tcx>, ClosureKind),
|
||||
|
||||
/// `T1 <: T2`
|
||||
///
|
||||
/// This obligation is created most often when we have two
|
||||
/// unresolved type variables and hence don't have enough
|
||||
/// information to process the subtyping obligation yet.
|
||||
Subtype(SubtypePredicate<'tcx>),
|
||||
|
||||
/// `T1` coerced to `T2`
|
||||
///
|
||||
/// Like a subtyping obligation, this is created most often
|
||||
/// when we have two unresolved type variables and hence
|
||||
/// don't have enough information to process the coercion
|
||||
/// obligation yet. At the moment, we actually process coercions
|
||||
/// very much like subtyping and don't handle the full coercion
|
||||
/// logic.
|
||||
Coerce(CoercePredicate<'tcx>),
|
||||
|
||||
/// Constants must be equal. The first component is the const that is expected.
|
||||
ConstEquate(Const<'tcx>, Const<'tcx>),
|
||||
|
||||
/// A marker predicate that is always ambiguous.
|
||||
/// Used for coherence to mark opaque types as possibly equal to each other but ambiguous.
|
||||
Ambiguous,
|
||||
|
||||
/// Separate from `ClauseKind::Projection` which is used for normalization in new solver.
|
||||
/// This predicate requires two terms to be equal to eachother.
|
||||
///
|
||||
/// Only used for new solver
|
||||
AliasRelate(Term<'tcx>, Term<'tcx>, AliasRelationDirection),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, Debug)]
|
||||
pub enum AliasRelationDirection {
|
||||
Equate,
|
||||
Subtype,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for AliasRelationDirection {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
AliasRelationDirection::Equate => write!(f, "=="),
|
||||
AliasRelationDirection::Subtype => write!(f, "<:"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The crate outlives map is computed during typeck and contains the
|
||||
/// outlives of every item in the local crate. You should not use it
|
||||
/// directly, because to do so will make your pass dependent on the
|
||||
|
@ -2632,6 +2632,13 @@ macro_rules! forward_display_to_print {
|
||||
}
|
||||
|
||||
macro_rules! define_print_and_forward_display {
|
||||
(($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
|
||||
define_print!(($self, $cx): $($ty $print)*);
|
||||
forward_display_to_print!($($ty),+);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! define_print {
|
||||
(($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
|
||||
$(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty {
|
||||
fn print(&$self, $cx: P) -> Result<P, PrintError> {
|
||||
@ -2643,8 +2650,6 @@ macro_rules! define_print_and_forward_display {
|
||||
Ok($cx)
|
||||
}
|
||||
})+
|
||||
|
||||
forward_display_to_print!($($ty),+);
|
||||
};
|
||||
}
|
||||
|
||||
@ -2742,6 +2747,51 @@ forward_display_to_print! {
|
||||
ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
|
||||
}
|
||||
|
||||
define_print! {
|
||||
(self, cx):
|
||||
|
||||
ty::ClauseKind<'tcx> {
|
||||
match *self {
|
||||
ty::ClauseKind::Trait(ref data) => {
|
||||
p!(print(data))
|
||||
}
|
||||
ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::Projection(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::ConstArgHasType(ct, ty) => {
|
||||
p!("the constant `", print(ct), "` has type `", print(ty), "`")
|
||||
},
|
||||
ty::ClauseKind::WellFormed(arg) => p!(print(arg), " well-formed"),
|
||||
ty::ClauseKind::ConstEvaluatable(ct) => {
|
||||
p!("the constant `", print(ct), "` can be evaluated")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind<'tcx> {
|
||||
match *self {
|
||||
ty::PredicateKind::Clause(data) => {
|
||||
p!(print(data))
|
||||
}
|
||||
ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
|
||||
ty::PredicateKind::Coerce(predicate) => p!(print(predicate)),
|
||||
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
||||
p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
|
||||
}
|
||||
ty::PredicateKind::ClosureKind(closure_def_id, _closure_args, kind) => p!(
|
||||
"the closure `",
|
||||
print_value_path(closure_def_id, &[]),
|
||||
write("` implements the trait `{}`", kind)
|
||||
),
|
||||
ty::PredicateKind::ConstEquate(c1, c2) => {
|
||||
p!("the constant `", print(c1), "` equals `", print(c2), "`")
|
||||
}
|
||||
ty::PredicateKind::Ambiguous => p!("ambiguous"),
|
||||
ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print_and_forward_display! {
|
||||
(self, cx):
|
||||
|
||||
@ -2870,55 +2920,13 @@ define_print_and_forward_display! {
|
||||
}
|
||||
|
||||
ty::Predicate<'tcx> {
|
||||
let binder = self.kind();
|
||||
p!(print(binder))
|
||||
p!(print(self.kind()))
|
||||
}
|
||||
|
||||
ty::Clause<'tcx> {
|
||||
p!(print(self.kind()))
|
||||
}
|
||||
|
||||
ty::ClauseKind<'tcx> {
|
||||
match *self {
|
||||
ty::ClauseKind::Trait(ref data) => {
|
||||
p!(print(data))
|
||||
}
|
||||
ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::Projection(predicate) => p!(print(predicate)),
|
||||
ty::ClauseKind::ConstArgHasType(ct, ty) => {
|
||||
p!("the constant `", print(ct), "` has type `", print(ty), "`")
|
||||
},
|
||||
ty::ClauseKind::WellFormed(arg) => p!(print(arg), " well-formed"),
|
||||
ty::ClauseKind::ConstEvaluatable(ct) => {
|
||||
p!("the constant `", print(ct), "` can be evaluated")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind<'tcx> {
|
||||
match *self {
|
||||
ty::PredicateKind::Clause(data) => {
|
||||
p!(print(data))
|
||||
}
|
||||
ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
|
||||
ty::PredicateKind::Coerce(predicate) => p!(print(predicate)),
|
||||
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
||||
p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
|
||||
}
|
||||
ty::PredicateKind::ClosureKind(closure_def_id, _closure_args, kind) => p!(
|
||||
"the closure `",
|
||||
print_value_path(closure_def_id, &[]),
|
||||
write("` implements the trait `{}`", kind)
|
||||
),
|
||||
ty::PredicateKind::ConstEquate(c1, c2) => {
|
||||
p!("the constant `", print(c1), "` equals `", print(c2), "`")
|
||||
}
|
||||
ty::PredicateKind::Ambiguous => p!("ambiguous"),
|
||||
ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)),
|
||||
}
|
||||
}
|
||||
|
||||
GenericArg<'tcx> {
|
||||
match self.unpack() {
|
||||
GenericArgKind::Lifetime(lt) => p!(print(lt)),
|
||||
|
@ -199,43 +199,6 @@ impl<'tcx> fmt::Debug for ty::Clause<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::ClauseKind<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
ty::ClauseKind::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"),
|
||||
ty::ClauseKind::Trait(ref a) => a.fmt(f),
|
||||
ty::ClauseKind::RegionOutlives(ref pair) => pair.fmt(f),
|
||||
ty::ClauseKind::TypeOutlives(ref pair) => pair.fmt(f),
|
||||
ty::ClauseKind::Projection(ref pair) => pair.fmt(f),
|
||||
ty::ClauseKind::WellFormed(ref data) => write!(f, "WellFormed({data:?})"),
|
||||
ty::ClauseKind::ConstEvaluatable(ct) => {
|
||||
write!(f, "ConstEvaluatable({ct:?})")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
ty::PredicateKind::Clause(ref a) => a.fmt(f),
|
||||
ty::PredicateKind::Subtype(ref pair) => pair.fmt(f),
|
||||
ty::PredicateKind::Coerce(ref pair) => pair.fmt(f),
|
||||
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
||||
write!(f, "ObjectSafe({trait_def_id:?})")
|
||||
}
|
||||
ty::PredicateKind::ClosureKind(closure_def_id, closure_args, kind) => {
|
||||
write!(f, "ClosureKind({closure_def_id:?}, {closure_args:?}, {kind:?})")
|
||||
}
|
||||
ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({c1:?}, {c2:?})"),
|
||||
ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"),
|
||||
ty::PredicateKind::AliasRelate(t1, t2, dir) => {
|
||||
write!(f, "AliasRelate({t1:?}, {dir:?}, {t2:?})")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for AliasTy<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
OptWithInfcx::new_no_ctx(self).fmt(f)
|
||||
@ -518,7 +481,6 @@ TrivialTypeTraversalAndLiftImpls! {
|
||||
::rustc_hir::Mutability,
|
||||
::rustc_hir::Unsafety,
|
||||
::rustc_target::spec::abi::Abi,
|
||||
crate::ty::AliasRelationDirection,
|
||||
crate::ty::ClosureKind,
|
||||
crate::ty::ParamConst,
|
||||
crate::ty::ParamTy,
|
||||
|
@ -33,10 +33,12 @@ use std::marker::PhantomData;
|
||||
use std::ops::{ControlFlow, Deref, Range};
|
||||
use ty::util::IntTypeExt;
|
||||
|
||||
use rustc_type_ir::ClauseKind as IrClauseKind;
|
||||
use rustc_type_ir::CollectAndApply;
|
||||
use rustc_type_ir::ConstKind as IrConstKind;
|
||||
use rustc_type_ir::DebugWithInfcx;
|
||||
use rustc_type_ir::DynKind;
|
||||
use rustc_type_ir::PredicateKind as IrPredicateKind;
|
||||
use rustc_type_ir::RegionKind as IrRegionKind;
|
||||
use rustc_type_ir::TyKind as IrTyKind;
|
||||
use rustc_type_ir::TyKind::*;
|
||||
@ -48,6 +50,8 @@ use super::GenericParamDefKind;
|
||||
pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>;
|
||||
pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
|
||||
pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
|
||||
pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>;
|
||||
pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
|
@ -1497,30 +1497,32 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
|
||||
type T = stable_mir::ty::ClauseKind;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
use ty::ClauseKind::*;
|
||||
use ty::ClauseKind;
|
||||
match *self {
|
||||
Trait(trait_object) => stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables)),
|
||||
RegionOutlives(region_outlives) => {
|
||||
ClauseKind::Trait(trait_object) => {
|
||||
stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables))
|
||||
}
|
||||
ClauseKind::RegionOutlives(region_outlives) => {
|
||||
stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables))
|
||||
}
|
||||
TypeOutlives(type_outlives) => {
|
||||
ClauseKind::TypeOutlives(type_outlives) => {
|
||||
let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives;
|
||||
stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate(
|
||||
tables.intern_ty(a),
|
||||
b.stable(tables),
|
||||
))
|
||||
}
|
||||
Projection(projection_predicate) => {
|
||||
ClauseKind::Projection(projection_predicate) => {
|
||||
stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables))
|
||||
}
|
||||
ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
|
||||
ClauseKind::ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
|
||||
const_.stable(tables),
|
||||
tables.intern_ty(ty),
|
||||
),
|
||||
WellFormed(generic_arg) => {
|
||||
ClauseKind::WellFormed(generic_arg) => {
|
||||
stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables))
|
||||
}
|
||||
ConstEvaluatable(const_) => {
|
||||
ClauseKind::ConstEvaluatable(const_) => {
|
||||
stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables))
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::Interner;
|
||||
use crate::{Interner, PredicateKind};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_serialize::{Decoder, Encoder};
|
||||
@ -30,9 +30,7 @@ pub trait TyEncoder: Encoder {
|
||||
|
||||
fn type_shorthands(&mut self) -> &mut FxHashMap<<Self::I as Interner>::Ty, usize>;
|
||||
|
||||
fn predicate_shorthands(
|
||||
&mut self,
|
||||
) -> &mut FxHashMap<<Self::I as Interner>::PredicateKind, usize>;
|
||||
fn predicate_shorthands(&mut self) -> &mut FxHashMap<PredicateKind<Self::I>, usize>;
|
||||
|
||||
fn encode_alloc_id(&mut self, alloc_id: &<Self::I as Interner>::AllocId);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use rustc_data_structures::stable_hasher::HashStable;
|
||||
use rustc_data_structures::stable_hasher::StableHasher;
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
@ -86,11 +87,7 @@ where
|
||||
I::ErrorGuaranteed: HashStable<CTX>,
|
||||
I::ExprConst: HashStable<CTX>,
|
||||
{
|
||||
fn hash_stable(
|
||||
&self,
|
||||
hcx: &mut CTX,
|
||||
hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
|
||||
) {
|
||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||
const_kind_discriminant(self).hash_stable(hcx, hasher);
|
||||
match self {
|
||||
Param(p) => p.hash_stable(hcx, hasher),
|
||||
|
@ -14,13 +14,9 @@ pub trait Interner: Sized {
|
||||
+ Ord
|
||||
+ IntoIterator<Item = Self::GenericArg>;
|
||||
type GenericArg: Clone + DebugWithInfcx<Self> + Hash + Ord;
|
||||
type Term: Clone + Debug + Hash + Ord;
|
||||
|
||||
type Binder<T>;
|
||||
|
||||
// Predicates
|
||||
type Predicate;
|
||||
type PredicateKind: Clone + Debug + Hash + PartialEq + Eq;
|
||||
|
||||
type TypeAndMut: Clone + Debug + Hash + Ord;
|
||||
|
||||
// Kinds of tys
|
||||
@ -56,6 +52,16 @@ pub trait Interner: Sized {
|
||||
type InferRegion: Clone + DebugWithInfcx<Self> + Hash + Ord;
|
||||
type PlaceholderRegion: Clone + Debug + Hash + Ord;
|
||||
|
||||
// Predicates
|
||||
type Predicate: Clone + Debug + Hash + Eq;
|
||||
type TraitPredicate: Clone + Debug + Hash + Eq;
|
||||
type RegionOutlivesPredicate: Clone + Debug + Hash + Eq;
|
||||
type TypeOutlivesPredicate: Clone + Debug + Hash + Eq;
|
||||
type ProjectionPredicate: Clone + Debug + Hash + Eq;
|
||||
type SubtypePredicate: Clone + Debug + Hash + Eq;
|
||||
type CoercePredicate: Clone + Debug + Hash + Eq;
|
||||
type ClosureKind: Clone + Debug + Hash + Eq;
|
||||
|
||||
fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Mutability);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ mod const_kind;
|
||||
mod debug;
|
||||
mod flags;
|
||||
mod interner;
|
||||
mod predicate_kind;
|
||||
mod region_kind;
|
||||
|
||||
pub use codec::*;
|
||||
@ -37,6 +38,7 @@ pub use const_kind::*;
|
||||
pub use debug::{DebugWithInfcx, InferCtxtLike, OptWithInfcx};
|
||||
pub use flags::*;
|
||||
pub use interner::*;
|
||||
pub use predicate_kind::*;
|
||||
pub use region_kind::*;
|
||||
pub use ty_info::*;
|
||||
pub use ty_kind::*;
|
||||
|
@ -49,4 +49,5 @@ TrivialTypeTraversalImpls! {
|
||||
u64,
|
||||
String,
|
||||
crate::DebruijnIndex,
|
||||
crate::AliasRelationDirection,
|
||||
}
|
||||
|
626
compiler/rustc_type_ir/src/predicate_kind.rs
Normal file
626
compiler/rustc_type_ir/src/predicate_kind.rs
Normal file
@ -0,0 +1,626 @@
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_serialize::Decoder;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use std::fmt;
|
||||
use std::hash;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
use crate::visit::{TypeVisitable, TypeVisitor};
|
||||
use crate::{HashStableContext, Interner};
|
||||
use crate::{TyDecoder, TyEncoder};
|
||||
|
||||
/// A clause is something that can appear in where bounds or be inferred
|
||||
/// by implied bounds.
|
||||
pub enum ClauseKind<I: Interner> {
|
||||
/// 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.
|
||||
Trait(I::TraitPredicate),
|
||||
|
||||
/// `where 'a: 'b`
|
||||
RegionOutlives(I::RegionOutlivesPredicate),
|
||||
|
||||
/// `where T: 'a`
|
||||
TypeOutlives(I::TypeOutlivesPredicate),
|
||||
|
||||
/// `where <T as TraitRef>::Name == X`, approximately.
|
||||
/// See the `ProjectionPredicate` struct for details.
|
||||
Projection(I::ProjectionPredicate),
|
||||
|
||||
/// Ensures that a const generic argument to a parameter `const N: u8`
|
||||
/// is of type `u8`.
|
||||
ConstArgHasType(I::Const, I::Ty),
|
||||
|
||||
/// No syntax: `T` well-formed.
|
||||
WellFormed(I::GenericArg),
|
||||
|
||||
/// Constant initializer must evaluate successfully.
|
||||
ConstEvaluatable(I::Const),
|
||||
}
|
||||
|
||||
impl<I: Interner> Clone for ClauseKind<I> {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Self::Trait(arg0) => Self::Trait(arg0.clone()),
|
||||
Self::RegionOutlives(arg0) => Self::RegionOutlives(arg0.clone()),
|
||||
Self::TypeOutlives(arg0) => Self::TypeOutlives(arg0.clone()),
|
||||
Self::Projection(arg0) => Self::Projection(arg0.clone()),
|
||||
Self::ConstArgHasType(arg0, arg1) => Self::ConstArgHasType(arg0.clone(), arg1.clone()),
|
||||
Self::WellFormed(arg0) => Self::WellFormed(arg0.clone()),
|
||||
Self::ConstEvaluatable(arg0) => Self::ConstEvaluatable(arg0.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> Copy for ClauseKind<I>
|
||||
where
|
||||
I::Ty: Copy,
|
||||
I::Const: Copy,
|
||||
I::GenericArg: Copy,
|
||||
I::TraitPredicate: Copy,
|
||||
I::ProjectionPredicate: Copy,
|
||||
I::TypeOutlivesPredicate: Copy,
|
||||
I::RegionOutlivesPredicate: Copy,
|
||||
{
|
||||
}
|
||||
|
||||
impl<I: Interner> PartialEq for ClauseKind<I> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(Self::Trait(l0), Self::Trait(r0)) => l0 == r0,
|
||||
(Self::RegionOutlives(l0), Self::RegionOutlives(r0)) => l0 == r0,
|
||||
(Self::TypeOutlives(l0), Self::TypeOutlives(r0)) => l0 == r0,
|
||||
(Self::Projection(l0), Self::Projection(r0)) => l0 == r0,
|
||||
(Self::ConstArgHasType(l0, l1), Self::ConstArgHasType(r0, r1)) => l0 == r0 && l1 == r1,
|
||||
(Self::WellFormed(l0), Self::WellFormed(r0)) => l0 == r0,
|
||||
(Self::ConstEvaluatable(l0), Self::ConstEvaluatable(r0)) => l0 == r0,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> Eq for ClauseKind<I> {}
|
||||
|
||||
fn clause_kind_discriminant<I: Interner>(value: &ClauseKind<I>) -> usize {
|
||||
match value {
|
||||
ClauseKind::Trait(_) => 0,
|
||||
ClauseKind::RegionOutlives(_) => 1,
|
||||
ClauseKind::TypeOutlives(_) => 2,
|
||||
ClauseKind::Projection(_) => 3,
|
||||
ClauseKind::ConstArgHasType(_, _) => 4,
|
||||
ClauseKind::WellFormed(_) => 5,
|
||||
ClauseKind::ConstEvaluatable(_) => 6,
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> hash::Hash for ClauseKind<I> {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
clause_kind_discriminant(self).hash(state);
|
||||
match self {
|
||||
ClauseKind::Trait(p) => p.hash(state),
|
||||
ClauseKind::RegionOutlives(p) => p.hash(state),
|
||||
ClauseKind::TypeOutlives(p) => p.hash(state),
|
||||
ClauseKind::Projection(p) => p.hash(state),
|
||||
ClauseKind::ConstArgHasType(c, t) => {
|
||||
c.hash(state);
|
||||
t.hash(state);
|
||||
}
|
||||
ClauseKind::WellFormed(t) => t.hash(state),
|
||||
ClauseKind::ConstEvaluatable(c) => c.hash(state),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ClauseKind<I>
|
||||
where
|
||||
I::Ty: HashStable<CTX>,
|
||||
I::Const: HashStable<CTX>,
|
||||
I::GenericArg: HashStable<CTX>,
|
||||
I::TraitPredicate: HashStable<CTX>,
|
||||
I::ProjectionPredicate: HashStable<CTX>,
|
||||
I::TypeOutlivesPredicate: HashStable<CTX>,
|
||||
I::RegionOutlivesPredicate: HashStable<CTX>,
|
||||
{
|
||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||
clause_kind_discriminant(self).hash_stable(hcx, hasher);
|
||||
match self {
|
||||
ClauseKind::Trait(p) => p.hash_stable(hcx, hasher),
|
||||
ClauseKind::RegionOutlives(p) => p.hash_stable(hcx, hasher),
|
||||
ClauseKind::TypeOutlives(p) => p.hash_stable(hcx, hasher),
|
||||
ClauseKind::Projection(p) => p.hash_stable(hcx, hasher),
|
||||
ClauseKind::ConstArgHasType(c, t) => {
|
||||
c.hash_stable(hcx, hasher);
|
||||
t.hash_stable(hcx, hasher);
|
||||
}
|
||||
ClauseKind::WellFormed(t) => t.hash_stable(hcx, hasher),
|
||||
ClauseKind::ConstEvaluatable(c) => c.hash_stable(hcx, hasher),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> TypeFoldable<I> for ClauseKind<I>
|
||||
where
|
||||
I::Ty: TypeFoldable<I>,
|
||||
I::Const: TypeFoldable<I>,
|
||||
I::GenericArg: TypeFoldable<I>,
|
||||
I::TraitPredicate: TypeFoldable<I>,
|
||||
I::ProjectionPredicate: TypeFoldable<I>,
|
||||
I::TypeOutlivesPredicate: TypeFoldable<I>,
|
||||
I::RegionOutlivesPredicate: TypeFoldable<I>,
|
||||
{
|
||||
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(match self {
|
||||
ClauseKind::Trait(p) => ClauseKind::Trait(p.try_fold_with(folder)?),
|
||||
ClauseKind::RegionOutlives(p) => ClauseKind::RegionOutlives(p.try_fold_with(folder)?),
|
||||
ClauseKind::TypeOutlives(p) => ClauseKind::TypeOutlives(p.try_fold_with(folder)?),
|
||||
ClauseKind::Projection(p) => ClauseKind::Projection(p.try_fold_with(folder)?),
|
||||
ClauseKind::ConstArgHasType(c, t) => {
|
||||
ClauseKind::ConstArgHasType(c.try_fold_with(folder)?, t.try_fold_with(folder)?)
|
||||
}
|
||||
ClauseKind::WellFormed(p) => ClauseKind::WellFormed(p.try_fold_with(folder)?),
|
||||
ClauseKind::ConstEvaluatable(p) => {
|
||||
ClauseKind::ConstEvaluatable(p.try_fold_with(folder)?)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> TypeVisitable<I> for ClauseKind<I>
|
||||
where
|
||||
I::Ty: TypeVisitable<I>,
|
||||
I::Const: TypeVisitable<I>,
|
||||
I::GenericArg: TypeVisitable<I>,
|
||||
I::TraitPredicate: TypeVisitable<I>,
|
||||
I::ProjectionPredicate: TypeVisitable<I>,
|
||||
I::TypeOutlivesPredicate: TypeVisitable<I>,
|
||||
I::RegionOutlivesPredicate: TypeVisitable<I>,
|
||||
{
|
||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
match self {
|
||||
ClauseKind::Trait(p) => p.visit_with(visitor),
|
||||
ClauseKind::RegionOutlives(p) => p.visit_with(visitor),
|
||||
ClauseKind::TypeOutlives(p) => p.visit_with(visitor),
|
||||
ClauseKind::Projection(p) => p.visit_with(visitor),
|
||||
ClauseKind::ConstArgHasType(c, t) => {
|
||||
c.visit_with(visitor)?;
|
||||
t.visit_with(visitor)
|
||||
}
|
||||
ClauseKind::WellFormed(p) => p.visit_with(visitor),
|
||||
ClauseKind::ConstEvaluatable(p) => p.visit_with(visitor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for ClauseKind<I>
|
||||
where
|
||||
I::Ty: Decodable<D>,
|
||||
I::Const: Decodable<D>,
|
||||
I::GenericArg: Decodable<D>,
|
||||
I::TraitPredicate: Decodable<D>,
|
||||
I::ProjectionPredicate: Decodable<D>,
|
||||
I::TypeOutlivesPredicate: Decodable<D>,
|
||||
I::RegionOutlivesPredicate: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Self {
|
||||
match Decoder::read_usize(d) {
|
||||
0 => ClauseKind::Trait(Decodable::decode(d)),
|
||||
1 => ClauseKind::RegionOutlives(Decodable::decode(d)),
|
||||
2 => ClauseKind::TypeOutlives(Decodable::decode(d)),
|
||||
3 => ClauseKind::Projection(Decodable::decode(d)),
|
||||
4 => ClauseKind::ConstArgHasType(Decodable::decode(d), Decodable::decode(d)),
|
||||
5 => ClauseKind::WellFormed(Decodable::decode(d)),
|
||||
6 => ClauseKind::ConstEvaluatable(Decodable::decode(d)),
|
||||
_ => panic!(
|
||||
"{}",
|
||||
format!(
|
||||
"invalid enum variant tag while decoding `{}`, expected 0..{}",
|
||||
"ClauseKind", 7,
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, E: TyEncoder> Encodable<E> for ClauseKind<I>
|
||||
where
|
||||
I::Ty: Encodable<E>,
|
||||
I::Const: Encodable<E>,
|
||||
I::GenericArg: Encodable<E>,
|
||||
I::TraitPredicate: Encodable<E>,
|
||||
I::ProjectionPredicate: Encodable<E>,
|
||||
I::TypeOutlivesPredicate: Encodable<E>,
|
||||
I::RegionOutlivesPredicate: Encodable<E>,
|
||||
{
|
||||
fn encode(&self, s: &mut E) {
|
||||
let discriminant = clause_kind_discriminant(self);
|
||||
match self {
|
||||
ClauseKind::Trait(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::RegionOutlives(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::TypeOutlives(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::Projection(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::ConstArgHasType(c, t) => s.emit_enum_variant(discriminant, |s| {
|
||||
c.encode(s);
|
||||
t.encode(s);
|
||||
}),
|
||||
ClauseKind::WellFormed(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
ClauseKind::ConstEvaluatable(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum PredicateKind<I: Interner> {
|
||||
/// Prove a clause
|
||||
Clause(ClauseKind<I>),
|
||||
|
||||
/// Trait must be object-safe.
|
||||
ObjectSafe(I::DefId),
|
||||
|
||||
/// No direct syntax. May be thought of as `where T: FnFoo<...>`
|
||||
/// for some generic args `...` and `T` being a closure type.
|
||||
/// Satisfied (or refuted) once we know the closure's kind.
|
||||
ClosureKind(I::DefId, I::GenericArgs, I::ClosureKind),
|
||||
|
||||
/// `T1 <: T2`
|
||||
///
|
||||
/// This obligation is created most often when we have two
|
||||
/// unresolved type variables and hence don't have enough
|
||||
/// information to process the subtyping obligation yet.
|
||||
Subtype(I::SubtypePredicate),
|
||||
|
||||
/// `T1` coerced to `T2`
|
||||
///
|
||||
/// Like a subtyping obligation, this is created most often
|
||||
/// when we have two unresolved type variables and hence
|
||||
/// don't have enough information to process the coercion
|
||||
/// obligation yet. At the moment, we actually process coercions
|
||||
/// very much like subtyping and don't handle the full coercion
|
||||
/// logic.
|
||||
Coerce(I::CoercePredicate),
|
||||
|
||||
/// Constants must be equal. The first component is the const that is expected.
|
||||
ConstEquate(I::Const, I::Const),
|
||||
|
||||
/// A marker predicate that is always ambiguous.
|
||||
/// Used for coherence to mark opaque types as possibly equal to each other but ambiguous.
|
||||
Ambiguous,
|
||||
|
||||
/// Separate from `ClauseKind::Projection` which is used for normalization in new solver.
|
||||
/// This predicate requires two terms to be equal to eachother.
|
||||
///
|
||||
/// Only used for new solver
|
||||
AliasRelate(I::Term, I::Term, AliasRelationDirection),
|
||||
}
|
||||
|
||||
impl<I: Interner> Copy for PredicateKind<I>
|
||||
where
|
||||
I::DefId: Copy,
|
||||
I::Const: Copy,
|
||||
I::GenericArgs: Copy,
|
||||
I::Term: Copy,
|
||||
I::CoercePredicate: Copy,
|
||||
I::SubtypePredicate: Copy,
|
||||
I::ClosureKind: Copy,
|
||||
ClauseKind<I>: Copy,
|
||||
{
|
||||
}
|
||||
|
||||
impl<I: Interner> Clone for PredicateKind<I> {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Self::Clause(arg0) => Self::Clause(arg0.clone()),
|
||||
Self::ObjectSafe(arg0) => Self::ObjectSafe(arg0.clone()),
|
||||
Self::ClosureKind(arg0, arg1, arg2) => {
|
||||
Self::ClosureKind(arg0.clone(), arg1.clone(), arg2.clone())
|
||||
}
|
||||
Self::Subtype(arg0) => Self::Subtype(arg0.clone()),
|
||||
Self::Coerce(arg0) => Self::Coerce(arg0.clone()),
|
||||
Self::ConstEquate(arg0, arg1) => Self::ConstEquate(arg0.clone(), arg1.clone()),
|
||||
Self::Ambiguous => Self::Ambiguous,
|
||||
Self::AliasRelate(arg0, arg1, arg2) => {
|
||||
Self::AliasRelate(arg0.clone(), arg1.clone(), arg2.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> PartialEq for PredicateKind<I> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(Self::Clause(l0), Self::Clause(r0)) => l0 == r0,
|
||||
(Self::ObjectSafe(l0), Self::ObjectSafe(r0)) => l0 == r0,
|
||||
(Self::ClosureKind(l0, l1, l2), Self::ClosureKind(r0, r1, r2)) => {
|
||||
l0 == r0 && l1 == r1 && l2 == r2
|
||||
}
|
||||
(Self::Subtype(l0), Self::Subtype(r0)) => l0 == r0,
|
||||
(Self::Coerce(l0), Self::Coerce(r0)) => l0 == r0,
|
||||
(Self::ConstEquate(l0, l1), Self::ConstEquate(r0, r1)) => l0 == r0 && l1 == r1,
|
||||
(Self::AliasRelate(l0, l1, l2), Self::AliasRelate(r0, r1, r2)) => {
|
||||
l0 == r0 && l1 == r1 && l2 == r2
|
||||
}
|
||||
_ => core::mem::discriminant(self) == core::mem::discriminant(other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> Eq for PredicateKind<I> {}
|
||||
|
||||
fn predicate_kind_discriminant<I: Interner>(value: &PredicateKind<I>) -> usize {
|
||||
match value {
|
||||
PredicateKind::Clause(_) => 0,
|
||||
PredicateKind::ObjectSafe(_) => 1,
|
||||
PredicateKind::ClosureKind(_, _, _) => 2,
|
||||
PredicateKind::Subtype(_) => 3,
|
||||
PredicateKind::Coerce(_) => 4,
|
||||
PredicateKind::ConstEquate(_, _) => 5,
|
||||
PredicateKind::Ambiguous => 6,
|
||||
PredicateKind::AliasRelate(_, _, _) => 7,
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> hash::Hash for PredicateKind<I> {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
predicate_kind_discriminant(self).hash(state);
|
||||
match self {
|
||||
PredicateKind::Clause(p) => p.hash(state),
|
||||
PredicateKind::ObjectSafe(d) => d.hash(state),
|
||||
PredicateKind::ClosureKind(d, g, k) => {
|
||||
d.hash(state);
|
||||
g.hash(state);
|
||||
k.hash(state);
|
||||
}
|
||||
PredicateKind::Subtype(p) => p.hash(state),
|
||||
PredicateKind::Coerce(p) => p.hash(state),
|
||||
PredicateKind::ConstEquate(c1, c2) => {
|
||||
c1.hash(state);
|
||||
c2.hash(state);
|
||||
}
|
||||
PredicateKind::Ambiguous => {}
|
||||
PredicateKind::AliasRelate(t1, t2, r) => {
|
||||
t1.hash(state);
|
||||
t2.hash(state);
|
||||
r.hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for PredicateKind<I>
|
||||
where
|
||||
I::DefId: HashStable<CTX>,
|
||||
I::Const: HashStable<CTX>,
|
||||
I::GenericArgs: HashStable<CTX>,
|
||||
I::Term: HashStable<CTX>,
|
||||
I::CoercePredicate: HashStable<CTX>,
|
||||
I::SubtypePredicate: HashStable<CTX>,
|
||||
I::ClosureKind: HashStable<CTX>,
|
||||
ClauseKind<I>: HashStable<CTX>,
|
||||
{
|
||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||
predicate_kind_discriminant(self).hash_stable(hcx, hasher);
|
||||
match self {
|
||||
PredicateKind::Clause(p) => p.hash_stable(hcx, hasher),
|
||||
PredicateKind::ObjectSafe(d) => d.hash_stable(hcx, hasher),
|
||||
PredicateKind::ClosureKind(d, g, k) => {
|
||||
d.hash_stable(hcx, hasher);
|
||||
g.hash_stable(hcx, hasher);
|
||||
k.hash_stable(hcx, hasher);
|
||||
}
|
||||
PredicateKind::Subtype(p) => p.hash_stable(hcx, hasher),
|
||||
PredicateKind::Coerce(p) => p.hash_stable(hcx, hasher),
|
||||
PredicateKind::ConstEquate(c1, c2) => {
|
||||
c1.hash_stable(hcx, hasher);
|
||||
c2.hash_stable(hcx, hasher);
|
||||
}
|
||||
PredicateKind::Ambiguous => {}
|
||||
PredicateKind::AliasRelate(t1, t2, r) => {
|
||||
t1.hash_stable(hcx, hasher);
|
||||
t2.hash_stable(hcx, hasher);
|
||||
r.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> TypeFoldable<I> for PredicateKind<I>
|
||||
where
|
||||
I::DefId: TypeFoldable<I>,
|
||||
I::Const: TypeFoldable<I>,
|
||||
I::GenericArgs: TypeFoldable<I>,
|
||||
I::Term: TypeFoldable<I>,
|
||||
I::CoercePredicate: TypeFoldable<I>,
|
||||
I::SubtypePredicate: TypeFoldable<I>,
|
||||
I::ClosureKind: TypeFoldable<I>,
|
||||
ClauseKind<I>: TypeFoldable<I>,
|
||||
{
|
||||
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(match self {
|
||||
PredicateKind::Clause(c) => PredicateKind::Clause(c.try_fold_with(folder)?),
|
||||
PredicateKind::ObjectSafe(d) => PredicateKind::ObjectSafe(d.try_fold_with(folder)?),
|
||||
PredicateKind::ClosureKind(d, g, k) => PredicateKind::ClosureKind(
|
||||
d.try_fold_with(folder)?,
|
||||
g.try_fold_with(folder)?,
|
||||
k.try_fold_with(folder)?,
|
||||
),
|
||||
PredicateKind::Subtype(s) => PredicateKind::Subtype(s.try_fold_with(folder)?),
|
||||
PredicateKind::Coerce(s) => PredicateKind::Coerce(s.try_fold_with(folder)?),
|
||||
PredicateKind::ConstEquate(a, b) => {
|
||||
PredicateKind::ConstEquate(a.try_fold_with(folder)?, b.try_fold_with(folder)?)
|
||||
}
|
||||
PredicateKind::Ambiguous => PredicateKind::Ambiguous,
|
||||
PredicateKind::AliasRelate(a, b, d) => PredicateKind::AliasRelate(
|
||||
a.try_fold_with(folder)?,
|
||||
b.try_fold_with(folder)?,
|
||||
d.try_fold_with(folder)?,
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> TypeVisitable<I> for PredicateKind<I>
|
||||
where
|
||||
I::DefId: TypeVisitable<I>,
|
||||
I::Const: TypeVisitable<I>,
|
||||
I::GenericArgs: TypeVisitable<I>,
|
||||
I::Term: TypeVisitable<I>,
|
||||
I::CoercePredicate: TypeVisitable<I>,
|
||||
I::SubtypePredicate: TypeVisitable<I>,
|
||||
I::ClosureKind: TypeVisitable<I>,
|
||||
ClauseKind<I>: TypeVisitable<I>,
|
||||
{
|
||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
match self {
|
||||
PredicateKind::Clause(p) => p.visit_with(visitor),
|
||||
PredicateKind::ObjectSafe(d) => d.visit_with(visitor),
|
||||
PredicateKind::ClosureKind(d, g, k) => {
|
||||
d.visit_with(visitor)?;
|
||||
g.visit_with(visitor)?;
|
||||
k.visit_with(visitor)
|
||||
}
|
||||
PredicateKind::Subtype(s) => s.visit_with(visitor),
|
||||
PredicateKind::Coerce(s) => s.visit_with(visitor),
|
||||
PredicateKind::ConstEquate(a, b) => {
|
||||
a.visit_with(visitor)?;
|
||||
b.visit_with(visitor)
|
||||
}
|
||||
PredicateKind::Ambiguous => ControlFlow::Continue(()),
|
||||
PredicateKind::AliasRelate(a, b, d) => {
|
||||
a.visit_with(visitor)?;
|
||||
b.visit_with(visitor)?;
|
||||
d.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for PredicateKind<I>
|
||||
where
|
||||
I::DefId: Decodable<D>,
|
||||
I::Const: Decodable<D>,
|
||||
I::GenericArgs: Decodable<D>,
|
||||
I::Term: Decodable<D>,
|
||||
I::CoercePredicate: Decodable<D>,
|
||||
I::SubtypePredicate: Decodable<D>,
|
||||
I::ClosureKind: Decodable<D>,
|
||||
ClauseKind<I>: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Self {
|
||||
match Decoder::read_usize(d) {
|
||||
0 => PredicateKind::Clause(Decodable::decode(d)),
|
||||
1 => PredicateKind::ObjectSafe(Decodable::decode(d)),
|
||||
2 => PredicateKind::ClosureKind(
|
||||
Decodable::decode(d),
|
||||
Decodable::decode(d),
|
||||
Decodable::decode(d),
|
||||
),
|
||||
3 => PredicateKind::Subtype(Decodable::decode(d)),
|
||||
4 => PredicateKind::Coerce(Decodable::decode(d)),
|
||||
5 => PredicateKind::ConstEquate(Decodable::decode(d), Decodable::decode(d)),
|
||||
6 => PredicateKind::Ambiguous,
|
||||
7 => PredicateKind::AliasRelate(
|
||||
Decodable::decode(d),
|
||||
Decodable::decode(d),
|
||||
Decodable::decode(d),
|
||||
),
|
||||
_ => panic!(
|
||||
"{}",
|
||||
format!(
|
||||
"invalid enum variant tag while decoding `{}`, expected 0..{}",
|
||||
"PredicateKind", 8,
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, E: TyEncoder> Encodable<E> for PredicateKind<I>
|
||||
where
|
||||
I::DefId: Encodable<E>,
|
||||
I::Const: Encodable<E>,
|
||||
I::GenericArgs: Encodable<E>,
|
||||
I::Term: Encodable<E>,
|
||||
I::CoercePredicate: Encodable<E>,
|
||||
I::SubtypePredicate: Encodable<E>,
|
||||
I::ClosureKind: Encodable<E>,
|
||||
ClauseKind<I>: Encodable<E>,
|
||||
{
|
||||
fn encode(&self, s: &mut E) {
|
||||
let discriminant = predicate_kind_discriminant(self);
|
||||
match self {
|
||||
PredicateKind::Clause(c) => s.emit_enum_variant(discriminant, |s| c.encode(s)),
|
||||
PredicateKind::ObjectSafe(d) => s.emit_enum_variant(discriminant, |s| d.encode(s)),
|
||||
PredicateKind::ClosureKind(d, g, k) => s.emit_enum_variant(discriminant, |s| {
|
||||
d.encode(s);
|
||||
g.encode(s);
|
||||
k.encode(s);
|
||||
}),
|
||||
PredicateKind::Subtype(c) => s.emit_enum_variant(discriminant, |s| c.encode(s)),
|
||||
PredicateKind::Coerce(c) => s.emit_enum_variant(discriminant, |s| c.encode(s)),
|
||||
PredicateKind::ConstEquate(a, b) => s.emit_enum_variant(discriminant, |s| {
|
||||
a.encode(s);
|
||||
b.encode(s);
|
||||
}),
|
||||
PredicateKind::Ambiguous => s.emit_enum_variant(discriminant, |_s| {}),
|
||||
PredicateKind::AliasRelate(a, b, d) => s.emit_enum_variant(discriminant, |s| {
|
||||
a.encode(s);
|
||||
b.encode(s);
|
||||
d.encode(s);
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
|
||||
#[derive(HashStable_Generic, Encodable, Decodable)]
|
||||
pub enum AliasRelationDirection {
|
||||
Equate,
|
||||
Subtype,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for AliasRelationDirection {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
AliasRelationDirection::Equate => write!(f, "=="),
|
||||
AliasRelationDirection::Subtype => write!(f, "<:"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Convert to DebugWithInfcx impl
|
||||
impl<I: Interner> fmt::Debug for ClauseKind<I> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ClauseKind::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"),
|
||||
ClauseKind::Trait(a) => a.fmt(f),
|
||||
ClauseKind::RegionOutlives(pair) => pair.fmt(f),
|
||||
ClauseKind::TypeOutlives(pair) => pair.fmt(f),
|
||||
ClauseKind::Projection(pair) => pair.fmt(f),
|
||||
ClauseKind::WellFormed(data) => write!(f, "WellFormed({data:?})"),
|
||||
ClauseKind::ConstEvaluatable(ct) => {
|
||||
write!(f, "ConstEvaluatable({ct:?})")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Convert to DebugWithInfcx impl
|
||||
impl<I: Interner> fmt::Debug for PredicateKind<I> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
PredicateKind::Clause(a) => a.fmt(f),
|
||||
PredicateKind::Subtype(pair) => pair.fmt(f),
|
||||
PredicateKind::Coerce(pair) => pair.fmt(f),
|
||||
PredicateKind::ObjectSafe(trait_def_id) => {
|
||||
write!(f, "ObjectSafe({trait_def_id:?})")
|
||||
}
|
||||
PredicateKind::ClosureKind(closure_def_id, closure_args, kind) => {
|
||||
write!(f, "ClosureKind({closure_def_id:?}, {closure_args:?}, {kind:?})")
|
||||
}
|
||||
PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({c1:?}, {c2:?})"),
|
||||
PredicateKind::Ambiguous => write!(f, "Ambiguous"),
|
||||
PredicateKind::AliasRelate(t1, t2, dir) => {
|
||||
write!(f, "AliasRelate({t1:?}, {dir:?}, {t2:?})")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
use rustc_data_structures::stable_hasher::HashStable;
|
||||
use rustc_data_structures::stable_hasher::StableHasher;
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
@ -381,11 +382,7 @@ where
|
||||
I::PlaceholderRegion: HashStable<CTX>,
|
||||
{
|
||||
#[inline]
|
||||
fn hash_stable(
|
||||
&self,
|
||||
hcx: &mut CTX,
|
||||
hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
|
||||
) {
|
||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||
std::mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
match self {
|
||||
ReErased | ReStatic | ReError(_) => {
|
||||
|
@ -640,7 +640,6 @@ where
|
||||
I::BoundTy: Encodable<E>,
|
||||
I::PlaceholderTy: Encodable<E>,
|
||||
I::InferTy: Encodable<E>,
|
||||
I::PredicateKind: Encodable<E>,
|
||||
I::AllocId: Encodable<E>,
|
||||
{
|
||||
fn encode(&self, e: &mut E) {
|
||||
@ -753,7 +752,6 @@ where
|
||||
I::BoundTy: Decodable<D>,
|
||||
I::PlaceholderTy: Decodable<D>,
|
||||
I::InferTy: Decodable<D>,
|
||||
I::PredicateKind: Decodable<D>,
|
||||
I::AllocId: Decodable<D>,
|
||||
{
|
||||
fn decode(d: &mut D) -> Self {
|
||||
@ -817,11 +815,7 @@ where
|
||||
I::ErrorGuaranteed: HashStable<CTX>,
|
||||
{
|
||||
#[inline]
|
||||
fn hash_stable(
|
||||
&self,
|
||||
__hcx: &mut CTX,
|
||||
__hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
|
||||
) {
|
||||
fn hash_stable(&self, __hcx: &mut CTX, __hasher: &mut StableHasher) {
|
||||
std::mem::discriminant(self).hash_stable(__hcx, __hasher);
|
||||
match self {
|
||||
Bool => {}
|
||||
|
Loading…
Reference in New Issue
Block a user