diff --git a/compiler/can/src/constraint.rs b/compiler/can/src/constraint.rs index 6927268108..7a8857a413 100644 --- a/compiler/can/src/constraint.rs +++ b/compiler/can/src/constraint.rs @@ -21,6 +21,7 @@ pub struct Constraints { pub includes_tags: Vec, pub strings: Vec<&'static str>, pub sketched_rows: Vec, + pub eq: Vec, } impl Default for Constraints { @@ -43,6 +44,7 @@ impl Constraints { let includes_tags = Vec::new(); let strings = Vec::new(); let sketched_rows = Vec::new(); + let eq = Vec::new(); types.extend([ Type::EmptyRec, @@ -94,6 +96,7 @@ impl Constraints { includes_tags, strings, sketched_rows, + eq, } } @@ -229,7 +232,7 @@ impl Constraints { let expected_index = Index::push_new(&mut self.expectations, expected); let category_index = Self::push_category(self, category); - Constraint::Eq(type_index, expected_index, category_index, region) + Constraint::Eq(Eq(type_index, expected_index, category_index, region)) } #[inline(always)] @@ -244,7 +247,7 @@ impl Constraints { let expected_index = Index::push_new(&mut self.expectations, expected); let category_index = Self::push_category(self, category); - Constraint::Eq(type_index, expected_index, category_index, region) + Constraint::Eq(Eq(type_index, expected_index, category_index, region)) } #[inline(always)] @@ -260,17 +263,17 @@ impl Constraints { let expected_index = Index::push_new(&mut self.expectations, expected); let category_index = Self::push_category(self, category); - let equal = Constraint::Eq(type_index, expected_index, category_index, region); + let equal = Constraint::Eq(Eq(type_index, expected_index, category_index, region)); let storage_type_index = Self::push_type_variable(storage_var); let storage_category = Category::Storage(std::file!(), std::line!()); let storage_category_index = Self::push_category(self, storage_category); - let storage = Constraint::Eq( + let storage = Constraint::Eq(Eq( storage_type_index, expected_index, storage_category_index, region, - ); + )); self.and_constraint([equal, storage]) } @@ -612,31 +615,31 @@ impl Constraints { sketched_rows: SketchedRows, context: ExhaustiveContext, ) -> Constraint { + let real_var = Self::push_type_variable(real_var); let real_category = Index::push_new(&mut self.categories, real_category); let expected_branches = Index::push_new(&mut self.expectations, expected_branches); + let equality = Eq(real_var, expected_branches, real_category, real_region); + let equality = Index::push_new(&mut self.eq, equality); let sketched_rows = Index::push_new(&mut self.sketched_rows, sketched_rows); - Constraint::Exhaustive { - real_var, - real_region, - real_category, - expected_branches, - sketched_rows, - context, - } + Constraint::Exhaustive(equality, sketched_rows, context) } } roc_error_macros::assert_sizeof_default!(Constraint, 3 * 8); +roc_error_macros::assert_sizeof_aarch64!(Constraint, 3 * 8); + +#[derive(Clone, Copy, Debug)] +pub struct Eq( + pub EitherIndex, + pub Index>, + pub Index, + pub Region, +); #[derive(Clone, Copy)] pub enum Constraint { - Eq( - EitherIndex, - Index>, - Index, - Region, - ), + Eq(Eq), Store( EitherIndex, Variable, @@ -669,14 +672,7 @@ pub enum Constraint { Index, Region, ), - Exhaustive { - real_var: Variable, - real_region: Region, - real_category: Index, - expected_branches: Index>, - sketched_rows: Index, - context: ExhaustiveContext, - }, + Exhaustive(Index, Index, ExhaustiveContext), } #[derive(Debug, Clone, Copy, Default)] @@ -706,7 +702,7 @@ pub struct IncludesTag { impl std::fmt::Debug for Constraint { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::Eq(arg0, arg1, arg2, arg3) => { + Self::Eq(Eq(arg0, arg1, arg2, arg3)) => { write!(f, "Eq({:?}, {:?}, {:?}, {:?})", arg0, arg1, arg2, arg3) } Self::Store(arg0, arg1, arg2, arg3) => { @@ -731,19 +727,8 @@ impl std::fmt::Debug for Constraint { arg0, arg1, arg2, arg3 ) } - Self::Exhaustive { - real_var: arg0, - real_region: arg1, - real_category: arg2, - expected_branches: arg3, - sketched_rows: arg4, - context: arg5, - } => { - write!( - f, - "Exhaustive({:?}, {:?}, {:?}, {:?}, {:?}, {:?})", - arg0, arg1, arg2, arg3, arg4, arg5 - ) + Self::Exhaustive(arg0, arg1, arg2) => { + write!(f, "Exhaustive({:?}, {:?}, {:?})", arg0, arg1, arg2) } } } diff --git a/compiler/solve/src/solve.rs b/compiler/solve/src/solve.rs index 7b9d8d65ef..72930cd335 100644 --- a/compiler/solve/src/solve.rs +++ b/compiler/solve/src/solve.rs @@ -776,7 +776,7 @@ fn solve( copy } - Eq(type_index, expectation_index, category_index, region) => { + Eq(roc_can::constraint::Eq(type_index, expectation_index, category_index, region)) => { let category = &constraints.categories[category_index.index()]; let actual = @@ -1197,14 +1197,7 @@ fn solve( } } } - &Exhaustive { - real_var, - real_region, - real_category, - expected_branches, - sketched_rows, - context, - } => { + &Exhaustive(eq, sketched_rows, context) => { // A few cases: // 1. Either condition or branch types already have a type error. In this case just // propagate it. @@ -1216,6 +1209,16 @@ fn solve( // 4. Condition and branch types aren't "almost equal", this is just a normal type // error. + let roc_can::constraint::Eq( + real_var, + expected_branches, + real_category, + real_region, + ) = constraints.eq[eq.index()]; + + let real_var = + either_type_index_to_var(constraints, subs, rank, pools, aliases, real_var); + let expected_branches = &constraints.expectations[expected_branches.index()]; let branches_var = type_to_var(subs, rank, pools, aliases, expected_branches.get_type_ref());