Auto merge of #52984 - fabric-and-ink:remove-canonical-var, r=scalexm
Replace CanonicalVar with DebruijnIndex Close #49887
This commit is contained in:
commit
0e2f912050
13 changed files with 65 additions and 49 deletions
|
|
@ -147,7 +147,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::CanonicalVar {
|
||||
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundTyIndex {
|
||||
#[inline]
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'gcx>,
|
||||
|
|
@ -915,7 +915,7 @@ impl_stable_hash_for!(enum ty::InferTy {
|
|||
FreshTy(a),
|
||||
FreshIntTy(a),
|
||||
FreshFloatTy(a),
|
||||
CanonicalTy(a),
|
||||
BoundTy(a),
|
||||
});
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use infer::InferCtxt;
|
|||
use std::sync::atomic::Ordering;
|
||||
use ty::fold::{TypeFoldable, TypeFolder};
|
||||
use ty::subst::Kind;
|
||||
use ty::{self, CanonicalVar, Lift, List, Ty, TyCtxt, TypeFlags};
|
||||
use ty::{self, BoundTy, BoundTyIndex, Lift, List, Ty, TyCtxt, TypeFlags};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
|
@ -225,7 +225,7 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
|||
query_state: &'cx mut OriginalQueryValues<'tcx>,
|
||||
// Note that indices is only used once `var_values` is big enough to be
|
||||
// heap-allocated.
|
||||
indices: FxHashMap<Kind<'tcx>, CanonicalVar>,
|
||||
indices: FxHashMap<Kind<'tcx>, BoundTyIndex>,
|
||||
canonicalize_region_mode: &'cx dyn CanonicalizeRegionMode,
|
||||
needs_canonical_flags: TypeFlags,
|
||||
}
|
||||
|
|
@ -283,7 +283,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
|
|||
bug!("encountered a fresh type during canonicalization")
|
||||
}
|
||||
|
||||
ty::Infer(ty::CanonicalTy(_)) => {
|
||||
ty::Infer(ty::BoundTy(_)) => {
|
||||
bug!("encountered a canonical type during canonicalization")
|
||||
}
|
||||
|
||||
|
|
@ -393,7 +393,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
/// or returns an existing variable if `kind` has already been
|
||||
/// seen. `kind` is expected to be an unbound variable (or
|
||||
/// potentially a free region).
|
||||
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> CanonicalVar {
|
||||
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> BoundTy {
|
||||
let Canonicalizer {
|
||||
variables,
|
||||
query_state,
|
||||
|
|
@ -408,12 +408,12 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
// avoid allocations in those cases. We also don't use `indices` to
|
||||
// determine if a kind has been seen before until the limit of 8 has
|
||||
// been exceeded, to also avoid allocations for `indices`.
|
||||
if !var_values.spilled() {
|
||||
let var = if !var_values.spilled() {
|
||||
// `var_values` is stack-allocated. `indices` isn't used yet. Do a
|
||||
// direct linear search of `var_values`.
|
||||
if let Some(idx) = var_values.iter().position(|&k| k == kind) {
|
||||
// `kind` is already present in `var_values`.
|
||||
CanonicalVar::new(idx)
|
||||
BoundTyIndex::new(idx)
|
||||
} else {
|
||||
// `kind` isn't present in `var_values`. Append it. Likewise
|
||||
// for `info` and `variables`.
|
||||
|
|
@ -428,11 +428,11 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
*indices = var_values
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &kind)| (kind, CanonicalVar::new(i)))
|
||||
.map(|(i, &kind)| (kind, BoundTyIndex::new(i)))
|
||||
.collect();
|
||||
}
|
||||
// The cv is the index of the appended element.
|
||||
CanonicalVar::new(var_values.len() - 1)
|
||||
BoundTyIndex::new(var_values.len() - 1)
|
||||
}
|
||||
} else {
|
||||
// `var_values` is large. Do a hashmap search via `indices`.
|
||||
|
|
@ -440,8 +440,13 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
variables.push(info);
|
||||
var_values.push(kind);
|
||||
assert_eq!(variables.len(), var_values.len());
|
||||
CanonicalVar::new(variables.len() - 1)
|
||||
BoundTyIndex::new(variables.len() - 1)
|
||||
})
|
||||
};
|
||||
|
||||
BoundTy {
|
||||
level: ty::INNERMOST,
|
||||
var,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -449,8 +454,9 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
let info = CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Region,
|
||||
};
|
||||
let cvar = self.canonical_var(info, r.into());
|
||||
self.tcx().mk_region(ty::ReCanonical(cvar))
|
||||
let b = self.canonical_var(info, r.into());
|
||||
debug_assert_eq!(ty::INNERMOST, b.level);
|
||||
self.tcx().mk_region(ty::ReCanonical(b.var))
|
||||
}
|
||||
|
||||
/// Given a type variable `ty_var` of the given kind, first check
|
||||
|
|
@ -466,8 +472,9 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
let info = CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Ty(ty_kind),
|
||||
};
|
||||
let cvar = self.canonical_var(info, ty_var.into());
|
||||
self.tcx().mk_infer(ty::InferTy::CanonicalTy(cvar))
|
||||
let b = self.canonical_var(info, ty_var.into());
|
||||
debug_assert_eq!(ty::INNERMOST, b.level);
|
||||
self.tcx().mk_infer(ty::InferTy::BoundTy(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ use std::ops::Index;
|
|||
use syntax::source_map::Span;
|
||||
use ty::fold::TypeFoldable;
|
||||
use ty::subst::Kind;
|
||||
use ty::{self, CanonicalVar, Lift, Region, List, TyCtxt};
|
||||
use ty::{self, BoundTyIndex, Lift, Region, List, TyCtxt};
|
||||
|
||||
mod canonicalizer;
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ impl<'gcx> UseSpecializedDecodable for CanonicalVarInfos<'gcx> {}
|
|||
/// canonicalized query response.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
|
||||
pub struct CanonicalVarValues<'tcx> {
|
||||
pub var_values: IndexVec<CanonicalVar, Kind<'tcx>>,
|
||||
pub var_values: IndexVec<BoundTyIndex, Kind<'tcx>>,
|
||||
}
|
||||
|
||||
/// When we canonicalize a value to form a query, we wind up replacing
|
||||
|
|
@ -264,7 +264,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
span: Span,
|
||||
variables: &List<CanonicalVarInfo>,
|
||||
) -> CanonicalVarValues<'tcx> {
|
||||
let var_values: IndexVec<CanonicalVar, Kind<'tcx>> = variables
|
||||
let var_values: IndexVec<BoundTyIndex, Kind<'tcx>> = variables
|
||||
.iter()
|
||||
.map(|info| self.fresh_inference_var_for_canonical_var(span, *info))
|
||||
.collect();
|
||||
|
|
@ -367,10 +367,10 @@ BraceStructLiftImpl! {
|
|||
} where R: Lift<'tcx>
|
||||
}
|
||||
|
||||
impl<'tcx> Index<CanonicalVar> for CanonicalVarValues<'tcx> {
|
||||
impl<'tcx> Index<BoundTyIndex> for CanonicalVarValues<'tcx> {
|
||||
type Output = Kind<'tcx>;
|
||||
|
||||
fn index(&self, value: CanonicalVar) -> &Kind<'tcx> {
|
||||
fn index(&self, value: BoundTyIndex) -> &Kind<'tcx> {
|
||||
&self.var_values[value]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ use traits::{FulfillmentContext, TraitEngine};
|
|||
use traits::{Obligation, ObligationCause, PredicateObligation};
|
||||
use ty::fold::TypeFoldable;
|
||||
use ty::subst::{Kind, UnpackedKind};
|
||||
use ty::{self, CanonicalVar, Lift, Ty, TyCtxt};
|
||||
use ty::{self, BoundTyIndex, Lift, Ty, TyCtxt};
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> {
|
||||
/// The "main method" for a canonicalized trait query. Given the
|
||||
|
|
@ -273,7 +273,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
for (index, original_value) in original_values.var_values.iter().enumerate() {
|
||||
// ...with the value `v_r` of that variable from the query.
|
||||
let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| {
|
||||
&v.var_values[CanonicalVar::new(index)]
|
||||
&v.var_values[BoundTyIndex::new(index)]
|
||||
});
|
||||
match (original_value.unpack(), result_value.unpack()) {
|
||||
(UnpackedKind::Lifetime(ty::ReErased), UnpackedKind::Lifetime(ty::ReErased)) => {
|
||||
|
|
@ -408,7 +408,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
// is directly equal to one of the canonical variables in the
|
||||
// result, then we can type the corresponding value from the
|
||||
// input. See the example above.
|
||||
let mut opt_values: IndexVec<CanonicalVar, Option<Kind<'tcx>>> =
|
||||
let mut opt_values: IndexVec<BoundTyIndex, Option<Kind<'tcx>>> =
|
||||
IndexVec::from_elem_n(None, query_response.variables.len());
|
||||
|
||||
// In terms of our example above, we are iterating over pairs like:
|
||||
|
|
@ -417,9 +417,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
match result_value.unpack() {
|
||||
UnpackedKind::Type(result_value) => {
|
||||
// e.g., here `result_value` might be `?0` in the example above...
|
||||
if let ty::Infer(ty::InferTy::CanonicalTy(index)) = result_value.sty {
|
||||
if let ty::Infer(ty::InferTy::BoundTy(b)) = result_value.sty {
|
||||
// in which case we would set `canonical_vars[0]` to `Some(?U)`.
|
||||
opt_values[index] = Some(*original_value);
|
||||
opt_values[b.var] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
UnpackedKind::Lifetime(result_value) => {
|
||||
|
|
@ -440,7 +440,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
.variables
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, info)| opt_values[CanonicalVar::new(index)].unwrap_or_else(||
|
||||
.map(|(index, info)| opt_values[BoundTyIndex::new(index)].unwrap_or_else(||
|
||||
self.fresh_inference_var_for_canonical_var(cause.span, *info)
|
||||
))
|
||||
.collect(),
|
||||
|
|
@ -470,7 +470,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
// canonical variable; this is taken from
|
||||
// `query_response.var_values` after applying the substitution
|
||||
// `result_subst`.
|
||||
let substituted_query_response = |index: CanonicalVar| -> Kind<'tcx> {
|
||||
let substituted_query_response = |index: BoundTyIndex| -> Kind<'tcx> {
|
||||
query_response.substitute_projected(self.tcx, &result_subst, |v| &v.var_values[index])
|
||||
};
|
||||
|
||||
|
|
@ -526,12 +526,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
variables1: &OriginalQueryValues<'tcx>,
|
||||
variables2: impl Fn(CanonicalVar) -> Kind<'tcx>,
|
||||
variables2: impl Fn(BoundTyIndex) -> Kind<'tcx>,
|
||||
) -> InferResult<'tcx, ()> {
|
||||
self.commit_if_ok(|_| {
|
||||
let mut obligations = vec![];
|
||||
for (index, value1) in variables1.var_values.iter().enumerate() {
|
||||
let value2 = variables2(CanonicalVar::new(index));
|
||||
let value2 = variables2(BoundTyIndex::new(index));
|
||||
|
||||
match (value1.unpack(), value2.unpack()) {
|
||||
(UnpackedKind::Type(v1), UnpackedKind::Type(v2)) => {
|
||||
|
|
|
|||
|
|
@ -85,10 +85,11 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
|
|||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match t.sty {
|
||||
ty::Infer(ty::InferTy::CanonicalTy(c)) => {
|
||||
match self.var_values.var_values[c].unpack() {
|
||||
ty::Infer(ty::InferTy::BoundTy(b)) => {
|
||||
debug_assert_eq!(ty::INNERMOST, b.level);
|
||||
match self.var_values.var_values[b.var].unpack() {
|
||||
UnpackedKind::Type(ty) => ty,
|
||||
r => bug!("{:?} is a type but value is {:?}", c, r),
|
||||
r => bug!("{:?} is a type but value is {:?}", b, r),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
|
|||
t
|
||||
}
|
||||
|
||||
ty::Infer(ty::CanonicalTy(..)) =>
|
||||
ty::Infer(ty::BoundTy(..)) =>
|
||||
bug!("encountered canonical ty during freshening"),
|
||||
|
||||
ty::Generator(..) |
|
||||
|
|
|
|||
|
|
@ -2421,7 +2421,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
ty::Infer(ty::TyVar(_)) => Ambiguous,
|
||||
|
||||
ty::UnnormalizedProjection(..)
|
||||
| ty::Infer(ty::CanonicalTy(_))
|
||||
| ty::Infer(ty::BoundTy(_))
|
||||
| ty::Infer(ty::FreshTy(_))
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
| ty::Infer(ty::FreshFloatTy(_)) => {
|
||||
|
|
@ -2506,7 +2506,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
ty::UnnormalizedProjection(..)
|
||||
| ty::Infer(ty::CanonicalTy(_))
|
||||
| ty::Infer(ty::BoundTy(_))
|
||||
| ty::Infer(ty::FreshTy(_))
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
| ty::Infer(ty::FreshFloatTy(_)) => {
|
||||
|
|
@ -2549,7 +2549,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
| ty::Param(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Projection(..)
|
||||
| ty::Infer(ty::CanonicalTy(_))
|
||||
| ty::Infer(ty::BoundTy(_))
|
||||
| ty::Infer(ty::TyVar(_))
|
||||
| ty::Infer(ty::FreshTy(_))
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
|
|||
ty::Infer(ty::TyVar(_)) => "inferred type".into(),
|
||||
ty::Infer(ty::IntVar(_)) => "integral variable".into(),
|
||||
ty::Infer(ty::FloatVar(_)) => "floating-point variable".into(),
|
||||
ty::Infer(ty::CanonicalTy(_)) |
|
||||
ty::Infer(ty::BoundTy(_)) |
|
||||
ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
|
||||
ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
|
||||
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ impl FlagComputation {
|
|||
ty::FreshTy(_) |
|
||||
ty::FreshIntTy(_) |
|
||||
ty::FreshFloatTy(_) |
|
||||
ty::CanonicalTy(_) => {
|
||||
ty::BoundTy(_) => {
|
||||
self.add_flags(TypeFlags::HAS_CANONICAL_VARS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
|
|||
|
||||
use hir;
|
||||
|
||||
pub use self::sty::{Binder, CanonicalVar, DebruijnIndex, INNERMOST};
|
||||
pub use self::sty::{Binder, BoundTy, BoundTyIndex, DebruijnIndex, INNERMOST};
|
||||
pub use self::sty::{FnSig, GenSig, PolyFnSig, PolyGenSig};
|
||||
pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
|
||||
pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut};
|
||||
|
|
|
|||
|
|
@ -1165,7 +1165,7 @@ pub enum RegionKind {
|
|||
ReClosureBound(RegionVid),
|
||||
|
||||
/// Canonicalized region, used only when preparing a trait query.
|
||||
ReCanonical(CanonicalVar),
|
||||
ReCanonical(BoundTyIndex),
|
||||
}
|
||||
|
||||
impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
|
||||
|
|
@ -1217,14 +1217,22 @@ pub enum InferTy {
|
|||
FreshIntTy(u32),
|
||||
FreshFloatTy(u32),
|
||||
|
||||
/// Canonicalized type variable, used only when preparing a trait query.
|
||||
CanonicalTy(CanonicalVar),
|
||||
/// Bound type variable, used only when preparing a trait query.
|
||||
BoundTy(BoundTy),
|
||||
}
|
||||
|
||||
newtype_index! {
|
||||
pub struct CanonicalVar { .. }
|
||||
pub struct BoundTyIndex { .. }
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct BoundTy {
|
||||
pub level: DebruijnIndex,
|
||||
pub var: BoundTyIndex,
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct BoundTy { level, var });
|
||||
|
||||
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct ExistentialProjection<'tcx> {
|
||||
|
|
@ -1919,7 +1927,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
|
||||
ty::Infer(ty::TyVar(_)) => false,
|
||||
|
||||
ty::Infer(ty::CanonicalTy(_)) |
|
||||
ty::Infer(ty::BoundTy(_)) |
|
||||
ty::Infer(ty::FreshTy(_)) |
|
||||
ty::Infer(ty::FreshIntTy(_)) |
|
||||
ty::Infer(ty::FreshFloatTy(_)) =>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
use hir::def_id::DefId;
|
||||
use infer::canonical::Canonical;
|
||||
use ty::{self, CanonicalVar, Lift, List, Ty, TyCtxt};
|
||||
use ty::{self, BoundTyIndex, Lift, List, Ty, TyCtxt};
|
||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
|
||||
use serialize::{self, Encodable, Encoder, Decodable, Decoder};
|
||||
|
|
@ -553,10 +553,10 @@ impl CanonicalUserSubsts<'tcx> {
|
|||
return false;
|
||||
}
|
||||
|
||||
self.value.substs.iter().zip(CanonicalVar::new(0)..).all(|(kind, cvar)| {
|
||||
self.value.substs.iter().zip(BoundTyIndex::new(0)..).all(|(kind, cvar)| {
|
||||
match kind.unpack() {
|
||||
UnpackedKind::Type(ty) => match ty.sty {
|
||||
ty::Infer(ty::CanonicalTy(cvar1)) => cvar == cvar1,
|
||||
ty::Infer(ty::BoundTy(ref b)) => cvar == b.var,
|
||||
_ => false,
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -984,7 +984,7 @@ define_print! {
|
|||
ty::TyVar(_) => write!(f, "_"),
|
||||
ty::IntVar(_) => write!(f, "{}", "{integer}"),
|
||||
ty::FloatVar(_) => write!(f, "{}", "{float}"),
|
||||
ty::CanonicalTy(_) => write!(f, "_"),
|
||||
ty::BoundTy(_) => write!(f, "_"),
|
||||
ty::FreshTy(v) => write!(f, "FreshTy({})", v),
|
||||
ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
|
||||
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
|
||||
|
|
@ -996,7 +996,7 @@ define_print! {
|
|||
ty::TyVar(ref v) => write!(f, "{:?}", v),
|
||||
ty::IntVar(ref v) => write!(f, "{:?}", v),
|
||||
ty::FloatVar(ref v) => write!(f, "{:?}", v),
|
||||
ty::CanonicalTy(v) => write!(f, "?{:?}", v.index()),
|
||||
ty::BoundTy(v) => write!(f, "?{:?}", v.var.index()),
|
||||
ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
|
||||
ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
|
||||
ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue