diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index dfe4a31825..b42461d47d 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -604,7 +604,9 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( match expr { Literal(literal) => build_exp_literal(env, literal), - RunLowLevel(op, symbols) => run_low_level(env, scope, parent, layout, *op, symbols), + RunLowLevel(op, symbols) => { + run_low_level(env, layout_ids, scope, parent, layout, *op, symbols) + } ForeignCall { foreign_symbol, @@ -1165,12 +1167,10 @@ fn list_literal<'a, 'ctx, 'env>( let builder = env.builder; let len_u64 = elems.len() as u64; - let elem_bytes = elem_layout.stack_size(env.ptr_bytes) as u64; let ptr = { - let bytes_len = elem_bytes * len_u64; let len_type = env.ptr_int(); - let len = len_type.const_int(bytes_len, false); + let len = len_type.const_int(len_u64, false); allocate_list(env, inplace, elem_layout, len) @@ -2410,6 +2410,7 @@ pub static COLD_CALL_CONV: u32 = 9; fn run_low_level<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, + layout_ids: &mut LayoutIds<'a>, scope: &Scope<'a, 'ctx>, parent: FunctionValue<'ctx>, layout: &Layout<'a>, @@ -2523,7 +2524,16 @@ fn run_low_level<'a, 'ctx, 'env>( let inplace = get_inplace_from_layout(layout); - list_map(env, inplace, parent, func, func_layout, list, list_layout) + list_map( + env, + layout_ids, + inplace, + parent, + func, + func_layout, + list, + list_layout, + ) } ListKeepIf => { // List.keepIf : List elem, (elem -> Bool) -> List elem diff --git a/compiler/gen/src/llvm/build_list.rs b/compiler/gen/src/llvm/build_list.rs index 904c3f0fe9..f2bca58085 100644 --- a/compiler/gen/src/llvm/build_list.rs +++ b/compiler/gen/src/llvm/build_list.rs @@ -3,12 +3,13 @@ use crate::llvm::build::{ }; use crate::llvm::compare::build_eq; use crate::llvm::convert::{basic_type_from_layout, collection, get_ptr_type}; +use crate::llvm::refcounting::decrement_refcount_layout; use inkwell::builder::Builder; use inkwell::context::Context; use inkwell::types::{BasicTypeEnum, PointerType}; use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue}; use inkwell::{AddressSpace, IntPredicate}; -use roc_mono::layout::{Builtin, Layout, MemoryMode}; +use roc_mono::layout::{Builtin, Layout, LayoutIds, MemoryMode}; /// List.single : a -> List a pub fn list_single<'a, 'ctx, 'env>( @@ -1320,6 +1321,7 @@ pub fn list_keep_if_help<'a, 'ctx, 'env>( /// List.map : List before, (before -> after) -> List after pub fn list_map<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, + layout_ids: &mut LayoutIds<'a>, inplace: InPlace, parent: FunctionValue<'ctx>, func: BasicValueEnum<'ctx>, @@ -1365,7 +1367,11 @@ pub fn list_map<'a, 'ctx, 'env>( incrementing_elem_loop(builder, ctx, parent, list_ptr, len, "#index", list_loop); - store_list(env, ret_list_ptr, len) + let result = store_list(env, ret_list_ptr, len); + + decrement_refcount_layout(env, parent, layout_ids, list, list_layout); + + result }; if_list_is_not_empty(env, parent, non_empty_fn, list, list_layout, "List.map") @@ -2044,6 +2050,7 @@ pub fn allocate_list<'a, 'ctx, 'env>( let elem_bytes = elem_layout.stack_size(env.ptr_bytes) as u64; let bytes_per_element = len_type.const_int(elem_bytes, false); + // dbg!(bytes_per_element, length); let number_of_data_bytes = builder.build_int_mul(bytes_per_element, length, "data_length"); let rc1 = match inplace {