From 768ee3e47a140e354575154f431421375b0b5203 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 6 Apr 2021 21:09:52 +0200 Subject: Align `InferenceVar` to Chalk --- crates/hir_ty/src/infer.rs | 19 ------------------- crates/hir_ty/src/infer/unify.rs | 36 ++++++++++++++++++++++++------------ crates/hir_ty/src/lib.rs | 2 +- crates/hir_ty/src/types.rs | 25 +++++++++++++++++++++++-- 4 files changed, 48 insertions(+), 34 deletions(-) (limited to 'crates/hir_ty') diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index efe9198cc..75d633c96 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -683,25 +683,6 @@ impl<'a> InferenceContext<'a> { } } -/// The kinds of placeholders we need during type inference. There's separate -/// values for general types, and for integer and float variables. The latter -/// two are used for inference of literal values (e.g. `100` could be one of -/// several integer types). -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -pub struct InferenceVar { - index: u32, -} - -impl InferenceVar { - fn to_inner(self) -> unify::TypeVarId { - unify::TypeVarId(self.index) - } - - fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self { - InferenceVar { index } - } -} - /// When inferring an expression, we propagate downward whatever type hint we /// are able in the form of an `Expectation`. #[derive(Clone, PartialEq, Eq, Debug)] diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 7d76cda68..d717e3375 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs @@ -51,7 +51,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { t.fold_binders( &mut |ty, binders| match ty.kind(&Interner) { &TyKind::InferenceVar(var, kind) => { - let inner = var.to_inner(); + let inner = from_inference_var(var); if self.var_stack.contains(&inner) { // recursive type return self.ctx.table.type_variable_table.fallback_value(var, kind); @@ -65,7 +65,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { result } else { let root = self.ctx.table.var_unification_table.find(inner); - let position = self.add(InferenceVar::from_inner(root), kind); + let position = self.add(to_inference_var(root), kind); TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner) } } @@ -207,16 +207,16 @@ impl TypeVariableTable { } pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) { - self.inner[iv.to_inner().0 as usize].diverging = diverging; + self.inner[from_inference_var(iv).0 as usize].diverging = diverging; } fn is_diverging(&mut self, iv: InferenceVar) -> bool { - self.inner[iv.to_inner().0 as usize].diverging + self.inner[from_inference_var(iv).0 as usize].diverging } fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { match kind { - _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never, + _ if self.inner[from_inference_var(iv).0 as usize].diverging => TyKind::Never, TyVariableKind::General => TyKind::Error, TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), @@ -250,7 +250,7 @@ impl InferenceTable { self.type_variable_table.push(TypeVariableData { diverging }); let key = self.var_unification_table.new_key(TypeVarValue::Unknown); assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); - TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner) + TyKind::InferenceVar(to_inference_var(key), kind).intern(&Interner) } pub(crate) fn new_type_var(&mut self) -> Ty { @@ -369,8 +369,12 @@ impl InferenceTable { == self.type_variable_table.is_diverging(*tv2) => { // both type vars are unknown since we tried to resolve them - if !self.var_unification_table.unioned(tv1.to_inner(), tv2.to_inner()) { - self.var_unification_table.union(tv1.to_inner(), tv2.to_inner()); + if !self + .var_unification_table + .unioned(from_inference_var(*tv1), from_inference_var(*tv2)) + { + self.var_unification_table + .union(from_inference_var(*tv1), from_inference_var(*tv2)); self.revision += 1; } true @@ -407,7 +411,7 @@ impl InferenceTable { ) => { // the type var is unknown since we tried to resolve it self.var_unification_table.union_value( - tv.to_inner(), + from_inference_var(*tv), TypeVarValue::Known(other.clone().intern(&Interner)), ); self.revision += 1; @@ -462,7 +466,7 @@ impl InferenceTable { } match ty.kind(&Interner) { TyKind::InferenceVar(tv, _) => { - let inner = tv.to_inner(); + let inner = from_inference_var(*tv); match self.var_unification_table.inlined_probe_value(inner).known() { Some(known_ty) => { // The known_ty can't be a type var itself @@ -485,7 +489,7 @@ impl InferenceTable { fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec, ty: Ty) -> Ty { ty.fold(&mut |ty| match ty.kind(&Interner) { &TyKind::InferenceVar(tv, kind) => { - let inner = tv.to_inner(); + let inner = from_inference_var(tv); if tv_stack.contains(&inner) { cov_mark::hit!(type_var_cycles_resolve_as_possible); // recursive type @@ -512,7 +516,7 @@ impl InferenceTable { fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec, ty: Ty) -> Ty { ty.fold(&mut |ty| match ty.kind(&Interner) { &TyKind::InferenceVar(tv, kind) => { - let inner = tv.to_inner(); + let inner = from_inference_var(tv); if tv_stack.contains(&inner) { cov_mark::hit!(type_var_cycles_resolve_completely); // recursive type @@ -555,6 +559,14 @@ impl UnifyKey for TypeVarId { } } +fn from_inference_var(var: InferenceVar) -> TypeVarId { + TypeVarId(var.index()) +} + +fn to_inference_var(TypeVarId(index): TypeVarId) -> InferenceVar { + index.into() +} + /// The value of a type variable: either we already know the type, or we don't /// know it yet. #[derive(Clone, PartialEq, Eq, Debug)] diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index f5b658cba..5c83a508d 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -42,7 +42,7 @@ use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; pub use autoderef::autoderef; pub use builder::TyBuilder; pub use chalk_ext::{ProjectionTyExt, TyExt}; -pub use infer::{could_unify, InferenceResult, InferenceVar}; +pub use infer::{could_unify, InferenceResult}; pub use lower::{ associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, TyDefId, TyLoweringContext, ValueTyDefId, diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs index 89c0ddd1a..eac1b7900 100644 --- a/crates/hir_ty/src/types.rs +++ b/crates/hir_ty/src/types.rs @@ -11,8 +11,7 @@ use smallvec::SmallVec; use crate::{ AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, Const, FnDefId, FnSig, ForeignDefId, - InferenceVar, Interner, Lifetime, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKind, - VariableKinds, + Interner, Lifetime, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKind, VariableKinds, }; #[derive(Clone, PartialEq, Eq, Debug, Hash)] @@ -524,3 +523,25 @@ pub enum Guidance { /// There's no useful information to feed back to type inference Unknown, } + +/// The kinds of placeholders we need during type inference. There's separate +/// values for general types, and for integer and float variables. The latter +/// two are used for inference of literal values (e.g. `100` could be one of +/// several integer types). +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub struct InferenceVar { + index: u32, +} + +impl From for InferenceVar { + fn from(index: u32) -> InferenceVar { + InferenceVar { index } + } +} + +impl InferenceVar { + /// Gets the underlying index value. + pub fn index(self) -> u32 { + self.index + } +} -- cgit v1.2.3