move back to one loc_symbols vector

This commit is contained in:
Folkert 2022-05-14 14:40:04 +02:00
parent 3f0449292d
commit 7face320eb
No known key found for this signature in database
GPG Key ID: 1F17F6FFD112B97C
4 changed files with 49 additions and 57 deletions

View File

@ -13,8 +13,7 @@ pub struct Constraints {
pub constraints: Vec<Constraint>,
pub types: Vec<Type>,
pub variables: Vec<Variable>,
pub symbols: Vec<Symbol>,
pub regions: Vec<Region>,
pub loc_symbols: Vec<(Symbol, Region)>,
pub let_constraints: Vec<LetConstraint>,
pub categories: Vec<Category>,
pub pattern_categories: Vec<PatternCategory>,
@ -39,8 +38,7 @@ impl Constraints {
let constraints = Vec::new();
let mut types = Vec::new();
let variables = Vec::new();
let symbols = Vec::new();
let regions = Vec::new();
let loc_symbols = Vec::new();
let let_constraints = Vec::new();
let mut categories = Vec::with_capacity(16);
let mut pattern_categories = Vec::with_capacity(16);
@ -94,8 +92,7 @@ impl Constraints {
constraints,
types,
variables,
symbols,
regions,
loc_symbols,
let_constraints,
categories,
pattern_categories,
@ -369,28 +366,24 @@ impl Constraints {
let it = it.into_iter();
let types_start = self.types.len();
let symbols_start = self.symbols.len();
let regions_start = self.regions.len();
let loc_symbols_start = self.loc_symbols.len();
// because we have an ExactSizeIterator, we can reserve space here
let length = it.len();
self.types.reserve(length);
self.symbols.reserve(length);
self.regions.reserve(length);
self.loc_symbols.reserve(length);
for (symbol, loc_type) in it {
let Loc { region, value } = loc_type;
self.types.push(value);
self.symbols.push(symbol);
self.regions.push(region);
self.loc_symbols.push((symbol, region));
}
DefTypes {
types: Slice::new(types_start as _, length as _),
symbols: Slice::new(symbols_start as _, length as _),
regions: Slice::new(regions_start as _, length as _),
loc_symbols: Slice::new(loc_symbols_start as _, length as _),
}
}
@ -657,24 +650,25 @@ impl Constraints {
Constraint::Exhaustive(equality, sketched_rows, context, exhaustive)
}
pub fn check_cycle<I, I1, I2>(
pub fn check_cycle<I, I1>(
&mut self,
symbols: I,
symbol_regions: I1,
expr_regions: I2,
loc_symbols: I,
expr_regions: I1,
cycle_mark: IllegalCycleMark,
) -> Constraint
where
I: IntoIterator<Item = Symbol>,
I: IntoIterator<Item = (Symbol, Region)>,
I1: IntoIterator<Item = Region>,
I2: IntoIterator<Item = Region>,
{
let symbols = Slice::extend_new(&mut self.symbols, symbols);
let symbol_regions = Slice::extend_new(&mut self.regions, symbol_regions);
let expr_regions = Slice::extend_new(&mut self.regions, expr_regions);
let def_names = Slice::extend_new(&mut self.loc_symbols, loc_symbols);
// we add a dummy symbol to these regions, so we can store the data in the loc_symbols vec
let it = expr_regions.into_iter().map(|r| (Symbol::ATTR_ATTR, r));
let expr_regions = Slice::extend_new(&mut self.loc_symbols, it);
let expr_regions = Slice::new(expr_regions.start() as _, expr_regions.len() as _);
let cycle = Cycle {
symbols,
symbol_regions,
def_names,
expr_regions,
};
let cycle_index = Index::push_new(&mut self.cycles, cycle);
@ -776,8 +770,7 @@ pub enum Constraint {
#[derive(Debug, Clone, Copy, Default)]
pub struct DefTypes {
pub types: Slice<Type>,
pub symbols: Slice<Symbol>,
pub regions: Slice<Region>,
pub loc_symbols: Slice<(Symbol, Region)>,
}
#[derive(Debug, Clone)]
@ -799,8 +792,7 @@ pub struct IncludesTag {
#[derive(Debug, Clone, Copy)]
pub struct Cycle {
pub symbols: Slice<Symbol>,
pub symbol_regions: Slice<Region>,
pub def_names: Slice<(Symbol, Region)>,
pub expr_regions: Slice<Region>,
}

View File

@ -105,6 +105,10 @@ impl<T> Slice<T> {
self.length as _
}
pub const fn start(&self) -> usize {
self.start as _
}
pub const fn is_empty(&self) -> bool {
self.length == 0
}

View File

@ -2135,7 +2135,7 @@ pub fn rec_defs_help(
flex_constraints,
);
let ((symbols, symbol_regions), expr_regions): ((Vec<_>, Vec<_>), Vec<_>) = defs
let (loc_symbols, expr_regions): (Vec<_>, Vec<_>) = defs
.iter()
.flat_map(|def| {
symbols_introduced_from_pattern(&def.loc_pattern)
@ -2143,8 +2143,7 @@ pub fn rec_defs_help(
})
.unzip();
let cycle_constraint =
constraints.check_cycle(symbols, symbol_regions, expr_regions, cycle_mark);
let cycle_constraint = constraints.check_cycle(loc_symbols, expr_regions, cycle_mark);
let rigid_constraints = {
let mut temp = rigid_info.constraints;

View File

@ -1399,31 +1399,32 @@ fn solve(
}
CheckCycle(cycle, cycle_mark) => {
let Cycle {
symbols,
symbol_regions,
def_names,
expr_regions,
} = &constraints.cycles[cycle.index()];
let symbols = &constraints.symbols[symbols.indices()];
let mut any_is_bad = false;
for symbol in symbols {
// If the type of a symbol is not a function, that's an error.
// Roc is strict, so only functions can be mutually recursive.
let var = env.get_var_by_symbol(symbol).expect("Symbol not solved!");
any_is_bad = any_is_bad
|| !matches!(
subs.get_content_without_compacting(var),
Content::Error | Content::Structure(FlatType::Func(..))
);
}
let symbols = &constraints.loc_symbols[def_names.indices()];
// If the type of a symbol is not a function, that's an error.
// Roc is strict, so only functions can be mutually recursive.
let any_is_bad = {
use Content::*;
symbols.iter().any(|(s, _)| {
let var = env.get_var_by_symbol(s).expect("Symbol not solved!");
let content = subs.get_content_without_compacting(var);
!matches!(content, Error | Structure(FlatType::Func(..)))
})
};
if any_is_bad {
let symbol_regions = &constraints.regions[symbol_regions.indices()];
let expr_regions = &constraints.regions[expr_regions.indices()];
// expr regions are stored in loc_symbols (that turned out to be convenient).
// The symbol is just a dummy, and should not be used
let expr_regions = &constraints.loc_symbols[expr_regions.indices()];
let cycle = (symbols.iter())
.zip(symbol_regions.iter())
let cycle = symbols
.iter()
.zip(expr_regions.iter())
.map(|((&symbol, &symbol_region), &expr_region)| CycleEntry {
.map(|(&(symbol, symbol_region), &(_, expr_region))| CycleEntry {
symbol,
symbol_region,
expr_region,
@ -1634,15 +1635,11 @@ impl LocalDefVarsVec<(Symbol, Loc<Variable>)> {
def_types_slice: roc_can::constraint::DefTypes,
) -> Self {
let types_slice = &constraints.types[def_types_slice.types.indices()];
let symbols_slice = &constraints.symbols[def_types_slice.symbols.indices()];
let regions_slice = &constraints.regions[def_types_slice.regions.indices()];
let loc_symbols_slice = &constraints.loc_symbols[def_types_slice.loc_symbols.indices()];
let mut local_def_vars = Self::with_length(types_slice.len());
for ((&symbol, &region), typ) in (symbols_slice.iter())
.zip(regions_slice.iter())
.zip(types_slice)
{
for (&(symbol, region), typ) in (loc_symbols_slice.iter()).zip(types_slice) {
let var = type_to_var(subs, rank, pools, aliases, typ);
local_def_vars.push((symbol, Loc { value: var, region }));