Remove TypeVariableTable
This commit is contained in:
parent
9716c0b949
commit
99c73537fa
2 changed files with 48 additions and 56 deletions
|
@ -101,7 +101,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
// here, we would coerce from `!` to `?T`.
|
// here, we would coerce from `!` to `?T`.
|
||||||
match to_ty.kind(&Interner) {
|
match to_ty.kind(&Interner) {
|
||||||
TyKind::InferenceVar(tv, TyVariableKind::General) => {
|
TyKind::InferenceVar(tv, TyVariableKind::General) => {
|
||||||
self.table.type_variable_table.set_diverging(*tv, true);
|
self.table.set_diverging(*tv, true);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,29 +127,6 @@ pub(crate) fn unify(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub(super) struct TypeVariableTable {
|
|
||||||
inner: Vec<TypeVariableData>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypeVariableTable {
|
|
||||||
pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
|
|
||||||
self.inner[iv.index() as usize].diverging = diverging;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
|
|
||||||
match kind {
|
|
||||||
_ if self.inner.get(iv.index() as usize).map_or(false, |data| data.diverging) => {
|
|
||||||
TyKind::Never
|
|
||||||
}
|
|
||||||
TyVariableKind::General => TyKind::Error,
|
|
||||||
TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
|
|
||||||
TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
|
|
||||||
}
|
|
||||||
.intern(&Interner)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub(crate) struct TypeVariableData {
|
pub(crate) struct TypeVariableData {
|
||||||
diverging: bool,
|
diverging: bool,
|
||||||
|
@ -162,7 +139,7 @@ pub(crate) struct InferenceTable<'a> {
|
||||||
pub db: &'a dyn HirDatabase,
|
pub db: &'a dyn HirDatabase,
|
||||||
pub trait_env: Arc<TraitEnvironment>,
|
pub trait_env: Arc<TraitEnvironment>,
|
||||||
pub(super) var_unification_table: ChalkInferenceTable,
|
pub(super) var_unification_table: ChalkInferenceTable,
|
||||||
pub(super) type_variable_table: TypeVariableTable,
|
pub(super) type_variable_table: Vec<TypeVariableData>,
|
||||||
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
|
pending_obligations: Vec<Canonicalized<InEnvironment<Goal>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +149,7 @@ impl<'a> InferenceTable<'a> {
|
||||||
db,
|
db,
|
||||||
trait_env,
|
trait_env,
|
||||||
var_unification_table: ChalkInferenceTable::new(),
|
var_unification_table: ChalkInferenceTable::new(),
|
||||||
type_variable_table: TypeVariableTable { inner: Vec::new() },
|
type_variable_table: Vec::new(),
|
||||||
pending_obligations: Vec::new(),
|
pending_obligations: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,18 +161,38 @@ impl<'a> InferenceTable<'a> {
|
||||||
/// marked as diverging if necessary, so that resolving them gives the right
|
/// marked as diverging if necessary, so that resolving them gives the right
|
||||||
/// result.
|
/// result.
|
||||||
pub(super) fn propagate_diverging_flag(&mut self) {
|
pub(super) fn propagate_diverging_flag(&mut self) {
|
||||||
for i in 0..self.type_variable_table.inner.len() {
|
for i in 0..self.type_variable_table.len() {
|
||||||
if !self.type_variable_table.inner[i].diverging {
|
if !self.type_variable_table[i].diverging {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let v = InferenceVar::from(i as u32);
|
let v = InferenceVar::from(i as u32);
|
||||||
let root = self.var_unification_table.inference_var_root(v);
|
let root = self.var_unification_table.inference_var_root(v);
|
||||||
if let Some(data) = self.type_variable_table.inner.get_mut(root.index() as usize) {
|
if let Some(data) = self.type_variable_table.get_mut(root.index() as usize) {
|
||||||
data.diverging = true;
|
data.diverging = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
|
||||||
|
self.type_variable_table[iv.index() as usize].diverging = diverging;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
|
||||||
|
match kind {
|
||||||
|
_ if self
|
||||||
|
.type_variable_table
|
||||||
|
.get(iv.index() as usize)
|
||||||
|
.map_or(false, |data| data.diverging) =>
|
||||||
|
{
|
||||||
|
TyKind::Never
|
||||||
|
}
|
||||||
|
TyVariableKind::General => TyKind::Error,
|
||||||
|
TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
|
||||||
|
TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
|
||||||
|
}
|
||||||
|
.intern(&Interner)
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn canonicalize<T: Fold<Interner> + HasInterner<Interner = Interner>>(
|
pub(super) fn canonicalize<T: Fold<Interner> + HasInterner<Interner = Interner>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: T,
|
t: T,
|
||||||
|
@ -239,16 +236,19 @@ impl<'a> InferenceTable<'a> {
|
||||||
var
|
var
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extend_type_variable_table(&mut self, to_index: usize) {
|
||||||
|
self.type_variable_table.extend(
|
||||||
|
(0..1 + to_index - self.type_variable_table.len())
|
||||||
|
.map(|_| TypeVariableData { diverging: false }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
|
fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
|
||||||
let var = self.var_unification_table.new_variable(UniverseIndex::ROOT);
|
let var = self.var_unification_table.new_variable(UniverseIndex::ROOT);
|
||||||
// Chalk might have created some type variables for its own purposes that we don't know about...
|
// Chalk might have created some type variables for its own purposes that we don't know about...
|
||||||
// TODO refactor this?
|
self.extend_type_variable_table(var.index() as usize);
|
||||||
self.type_variable_table.inner.extend(
|
assert_eq!(var.index() as usize, self.type_variable_table.len() - 1);
|
||||||
(0..1 + var.index() as usize - self.type_variable_table.inner.len())
|
self.type_variable_table[var.index() as usize].diverging = diverging;
|
||||||
.map(|_| TypeVariableData { diverging: false }),
|
|
||||||
);
|
|
||||||
assert_eq!(var.index() as usize, self.type_variable_table.inner.len() - 1);
|
|
||||||
self.type_variable_table.inner[var.index() as usize].diverging = diverging;
|
|
||||||
var.to_ty_with_kind(&Interner, kind)
|
var.to_ty_with_kind(&Interner, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,12 +289,7 @@ impl<'a> InferenceTable<'a> {
|
||||||
T: HasInterner<Interner = Interner> + Fold<Interner>,
|
T: HasInterner<Interner = Interner> + Fold<Interner>,
|
||||||
{
|
{
|
||||||
t.fold_with(
|
t.fold_with(
|
||||||
&mut resolve::Resolver {
|
&mut resolve::Resolver { table: self, var_stack, fallback },
|
||||||
type_variable_table: &self.type_variable_table,
|
|
||||||
var_unification_table: &mut self.var_unification_table,
|
|
||||||
var_stack,
|
|
||||||
fallback,
|
|
||||||
},
|
|
||||||
DebruijnIndex::INNERMOST,
|
DebruijnIndex::INNERMOST,
|
||||||
)
|
)
|
||||||
.expect("fold failed unexpectedly")
|
.expect("fold failed unexpectedly")
|
||||||
|
@ -433,14 +428,12 @@ impl<'a> InferenceTable<'a> {
|
||||||
|
|
||||||
impl<'a> fmt::Debug for InferenceTable<'a> {
|
impl<'a> fmt::Debug for InferenceTable<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("InferenceTable")
|
f.debug_struct("InferenceTable").field("num_vars", &self.type_variable_table.len()).finish()
|
||||||
.field("num_vars", &self.type_variable_table.inner.len())
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod resolve {
|
mod resolve {
|
||||||
use super::{ChalkInferenceTable, TypeVariableTable};
|
use super::InferenceTable;
|
||||||
use crate::{
|
use crate::{
|
||||||
ConcreteConst, Const, ConstData, ConstValue, DebruijnIndex, GenericArg, InferenceVar,
|
ConcreteConst, Const, ConstData, ConstValue, DebruijnIndex, GenericArg, InferenceVar,
|
||||||
Interner, Ty, TyVariableKind, VariableKind,
|
Interner, Ty, TyVariableKind, VariableKind,
|
||||||
|
@ -452,13 +445,12 @@ mod resolve {
|
||||||
};
|
};
|
||||||
use hir_def::type_ref::ConstScalar;
|
use hir_def::type_ref::ConstScalar;
|
||||||
|
|
||||||
pub(super) struct Resolver<'a, F> {
|
pub(super) struct Resolver<'a, 'b, F> {
|
||||||
pub type_variable_table: &'a TypeVariableTable,
|
pub table: &'a mut InferenceTable<'b>,
|
||||||
pub var_unification_table: &'a mut ChalkInferenceTable,
|
|
||||||
pub var_stack: &'a mut Vec<InferenceVar>,
|
pub var_stack: &'a mut Vec<InferenceVar>,
|
||||||
pub fallback: F,
|
pub fallback: F,
|
||||||
}
|
}
|
||||||
impl<'a, 'i, F> Folder<'i, Interner> for Resolver<'a, F>
|
impl<'a, 'b, 'i, F> Folder<'i, Interner> for Resolver<'a, 'b, F>
|
||||||
where
|
where
|
||||||
F: Fn(InferenceVar, VariableKind, GenericArg, DebruijnIndex) -> GenericArg + 'i,
|
F: Fn(InferenceVar, VariableKind, GenericArg, DebruijnIndex) -> GenericArg + 'i,
|
||||||
{
|
{
|
||||||
|
@ -476,15 +468,15 @@ mod resolve {
|
||||||
kind: TyVariableKind,
|
kind: TyVariableKind,
|
||||||
outer_binder: DebruijnIndex,
|
outer_binder: DebruijnIndex,
|
||||||
) -> Fallible<Ty> {
|
) -> Fallible<Ty> {
|
||||||
let var = self.var_unification_table.inference_var_root(var);
|
let var = self.table.var_unification_table.inference_var_root(var);
|
||||||
if self.var_stack.contains(&var) {
|
if self.var_stack.contains(&var) {
|
||||||
// recursive type
|
// recursive type
|
||||||
let default = self.type_variable_table.fallback_value(var, kind).cast(&Interner);
|
let default = self.table.fallback_value(var, kind).cast(&Interner);
|
||||||
return Ok((self.fallback)(var, VariableKind::Ty(kind), default, outer_binder)
|
return Ok((self.fallback)(var, VariableKind::Ty(kind), default, outer_binder)
|
||||||
.assert_ty_ref(&Interner)
|
.assert_ty_ref(&Interner)
|
||||||
.clone());
|
.clone());
|
||||||
}
|
}
|
||||||
let result = if let Some(known_ty) = self.var_unification_table.probe_var(var) {
|
let result = if let Some(known_ty) = self.table.var_unification_table.probe_var(var) {
|
||||||
// known_ty may contain other variables that are known by now
|
// known_ty may contain other variables that are known by now
|
||||||
self.var_stack.push(var);
|
self.var_stack.push(var);
|
||||||
let result =
|
let result =
|
||||||
|
@ -492,7 +484,7 @@ mod resolve {
|
||||||
self.var_stack.pop();
|
self.var_stack.pop();
|
||||||
result.assert_ty_ref(&Interner).clone()
|
result.assert_ty_ref(&Interner).clone()
|
||||||
} else {
|
} else {
|
||||||
let default = self.type_variable_table.fallback_value(var, kind).cast(&Interner);
|
let default = self.table.fallback_value(var, kind).cast(&Interner);
|
||||||
(self.fallback)(var, VariableKind::Ty(kind), default, outer_binder)
|
(self.fallback)(var, VariableKind::Ty(kind), default, outer_binder)
|
||||||
.assert_ty_ref(&Interner)
|
.assert_ty_ref(&Interner)
|
||||||
.clone()
|
.clone()
|
||||||
|
@ -506,7 +498,7 @@ mod resolve {
|
||||||
var: InferenceVar,
|
var: InferenceVar,
|
||||||
outer_binder: DebruijnIndex,
|
outer_binder: DebruijnIndex,
|
||||||
) -> Fallible<Const> {
|
) -> Fallible<Const> {
|
||||||
let var = self.var_unification_table.inference_var_root(var);
|
let var = self.table.var_unification_table.inference_var_root(var);
|
||||||
let default = ConstData {
|
let default = ConstData {
|
||||||
ty: ty.clone(),
|
ty: ty.clone(),
|
||||||
value: ConstValue::Concrete(ConcreteConst { interned: ConstScalar::Unknown }),
|
value: ConstValue::Concrete(ConcreteConst { interned: ConstScalar::Unknown }),
|
||||||
|
@ -519,7 +511,7 @@ mod resolve {
|
||||||
.assert_const_ref(&Interner)
|
.assert_const_ref(&Interner)
|
||||||
.clone());
|
.clone());
|
||||||
}
|
}
|
||||||
let result = if let Some(known_ty) = self.var_unification_table.probe_var(var) {
|
let result = if let Some(known_ty) = self.table.var_unification_table.probe_var(var) {
|
||||||
// known_ty may contain other variables that are known by now
|
// known_ty may contain other variables that are known by now
|
||||||
self.var_stack.push(var);
|
self.var_stack.push(var);
|
||||||
let result =
|
let result =
|
||||||
|
|
Loading…
Reference in a new issue