simplify list layout

This commit is contained in:
Folkert 2021-05-26 14:28:56 +02:00
parent bfe49d2188
commit e2b200b84f
10 changed files with 62 additions and 93 deletions

View file

@ -116,7 +116,7 @@ fn jit_to_ast_help<'a>(
} }
})) }))
} }
Layout::Builtin(Builtin::List(_, elem_layout)) => Ok(run_jit_function!( Layout::Builtin(Builtin::List(elem_layout)) => Ok(run_jit_function!(
lib, lib,
main_fn_name, main_fn_name,
(*const u8, usize), (*const u8, usize),
@ -291,7 +291,7 @@ fn ptr_to_ast<'a>(
items: &[], items: &[],
final_comments: &[], final_comments: &[],
}, },
Layout::Builtin(Builtin::List(_, elem_layout)) => { Layout::Builtin(Builtin::List(elem_layout)) => {
// Turn the (ptr, len) wrapper struct into actual ptr and len values. // Turn the (ptr, len) wrapper struct into actual ptr and len values.
let len = unsafe { *(ptr.offset(env.ptr_bytes as isize) as *const usize) }; let len = unsafe { *(ptr.offset(env.ptr_bytes as isize) as *const usize) };
let ptr = unsafe { *(ptr as *const *const u8) }; let ptr = unsafe { *(ptr as *const *const u8) };

View file

@ -2180,7 +2180,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
let (value, layout) = load_symbol_and_layout(scope, symbol); let (value, layout) = load_symbol_and_layout(scope, symbol);
match layout { match layout {
Layout::Builtin(Builtin::List(_, _)) => { Layout::Builtin(Builtin::List(_)) => {
debug_assert!(value.is_struct_value()); debug_assert!(value.is_struct_value());
// because of how we insert DECREF for lists, we can't guarantee that // because of how we insert DECREF for lists, we can't guarantee that
@ -3585,7 +3585,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
match list_layout { match list_layout {
Layout::Builtin(Builtin::EmptyList) => default, Layout::Builtin(Builtin::EmptyList) => default,
Layout::Builtin(Builtin::List(_, element_layout)) => { Layout::Builtin(Builtin::List(element_layout)) => {
let argument_layouts = &[**element_layout, *default_layout]; let argument_layouts = &[**element_layout, *default_layout];
let roc_function_call = roc_function_call( let roc_function_call = roc_function_call(
@ -3627,8 +3627,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
match (list_layout, return_layout) { match (list_layout, return_layout) {
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
( (
Layout::Builtin(Builtin::List(_, element_layout)), Layout::Builtin(Builtin::List(element_layout)),
Layout::Builtin(Builtin::List(_, result_layout)), Layout::Builtin(Builtin::List(result_layout)),
) => { ) => {
let argument_layouts = &[**element_layout]; let argument_layouts = &[**element_layout];
@ -3658,9 +3658,9 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
match (list1_layout, list2_layout, return_layout) { match (list1_layout, list2_layout, return_layout) {
( (
Layout::Builtin(Builtin::List(_, element1_layout)), Layout::Builtin(Builtin::List(element1_layout)),
Layout::Builtin(Builtin::List(_, element2_layout)), Layout::Builtin(Builtin::List(element2_layout)),
Layout::Builtin(Builtin::List(_, result_layout)), Layout::Builtin(Builtin::List(result_layout)),
) => { ) => {
let argument_layouts = &[**element1_layout, **element2_layout]; let argument_layouts = &[**element1_layout, **element2_layout];
@ -3702,10 +3702,10 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
match (list1_layout, list2_layout, list3_layout, return_layout) { match (list1_layout, list2_layout, list3_layout, return_layout) {
( (
Layout::Builtin(Builtin::List(_, element1_layout)), Layout::Builtin(Builtin::List(element1_layout)),
Layout::Builtin(Builtin::List(_, element2_layout)), Layout::Builtin(Builtin::List(element2_layout)),
Layout::Builtin(Builtin::List(_, element3_layout)), Layout::Builtin(Builtin::List(element3_layout)),
Layout::Builtin(Builtin::List(_, result_layout)), Layout::Builtin(Builtin::List(result_layout)),
) => { ) => {
let argument_layouts = let argument_layouts =
&[**element1_layout, **element2_layout, **element3_layout]; &[**element1_layout, **element2_layout, **element3_layout];
@ -3752,8 +3752,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
match (list_layout, return_layout) { match (list_layout, return_layout) {
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
( (
Layout::Builtin(Builtin::List(_, element_layout)), Layout::Builtin(Builtin::List(element_layout)),
Layout::Builtin(Builtin::List(_, result_layout)), Layout::Builtin(Builtin::List(result_layout)),
) => { ) => {
let argument_layouts = &[Layout::Builtin(Builtin::Usize), **element_layout]; let argument_layouts = &[Layout::Builtin(Builtin::Usize), **element_layout];
@ -3784,7 +3784,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
match list_layout { match list_layout {
Layout::Builtin(Builtin::EmptyList) => empty_list(env), Layout::Builtin(Builtin::EmptyList) => empty_list(env),
Layout::Builtin(Builtin::List(_, element_layout)) => { Layout::Builtin(Builtin::List(element_layout)) => {
let argument_layouts = &[**element_layout]; let argument_layouts = &[**element_layout];
let roc_function_call = roc_function_call( let roc_function_call = roc_function_call(
@ -3816,8 +3816,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
(_, Layout::Builtin(Builtin::EmptyList)) (_, Layout::Builtin(Builtin::EmptyList))
| (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), | (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
( (
Layout::Builtin(Builtin::List(_, before_layout)), Layout::Builtin(Builtin::List(before_layout)),
Layout::Builtin(Builtin::List(_, after_layout)), Layout::Builtin(Builtin::List(after_layout)),
) => { ) => {
let argument_layouts = &[**before_layout]; let argument_layouts = &[**before_layout];
@ -3860,8 +3860,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
(_, Layout::Builtin(Builtin::EmptyList)) (_, Layout::Builtin(Builtin::EmptyList))
| (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), | (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
( (
Layout::Builtin(Builtin::List(_, before_layout)), Layout::Builtin(Builtin::List(before_layout)),
Layout::Builtin(Builtin::List(_, after_layout)), Layout::Builtin(Builtin::List(after_layout)),
) => { ) => {
let argument_layouts = &[**before_layout]; let argument_layouts = &[**before_layout];
@ -3911,7 +3911,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
match list_layout { match list_layout {
Layout::Builtin(Builtin::EmptyList) => empty_list(env), Layout::Builtin(Builtin::EmptyList) => empty_list(env),
Layout::Builtin(Builtin::List(_, element_layout)) => { Layout::Builtin(Builtin::List(element_layout)) => {
use crate::llvm::bitcode::build_compare_wrapper; use crate::llvm::bitcode::build_compare_wrapper;
let argument_layouts = &[**element_layout, **element_layout]; let argument_layouts = &[**element_layout, **element_layout];
@ -4179,7 +4179,7 @@ fn run_low_level<'a, 'ctx, 'env>(
match list_layout { match list_layout {
Layout::Builtin(Builtin::EmptyList) => empty_list(env), Layout::Builtin(Builtin::EmptyList) => empty_list(env),
Layout::Builtin(Builtin::List(_, element_layout)) => list_drop( Layout::Builtin(Builtin::List(element_layout)) => list_drop(
env, env,
layout_ids, layout_ids,
original_wrapper, original_wrapper,
@ -4448,7 +4448,7 @@ fn run_low_level<'a, 'ctx, 'env>(
// no elements, so nothing to remove // no elements, so nothing to remove
empty_list(env) empty_list(env)
} }
Layout::Builtin(Builtin::List(_, element_layout)) => list_set( Layout::Builtin(Builtin::List(element_layout)) => list_set(
env, env,
layout_ids, layout_ids,
list, list,
@ -4469,7 +4469,7 @@ fn run_low_level<'a, 'ctx, 'env>(
// no elements, so nothing to remove // no elements, so nothing to remove
empty_list(env) empty_list(env)
} }
Layout::Builtin(Builtin::List(_, element_layout)) => list_set( Layout::Builtin(Builtin::List(element_layout)) => list_set(
env, env,
layout_ids, layout_ids,
list, list,
@ -4646,7 +4646,7 @@ fn run_low_level<'a, 'ctx, 'env>(
match list_layout { match list_layout {
Layout::Builtin(Builtin::EmptyList) => dict_empty(env), Layout::Builtin(Builtin::EmptyList) => dict_empty(env),
Layout::Builtin(Builtin::List(_, key_layout)) => { Layout::Builtin(Builtin::List(key_layout)) => {
set_from_list(env, layout_ids, list, key_layout) set_from_list(env, layout_ids, list, key_layout)
} }
_ => unreachable!("invalid dict layout"), _ => unreachable!("invalid dict layout"),

View file

@ -148,7 +148,7 @@ fn hash_builtin<'a, 'ctx, 'env>(
Builtin::Set(_) => { Builtin::Set(_) => {
todo!("Implement Hash for Set") todo!("Implement Hash for Set")
} }
Builtin::List(_, element_layout) => build_hash_list( Builtin::List(element_layout) => build_hash_list(
env, env,
layout_ids, layout_ids,
layout, layout,

View file

@ -14,7 +14,7 @@ use inkwell::types::{BasicTypeEnum, PointerType};
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue}; use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue};
use inkwell::{AddressSpace, IntPredicate}; use inkwell::{AddressSpace, IntPredicate};
use roc_builtins::bitcode; use roc_builtins::bitcode;
use roc_mono::layout::{Builtin, InPlace, Layout, LayoutIds, MemoryMode}; use roc_mono::layout::{Builtin, InPlace, Layout, LayoutIds};
fn list_returned_from_zig<'a, 'ctx, 'env>( fn list_returned_from_zig<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
@ -196,12 +196,12 @@ pub fn list_join<'a, 'ctx, 'env>(
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {
match outer_list_layout { match outer_list_layout {
Layout::Builtin(Builtin::EmptyList) Layout::Builtin(Builtin::EmptyList)
| Layout::Builtin(Builtin::List(_, Layout::Builtin(Builtin::EmptyList))) => { | Layout::Builtin(Builtin::List(Layout::Builtin(Builtin::EmptyList))) => {
// If the input list is empty, or if it is a list of empty lists // If the input list is empty, or if it is a list of empty lists
// then simply return an empty list // then simply return an empty list
empty_list(env) empty_list(env)
} }
Layout::Builtin(Builtin::List(_, Layout::Builtin(Builtin::List(_, element_layout)))) => { Layout::Builtin(Builtin::List(Layout::Builtin(Builtin::List(element_layout)))) => {
call_bitcode_fn_returns_list( call_bitcode_fn_returns_list(
env, env,
&[ &[
@ -231,13 +231,7 @@ pub fn list_reverse<'a, 'ctx, 'env>(
// this pointer will never actually be dereferenced // this pointer will never actually be dereferenced
Layout::Builtin(Builtin::Int64), Layout::Builtin(Builtin::Int64),
), ),
Layout::Builtin(Builtin::List(memory_mode, elem_layout)) => ( Layout::Builtin(Builtin::List(elem_layout)) => (InPlace::Clone, *elem_layout),
match memory_mode {
MemoryMode::Unique => InPlace::InPlace,
MemoryMode::Refcounted => InPlace::Clone,
},
*elem_layout,
),
_ => unreachable!("Invalid layout {:?} in List.reverse", list_layout), _ => unreachable!("Invalid layout {:?} in List.reverse", list_layout),
}; };
@ -264,7 +258,7 @@ pub fn list_get_unsafe<'a, 'ctx, 'env>(
let builder = env.builder; let builder = env.builder;
match list_layout { match list_layout {
Layout::Builtin(Builtin::List(_, elem_layout)) => { Layout::Builtin(Builtin::List(elem_layout)) => {
let elem_type = basic_type_from_layout(env, elem_layout); let elem_type = basic_type_from_layout(env, elem_layout);
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic); let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
// Load the pointer to the array data // Load the pointer to the array data
@ -861,7 +855,7 @@ pub fn list_concat<'a, 'ctx, 'env>(
// then simply return an empty list // then simply return an empty list
empty_list(env) empty_list(env)
} }
Layout::Builtin(Builtin::List(_, elem_layout)) => call_bitcode_fn_returns_list( Layout::Builtin(Builtin::List(elem_layout)) => call_bitcode_fn_returns_list(
env, env,
&[ &[
pass_list_as_i128(env, first_list), pass_list_as_i128(env, first_list),

View file

@ -99,7 +99,7 @@ fn build_eq_builtin<'a, 'ctx, 'env>(
Builtin::Float16 => float_cmp(FloatPredicate::OEQ, "eq_f16"), Builtin::Float16 => float_cmp(FloatPredicate::OEQ, "eq_f16"),
Builtin::Str => str_equal(env, lhs_val, rhs_val), Builtin::Str => str_equal(env, lhs_val, rhs_val),
Builtin::List(_, elem) => build_list_eq( Builtin::List(elem) => build_list_eq(
env, env,
layout_ids, layout_ids,
&Layout::Builtin(*builtin), &Layout::Builtin(*builtin),
@ -249,7 +249,7 @@ fn build_neq_builtin<'a, 'ctx, 'env>(
result.into() result.into()
} }
Builtin::List(_, elem) => { Builtin::List(elem) => {
let is_equal = build_list_eq( let is_equal = build_list_eq(
env, env,
layout_ids, layout_ids,

View file

@ -170,7 +170,7 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
Float16 => context.f16_type().as_basic_type_enum(), Float16 => context.f16_type().as_basic_type_enum(),
Dict(_, _) | EmptyDict => zig_dict_type(env).into(), Dict(_, _) | EmptyDict => zig_dict_type(env).into(),
Set(_) | EmptySet => zig_dict_type(env).into(), Set(_) | EmptySet => zig_dict_type(env).into(),
List(_, _) | EmptyList => zig_list_type(env).into(), List(_) | EmptyList => zig_list_type(env).into(),
Str | EmptyStr => zig_str_type(env).into(), Str | EmptyStr => zig_str_type(env).into(),
} }
} }

View file

@ -15,7 +15,7 @@ use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, Str
use inkwell::{AddressSpace, IntPredicate}; use inkwell::{AddressSpace, IntPredicate};
use roc_module::symbol::Interns; use roc_module::symbol::Interns;
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_mono::layout::{Builtin, Layout, LayoutIds, MemoryMode, UnionLayout}; use roc_mono::layout::{Builtin, Layout, LayoutIds, UnionLayout};
pub const REFCOUNT_MAX: usize = 0_usize; pub const REFCOUNT_MAX: usize = 0_usize;
@ -469,21 +469,17 @@ fn modify_refcount_builtin<'a, 'ctx, 'env>(
use Builtin::*; use Builtin::*;
match builtin { match builtin {
List(memory_mode, element_layout) => { List(element_layout) => {
if let MemoryMode::Refcounted = memory_mode { let function = modify_refcount_list(
let function = modify_refcount_list( env,
env, layout_ids,
layout_ids, mode,
mode, when_recursive,
when_recursive, layout,
layout, element_layout,
element_layout, );
);
Some(function) Some(function)
} else {
None
}
} }
Set(element_layout) => { Set(element_layout) => {
let key_layout = &Layout::Struct(&[]); let key_layout = &Layout::Struct(&[]);
@ -1687,7 +1683,7 @@ pub fn refcount_offset<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>, layout: &Layou
let value_bytes = layout.stack_size(env.ptr_bytes) as u64; let value_bytes = layout.stack_size(env.ptr_bytes) as u64;
match layout { match layout {
Layout::Builtin(Builtin::List(_, _)) => env.ptr_bytes as u64, Layout::Builtin(Builtin::List(_)) => env.ptr_bytes as u64,
Layout::Builtin(Builtin::Str) => env.ptr_bytes as u64, Layout::Builtin(Builtin::Str) => env.ptr_bytes as u64,
Layout::RecursivePointer | Layout::Union(_) => env.ptr_bytes as u64, Layout::RecursivePointer | Layout::Union(_) => env.ptr_bytes as u64,
_ => (env.ptr_bytes as u64).max(value_bytes), _ => (env.ptr_bytes as u64).max(value_bytes),

View file

@ -548,7 +548,7 @@ fn builtin_spec(builder: &mut FuncDefBuilder, builtin: &Builtin) -> Result<TypeI
Str => todo!(), Str => todo!(),
Dict(_, _) => todo!(), Dict(_, _) => todo!(),
Set(_) => todo!(), Set(_) => todo!(),
List(_, _) => { List(_) => {
// TODO should incorporate the element type into the name // TODO should incorporate the element type into the name
Ok(builder.add_named_type(MOD_LIST, TypeName(b"List"))) Ok(builder.add_named_type(MOD_LIST, TypeName(b"List")))
} }

View file

@ -3,8 +3,8 @@
use self::InProgressProc::*; use self::InProgressProc::*;
use crate::exhaustive::{Ctor, Guard, RenderAs, TagId}; use crate::exhaustive::{Ctor, Guard, RenderAs, TagId};
use crate::layout::{ use crate::layout::{
Builtin, ClosureRepresentation, LambdaSet, Layout, LayoutCache, LayoutProblem, MemoryMode, Builtin, ClosureRepresentation, LambdaSet, Layout, LayoutCache, LayoutProblem, UnionLayout,
UnionLayout, WrappedVariant, TAG_SIZE, WrappedVariant, TAG_SIZE,
}; };
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use bumpalo::Bump; use bumpalo::Bump;
@ -3364,10 +3364,7 @@ pub fn with_hole<'a>(
Stmt::Let( Stmt::Let(
assigned, assigned,
expr, expr,
Layout::Builtin(Builtin::List( Layout::Builtin(Builtin::List(env.arena.alloc(elem_layout))),
MemoryMode::Refcounted,
env.arena.alloc(elem_layout),
)),
hole, hole,
) )
} }
@ -3399,12 +3396,10 @@ pub fn with_hole<'a>(
elems: arg_symbols, elems: arg_symbols,
}; };
let mode = MemoryMode::Refcounted;
let stmt = Stmt::Let( let stmt = Stmt::Let(
assigned, assigned,
expr, expr,
Layout::Builtin(Builtin::List(mode, env.arena.alloc(elem_layout))), Layout::Builtin(Builtin::List(env.arena.alloc(elem_layout))),
hole, hole,
); );

View file

@ -48,10 +48,7 @@ impl<'a> Layout<'a> {
pub fn in_place(&self) -> InPlace { pub fn in_place(&self) -> InPlace {
match self { match self {
Layout::Builtin(Builtin::EmptyList) => InPlace::InPlace, Layout::Builtin(Builtin::EmptyList) => InPlace::InPlace,
Layout::Builtin(Builtin::List(memory_mode, _)) => match memory_mode { Layout::Builtin(Builtin::List(_)) => InPlace::Clone,
MemoryMode::Unique => InPlace::InPlace,
MemoryMode::Refcounted => InPlace::Clone,
},
Layout::Builtin(Builtin::EmptyStr) => InPlace::InPlace, Layout::Builtin(Builtin::EmptyStr) => InPlace::InPlace,
Layout::Builtin(Builtin::Str) => InPlace::Clone, Layout::Builtin(Builtin::Str) => InPlace::Clone,
Layout::Builtin(Builtin::Int1) => InPlace::Clone, Layout::Builtin(Builtin::Int1) => InPlace::Clone,
@ -331,12 +328,6 @@ impl<'a> LambdaSet<'a> {
} }
} }
#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy)]
pub enum MemoryMode {
Unique,
Refcounted,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Builtin<'a> { pub enum Builtin<'a> {
Int128, Int128,
@ -353,7 +344,7 @@ pub enum Builtin<'a> {
Str, Str,
Dict(&'a Layout<'a>, &'a Layout<'a>), Dict(&'a Layout<'a>, &'a Layout<'a>),
Set(&'a Layout<'a>), Set(&'a Layout<'a>),
List(MemoryMode, &'a Layout<'a>), List(&'a Layout<'a>),
EmptyStr, EmptyStr,
EmptyList, EmptyList,
EmptyDict, EmptyDict,
@ -606,7 +597,7 @@ impl<'a> Layout<'a> {
RecursivePointer => true, RecursivePointer => true,
Builtin(List(MemoryMode::Refcounted, _)) | Builtin(Str) => true, Builtin(List(_)) | Builtin(Str) => true,
_ => false, _ => false,
} }
@ -855,7 +846,7 @@ impl<'a> Builtin<'a> {
Str | EmptyStr => Builtin::STR_WORDS * pointer_size, Str | EmptyStr => Builtin::STR_WORDS * pointer_size,
Dict(_, _) | EmptyDict => Builtin::DICT_WORDS * pointer_size, Dict(_, _) | EmptyDict => Builtin::DICT_WORDS * pointer_size,
Set(_) | EmptySet => Builtin::SET_WORDS * pointer_size, Set(_) | EmptySet => Builtin::SET_WORDS * pointer_size,
List(_, _) | EmptyList => Builtin::LIST_WORDS * pointer_size, List(_) | EmptyList => Builtin::LIST_WORDS * pointer_size,
} }
} }
@ -881,7 +872,7 @@ impl<'a> Builtin<'a> {
Str | EmptyStr => pointer_size, Str | EmptyStr => pointer_size,
Dict(_, _) | EmptyDict => pointer_size, Dict(_, _) | EmptyDict => pointer_size,
Set(_) | EmptySet => pointer_size, Set(_) | EmptySet => pointer_size,
List(_, _) | EmptyList => pointer_size, List(_) | EmptyList => pointer_size,
} }
} }
@ -891,7 +882,7 @@ impl<'a> Builtin<'a> {
match self { match self {
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Float128 | Float64 | Float32 Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Float128 | Float64 | Float32
| Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => true, | Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => true,
Str | Dict(_, _) | Set(_) | List(_, _) => false, Str | Dict(_, _) | Set(_) | List(_) => false,
} }
} }
@ -902,10 +893,7 @@ impl<'a> Builtin<'a> {
match self { match self {
Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Float128 | Float64 | Float32 Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Float128 | Float64 | Float32
| Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => false, | Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => false,
List(mode, element_layout) => match mode { List(_) => true,
MemoryMode::Refcounted => true,
MemoryMode::Unique => element_layout.contains_refcounted(),
},
Str | Dict(_, _) | Set(_) => true, Str | Dict(_, _) | Set(_) => true,
} }
@ -938,7 +926,7 @@ impl<'a> Builtin<'a> {
EmptySet => alloc.text("EmptySet"), EmptySet => alloc.text("EmptySet"),
Str => alloc.text("Str"), Str => alloc.text("Str"),
List(_, layout) => alloc List(layout) => alloc
.text("List ") .text("List ")
.append(layout.to_doc(alloc, Parens::InTypeParam)), .append(layout.to_doc(alloc, Parens::InTypeParam)),
Set(layout) => alloc Set(layout) => alloc
@ -1878,11 +1866,7 @@ pub fn list_layout_from_elem<'a>(
_ => { _ => {
let elem_layout = Layout::from_var(env, elem_var)?; let elem_layout = Layout::from_var(env, elem_var)?;
// This is a normal list. Ok(Layout::Builtin(Builtin::List(env.arena.alloc(elem_layout))))
Ok(Layout::Builtin(Builtin::List(
MemoryMode::Refcounted,
env.arena.alloc(elem_layout),
)))
} }
} }
} }
@ -1948,7 +1932,7 @@ impl<'a> std::convert::TryFrom<&Layout<'a>> for ListLayout<'a> {
fn try_from(value: &Layout<'a>) -> Result<Self, Self::Error> { fn try_from(value: &Layout<'a>) -> Result<Self, Self::Error> {
match value { match value {
Layout::Builtin(Builtin::EmptyList) => Ok(ListLayout::EmptyList), Layout::Builtin(Builtin::EmptyList) => Ok(ListLayout::EmptyList),
Layout::Builtin(Builtin::List(_, element)) => Ok(ListLayout::List(element)), Layout::Builtin(Builtin::List(element)) => Ok(ListLayout::List(element)),
_ => Err(()), _ => Err(()),
} }
} }