From a45001376d403e7682a4d02074a00d4dbe88b558 Mon Sep 17 00:00:00 2001 From: microproofs Date: Wed, 13 Sep 2023 00:33:02 -0400 Subject: [PATCH] fix: is_record was used incorrectly in code gen, the real solution was to look up the datatype and check constructors length --- crates/aiken-lang/src/gen_uplc.rs | 15 ++++----- crates/aiken-lang/src/gen_uplc/builder.rs | 38 ++++++++++++++--------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 8376a1e61..2c01a2641 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -476,7 +476,7 @@ impl<'a> CodeGenerator<'a> { assignment.hoist_over(clause_then) } else { clauses = if subject.tipo().is_list() { - rearrange_list_clauses(clauses) + rearrange_list_clauses(clauses, &self.data_types) } else { clauses }; @@ -1767,8 +1767,8 @@ impl<'a> CodeGenerator<'a> { let mut is_wild_card_elems_clause = clause.guard.is_none(); for element in elements.iter() { - is_wild_card_elems_clause = - is_wild_card_elems_clause && !pattern_has_conditions(element); + is_wild_card_elems_clause = is_wild_card_elems_clause + && !pattern_has_conditions(element, &self.data_types); } if *checked_index < elements_len.try_into().unwrap() @@ -2447,9 +2447,7 @@ impl<'a> CodeGenerator<'a> { } } Pattern::Constructor { - name: constr_name, - is_record, - .. + name: constr_name, .. } => { if subject_tipo.is_bool() { props.complex_clause = true; @@ -2461,7 +2459,10 @@ impl<'a> CodeGenerator<'a> { } else { let (cond, assign) = self.clause_pattern(pattern, subject_tipo, props); - if *is_record { + let data_type = lookup_data_type_by_tipo(&self.data_types, subject_tipo) + .expect("Missing data type"); + + if data_type.constructors.len() == 1 { assign } else { props.complex_clause = true; diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 1804503a6..7dad571da 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -763,28 +763,36 @@ pub fn modify_self_calls( recursive_nonstatics } -pub fn pattern_has_conditions(pattern: &TypedPattern) -> bool { +pub fn pattern_has_conditions( + pattern: &TypedPattern, + data_types: &IndexMap, +) -> bool { match pattern { + Pattern::List { .. } | Pattern::Int { .. } => true, + Pattern::Tuple { elems, .. } => elems + .iter() + .any(|elem| pattern_has_conditions(elem, data_types)), Pattern::Constructor { - is_record: false, .. + arguments, tipo, .. + } => { + let data_type = + lookup_data_type_by_tipo(data_types, tipo).expect("Data type not found"); + + data_type.constructors.len() > 1 + || arguments + .iter() + .any(|arg| pattern_has_conditions(&arg.value, data_types)) } - | Pattern::List { .. } - | Pattern::Int { .. } => true, - Pattern::Tuple { elems, .. } => elems.iter().any(pattern_has_conditions), - Pattern::Constructor { - is_record: true, - arguments, - .. - } => arguments - .iter() - .any(|arg| pattern_has_conditions(&arg.value)), - Pattern::Assign { pattern, .. } => pattern_has_conditions(pattern), + Pattern::Assign { pattern, .. } => pattern_has_conditions(pattern, data_types), Pattern::Var { .. } | Pattern::Discard { .. } => false, } } // TODO: write some tests -pub fn rearrange_list_clauses(clauses: Vec) -> Vec { +pub fn rearrange_list_clauses( + clauses: Vec, + data_types: &IndexMap, +) -> Vec { let mut sorted_clauses = clauses; // if we have a list sort clauses so we can plug holes for cases not covered by clauses @@ -954,7 +962,7 @@ pub fn rearrange_list_clauses(clauses: Vec) -> Vec { for element in elements.iter() { is_wild_card_elems_clause = - is_wild_card_elems_clause && !pattern_has_conditions(element); + is_wild_card_elems_clause && !pattern_has_conditions(element, data_types); } if is_wild_card_elems_clause {