Leave variables behind when converting Types to variables

This is part one of addressing the present issues with emplacing type
directly where type variables should be reused. Now, when an
`Index<Type>` is converted to a variable in solving, we leave the
converted variable in the `Type`'s place. Specifically, we keep an index
to a `Cell<Type>`.

Note that this transformation is only temporary, it will be removed once
we merge this with the `Type` SoA representation, but it is needed in
the meantime as I transform the `Constrain` API to get rid of
type-emplacement.
This commit is contained in:
Ayaz Hafiz 2022-10-24 11:42:35 -05:00
parent 50fac9cc9e
commit d3e14550d8
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
2 changed files with 101 additions and 52 deletions

View file

@ -11,7 +11,7 @@ use crate::specialize::{
use bumpalo::Bump;
use roc_can::abilities::{AbilitiesStore, MemberSpecializationInfo};
use roc_can::constraint::Constraint::{self, *};
use roc_can::constraint::{Constraints, Cycle, LetConstraint, OpportunisticResolve};
use roc_can::constraint::{Constraints, Cycle, LetConstraint, OpportunisticResolve, TypeOrVar};
use roc_can::expected::{Expected, PExpected};
use roc_can::expr::PendingDerives;
use roc_can::module::ExposedByModule;
@ -1323,24 +1323,47 @@ fn solve(
region,
} = includes_tag;
let typ = &constraints.types[type_index.index()];
let tys = &constraints.types[types.indices()];
let typ_cell = &constraints.types[type_index.index()];
let tys_cells = &constraints.types[types.indices()];
let pattern_category = &constraints.pattern_categories[pattern_category.index()];
let actual = type_to_var(
subs,
rank,
problems,
abilities_store,
obligation_cache,
pools,
aliases,
typ,
);
let tag_ty = Type::TagUnion(
vec![(tag_name.clone(), tys.to_vec())],
TypeExtension::Closed,
);
let actual = {
let typ = typ_cell.replace(Type::EmptyTagUnion);
let actual = type_to_var(
subs,
rank,
problems,
abilities_store,
obligation_cache,
pools,
aliases,
&typ,
);
typ_cell.replace(Type::Variable(actual));
actual
};
let tys = {
let mut tys = Vec::with_capacity(tys_cells.len());
for cell in tys_cells {
let ty = cell.replace(Type::EmptyTagUnion);
let actual = type_to_var(
subs,
rank,
problems,
abilities_store,
obligation_cache,
pools,
aliases,
&ty,
);
cell.replace(Type::Variable(actual));
tys.push(Type::Variable(actual));
}
tys
};
let tag_ty = Type::TagUnion(vec![(tag_name.clone(), tys)], TypeExtension::Closed);
let includes = type_to_var(
subs,
rank,
@ -2033,7 +2056,8 @@ impl LocalDefVarsVec<(Symbol, Loc<Variable>)> {
let mut local_def_vars = Self::with_length(types_slice.len());
for (&(symbol, region), typ) in (loc_symbols_slice.iter()).zip(types_slice) {
for (&(symbol, region), typ_cell) in (loc_symbols_slice.iter()).zip(types_slice) {
let typ = typ_cell.replace(Type::EmptyTagUnion);
let var = type_to_var(
subs,
rank,
@ -2042,8 +2066,9 @@ impl LocalDefVarsVec<(Symbol, Loc<Variable>)> {
obligation_cache,
pools,
aliases,
typ,
&typ,
);
typ_cell.replace(Type::Variable(var));
local_def_vars.push((symbol, Loc { value: var, region }));
}
@ -2078,13 +2103,14 @@ fn either_type_index_to_var(
abilities_store: &mut AbilitiesStore,
obligation_cache: &mut ObligationCache,
aliases: &mut Aliases,
either_type_index: roc_collections::soa::EitherIndex<Type, Variable>,
either_type_index: TypeOrVar,
) -> Variable {
match either_type_index.split() {
Ok(type_index) => {
let typ = &constraints.types[type_index.index()];
let typ_cell = &constraints.types[type_index.index()];
type_to_var(
let typ = typ_cell.replace(Type::EmptyTagUnion);
let var = type_to_var(
subs,
rank,
problems,
@ -2092,8 +2118,10 @@ fn either_type_index_to_var(
obligation_cache,
pools,
aliases,
typ,
)
&typ,
);
typ_cell.replace(Type::Variable(var));
var
}
Err(var_index) => {
// we cheat, and store the variable directly in the index