Remove Ord from Ty, Const, and Region

This commit is contained in:
Oli Scherer 2024-03-21 13:10:28 +00:00
parent 939df293d8
commit dc95bd69f2
12 changed files with 51 additions and 86 deletions

View File

@ -1018,7 +1018,11 @@ impl<'tcx> PatRangeBoundary<'tcx> {
(Finite(mir::Const::Ty(a)), Finite(mir::Const::Ty(b))) (Finite(mir::Const::Ty(a)), Finite(mir::Const::Ty(b)))
if matches!(ty.kind(), ty::Uint(_) | ty::Char) => if matches!(ty.kind(), ty::Uint(_) | ty::Char) =>
{ {
return Some(a.kind().cmp(&b.kind())); if let Some(a) = a.try_to_valtree() {
if let Some(b) = b.try_to_valtree() {
return Some(a.cmp(&b));
}
}
} }
( (
Finite(mir::Const::Val(mir::ConstValue::Scalar(Scalar::Int(a)), _)), Finite(mir::Const::Val(mir::ConstValue::Scalar(Scalar::Int(a)), _)),

View File

@ -23,7 +23,7 @@ pub use valtree::*;
pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>; pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
/// Use this rather than `ConstData`, whenever possible. /// Use this rather than `ConstData`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
#[rustc_pass_by_value] #[rustc_pass_by_value]
pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>); pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>);
@ -52,7 +52,7 @@ impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
} }
/// Typed constant value. /// Typed constant value.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[derive(HashStable, TyEncodable, TyDecodable)] #[derive(HashStable, TyEncodable, TyDecodable)]
pub struct ConstData<'tcx> { pub struct ConstData<'tcx> {
pub ty: Ty<'tcx>, pub ty: Ty<'tcx>,

View File

@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
use rustc_macros::HashStable; use rustc_macros::HashStable;
/// An unevaluated (potentially generic) constant used in the type-system. /// An unevaluated (potentially generic) constant used in the type-system.
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Copy, Clone, Eq, PartialEq, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct UnevaluatedConst<'tcx> { pub struct UnevaluatedConst<'tcx> {
pub def: DefId, pub def: DefId,
@ -62,7 +62,7 @@ impl<'tcx> UnevaluatedConst<'tcx> {
} }
} }
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Eq, PartialEq, Hash)]
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
pub enum Expr<'tcx> { pub enum Expr<'tcx> {
Binop(mir::BinOp, Const<'tcx>, Const<'tcx>), Binop(mir::BinOp, Const<'tcx>, Const<'tcx>),

View File

@ -17,7 +17,6 @@ use rustc_type_ir::WithCachedTypeInfo;
use smallvec::SmallVec; use smallvec::SmallVec;
use core::intrinsics; use core::intrinsics;
use std::cmp::Ordering;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
use std::num::NonZero; use std::num::NonZero;
@ -68,7 +67,7 @@ const TYPE_TAG: usize = 0b00;
const REGION_TAG: usize = 0b01; const REGION_TAG: usize = 0b01;
const CONST_TAG: usize = 0b10; const CONST_TAG: usize = 0b10;
#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)] #[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, HashStable)]
pub enum GenericArgKind<'tcx> { pub enum GenericArgKind<'tcx> {
Lifetime(ty::Region<'tcx>), Lifetime(ty::Region<'tcx>),
Type(Ty<'tcx>), Type(Ty<'tcx>),
@ -100,18 +99,6 @@ impl<'tcx> GenericArgKind<'tcx> {
} }
} }
impl<'tcx> Ord for GenericArg<'tcx> {
fn cmp(&self, other: &GenericArg<'tcx>) -> Ordering {
self.unpack().cmp(&other.unpack())
}
}
impl<'tcx> PartialOrd for GenericArg<'tcx> {
fn partial_cmp(&self, other: &GenericArg<'tcx>) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<'tcx> From<ty::Region<'tcx>> for GenericArg<'tcx> { impl<'tcx> From<ty::Region<'tcx>> for GenericArg<'tcx> {
#[inline] #[inline]
fn from(r: ty::Region<'tcx>) -> GenericArg<'tcx> { fn from(r: ty::Region<'tcx>) -> GenericArg<'tcx> {

View File

@ -517,7 +517,7 @@ pub struct CReaderCacheKey {
} }
/// Use this rather than `TyKind`, whenever possible. /// Use this rather than `TyKind`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
#[rustc_diagnostic_item = "Ty"] #[rustc_diagnostic_item = "Ty"]
#[rustc_pass_by_value] #[rustc_pass_by_value]
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>); pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
@ -702,7 +702,7 @@ const TAG_MASK: usize = 0b11;
const TYPE_TAG: usize = 0b00; const TYPE_TAG: usize = 0b00;
const CONST_TAG: usize = 0b01; const CONST_TAG: usize = 0b01;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable)] #[derive(HashStable, TypeFoldable, TypeVisitable)]
pub enum TermKind<'tcx> { pub enum TermKind<'tcx> {
Ty(Ty<'tcx>), Ty(Ty<'tcx>),
@ -980,7 +980,7 @@ impl PlaceholderLike for PlaceholderType {
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)] #[derive(TyEncodable, TyDecodable)]
pub struct BoundConst<'tcx> { pub struct BoundConst<'tcx> {
pub var: BoundVar, pub var: BoundVar,
pub ty: Ty<'tcx>, pub ty: Ty<'tcx>,

View File

@ -192,7 +192,7 @@ impl<'tcx> Clause<'tcx> {
} }
} }
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub enum ExistentialPredicate<'tcx> { pub enum ExistentialPredicate<'tcx> {
/// E.g., `Iterator`. /// E.g., `Iterator`.
@ -336,7 +336,7 @@ impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
/// ///
/// Trait references also appear in object types like `Foo<U>`, but in /// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the generic parameters. /// that case the `Self` parameter is absent from the generic parameters.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct TraitRef<'tcx> { pub struct TraitRef<'tcx> {
pub def_id: DefId, pub def_id: DefId,
@ -420,7 +420,7 @@ impl<'tcx> IntoDiagArg for TraitRef<'tcx> {
/// ``` /// ```
/// The generic parameters don't include the erased `Self`, only trait /// The generic parameters don't include the erased `Self`, only trait
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ExistentialTraitRef<'tcx> { pub struct ExistentialTraitRef<'tcx> {
pub def_id: DefId, pub def_id: DefId,
@ -476,7 +476,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
} }
/// A `ProjectionPredicate` for an `ExistentialTraitRef`. /// A `ProjectionPredicate` for an `ExistentialTraitRef`.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ExistentialProjection<'tcx> { pub struct ExistentialProjection<'tcx> {
pub def_id: DefId, pub def_id: DefId,

View File

@ -14,7 +14,7 @@ use crate::ty::{self, BoundVar, TyCtxt, TypeFlags};
pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>; pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
/// Use this rather than `RegionKind`, whenever possible. /// Use this rather than `RegionKind`, whenever possible.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
#[rustc_pass_by_value] #[rustc_pass_by_value]
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>); pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);

View File

@ -1109,7 +1109,7 @@ where
/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`. /// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
/// * For an inherent projection, this would be `Ty::N<...>`. /// * For an inherent projection, this would be `Ty::N<...>`.
/// * For an opaque type, there is no explicit syntax. /// * For an opaque type, there is no explicit syntax.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct AliasTy<'tcx> { pub struct AliasTy<'tcx> {
/// The parameters of the associated or opaque item. /// The parameters of the associated or opaque item.
@ -1278,7 +1278,7 @@ pub struct GenSig<'tcx> {
/// - `inputs`: is the list of arguments and their modes. /// - `inputs`: is the list of arguments and their modes.
/// - `output`: is the return type. /// - `output`: is the return type.
/// - `c_variadic`: indicates whether this is a C-variadic function. /// - `c_variadic`: indicates whether this is a C-variadic function.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct FnSig<'tcx> { pub struct FnSig<'tcx> {
pub inputs_and_output: &'tcx List<Ty<'tcx>>, pub inputs_and_output: &'tcx List<Ty<'tcx>>,
@ -2661,7 +2661,7 @@ impl<'tcx> Ty<'tcx> {
/// a miscompilation or unsoundness. /// a miscompilation or unsoundness.
/// ///
/// When in doubt, use `VarianceDiagInfo::default()` /// When in doubt, use `VarianceDiagInfo::default()`
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub enum VarianceDiagInfo<'tcx> { pub enum VarianceDiagInfo<'tcx> {
/// No additional information - this is the default. /// No additional information - this is the default.
/// We will not add any additional information to error messages. /// We will not add any additional information to error messages.

View File

@ -8,15 +8,7 @@ use self::ConstKind::*;
/// Represents a constant in Rust. /// Represents a constant in Rust.
#[derive(derivative::Derivative)] #[derive(derivative::Derivative)]
#[derivative( #[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))]
Clone(bound = ""),
Copy(bound = ""),
PartialOrd(bound = ""),
PartialOrd = "feature_allow_slow_enum",
Ord(bound = ""),
Ord = "feature_allow_slow_enum",
Hash(bound = "")
)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
pub enum ConstKind<I: Interner> { pub enum ConstKind<I: Interner> {
/// A const generic parameter. /// A const generic parameter.

View File

@ -10,15 +10,15 @@ use crate::{
pub trait Interner: Sized { pub trait Interner: Sized {
type DefId: Copy + Debug + Hash + Ord; type DefId: Copy + Debug + Hash + Ord;
type AdtDef: Copy + Debug + Hash + Ord; type AdtDef: Copy + Debug + Hash + Eq;
type GenericArgs: Copy type GenericArgs: Copy
+ DebugWithInfcx<Self> + DebugWithInfcx<Self>
+ Hash + Hash
+ Ord + Eq
+ IntoIterator<Item = Self::GenericArg>; + IntoIterator<Item = Self::GenericArg>;
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord; type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq;
type Term: Copy + Debug + Hash + Ord; type Term: Copy + Debug + Hash + Eq;
type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>; type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>;
type BoundVars: IntoIterator<Item = Self::BoundVar>; type BoundVars: IntoIterator<Item = Self::BoundVar>;
@ -30,56 +30,56 @@ pub trait Interner: Sized {
type Ty: Copy type Ty: Copy
+ DebugWithInfcx<Self> + DebugWithInfcx<Self>
+ Hash + Hash
+ Ord + Eq
+ Into<Self::GenericArg> + Into<Self::GenericArg>
+ IntoKind<Kind = TyKind<Self>> + IntoKind<Kind = TyKind<Self>>
+ TypeSuperVisitable<Self> + TypeSuperVisitable<Self>
+ Flags + Flags
+ new::Ty<Self>; + new::Ty<Self>;
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>; type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord; type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Eq;
type ParamTy: Copy + Debug + Hash + Ord; type ParamTy: Copy + Debug + Hash + Eq;
type BoundTy: Copy + Debug + Hash + Ord; type BoundTy: Copy + Debug + Hash + Eq;
type PlaceholderTy: Copy + Debug + Hash + Ord + PlaceholderLike; type PlaceholderTy: Copy + Debug + Hash + Eq + PlaceholderLike;
// Things stored inside of tys // Things stored inside of tys
type ErrorGuaranteed: Copy + Debug + Hash + Ord; type ErrorGuaranteed: Copy + Debug + Hash + Eq;
type BoundExistentialPredicates: Copy + DebugWithInfcx<Self> + Hash + Ord; type BoundExistentialPredicates: Copy + DebugWithInfcx<Self> + Hash + Eq;
type PolyFnSig: Copy + DebugWithInfcx<Self> + Hash + Ord; type PolyFnSig: Copy + DebugWithInfcx<Self> + Hash + Eq;
type AllocId: Copy + Debug + Hash + Ord; type AllocId: Copy + Debug + Hash + Eq;
// Kinds of consts // Kinds of consts
type Const: Copy type Const: Copy
+ DebugWithInfcx<Self> + DebugWithInfcx<Self>
+ Hash + Hash
+ Ord + Eq
+ Into<Self::GenericArg> + Into<Self::GenericArg>
+ IntoKind<Kind = ConstKind<Self>> + IntoKind<Kind = ConstKind<Self>>
+ ConstTy<Self> + ConstTy<Self>
+ TypeSuperVisitable<Self> + TypeSuperVisitable<Self>
+ Flags + Flags
+ new::Const<Self>; + new::Const<Self>;
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord; type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike; type PlaceholderConst: Copy + Debug + Hash + Eq + PlaceholderLike;
type ParamConst: Copy + Debug + Hash + Ord; type ParamConst: Copy + Debug + Hash + Eq;
type BoundConst: Copy + Debug + Hash + Ord; type BoundConst: Copy + Debug + Hash + Eq;
type ValueConst: Copy + Debug + Hash + Ord; type ValueConst: Copy + Debug + Hash + Eq;
type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Ord; type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
// Kinds of regions // Kinds of regions
type Region: Copy type Region: Copy
+ DebugWithInfcx<Self> + DebugWithInfcx<Self>
+ Hash + Hash
+ Ord + Eq
+ Into<Self::GenericArg> + Into<Self::GenericArg>
+ IntoKind<Kind = RegionKind<Self>> + IntoKind<Kind = RegionKind<Self>>
+ Flags + Flags
+ new::Region<Self>; + new::Region<Self>;
type EarlyParamRegion: Copy + Debug + Hash + Ord; type EarlyParamRegion: Copy + Debug + Hash + Eq;
type LateParamRegion: Copy + Debug + Hash + Ord; type LateParamRegion: Copy + Debug + Hash + Eq;
type BoundRegion: Copy + Debug + Hash + Ord; type BoundRegion: Copy + Debug + Hash + Eq;
type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Ord; type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Eq;
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike; type PlaceholderRegion: Copy + Debug + Hash + Eq + PlaceholderLike;
// Predicates // Predicates
type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags; type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;

View File

@ -113,15 +113,7 @@ use self::RegionKind::*;
/// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
#[derive(derivative::Derivative)] #[derive(derivative::Derivative)]
#[derivative( #[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))]
Clone(bound = ""),
Copy(bound = ""),
PartialOrd(bound = ""),
PartialOrd = "feature_allow_slow_enum",
Ord(bound = ""),
Ord = "feature_allow_slow_enum",
Hash(bound = "")
)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))]
pub enum RegionKind<I: Interner> { pub enum RegionKind<I: Interner> {
/// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`. /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`.

View File

@ -63,15 +63,7 @@ impl AliasKind {
/// converted to this representation using `<dyn HirTyLowerer>::lower_ty`. /// converted to this representation using `<dyn HirTyLowerer>::lower_ty`.
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")] #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
#[derive(derivative::Derivative)] #[derive(derivative::Derivative)]
#[derivative( #[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))]
Clone(bound = ""),
Copy(bound = ""),
PartialOrd(bound = ""),
PartialOrd = "feature_allow_slow_enum",
Ord(bound = ""),
Ord = "feature_allow_slow_enum",
Hash(bound = "")
)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
pub enum TyKind<I: Interner> { pub enum TyKind<I: Interner> {
/// The primitive boolean type. Written as `bool`. /// The primitive boolean type. Written as `bool`.
@ -803,8 +795,6 @@ impl<I: Interner> DebugWithInfcx<I> for InferTy {
#[derivative( #[derivative(
Clone(bound = ""), Clone(bound = ""),
Copy(bound = ""), Copy(bound = ""),
PartialOrd(bound = ""),
Ord(bound = ""),
PartialEq(bound = ""), PartialEq(bound = ""),
Eq(bound = ""), Eq(bound = ""),
Hash(bound = ""), Hash(bound = ""),