Uplift ClauseKind and PredicateKind

This commit is contained in:
Michael Goulet 2023-10-20 20:43:33 +00:00
parent 249624b504
commit 573f475853
15 changed files with 735 additions and 217 deletions

View File

@ -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,
)

View File

@ -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) {

View File

@ -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

View File

@ -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)),

View File

@ -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,

View File

@ -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)]

View File

@ -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))
}
}

View File

@ -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);
}

View File

@ -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),

View File

@ -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);
}

View File

@ -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::*;

View File

@ -49,4 +49,5 @@ TrivialTypeTraversalImpls! {
u64,
String,
crate::DebruijnIndex,
crate::AliasRelationDirection,
}

View 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:?})")
}
}
}
}

View File

@ -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(_) => {

View File

@ -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 => {}