mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge pull request #6462 from roc-lang/list-prepend-bug
List prepend bug
This commit is contained in:
commit
ea10f13837
4 changed files with 45 additions and 13 deletions
|
@ -3299,7 +3299,7 @@ impl<
|
||||||
let elem_layout = arg_layouts[1];
|
let elem_layout = arg_layouts[1];
|
||||||
|
|
||||||
// List alignment argument (u32).
|
// 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.
|
// Have to pass the input element by pointer, so put it on the stack and load it's address.
|
||||||
self.storage_manager
|
self.storage_manager
|
||||||
|
|
|
@ -75,19 +75,36 @@ impl Wasm32Sized for isize {
|
||||||
const ALIGN_OF_WASM: usize = 4;
|
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<T: Wasm32Sized, U: Wasm32Sized> Wasm32Sized for (T, U) {
|
impl<T: Wasm32Sized, U: Wasm32Sized> 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]);
|
const ALIGN_OF_WASM: usize = max(&[T::ALIGN_OF_WASM, U::ALIGN_OF_WASM]);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Wasm32Sized, U: Wasm32Sized, V: Wasm32Sized> Wasm32Sized for (T, U, V) {
|
impl<T: Wasm32Sized, U: Wasm32Sized, V: Wasm32Sized> 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]);
|
const ALIGN_OF_WASM: usize = max(&[T::ALIGN_OF_WASM, U::ALIGN_OF_WASM, V::ALIGN_OF_WASM]);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Wasm32Sized, U: Wasm32Sized, V: Wasm32Sized, W: Wasm32Sized> Wasm32Sized for (T, U, V, W) {
|
impl<T: Wasm32Sized, U: Wasm32Sized, V: Wasm32Sized, W: Wasm32Sized> Wasm32Sized for (T, U, V, W) {
|
||||||
const SIZE_OF_WASM: usize =
|
const SIZE_OF_WASM: usize = next_multiple_of(
|
||||||
T::SIZE_OF_WASM + U::SIZE_OF_WASM + V::SIZE_OF_WASM + W::SIZE_OF_WASM;
|
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(&[
|
const ALIGN_OF_WASM: usize = max(&[
|
||||||
T::ALIGN_OF_WASM,
|
T::ALIGN_OF_WASM,
|
||||||
U::ALIGN_OF_WASM,
|
U::ALIGN_OF_WASM,
|
||||||
|
|
|
@ -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]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
|
||||||
fn list_walk_backwards_empty_all_inline() {
|
fn list_walk_backwards_empty_all_inline() {
|
||||||
|
|
|
@ -91,15 +91,11 @@ impl<T: FromWasm32Memory + Clone> FromWasm32Memory for RocList<T> {
|
||||||
let capacity =
|
let capacity =
|
||||||
<u32 as FromWasm32Memory>::decode(memory, offset + 4 * Builtin::WRAPPER_CAPACITY);
|
<u32 as FromWasm32Memory>::decode(memory, offset + 4 * Builtin::WRAPPER_CAPACITY);
|
||||||
|
|
||||||
let mut items = Vec::with_capacity(length as usize);
|
let step = <T as Wasm32Sized>::SIZE_OF_WASM;
|
||||||
|
|
||||||
for i in 0..length {
|
let items: Vec<_> = (0..length)
|
||||||
let item = <T as FromWasm32Memory>::decode(
|
.map(|i| <T as FromWasm32Memory>::decode(memory, elements + i * step as u32))
|
||||||
memory,
|
.collect();
|
||||||
elements + i * <T as Wasm32Sized>::SIZE_OF_WASM as u32,
|
|
||||||
);
|
|
||||||
items.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut list = RocList::with_capacity(capacity as usize);
|
let mut list = RocList::with_capacity(capacity as usize);
|
||||||
list.extend_from_slice(&items);
|
list.extend_from_slice(&items);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue