diff --git a/crates/compiler/gen_dev/src/generic64/mod.rs b/crates/compiler/gen_dev/src/generic64/mod.rs index e33942dfee..0ae17f2e07 100644 --- a/crates/compiler/gen_dev/src/generic64/mod.rs +++ b/crates/compiler/gen_dev/src/generic64/mod.rs @@ -3299,7 +3299,7 @@ impl< let elem_layout = arg_layouts[1]; // List alignment argument (u32). - self.load_layout_alignment(*ret_layout, Symbol::DEV_TMP); + self.load_layout_alignment(elem_layout, Symbol::DEV_TMP); // Have to pass the input element by pointer, so put it on the stack and load it's address. self.storage_manager diff --git a/crates/compiler/gen_wasm/src/wasm32_sized.rs b/crates/compiler/gen_wasm/src/wasm32_sized.rs index 05ac6d95ec..003d8f9ca6 100644 --- a/crates/compiler/gen_wasm/src/wasm32_sized.rs +++ b/crates/compiler/gen_wasm/src/wasm32_sized.rs @@ -75,19 +75,36 @@ impl Wasm32Sized for isize { const ALIGN_OF_WASM: usize = 4; } +const fn next_multiple_of(lhs: usize, rhs: usize) -> usize { + if lhs == 0 { + return lhs; + } + + match lhs % rhs { + 0 => lhs, + r => lhs + (rhs - r), + } +} + impl Wasm32Sized for (T, U) { - const SIZE_OF_WASM: usize = T::SIZE_OF_WASM + U::SIZE_OF_WASM; + const SIZE_OF_WASM: usize = + next_multiple_of(T::SIZE_OF_WASM + U::SIZE_OF_WASM, Self::ALIGN_OF_WASM); const ALIGN_OF_WASM: usize = max(&[T::ALIGN_OF_WASM, U::ALIGN_OF_WASM]); } impl Wasm32Sized for (T, U, V) { - const SIZE_OF_WASM: usize = T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM; + const SIZE_OF_WASM: usize = next_multiple_of( + T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM, + Self::ALIGN_OF_WASM, + ); const ALIGN_OF_WASM: usize = max(&[T::ALIGN_OF_WASM, U::ALIGN_OF_WASM, V::ALIGN_OF_WASM]); } impl Wasm32Sized for (T, U, V, W) { - const SIZE_OF_WASM: usize = - T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM + W::SIZE_OF_WASM; + const SIZE_OF_WASM: usize = next_multiple_of( + T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM + W::SIZE_OF_WASM, + Self::ALIGN_OF_WASM, + ); const ALIGN_OF_WASM: usize = max(&[ T::ALIGN_OF_WASM, U::ALIGN_OF_WASM, diff --git a/crates/compiler/test_gen/src/gen_list.rs b/crates/compiler/test_gen/src/gen_list.rs index fdf062621e..b8503d69f8 100644 --- a/crates/compiler/test_gen/src/gen_list.rs +++ b/crates/compiler/test_gen/src/gen_list.rs @@ -910,6 +910,25 @@ fn list_prepend_big_list() { ); } +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))] +fn list_prepend_record() { + assert_evals_to!( + indoc!( + r" + payment1 : { amount: Dec, date: [RD I32] } + payment1 = { amount: 1dec, date: (RD 1000) } + payment2 : { amount: Dec, date: [RD I32] } + payment2 = { amount: 2dec, date: (RD 1001) } + + List.prepend [payment2] payment1 + " + ), + RocList::from_slice(&[(RocDec::from(1), 1000i32), (RocDec::from(2), 1001i32),]), + RocList<(RocDec, i32)> + ); +} + #[test] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))] fn list_walk_backwards_empty_all_inline() { diff --git a/crates/compiler/test_gen/src/helpers/from_wasm32_memory.rs b/crates/compiler/test_gen/src/helpers/from_wasm32_memory.rs index 218292a588..f124006e87 100644 --- a/crates/compiler/test_gen/src/helpers/from_wasm32_memory.rs +++ b/crates/compiler/test_gen/src/helpers/from_wasm32_memory.rs @@ -91,15 +91,11 @@ impl FromWasm32Memory for RocList { let capacity = ::decode(memory, offset + 4 * Builtin::WRAPPER_CAPACITY); - let mut items = Vec::with_capacity(length as usize); + let step = ::SIZE_OF_WASM; - for i in 0..length { - let item = ::decode( - memory, - elements + i * ::SIZE_OF_WASM as u32, - ); - items.push(item); - } + let items: Vec<_> = (0..length) + .map(|i| ::decode(memory, elements + i * step as u32)) + .collect(); let mut list = RocList::with_capacity(capacity as usize); list.extend_from_slice(&items);