From 8d60f08f65cfb352db5a81f389dfeffeabcbefc9 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sat, 31 Aug 2024 00:03:46 +0200 Subject: [PATCH 1/2] Add acceptance test 111 Seems like nested tuples are inferred wrongly when type-casted. ``` type mismatch Expected (list a) Got integer ``` --- examples/acceptance_tests/111/aiken.toml | 9 +++++++++ examples/acceptance_tests/111/lib/foo.ak | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 examples/acceptance_tests/111/aiken.toml create mode 100644 examples/acceptance_tests/111/lib/foo.ak diff --git a/examples/acceptance_tests/111/aiken.toml b/examples/acceptance_tests/111/aiken.toml new file mode 100644 index 00000000..40ab87df --- /dev/null +++ b/examples/acceptance_tests/111/aiken.toml @@ -0,0 +1,9 @@ +name = "aiken-lang/acceptance_test_111" +version = "0.0.0" +license = "Apache-2.0" +description = "Aiken contracts for project 'aiken-lang/111'" + +[repository] +user = "aiken-lang" +project = "111" +platform = "github" diff --git a/examples/acceptance_tests/111/lib/foo.ak b/examples/acceptance_tests/111/lib/foo.ak new file mode 100644 index 00000000..ae635882 --- /dev/null +++ b/examples/acceptance_tests/111/lib/foo.ak @@ -0,0 +1,16 @@ +type Point = + (ByteArray, Int) + +type NestedTuples { + points: (Point, Point), +} + +test boom() { + let original = NestedTuples { points: (("", 14), ("foo", 42)) } + + let data: Data = original + + expect recovered: NestedTuples = data + + original == recovered +} From 53af366b5951c16597409b49385c35624ef44335 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sun, 1 Sep 2024 18:08:20 +0200 Subject: [PATCH 2/2] Ensure uniqueness of intermediate variables in expect_type_assign For recursive structures like Tuples, the span itself isn't enough to ensure uniqueness of elements (in particular tuples) holding elements of the same type. --- crates/aiken-lang/src/gen_uplc.rs | 41 ++++++++++++++++++++++--------- crates/uplc/src/builder.rs | 10 ++++++-- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index a52153be..b95f9ca4 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -1616,10 +1616,17 @@ impl<'a> CodeGenerator<'a> { assert!(inner_pair_types.len() == 2); - let map_name = format!("__map_span_{}_{}", location.start, location.end); - let pair_name = format!("__pair_span_{}_{}", location.start, location.end); - let fst_name = format!("__pair_fst_span_{}_{}", location.start, location.end); - let snd_name = format!("__pair_snd_span_{}_{}", location.start, location.end); + let map_name = format!("__map_{}_span_{}_{}", depth, location.start, location.end); + let pair_name = + format!("__pair_{}_span_{}_{}", depth, location.start, location.end); + let fst_name = format!( + "__pair_fst_{}_span_{}_{}", + depth, location.start, location.end + ); + let snd_name = format!( + "__pair_snd_{}_span_{}_{}", + depth, location.start, location.end + ); let expect_snd = self.expect_type_assign( &inner_pair_types[1], @@ -1738,7 +1745,8 @@ impl<'a> CodeGenerator<'a> { assert!(!tuple_inner_types.is_empty()); - let tuple_name = format!("__tuple_span_{}_{}", location.start, location.end); + let tuple_name = + format!("__tuple_{}_span_{}_{}", depth, location.start, location.end); let mut tuple_expect_items = vec![]; @@ -1748,8 +1756,8 @@ impl<'a> CodeGenerator<'a> { .enumerate() .rfold(then, |then, (index, arg)| { let tuple_index_name = format!( - "__tuple_index_{}_span_{}_{}", - index, location.start, location.end + "__tuple_{}_index_{}_span_{}_{}", + depth, index, location.start, location.end ); let expect_tuple_item = self.expect_type_assign( @@ -1789,8 +1797,10 @@ impl<'a> CodeGenerator<'a> { if inner_list_type.is_data() { then } else { - let list_name = format!("__list_span_{}_{}", location.start, location.end); - let item_name = format!("__item_span_{}_{}", location.start, location.end); + let list_name = + format!("__list_{}_span_{}_{}", depth, location.start, location.end); + let item_name = + format!("__item_{}_span_{}_{}", depth, location.start, location.end); let unwrap_function = AirTree::anon_func( vec![ @@ -1902,10 +1912,17 @@ impl<'a> CodeGenerator<'a> { assert!(tuple_inner_types.len() == 2); - let pair_name = format!("__pair_span_{}_{}", location.start, location.end); + let pair_name = + format!("__pair_{}_span_{}_{}", depth, location.start, location.end); - let fst_name = format!("__pair_fst_span_{}_{}", location.start, location.end); - let snd_name = format!("__pair_snd_span_{}_{}", location.start, location.end); + let fst_name = format!( + "__pair_fst_{}_span_{}_{}", + depth, location.start, location.end + ); + let snd_name = format!( + "__pair_snd_{}_span_{}_{}", + depth, location.start, location.end + ); let expect_snd = self.expect_type_assign( &tuple_inner_types[1], diff --git a/crates/uplc/src/builder.rs b/crates/uplc/src/builder.rs index a340e916..e4174c1c 100644 --- a/crates/uplc/src/builder.rs +++ b/crates/uplc/src/builder.rs @@ -10,7 +10,10 @@ pub const CONSTR_INDEX_EXPOSER: &str = "__constr_index_exposer"; pub const EXPECT_ON_LIST: &str = "__expect_on_list"; pub const INNER_EXPECT_ON_LIST: &str = "__inner_expect_on_list"; -impl Term { +impl Term +where + T: std::fmt::Debug, +{ // Terms pub fn apply(self, arg: Self) -> Self { Term::Apply { @@ -391,7 +394,10 @@ impl Term { } } -impl Term { +impl Term +where + T: std::fmt::Debug, +{ pub fn delayed_choose_data( self, constr_case: Self,