mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
Remove unneeded type storage in constraining
This commit is contained in:
parent
5564796927
commit
a52e9d605d
3 changed files with 24 additions and 89 deletions
|
@ -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: {}:",
|
||||
|
|
|
@ -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(),
|
||||
Ok(typ_index) => !matches!(
|
||||
types[typ_index].get(),
|
||||
TypeTag::Apply { .. } | TypeTag::Function(..) | TypeTag::Record(..)
|
||||
)
|
||||
}
|
||||
),
|
||||
Err(_) => {
|
||||
// Variables are opaque at this point, assume yes
|
||||
true
|
||||
|
|
|
@ -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,40 +2220,7 @@ 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(
|
||||
subs,
|
||||
rank,
|
||||
problems,
|
||||
abilities_store,
|
||||
obligation_cache,
|
||||
pools,
|
||||
types,
|
||||
aliases,
|
||||
typ_cell,
|
||||
)
|
||||
}
|
||||
Err(var_index) => {
|
||||
// we cheat, and store the variable directly in the index
|
||||
unsafe { Variable::from_index(var_index.index() as _) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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();
|
||||
// Converts the celled type to a variable, emplacing the new variable for re-use.
|
||||
let var = type_to_var(
|
||||
subs,
|
||||
rank,
|
||||
|
@ -2275,13 +2230,19 @@ fn type_cell_to_var(
|
|||
pools,
|
||||
types,
|
||||
aliases,
|
||||
typ,
|
||||
type_index,
|
||||
);
|
||||
unsafe {
|
||||
types.emplace_variable(typ, var);
|
||||
types.emplace_variable(type_index, var);
|
||||
}
|
||||
|
||||
var
|
||||
}
|
||||
Err(var_index) => {
|
||||
// we cheat, and store the variable directly in the index
|
||||
unsafe { Variable::from_index(var_index.index() as _) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn type_to_var(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue