Remove unneeded type storage in constraining

This commit is contained in:
Ayaz Hafiz 2022-11-09 15:56:29 -06:00
parent 5564796927
commit a52e9d605d
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
3 changed files with 24 additions and 89 deletions

View file

@ -12,7 +12,6 @@ use roc_types::types::{Category, PatternCategory, TypeCell, TypeTag, Types};
pub struct Constraints {
pub constraints: Vec<Constraint>,
pub types: Vec<Cell<Index<TypeCell>>>,
pub type_slices: Vec<TypeOrVar>,
pub variables: Vec<Variable>,
pub loc_symbols: Vec<(Symbol, Region)>,
@ -60,12 +59,11 @@ impl Default for Constraints {
pub type ExpectedTypeIndex = Index<Expected<TypeOrVar>>;
pub type PExpectedTypeIndex = Index<PExpected<TypeOrVar>>;
pub type TypeOrVar = EitherIndex<Cell<Index<TypeCell>>, Variable>;
pub type TypeOrVar = EitherIndex<TypeCell, Variable>;
impl Constraints {
pub fn new() -> Self {
let constraints = Vec::new();
let mut types = Vec::new();
let type_slices = Vec::with_capacity(16);
let variables = Vec::new();
let loc_symbols = Vec::new();
@ -81,12 +79,6 @@ impl Constraints {
let pattern_eq = Vec::new();
let cycles = Vec::new();
types.extend([
Cell::new(Types::EMPTY_RECORD),
Cell::new(Types::EMPTY_TAG_UNION),
Cell::new(Types::STR),
]);
categories.extend([
Category::Record,
Category::ForeignCall,
@ -120,7 +112,6 @@ impl Constraints {
Self {
constraints,
types,
type_slices,
variables,
loc_symbols,
@ -170,24 +161,11 @@ impl Constraints {
pub const PCATEGORY_CHARACTER: Index<PatternCategory> = Index::new(10);
#[inline(always)]
pub fn push_type(
&mut self,
types: &Types,
typ: Index<TypeCell>,
) -> EitherIndex<Cell<Index<TypeCell>>, Variable> {
match types[typ].get() {
TypeTag::EmptyRecord => EitherIndex::from_left(Self::EMPTY_RECORD),
TypeTag::EmptyTagUnion => EitherIndex::from_left(Self::EMPTY_TAG_UNION),
TypeTag::Apply {
symbol: Symbol::STR_STR,
..
} => EitherIndex::from_left(Self::STR),
TypeTag::Variable(var) => Self::push_type_variable(var),
_ => {
let index: Index<Cell<Index<TypeCell>>> =
Index::push_new(&mut self.types, Cell::new(typ));
EitherIndex::from_left(index)
}
pub fn push_type(&mut self, types: &Types, typ: Index<TypeCell>) -> TypeOrVar {
if let TypeTag::Variable(var) = types[typ].get() {
Self::push_type_variable(var)
} else {
EitherIndex::from_left(typ)
}
}
@ -199,7 +177,6 @@ impl Constraints {
writeln!(buf, "Constraints statistics for module {:?}:", module_id)?;
writeln!(buf, " constraints length: {}:", self.constraints.len())?;
writeln!(buf, " types length: {}:", self.types.len())?;
writeln!(
buf,
" let_constraints length: {}:",

View file

@ -204,7 +204,7 @@ pub fn constrain_pattern(
// _ -> ""
// so, we know that "x" (in this case, a tag union) must be open.
let expected_type = *constraints[expected].get_type_ref();
if could_be_a_tag_union(types, constraints, expected_type) {
if could_be_a_tag_union(types, expected_type) {
state
.delayed_is_open_constraints
.push(constraints.is_open_type(expected_type));
@ -218,7 +218,7 @@ pub fn constrain_pattern(
let expected = &constraints[expected];
let type_index = *expected.get_type_ref();
if could_be_a_tag_union(types, constraints, type_index) {
if could_be_a_tag_union(types, type_index) {
state
.delayed_is_open_constraints
.push(constraints.is_open_type(type_index));
@ -240,7 +240,7 @@ pub fn constrain_pattern(
let expected = &constraints[expected];
let type_index = *expected.get_type_ref();
if could_be_a_tag_union(types, constraints, type_index) {
if could_be_a_tag_union(types, type_index) {
state.constraints.push(constraints.is_open_type(type_index));
}
@ -766,15 +766,12 @@ pub fn constrain_pattern(
}
}
fn could_be_a_tag_union(types: &Types, constraints: &mut Constraints, typ: TypeOrVar) -> bool {
fn could_be_a_tag_union(types: &Types, typ: TypeOrVar) -> bool {
match typ.split() {
Ok(typ_index) => {
let typ_cell = &mut constraints.types[typ_index.index()];
!matches!(
types[*typ_cell.get_mut()].get(),
TypeTag::Apply { .. } | TypeTag::Function(..) | TypeTag::Record(..)
)
}
Ok(typ_index) => !matches!(
types[typ_index].get(),
TypeTag::Apply { .. } | TypeTag::Function(..) | TypeTag::Record(..)
),
Err(_) => {
// Variables are opaque at this point, assume yes
true

View file

@ -896,7 +896,6 @@ fn solve(
let category = &constraints.categories[category_index.index()];
let actual = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -910,7 +909,6 @@ fn solve(
let expectation = &constraints.expectations[expectation_index.index()];
let expected = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -980,7 +978,6 @@ fn solve(
// a special version of Eq that is used to store types in the AST.
// IT DOES NOT REPORT ERRORS!
let actual = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -1024,7 +1021,6 @@ fn solve(
let expectation = &constraints.expectations[expectation_index.index()];
let expected = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -1119,7 +1115,6 @@ fn solve(
let category = &constraints.pattern_categories[category_index.index()];
let actual = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -1133,7 +1128,6 @@ fn solve(
let expectation = &constraints.pattern_expectations[expectation_index.index()];
let expected = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -1300,7 +1294,6 @@ fn solve(
}
IsOpenType(type_index) => {
let actual = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -1330,7 +1323,6 @@ fn solve(
let pattern_category = &constraints.pattern_categories[pattern_category.index()];
let actual = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -1464,7 +1456,6 @@ fn solve(
};
let real_var = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -1477,7 +1468,6 @@ fn solve(
);
let branches_var = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -2182,7 +2172,6 @@ impl LocalDefVarsVec<(Symbol, Loc<Variable>)> {
for (&(symbol, region), typ_index) in (loc_symbols_slice.iter()).zip(type_indices_slice) {
let var = either_type_index_to_var(
constraints,
subs,
rank,
pools,
@ -2201,7 +2190,7 @@ impl LocalDefVarsVec<(Symbol, Loc<Variable>)> {
}
}
use std::cell::{Cell, RefCell};
use std::cell::RefCell;
use std::ops::ControlFlow;
std::thread_local! {
/// Scratchpad arena so we don't need to allocate a new one all the time
@ -2219,7 +2208,6 @@ fn put_scratchpad(scratchpad: bumpalo::Bump) {
}
fn either_type_index_to_var(
constraints: &Constraints,
subs: &mut Subs,
rank: Rank,
pools: &mut Pools,
@ -2232,9 +2220,8 @@ fn either_type_index_to_var(
) -> Variable {
match either_type_index.split() {
Ok(type_index) => {
let typ_cell = &constraints.types[type_index.index()];
type_cell_to_var(
// Converts the celled type to a variable, emplacing the new variable for re-use.
let var = type_to_var(
subs,
rank,
problems,
@ -2243,8 +2230,13 @@ fn either_type_index_to_var(
pools,
types,
aliases,
typ_cell,
)
type_index,
);
unsafe {
types.emplace_variable(type_index, var);
}
var
}
Err(var_index) => {
// we cheat, and store the variable directly in the index
@ -2253,37 +2245,6 @@ fn either_type_index_to_var(
}
}
/// Converts a type in a cell to a variable, leaving the converted variable behind for re-use.
fn type_cell_to_var(
subs: &mut Subs,
rank: Rank,
problems: &mut Vec<TypeError>,
abilities_store: &mut AbilitiesStore,
obligation_cache: &mut ObligationCache,
pools: &mut Pools,
types: &mut Types,
aliases: &mut Aliases,
typ_cell: &Cell<Index<TypeCell>>,
) -> Variable {
let typ = typ_cell.get();
let var = type_to_var(
subs,
rank,
problems,
abilities_store,
obligation_cache,
pools,
types,
aliases,
typ,
);
unsafe {
types.emplace_variable(typ, var);
}
var
}
pub(crate) fn type_to_var(
subs: &mut Subs,
rank: Rank,