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

View file

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

View file

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

View file

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