summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_type_ir/src/lib.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_type_ir/src/lib.rs
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_type_ir/src/lib.rs')
-rw-r--r--compiler/rustc_type_ir/src/lib.rs592
1 files changed, 21 insertions, 571 deletions
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 83401b65c..e8785fff2 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -1,310 +1,55 @@
#![feature(associated_type_defaults)]
#![feature(fmt_helpers_for_derive)]
+#![feature(get_mut_unchecked)]
#![feature(min_specialization)]
#![feature(never_type)]
+#![feature(new_uninit)]
#![feature(rustc_attrs)]
#![feature(unwrap_infallible)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![allow(internal_features)]
+extern crate self as rustc_type_ir;
+
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate rustc_macros;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::unify::{EqUnifyValue, UnifyKey};
-use smallvec::SmallVec;
use std::fmt;
-use std::fmt::Debug;
use std::hash::Hash;
-use std::mem::discriminant;
pub mod codec;
pub mod fold;
-pub mod sty;
pub mod ty_info;
+pub mod ty_kind;
pub mod visit;
#[macro_use]
mod macros;
-mod structural_impls;
-
+mod canonical;
+mod const_kind;
+mod debug;
+mod flags;
+mod interner;
+mod predicate_kind;
+mod region_kind;
+
+pub use canonical::*;
pub use codec::*;
-pub use structural_impls::{DebugWithInfcx, InferCtxtLike, OptWithInfcx};
-pub use sty::*;
+pub use const_kind::*;
+pub use debug::{DebugWithInfcx, InferCtxtLike, WithInfcx};
+pub use flags::*;
+pub use interner::*;
+pub use predicate_kind::*;
+pub use region_kind::*;
pub use ty_info::*;
+pub use ty_kind::*;
/// Needed so we can use #[derive(HashStable_Generic)]
pub trait HashStableContext {}
-pub trait Interner: Sized {
- type AdtDef: Clone + Debug + Hash + Ord;
- type GenericArgsRef: Clone
- + DebugWithInfcx<Self>
- + Hash
- + Ord
- + IntoIterator<Item = Self::GenericArg>;
- type GenericArg: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type DefId: Clone + Debug + Hash + Ord;
- type Binder<T>;
- type Ty: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type Const: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type Region: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type Predicate;
- type TypeAndMut: Clone + Debug + Hash + Ord;
- type Mutability: Clone + Debug + Hash + Ord;
- type Movability: Clone + Debug + Hash + Ord;
- type PolyFnSig: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type ListBinderExistentialPredicate: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type BinderListTy: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type ListTy: Clone + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
- type AliasTy: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type ParamTy: Clone + Debug + Hash + Ord;
- type BoundTy: Clone + Debug + Hash + Ord;
- type PlaceholderType: Clone + Debug + Hash + Ord;
- type InferTy: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type ErrorGuaranteed: Clone + Debug + Hash + Ord;
- type PredicateKind: Clone + Debug + Hash + PartialEq + Eq;
- type AllocId: Clone + Debug + Hash + Ord;
-
- type InferConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type AliasConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type PlaceholderConst: Clone + Debug + Hash + Ord;
- type ParamConst: Clone + Debug + Hash + Ord;
- type BoundConst: Clone + Debug + Hash + Ord;
- type ValueConst: Clone + Debug + Hash + Ord;
- type ExprConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
-
- type EarlyBoundRegion: Clone + Debug + Hash + Ord;
- type BoundRegion: Clone + Debug + Hash + Ord;
- type FreeRegion: Clone + Debug + Hash + Ord;
- type RegionVid: Clone + DebugWithInfcx<Self> + Hash + Ord;
- type PlaceholderRegion: Clone + Debug + Hash + Ord;
-
- fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Self::Mutability);
- fn mutability_is_mut(mutbl: Self::Mutability) -> bool;
-}
-
-/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
-/// that produces `T` items. You could combine them with
-/// `f(&iter.collect::<Vec<_>>())`, but this requires allocating memory for the
-/// `Vec`.
-///
-/// This trait allows for faster implementations, intended for cases where the
-/// number of items produced by the iterator is small. There is a blanket impl
-/// for `T` items, but there is also a fallible impl for `Result<T, E>` items.
-pub trait CollectAndApply<T, R>: Sized {
- type Output;
-
- /// Produce a result of type `Self::Output` from `iter`. The result will
- /// typically be produced by applying `f` on the elements produced by
- /// `iter`, though this may not happen in some impls, e.g. if an error
- /// occurred during iteration.
- fn collect_and_apply<I, F>(iter: I, f: F) -> Self::Output
- where
- I: Iterator<Item = Self>,
- F: FnOnce(&[T]) -> R;
-}
-
-/// The blanket impl that always collects all elements and applies `f`.
-impl<T, R> CollectAndApply<T, R> for T {
- type Output = R;
-
- /// Equivalent to `f(&iter.collect::<Vec<_>>())`.
- fn collect_and_apply<I, F>(mut iter: I, f: F) -> R
- where
- I: Iterator<Item = T>,
- F: FnOnce(&[T]) -> R,
- {
- // This code is hot enough that it's worth specializing for the most
- // common length lists, to avoid the overhead of `SmallVec` creation.
- // Lengths 0, 1, and 2 typically account for ~95% of cases. If
- // `size_hint` is incorrect a panic will occur via an `unwrap` or an
- // `assert`.
- match iter.size_hint() {
- (0, Some(0)) => {
- assert!(iter.next().is_none());
- f(&[])
- }
- (1, Some(1)) => {
- let t0 = iter.next().unwrap();
- assert!(iter.next().is_none());
- f(&[t0])
- }
- (2, Some(2)) => {
- let t0 = iter.next().unwrap();
- let t1 = iter.next().unwrap();
- assert!(iter.next().is_none());
- f(&[t0, t1])
- }
- _ => f(&iter.collect::<SmallVec<[_; 8]>>()),
- }
- }
-}
-
-/// A fallible impl that will fail, without calling `f`, if there are any
-/// errors during collection.
-impl<T, R, E> CollectAndApply<T, R> for Result<T, E> {
- type Output = Result<R, E>;
-
- /// Equivalent to `Ok(f(&iter.collect::<Result<Vec<_>>>()?))`.
- fn collect_and_apply<I, F>(mut iter: I, f: F) -> Result<R, E>
- where
- I: Iterator<Item = Result<T, E>>,
- F: FnOnce(&[T]) -> R,
- {
- // This code is hot enough that it's worth specializing for the most
- // common length lists, to avoid the overhead of `SmallVec` creation.
- // Lengths 0, 1, and 2 typically account for ~95% of cases. If
- // `size_hint` is incorrect a panic will occur via an `unwrap` or an
- // `assert`, unless a failure happens first, in which case the result
- // will be an error anyway.
- Ok(match iter.size_hint() {
- (0, Some(0)) => {
- assert!(iter.next().is_none());
- f(&[])
- }
- (1, Some(1)) => {
- let t0 = iter.next().unwrap()?;
- assert!(iter.next().is_none());
- f(&[t0])
- }
- (2, Some(2)) => {
- let t0 = iter.next().unwrap()?;
- let t1 = iter.next().unwrap()?;
- assert!(iter.next().is_none());
- f(&[t0, t1])
- }
- _ => f(&iter.collect::<Result<SmallVec<[_; 8]>, _>>()?),
- })
- }
-}
-
-bitflags! {
- /// Flags that we track on types. These flags are propagated upwards
- /// through the type during type construction, so that we can quickly check
- /// whether the type has various kinds of types in it without recursing
- /// over the type itself.
- pub struct TypeFlags: u32 {
- // Does this have parameters? Used to determine whether substitution is
- // required.
- /// Does this have `Param`?
- const HAS_TY_PARAM = 1 << 0;
- /// Does this have `ReEarlyBound`?
- const HAS_RE_PARAM = 1 << 1;
- /// Does this have `ConstKind::Param`?
- const HAS_CT_PARAM = 1 << 2;
-
- const HAS_PARAM = TypeFlags::HAS_TY_PARAM.bits
- | TypeFlags::HAS_RE_PARAM.bits
- | TypeFlags::HAS_CT_PARAM.bits;
-
- /// Does this have `Infer`?
- const HAS_TY_INFER = 1 << 3;
- /// Does this have `ReVar`?
- const HAS_RE_INFER = 1 << 4;
- /// Does this have `ConstKind::Infer`?
- const HAS_CT_INFER = 1 << 5;
-
- /// Does this have inference variables? Used to determine whether
- /// inference is required.
- const HAS_INFER = TypeFlags::HAS_TY_INFER.bits
- | TypeFlags::HAS_RE_INFER.bits
- | TypeFlags::HAS_CT_INFER.bits;
-
- /// Does this have `Placeholder`?
- const HAS_TY_PLACEHOLDER = 1 << 6;
- /// Does this have `RePlaceholder`?
- const HAS_RE_PLACEHOLDER = 1 << 7;
- /// Does this have `ConstKind::Placeholder`?
- const HAS_CT_PLACEHOLDER = 1 << 8;
-
- /// Does this have placeholders?
- const HAS_PLACEHOLDER = TypeFlags::HAS_TY_PLACEHOLDER.bits
- | TypeFlags::HAS_RE_PLACEHOLDER.bits
- | TypeFlags::HAS_CT_PLACEHOLDER.bits;
-
- /// `true` if there are "names" of regions and so forth
- /// that are local to a particular fn/inferctxt
- const HAS_FREE_LOCAL_REGIONS = 1 << 9;
-
- /// `true` if there are "names" of types and regions and so forth
- /// that are local to a particular fn
- const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_PARAM.bits
- | TypeFlags::HAS_CT_PARAM.bits
- | TypeFlags::HAS_TY_INFER.bits
- | TypeFlags::HAS_CT_INFER.bits
- | TypeFlags::HAS_TY_PLACEHOLDER.bits
- | TypeFlags::HAS_CT_PLACEHOLDER.bits
- // We consider 'freshened' types and constants
- // to depend on a particular fn.
- // The freshening process throws away information,
- // which can make things unsuitable for use in a global
- // cache. Note that there is no 'fresh lifetime' flag -
- // freshening replaces all lifetimes with `ReErased`,
- // which is different from how types/const are freshened.
- | TypeFlags::HAS_TY_FRESH.bits
- | TypeFlags::HAS_CT_FRESH.bits
- | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits
- | TypeFlags::HAS_RE_ERASED.bits;
-
- /// Does this have `Projection`?
- const HAS_TY_PROJECTION = 1 << 10;
- /// Does this have `Inherent`?
- const HAS_TY_INHERENT = 1 << 11;
- /// Does this have `Opaque`?
- const HAS_TY_OPAQUE = 1 << 12;
- /// Does this have `ConstKind::Unevaluated`?
- const HAS_CT_PROJECTION = 1 << 13;
-
- /// Could this type be normalized further?
- const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits
- | TypeFlags::HAS_TY_OPAQUE.bits
- | TypeFlags::HAS_TY_INHERENT.bits
- | TypeFlags::HAS_CT_PROJECTION.bits;
-
- /// Is an error type/const reachable?
- const HAS_ERROR = 1 << 14;
-
- /// Does this have any region that "appears free" in the type?
- /// Basically anything but `ReLateBound` and `ReErased`.
- const HAS_FREE_REGIONS = 1 << 15;
-
- /// Does this have any `ReLateBound` regions?
- const HAS_RE_LATE_BOUND = 1 << 16;
- /// Does this have any `Bound` types?
- const HAS_TY_LATE_BOUND = 1 << 17;
- /// Does this have any `ConstKind::Bound` consts?
- const HAS_CT_LATE_BOUND = 1 << 18;
- /// Does this have any bound variables?
- /// Used to check if a global bound is safe to evaluate.
- const HAS_LATE_BOUND = TypeFlags::HAS_RE_LATE_BOUND.bits
- | TypeFlags::HAS_TY_LATE_BOUND.bits
- | TypeFlags::HAS_CT_LATE_BOUND.bits;
-
- /// Does this have any `ReErased` regions?
- const HAS_RE_ERASED = 1 << 19;
-
- /// Does this value have parameters/placeholders/inference variables which could be
- /// replaced later, in a way that would change the results of `impl` specialization?
- const STILL_FURTHER_SPECIALIZABLE = 1 << 20;
-
- /// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`?
- const HAS_TY_FRESH = 1 << 21;
-
- /// Does this value have `InferConst::Fresh`?
- const HAS_CT_FRESH = 1 << 22;
-
- /// Does this have `Generator` or `GeneratorWitness`?
- const HAS_TY_GENERATOR = 1 << 23;
-
- /// Does this have any binders with bound vars (e.g. that need to be anonymized)?
- const HAS_BINDER_VARS = 1 << 24;
- }
-}
-
rustc_index::newtype_index! {
/// A [De Bruijn index][dbi] is a standard means of representing
/// regions (and perhaps later types) in a higher-ranked setting. In
@@ -428,259 +173,6 @@ pub fn debug_bound_var<T: std::fmt::Write>(
}
}
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
-pub enum IntTy {
- Isize,
- I8,
- I16,
- I32,
- I64,
- I128,
-}
-
-impl IntTy {
- pub fn name_str(&self) -> &'static str {
- match *self {
- IntTy::Isize => "isize",
- IntTy::I8 => "i8",
- IntTy::I16 => "i16",
- IntTy::I32 => "i32",
- IntTy::I64 => "i64",
- IntTy::I128 => "i128",
- }
- }
-
- pub fn bit_width(&self) -> Option<u64> {
- Some(match *self {
- IntTy::Isize => return None,
- IntTy::I8 => 8,
- IntTy::I16 => 16,
- IntTy::I32 => 32,
- IntTy::I64 => 64,
- IntTy::I128 => 128,
- })
- }
-
- pub fn normalize(&self, target_width: u32) -> Self {
- match self {
- IntTy::Isize => match target_width {
- 16 => IntTy::I16,
- 32 => IntTy::I32,
- 64 => IntTy::I64,
- _ => unreachable!(),
- },
- _ => *self,
- }
- }
-
- pub fn to_unsigned(self) -> UintTy {
- match self {
- IntTy::Isize => UintTy::Usize,
- IntTy::I8 => UintTy::U8,
- IntTy::I16 => UintTy::U16,
- IntTy::I32 => UintTy::U32,
- IntTy::I64 => UintTy::U64,
- IntTy::I128 => UintTy::U128,
- }
- }
-}
-
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
-pub enum UintTy {
- Usize,
- U8,
- U16,
- U32,
- U64,
- U128,
-}
-
-impl UintTy {
- pub fn name_str(&self) -> &'static str {
- match *self {
- UintTy::Usize => "usize",
- UintTy::U8 => "u8",
- UintTy::U16 => "u16",
- UintTy::U32 => "u32",
- UintTy::U64 => "u64",
- UintTy::U128 => "u128",
- }
- }
-
- pub fn bit_width(&self) -> Option<u64> {
- Some(match *self {
- UintTy::Usize => return None,
- UintTy::U8 => 8,
- UintTy::U16 => 16,
- UintTy::U32 => 32,
- UintTy::U64 => 64,
- UintTy::U128 => 128,
- })
- }
-
- pub fn normalize(&self, target_width: u32) -> Self {
- match self {
- UintTy::Usize => match target_width {
- 16 => UintTy::U16,
- 32 => UintTy::U32,
- 64 => UintTy::U64,
- _ => unreachable!(),
- },
- _ => *self,
- }
- }
-
- pub fn to_signed(self) -> IntTy {
- match self {
- UintTy::Usize => IntTy::Isize,
- UintTy::U8 => IntTy::I8,
- UintTy::U16 => IntTy::I16,
- UintTy::U32 => IntTy::I32,
- UintTy::U64 => IntTy::I64,
- UintTy::U128 => IntTy::I128,
- }
- }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[derive(Encodable, Decodable, HashStable_Generic)]
-pub enum FloatTy {
- F32,
- F64,
-}
-
-impl FloatTy {
- pub fn name_str(self) -> &'static str {
- match self {
- FloatTy::F32 => "f32",
- FloatTy::F64 => "f64",
- }
- }
-
- pub fn bit_width(self) -> u64 {
- match self {
- FloatTy::F32 => 32,
- FloatTy::F64 => 64,
- }
- }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq)]
-pub enum IntVarValue {
- IntType(IntTy),
- UintType(UintTy),
-}
-
-#[derive(Clone, Copy, PartialEq, Eq)]
-pub struct FloatVarValue(pub FloatTy);
-
-rustc_index::newtype_index! {
- /// A **ty**pe **v**ariable **ID**.
- #[debug_format = "?{}t"]
- pub struct TyVid {}
-}
-
-rustc_index::newtype_index! {
- /// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**.
- #[debug_format = "?{}i"]
- pub struct IntVid {}
-}
-
-rustc_index::newtype_index! {
- /// A **float**ing-point (`f32` or `f64`) type **v**ariable **ID**.
- #[debug_format = "?{}f"]
- pub struct FloatVid {}
-}
-
-/// A placeholder for a type that hasn't been inferred yet.
-///
-/// E.g., if we have an empty array (`[]`), then we create a fresh
-/// type variable for the element type since we won't know until it's
-/// used what the element type is supposed to be.
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
-pub enum InferTy {
- /// A type variable.
- TyVar(TyVid),
- /// An integral type variable (`{integer}`).
- ///
- /// These are created when the compiler sees an integer literal like
- /// `1` that could be several different types (`u8`, `i32`, `u32`, etc.).
- /// We don't know until it's used what type it's supposed to be, so
- /// we create a fresh type variable.
- IntVar(IntVid),
- /// A floating-point type variable (`{float}`).
- ///
- /// These are created when the compiler sees an float literal like
- /// `1.0` that could be either an `f32` or an `f64`.
- /// We don't know until it's used what type it's supposed to be, so
- /// we create a fresh type variable.
- FloatVar(FloatVid),
-
- /// A [`FreshTy`][Self::FreshTy] is one that is generated as a replacement
- /// for an unbound type variable. This is convenient for caching etc. See
- /// `rustc_infer::infer::freshen` for more details.
- ///
- /// Compare with [`TyVar`][Self::TyVar].
- FreshTy(u32),
- /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`IntVar`][Self::IntVar].
- FreshIntTy(u32),
- /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`FloatVar`][Self::FloatVar].
- FreshFloatTy(u32),
-}
-
-/// Raw `TyVid` are used as the unification key for `sub_relations`;
-/// they carry no values.
-impl UnifyKey for TyVid {
- type Value = ();
- #[inline]
- fn index(&self) -> u32 {
- self.as_u32()
- }
- #[inline]
- fn from_index(i: u32) -> TyVid {
- TyVid::from_u32(i)
- }
- fn tag() -> &'static str {
- "TyVid"
- }
-}
-
-impl EqUnifyValue for IntVarValue {}
-
-impl UnifyKey for IntVid {
- type Value = Option<IntVarValue>;
- #[inline] // make this function eligible for inlining - it is quite hot.
- fn index(&self) -> u32 {
- self.as_u32()
- }
- #[inline]
- fn from_index(i: u32) -> IntVid {
- IntVid::from_u32(i)
- }
- fn tag() -> &'static str {
- "IntVid"
- }
-}
-
-impl EqUnifyValue for FloatVarValue {}
-
-impl UnifyKey for FloatVid {
- type Value = Option<FloatVarValue>;
- #[inline]
- fn index(&self) -> u32 {
- self.as_u32()
- }
- #[inline]
- fn from_index(i: u32) -> FloatVid {
- FloatVid::from_u32(i)
- }
- fn tag() -> &'static str {
- "FloatVid"
- }
-}
-
#[derive(Copy, Clone, PartialEq, Eq, Decodable, Encodable, Hash, HashStable_Generic)]
#[rustc_pass_by_value]
pub enum Variance {
@@ -750,34 +242,6 @@ impl Variance {
}
}
-impl<CTX> HashStable<CTX> for InferTy {
- fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
- use InferTy::*;
- discriminant(self).hash_stable(ctx, hasher);
- match self {
- TyVar(_) | IntVar(_) | FloatVar(_) => {
- panic!("type variables should not be hashed: {self:?}")
- }
- FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher),
- }
- }
-}
-
-impl fmt::Debug for IntVarValue {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match *self {
- IntVarValue::IntType(ref v) => v.fmt(f),
- IntVarValue::UintType(ref v) => v.fmt(f),
- }
- }
-}
-
-impl fmt::Debug for FloatVarValue {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
impl fmt::Debug for Variance {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match *self {
@@ -789,20 +253,6 @@ impl fmt::Debug for Variance {
}
}
-impl fmt::Display for InferTy {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- use InferTy::*;
- match *self {
- TyVar(_) => write!(f, "_"),
- IntVar(_) => write!(f, "{}", "{integer}"),
- FloatVar(_) => write!(f, "{}", "{float}"),
- FreshTy(v) => write!(f, "FreshTy({v})"),
- FreshIntTy(v) => write!(f, "FreshIntTy({v})"),
- FreshFloatTy(v) => write!(f, "FreshFloatTy({v})"),
- }
- }
-}
-
rustc_index::newtype_index! {
/// "Universes" are used during type- and trait-checking in the
/// presence of `for<..>` binders to control what sets of names are