diff --git a/crates/aiken-lang/src/uplc.rs b/crates/aiken-lang/src/uplc.rs index 0fd2dd02..f616faa1 100644 --- a/crates/aiken-lang/src/uplc.rs +++ b/crates/aiken-lang/src/uplc.rs @@ -1753,7 +1753,7 @@ impl<'a> CodeGenerator<'a> { tail: tail.is_some(), scope, tipo: tipo.clone().into(), - check_last_item: false, + check_last_item: true, }); } else { pattern_vec.push(Air::Let { @@ -1768,7 +1768,8 @@ impl<'a> CodeGenerator<'a> { Pattern::Constructor { arguments, constructor, - tipo, + tipo: constr_tipo, + name: constr_name, .. } => { let mut nested_pattern = vec![]; @@ -1779,7 +1780,7 @@ impl<'a> CodeGenerator<'a> { let mut type_map: IndexMap> = IndexMap::new(); - for (index, arg) in tipo.arg_types().unwrap().iter().enumerate() { + for (index, arg) in constr_tipo.arg_types().unwrap().iter().enumerate() { let field_type = arg.clone(); type_map.insert(index, field_type); } @@ -1816,17 +1817,68 @@ impl<'a> CodeGenerator<'a> { (*index, var_name.clone(), field_type.clone()) }) .collect_vec(), - scope, + scope: scope.clone(), check_last_item: false, }); } else { pattern_vec.push(Air::Let { - scope, + scope: scope.clone(), name: "_".to_string(), }); } - pattern_vec.append(values); + if matches!(assignment_properties.kind, AssignmentKind::Expect) { + let data_type = + lookup_data_type_by_tipo(self.data_types.clone(), tipo).unwrap(); + + let (index, _) = data_type + .constructors + .iter() + .enumerate() + .find(|(_, constr)| &constr.name == constr_name) + .unwrap(); + + let constr_name = format!("__{}_{}", constr_name, self.id_gen.next()); + + pattern_vec.push(Air::Let { + scope: scope.clone(), + name: constr_name.clone(), + }); + + pattern_vec.append(values); + + pattern_vec.push(Air::AssertConstr { + scope: scope.clone(), + constr_index: index, + }); + + pattern_vec.push(Air::Var { + scope: scope.clone(), + constructor: ValueConstructor::public( + tipo.clone().into(), + ValueConstructorVariant::LocalVariable { + location: Span::empty(), + }, + ), + name: constr_name.clone(), + variant_name: String::new(), + }); + + pattern_vec.push(Air::Var { + scope, + constructor: ValueConstructor::public( + tipo.clone().into(), + ValueConstructorVariant::LocalVariable { + location: Span::empty(), + }, + ), + name: constr_name, + variant_name: String::new(), + }); + } else { + pattern_vec.append(values); + } + pattern_vec.append(&mut nested_pattern); } Pattern::Tuple { elems, .. } => { diff --git a/examples/acceptance_tests/040/lib/tests.ak b/examples/acceptance_tests/040/lib/tests.ak index 3bd58bd9..771c5075 100644 --- a/examples/acceptance_tests/040/lib/tests.ak +++ b/examples/acceptance_tests/040/lib/tests.ak @@ -16,7 +16,7 @@ pub type Car { } } -test update_owner1() { +test expect_ford1() { let initial_car = builtin.constr_data( 1, @@ -31,3 +31,27 @@ test update_owner1() { expect Ford { owner, wheels, truck_bed_limit, .. }: Car = initial_car owner == #"" && wheels == 4 && truck_bed_limit == 10000 } + + +test expect_ford2() { + let initial_car = Ford {remote_connect: #"", owner: #[34,34,34,34,34], wheels: 6, truck_bed_limit: 15000, car_doors: []} + expect Ford { owner, wheels, remote_connect, .. } = initial_car + owner == #[34,34,34,34,34] && wheels == 6 && remote_connect == #"" +} + + + + +test expect_list1() { + let initial_car = [5,6,7] + expect [a,b,c] = initial_car + a == 5 && b == 6 && c == 7 +} + + + +test expect_list2() { + let initial_car = [5,6,7] + expect [a, ..d] = initial_car + a == 5 && d == [6, 7] +}