diff --git a/compiler/can/src/constraint.rs b/compiler/can/src/constraint.rs index 70573d252a..193782daf5 100644 --- a/compiler/can/src/constraint.rs +++ b/compiler/can/src/constraint.rs @@ -1,5 +1,5 @@ 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::symbol::Symbol; use roc_region::all::{Loc, Region}; @@ -120,11 +120,18 @@ impl Constraints { pub const PCATEGORY_CHARACTER: Index = Index::new(10); #[inline(always)] - pub fn push_type(&mut self, typ: Type) -> Index { + pub fn push_type(&mut self, typ: Type) -> EitherIndex { match typ { - Type::EmptyRec => Self::EMPTY_RECORD, - Type::EmptyTagUnion => Self::EMPTY_TAG_UNION, - other => Index::push_new(&mut self.types, other), + Type::EmptyRec => EitherIndex::from_left(Self::EMPTY_RECORD), + Type::EmptyTagUnion => EitherIndex::from_left(Self::EMPTY_TAG_UNION), + Type::Variable(var) => { + let index: Index = Index::push_new(&mut self.variables, var); + EitherIndex::from_right(index) + } + other => { + let index: Index = Index::push_new(&mut self.types, other); + EitherIndex::from_left(index) + } } } @@ -180,7 +187,7 @@ impl Constraints { category: Category, region: Region, ) -> 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 category_index = Self::push_category(self, category); @@ -194,7 +201,7 @@ impl Constraints { category: PatternCategory, region: Region, ) -> 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 category_index = Self::push_pattern_category(self, category); @@ -208,7 +215,7 @@ impl Constraints { category: PatternCategory, region: Region, ) -> 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 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 { - let type_index = Index::push_new(&mut self.types, typ); + let type_index = self.push_type(typ); Constraint::IsOpenType(type_index) } @@ -446,7 +453,7 @@ impl Constraints { filename: &'static str, line_number: u32, ) -> 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); 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)] pub enum Constraint { - Eq(Index, Index>, Index, Region), - Store(Index, Variable, Index<&'static str>, u32), + Eq( + EitherIndex, + Index>, + Index, + Region, + ), + Store( + EitherIndex, + Variable, + Index<&'static str>, + u32, + ), Lookup(Symbol, Index>, Region), Pattern( - Index, + EitherIndex, Index>, Index, Region, @@ -471,10 +488,10 @@ pub enum Constraint { Let(Index), And(Slice), /// Presence constraints - IsOpenType(Index), // Theory; always applied to a variable? if yes the use that + IsOpenType(EitherIndex), // Theory; always applied to a variable? if yes the use that IncludesTag(Index), PatternPresence( - Index, + EitherIndex, Index>, Index, Region, diff --git a/compiler/constrain/src/expr.rs b/compiler/constrain/src/expr.rs index d9ca97f672..1318f6972a 100644 --- a/compiler/constrain/src/expr.rs +++ b/compiler/constrain/src/expr.rs @@ -1248,14 +1248,7 @@ fn constrain_empty_record( region: Region, expected: Expected, ) -> Constraint { - let expected_index = constraints.push_expected_type(expected); - - Constraint::Eq( - Constraints::EMPTY_RECORD, - expected_index, - Constraints::CATEGORY_RECORD, - region, - ) + constraints.equal_types(Type::EmptyRec, expected, Category::Record, region) } /// Constrain top-level module declarations diff --git a/compiler/solve/src/solve.rs b/compiler/solve/src/solve.rs index c94a8feafb..e0afc00962 100644 --- a/compiler/solve/src/solve.rs +++ b/compiler/solve/src/solve.rs @@ -414,11 +414,18 @@ fn solve( copy } 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 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( subs, rank, @@ -457,11 +464,16 @@ fn solve( } } 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. // 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; match unify(subs, actual, target, Mode::EQ) { @@ -572,11 +584,18 @@ fn solve( } Pattern(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 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( subs, rank, @@ -700,9 +719,15 @@ fn solve( } } 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); match new_desc.content { Content::Structure(FlatType::TagUnion(tags, _)) => {