use EitherIndex<Type, Variable> to halve number of types stored

This commit is contained in:
Folkert 2022-03-13 01:46:49 +01:00
parent da03b0c2b3
commit b3d9f9c2de
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
3 changed files with 69 additions and 34 deletions

View file

@ -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,

View file

@ -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

View file

@ -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, _)) => {