From 2dfa7d6ef1b3e511a3da9c2d596ec9ee4c07b58f Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 28 Dec 2022 22:52:32 +0100 Subject: [PATCH 1/2] fix memory leak in List.concat --- crates/compiler/builtins/bitcode/src/list.zig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/compiler/builtins/bitcode/src/list.zig b/crates/compiler/builtins/bitcode/src/list.zig index eef76bfbaf..c55ad34a46 100644 --- a/crates/compiler/builtins/bitcode/src/list.zig +++ b/crates/compiler/builtins/bitcode/src/list.zig @@ -740,9 +740,8 @@ fn swapElements(source_ptr: [*]u8, element_width: usize, index_1: usize, index_2 } pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_width: usize) callconv(.C) RocList { - if (list_a.isEmpty()) { - return list_b; - } else if (list_b.isEmpty()) { + // NOTE we always use list_a! because it is owned, we must consume it, and it may have unused capacity + if (list_b.isEmpty()) { return list_a; } else if (list_a.isUnique()) { const total_length: usize = list_a.len() + list_b.len(); From 05e23f8c5c1dfe712294e9972138fab5ce0bc45e Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 28 Dec 2022 23:21:31 +0100 Subject: [PATCH 2/2] decref owned but empty list in List.concat --- crates/compiler/builtins/bitcode/src/list.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/compiler/builtins/bitcode/src/list.zig b/crates/compiler/builtins/bitcode/src/list.zig index c55ad34a46..37d29fbe1d 100644 --- a/crates/compiler/builtins/bitcode/src/list.zig +++ b/crates/compiler/builtins/bitcode/src/list.zig @@ -742,6 +742,9 @@ fn swapElements(source_ptr: [*]u8, element_width: usize, index_1: usize, index_2 pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_width: usize) callconv(.C) RocList { // NOTE we always use list_a! because it is owned, we must consume it, and it may have unused capacity if (list_b.isEmpty()) { + // we must consume this list. Even though it has no elements, it could still have capacity + list_b.deinit(usize); + return list_a; } else if (list_a.isUnique()) { const total_length: usize = list_a.len() + list_b.len();