mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
use EitherIndex<Type, Variable> to halve number of types stored
This commit is contained in:
parent
da03b0c2b3
commit
b3d9f9c2de
3 changed files with 69 additions and 34 deletions
|
@ -1,5 +1,5 @@
|
||||||
use crate::expected::{Expected, PExpected};
|
use crate::expected::{Expected, PExpected};
|
||||||
use roc_collections::soa::{Index, Slice};
|
use roc_collections::soa::{EitherIndex, Index, Slice};
|
||||||
use roc_module::ident::TagName;
|
use roc_module::ident::TagName;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_region::all::{Loc, Region};
|
use roc_region::all::{Loc, Region};
|
||||||
|
@ -120,11 +120,18 @@ impl Constraints {
|
||||||
pub const PCATEGORY_CHARACTER: Index<PatternCategory> = Index::new(10);
|
pub const PCATEGORY_CHARACTER: Index<PatternCategory> = Index::new(10);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn push_type(&mut self, typ: Type) -> Index<Type> {
|
pub fn push_type(&mut self, typ: Type) -> EitherIndex<Type, Variable> {
|
||||||
match typ {
|
match typ {
|
||||||
Type::EmptyRec => Self::EMPTY_RECORD,
|
Type::EmptyRec => EitherIndex::from_left(Self::EMPTY_RECORD),
|
||||||
Type::EmptyTagUnion => Self::EMPTY_TAG_UNION,
|
Type::EmptyTagUnion => EitherIndex::from_left(Self::EMPTY_TAG_UNION),
|
||||||
other => Index::push_new(&mut self.types, other),
|
Type::Variable(var) => {
|
||||||
|
let index: Index<Variable> = Index::push_new(&mut self.variables, var);
|
||||||
|
EitherIndex::from_right(index)
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
let index: Index<Type> = Index::push_new(&mut self.types, other);
|
||||||
|
EitherIndex::from_left(index)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +187,7 @@ impl Constraints {
|
||||||
category: Category,
|
category: Category,
|
||||||
region: Region,
|
region: Region,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let type_index = Index::push_new(&mut self.types, typ);
|
let type_index = self.push_type(typ);
|
||||||
let expected_index = Index::push_new(&mut self.expectations, expected);
|
let expected_index = Index::push_new(&mut self.expectations, expected);
|
||||||
let category_index = Self::push_category(self, category);
|
let category_index = Self::push_category(self, category);
|
||||||
|
|
||||||
|
@ -194,7 +201,7 @@ impl Constraints {
|
||||||
category: PatternCategory,
|
category: PatternCategory,
|
||||||
region: Region,
|
region: Region,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let type_index = Index::push_new(&mut self.types, typ);
|
let type_index = self.push_type(typ);
|
||||||
let expected_index = Index::push_new(&mut self.pattern_expectations, expected);
|
let expected_index = Index::push_new(&mut self.pattern_expectations, expected);
|
||||||
let category_index = Self::push_pattern_category(self, category);
|
let category_index = Self::push_pattern_category(self, category);
|
||||||
|
|
||||||
|
@ -208,7 +215,7 @@ impl Constraints {
|
||||||
category: PatternCategory,
|
category: PatternCategory,
|
||||||
region: Region,
|
region: Region,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let type_index = Index::push_new(&mut self.types, typ);
|
let type_index = self.push_type(typ);
|
||||||
let expected_index = Index::push_new(&mut self.pattern_expectations, expected);
|
let expected_index = Index::push_new(&mut self.pattern_expectations, expected);
|
||||||
let category_index = Index::push_new(&mut self.pattern_categories, category);
|
let category_index = Index::push_new(&mut self.pattern_categories, category);
|
||||||
|
|
||||||
|
@ -216,7 +223,7 @@ impl Constraints {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_open_type(&mut self, typ: Type) -> Constraint {
|
pub fn is_open_type(&mut self, typ: Type) -> Constraint {
|
||||||
let type_index = Index::push_new(&mut self.types, typ);
|
let type_index = self.push_type(typ);
|
||||||
|
|
||||||
Constraint::IsOpenType(type_index)
|
Constraint::IsOpenType(type_index)
|
||||||
}
|
}
|
||||||
|
@ -446,7 +453,7 @@ impl Constraints {
|
||||||
filename: &'static str,
|
filename: &'static str,
|
||||||
line_number: u32,
|
line_number: u32,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let type_index = Index::push_new(&mut self.types, typ);
|
let type_index = self.push_type(typ);
|
||||||
let string_index = Index::push_new(&mut self.strings, filename);
|
let string_index = Index::push_new(&mut self.strings, filename);
|
||||||
|
|
||||||
Constraint::Store(type_index, variable, string_index, line_number)
|
Constraint::Store(type_index, variable, string_index, line_number)
|
||||||
|
@ -457,11 +464,21 @@ static_assertions::assert_eq_size!([u8; 3 * 8], Constraint);
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Constraint {
|
pub enum Constraint {
|
||||||
Eq(Index<Type>, Index<Expected<Type>>, Index<Category>, Region),
|
Eq(
|
||||||
Store(Index<Type>, Variable, Index<&'static str>, u32),
|
EitherIndex<Type, Variable>,
|
||||||
|
Index<Expected<Type>>,
|
||||||
|
Index<Category>,
|
||||||
|
Region,
|
||||||
|
),
|
||||||
|
Store(
|
||||||
|
EitherIndex<Type, Variable>,
|
||||||
|
Variable,
|
||||||
|
Index<&'static str>,
|
||||||
|
u32,
|
||||||
|
),
|
||||||
Lookup(Symbol, Index<Expected<Type>>, Region),
|
Lookup(Symbol, Index<Expected<Type>>, Region),
|
||||||
Pattern(
|
Pattern(
|
||||||
Index<Type>,
|
EitherIndex<Type, Variable>,
|
||||||
Index<PExpected<Type>>,
|
Index<PExpected<Type>>,
|
||||||
Index<PatternCategory>,
|
Index<PatternCategory>,
|
||||||
Region,
|
Region,
|
||||||
|
@ -471,10 +488,10 @@ pub enum Constraint {
|
||||||
Let(Index<LetConstraint>),
|
Let(Index<LetConstraint>),
|
||||||
And(Slice<Constraint>),
|
And(Slice<Constraint>),
|
||||||
/// Presence constraints
|
/// Presence constraints
|
||||||
IsOpenType(Index<Type>), // Theory; always applied to a variable? if yes the use that
|
IsOpenType(EitherIndex<Type, Variable>), // Theory; always applied to a variable? if yes the use that
|
||||||
IncludesTag(Index<IncludesTag>),
|
IncludesTag(Index<IncludesTag>),
|
||||||
PatternPresence(
|
PatternPresence(
|
||||||
Index<Type>,
|
EitherIndex<Type, Variable>,
|
||||||
Index<PExpected<Type>>,
|
Index<PExpected<Type>>,
|
||||||
Index<PatternCategory>,
|
Index<PatternCategory>,
|
||||||
Region,
|
Region,
|
||||||
|
|
|
@ -1248,14 +1248,7 @@ fn constrain_empty_record(
|
||||||
region: Region,
|
region: Region,
|
||||||
expected: Expected<Type>,
|
expected: Expected<Type>,
|
||||||
) -> Constraint {
|
) -> Constraint {
|
||||||
let expected_index = constraints.push_expected_type(expected);
|
constraints.equal_types(Type::EmptyRec, expected, Category::Record, region)
|
||||||
|
|
||||||
Constraint::Eq(
|
|
||||||
Constraints::EMPTY_RECORD,
|
|
||||||
expected_index,
|
|
||||||
Constraints::CATEGORY_RECORD,
|
|
||||||
region,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constrain top-level module declarations
|
/// Constrain top-level module declarations
|
||||||
|
|
|
@ -414,11 +414,18 @@ fn solve(
|
||||||
copy
|
copy
|
||||||
}
|
}
|
||||||
Eq(type_index, expectation_index, category_index, region) => {
|
Eq(type_index, expectation_index, category_index, region) => {
|
||||||
let typ = &constraints.types[type_index.index()];
|
|
||||||
let expectation = &constraints.expectations[expectation_index.index()];
|
|
||||||
let category = &constraints.categories[category_index.index()];
|
let category = &constraints.categories[category_index.index()];
|
||||||
|
|
||||||
let actual = type_to_var(subs, rank, pools, cached_aliases, typ);
|
let actual = either_type_index_to_var(
|
||||||
|
constraints,
|
||||||
|
subs,
|
||||||
|
rank,
|
||||||
|
pools,
|
||||||
|
cached_aliases,
|
||||||
|
*type_index,
|
||||||
|
);
|
||||||
|
|
||||||
|
let expectation = &constraints.expectations[expectation_index.index()];
|
||||||
let expected = type_to_var(
|
let expected = type_to_var(
|
||||||
subs,
|
subs,
|
||||||
rank,
|
rank,
|
||||||
|
@ -457,11 +464,16 @@ fn solve(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Store(source_index, target, _filename, _linenr) => {
|
Store(source_index, target, _filename, _linenr) => {
|
||||||
let source = &constraints.types[source_index.index()];
|
|
||||||
|
|
||||||
// a special version of Eq that is used to store types in the AST.
|
// a special version of Eq that is used to store types in the AST.
|
||||||
// IT DOES NOT REPORT ERRORS!
|
// IT DOES NOT REPORT ERRORS!
|
||||||
let actual = type_to_var(subs, rank, pools, cached_aliases, source);
|
let actual = either_type_index_to_var(
|
||||||
|
constraints,
|
||||||
|
subs,
|
||||||
|
rank,
|
||||||
|
pools,
|
||||||
|
cached_aliases,
|
||||||
|
*source_index,
|
||||||
|
);
|
||||||
let target = *target;
|
let target = *target;
|
||||||
|
|
||||||
match unify(subs, actual, target, Mode::EQ) {
|
match unify(subs, actual, target, Mode::EQ) {
|
||||||
|
@ -572,11 +584,18 @@ fn solve(
|
||||||
}
|
}
|
||||||
Pattern(type_index, expectation_index, category_index, region)
|
Pattern(type_index, expectation_index, category_index, region)
|
||||||
| PatternPresence(type_index, expectation_index, category_index, region) => {
|
| PatternPresence(type_index, expectation_index, category_index, region) => {
|
||||||
let typ = &constraints.types[type_index.index()];
|
|
||||||
let expectation = &constraints.pattern_expectations[expectation_index.index()];
|
|
||||||
let category = &constraints.pattern_categories[category_index.index()];
|
let category = &constraints.pattern_categories[category_index.index()];
|
||||||
|
|
||||||
let actual = type_to_var(subs, rank, pools, cached_aliases, typ);
|
let actual = either_type_index_to_var(
|
||||||
|
constraints,
|
||||||
|
subs,
|
||||||
|
rank,
|
||||||
|
pools,
|
||||||
|
cached_aliases,
|
||||||
|
*type_index,
|
||||||
|
);
|
||||||
|
|
||||||
|
let expectation = &constraints.pattern_expectations[expectation_index.index()];
|
||||||
let expected = type_to_var(
|
let expected = type_to_var(
|
||||||
subs,
|
subs,
|
||||||
rank,
|
rank,
|
||||||
|
@ -700,9 +719,15 @@ fn solve(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IsOpenType(type_index) => {
|
IsOpenType(type_index) => {
|
||||||
let typ = &constraints.types[type_index.index()];
|
let actual = either_type_index_to_var(
|
||||||
|
constraints,
|
||||||
|
subs,
|
||||||
|
rank,
|
||||||
|
pools,
|
||||||
|
cached_aliases,
|
||||||
|
*type_index,
|
||||||
|
);
|
||||||
|
|
||||||
let actual = type_to_var(subs, rank, pools, cached_aliases, typ);
|
|
||||||
let mut new_desc = subs.get(actual);
|
let mut new_desc = subs.get(actual);
|
||||||
match new_desc.content {
|
match new_desc.content {
|
||||||
Content::Structure(FlatType::TagUnion(tags, _)) => {
|
Content::Structure(FlatType::TagUnion(tags, _)) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue