diff --git a/cli/src/repl/eval.rs b/cli/src/repl/eval.rs index 94f51ec6cf..21304feab9 100644 --- a/cli/src/repl/eval.rs +++ b/cli/src/repl/eval.rs @@ -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, main_fn_name, (*const u8, usize), @@ -125,12 +125,6 @@ fn jit_to_ast_help<'a>( Layout::Builtin(other) => { todo!("add support for rendering builtin {:?} to the REPL", other) } - Layout::PhantomEmptyStruct => Ok(run_jit_function!(lib, main_fn_name, &u8, |_| { - Expr::Record { - fields: &[], - final_comments: env.arena.alloc([]), - } - })), Layout::Struct(field_layouts) => { let ptr_to_ast = |ptr: *const u8| match content { Content::Structure(FlatType::Record(fields, _)) => { @@ -247,7 +241,6 @@ fn jit_to_ast_help<'a>( Layout::Closure(_, _, _) => Err(ToAstProblem::FunctionLayout), Layout::FunctionPointer(_, _) => Err(ToAstProblem::FunctionLayout), - Layout::Pointer(_) => todo!("add support for rendering pointers in the REPL"), } } @@ -298,7 +291,7 @@ fn ptr_to_ast<'a>( items: &[], 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. let len = unsafe { *(ptr.offset(env.ptr_bytes as isize) as *const usize) }; let ptr = unsafe { *(ptr as *const *const u8) }; diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index c1a0006844..c5e9cdd7c8 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -906,9 +906,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( arguments, tag_layout, .. - } if *union_size == 1 - && matches!(tag_layout, Layout::Union(UnionLayout::NonRecursive(_))) => - { + } if *union_size == 1 && matches!(tag_layout, UnionLayout::NonRecursive(_)) => { let it = arguments.iter(); let ctx = env.context; @@ -956,7 +954,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( Tag { arguments, - tag_layout: Layout::Union(UnionLayout::NonRecursive(fields)), + tag_layout: UnionLayout::NonRecursive(fields), union_size, tag_id, .. @@ -1044,7 +1042,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( } Tag { arguments, - tag_layout: Layout::Union(UnionLayout::Recursive(fields)), + tag_layout: UnionLayout::Recursive(fields), union_size, tag_id, .. @@ -1119,7 +1117,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( Tag { arguments, - tag_layout: Layout::Union(UnionLayout::NonNullableUnwrapped(fields)), + tag_layout: UnionLayout::NonNullableUnwrapped(fields), union_size, tag_id, .. @@ -1195,10 +1193,10 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( Tag { arguments, tag_layout: - Layout::Union(UnionLayout::NullableWrapped { + UnionLayout::NullableWrapped { nullable_id, other_tags: fields, - }), + }, union_size, tag_id, .. @@ -1287,11 +1285,11 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( Tag { arguments, tag_layout: - Layout::Union(UnionLayout::NullableUnwrapped { + UnionLayout::NullableUnwrapped { nullable_id, other_fields, .. - }), + }, union_size, tag_id, tag_name, @@ -1387,8 +1385,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( data_ptr.into() } - Tag { .. } => unreachable!("tags should have a Union or RecursiveUnion layout"), - Reset(_) => todo!(), Reuse { .. } => todo!(), @@ -2180,7 +2176,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>( let (value, layout) = load_symbol_and_layout(scope, symbol); match layout { - Layout::Builtin(Builtin::List(_, _)) => { + Layout::Builtin(Builtin::List(_)) => { debug_assert!(value.is_struct_value()); // because of how we insert DECREF for lists, we can't guarantee that @@ -3360,11 +3356,9 @@ pub fn build_proc<'a, 'ctx, 'env>( } Layout::Builtin(_) => {} - Layout::PhantomEmptyStruct => {} Layout::Struct(_) => {} Layout::Union(_) => {} Layout::RecursivePointer => {} - Layout::Pointer(_) => {} } } } @@ -3587,7 +3581,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>( match list_layout { 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 roc_function_call = roc_function_call( @@ -3629,8 +3623,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>( match (list_layout, return_layout) { (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), ( - Layout::Builtin(Builtin::List(_, element_layout)), - Layout::Builtin(Builtin::List(_, result_layout)), + Layout::Builtin(Builtin::List(element_layout)), + Layout::Builtin(Builtin::List(result_layout)), ) => { let argument_layouts = &[**element_layout]; @@ -3660,9 +3654,9 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>( match (list1_layout, list2_layout, return_layout) { ( - Layout::Builtin(Builtin::List(_, element1_layout)), - Layout::Builtin(Builtin::List(_, element2_layout)), - Layout::Builtin(Builtin::List(_, result_layout)), + Layout::Builtin(Builtin::List(element1_layout)), + Layout::Builtin(Builtin::List(element2_layout)), + Layout::Builtin(Builtin::List(result_layout)), ) => { let argument_layouts = &[**element1_layout, **element2_layout]; @@ -3704,10 +3698,10 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>( match (list1_layout, list2_layout, list3_layout, return_layout) { ( - Layout::Builtin(Builtin::List(_, element1_layout)), - Layout::Builtin(Builtin::List(_, element2_layout)), - Layout::Builtin(Builtin::List(_, element3_layout)), - Layout::Builtin(Builtin::List(_, result_layout)), + Layout::Builtin(Builtin::List(element1_layout)), + Layout::Builtin(Builtin::List(element2_layout)), + Layout::Builtin(Builtin::List(element3_layout)), + Layout::Builtin(Builtin::List(result_layout)), ) => { let argument_layouts = &[**element1_layout, **element2_layout, **element3_layout]; @@ -3754,8 +3748,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>( match (list_layout, return_layout) { (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), ( - Layout::Builtin(Builtin::List(_, element_layout)), - Layout::Builtin(Builtin::List(_, result_layout)), + Layout::Builtin(Builtin::List(element_layout)), + Layout::Builtin(Builtin::List(result_layout)), ) => { let argument_layouts = &[Layout::Builtin(Builtin::Usize), **element_layout]; @@ -3786,7 +3780,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>( match list_layout { 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 roc_function_call = roc_function_call( @@ -3818,8 +3812,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>( (_, Layout::Builtin(Builtin::EmptyList)) | (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), ( - Layout::Builtin(Builtin::List(_, before_layout)), - Layout::Builtin(Builtin::List(_, after_layout)), + Layout::Builtin(Builtin::List(before_layout)), + Layout::Builtin(Builtin::List(after_layout)), ) => { let argument_layouts = &[**before_layout]; @@ -3862,8 +3856,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>( (_, Layout::Builtin(Builtin::EmptyList)) | (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), ( - Layout::Builtin(Builtin::List(_, before_layout)), - Layout::Builtin(Builtin::List(_, after_layout)), + Layout::Builtin(Builtin::List(before_layout)), + Layout::Builtin(Builtin::List(after_layout)), ) => { let argument_layouts = &[**before_layout]; @@ -3913,7 +3907,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>( match list_layout { 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; let argument_layouts = &[**element_layout, **element_layout]; @@ -4181,7 +4175,7 @@ fn run_low_level<'a, 'ctx, 'env>( match list_layout { Layout::Builtin(Builtin::EmptyList) => empty_list(env), - Layout::Builtin(Builtin::List(_, element_layout)) => list_drop( + Layout::Builtin(Builtin::List(element_layout)) => list_drop( env, layout_ids, original_wrapper, @@ -4450,7 +4444,7 @@ fn run_low_level<'a, 'ctx, 'env>( // no elements, so nothing to remove empty_list(env) } - Layout::Builtin(Builtin::List(_, element_layout)) => list_set( + Layout::Builtin(Builtin::List(element_layout)) => list_set( env, layout_ids, list, @@ -4471,7 +4465,7 @@ fn run_low_level<'a, 'ctx, 'env>( // no elements, so nothing to remove empty_list(env) } - Layout::Builtin(Builtin::List(_, element_layout)) => list_set( + Layout::Builtin(Builtin::List(element_layout)) => list_set( env, layout_ids, list, @@ -4648,7 +4642,7 @@ fn run_low_level<'a, 'ctx, 'env>( match list_layout { 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) } _ => unreachable!("invalid dict layout"), diff --git a/compiler/gen/src/llvm/build_hash.rs b/compiler/gen/src/llvm/build_hash.rs index 95db536a88..195ff1f30e 100644 --- a/compiler/gen/src/llvm/build_hash.rs +++ b/compiler/gen/src/llvm/build_hash.rs @@ -56,11 +56,6 @@ fn build_hash_layout<'a, 'ctx, 'env>( val.into_struct_value(), ), - Layout::PhantomEmptyStruct => { - // just does nothing and returns the seed - seed - } - Layout::Union(union_layout) => { build_hash_tag(env, layout_ids, layout, union_layout, seed, val) } @@ -91,10 +86,6 @@ fn build_hash_layout<'a, 'ctx, 'env>( } }, - Layout::Pointer(_) => { - unreachable!("unused") - } - Layout::FunctionPointer(_, _) | Layout::Closure(_, _, _) => { unreachable!("the type system will guarantee these are never hashed") } @@ -157,7 +148,7 @@ fn hash_builtin<'a, 'ctx, 'env>( Builtin::Set(_) => { todo!("Implement Hash for Set") } - Builtin::List(_, element_layout) => build_hash_list( + Builtin::List(element_layout) => build_hash_list( env, layout_ids, layout, diff --git a/compiler/gen/src/llvm/build_list.rs b/compiler/gen/src/llvm/build_list.rs index f71e4a507a..5a7fea02c9 100644 --- a/compiler/gen/src/llvm/build_list.rs +++ b/compiler/gen/src/llvm/build_list.rs @@ -14,7 +14,7 @@ use inkwell::types::{BasicTypeEnum, PointerType}; use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue}; use inkwell::{AddressSpace, IntPredicate}; 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>( env: &Env<'a, 'ctx, 'env>, @@ -196,12 +196,12 @@ pub fn list_join<'a, 'ctx, 'env>( ) -> BasicValueEnum<'ctx> { match outer_list_layout { 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 // then simply return an empty list 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( env, &[ @@ -231,13 +231,7 @@ pub fn list_reverse<'a, 'ctx, 'env>( // this pointer will never actually be dereferenced Layout::Builtin(Builtin::Int64), ), - Layout::Builtin(Builtin::List(memory_mode, elem_layout)) => ( - match memory_mode { - MemoryMode::Unique => InPlace::InPlace, - MemoryMode::Refcounted => InPlace::Clone, - }, - *elem_layout, - ), + Layout::Builtin(Builtin::List(elem_layout)) => (InPlace::Clone, *elem_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; 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 ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic); // Load the pointer to the array data @@ -861,7 +855,7 @@ pub fn list_concat<'a, 'ctx, 'env>( // then simply return an empty list 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, &[ pass_list_as_i128(env, first_list), diff --git a/compiler/gen/src/llvm/compare.rs b/compiler/gen/src/llvm/compare.rs index 0cf32263d0..7f9cf127dd 100644 --- a/compiler/gen/src/llvm/compare.rs +++ b/compiler/gen/src/llvm/compare.rs @@ -99,7 +99,7 @@ fn build_eq_builtin<'a, 'ctx, 'env>( Builtin::Float16 => float_cmp(FloatPredicate::OEQ, "eq_f16"), Builtin::Str => str_equal(env, lhs_val, rhs_val), - Builtin::List(_, elem) => build_list_eq( + Builtin::List(elem) => build_list_eq( env, layout_ids, &Layout::Builtin(*builtin), @@ -159,11 +159,6 @@ fn build_eq<'a, 'ctx, 'env>( rhs_val, ), - Layout::PhantomEmptyStruct => { - // always equal to itself - env.context.bool_type().const_int(1, false).into() - } - Layout::RecursivePointer => match when_recursive { WhenRecursive::Unreachable => { unreachable!("recursion pointers should never be compared directly") @@ -197,10 +192,6 @@ fn build_eq<'a, 'ctx, 'env>( } }, - Layout::Pointer(_) => { - unreachable!("unused") - } - Layout::FunctionPointer(_, _) | Layout::Closure(_, _, _) => { unreachable!("the type system will guarantee these are never compared") } @@ -258,7 +249,7 @@ fn build_neq_builtin<'a, 'ctx, 'env>( result.into() } - Builtin::List(_, elem) => { + Builtin::List(elem) => { let is_equal = build_list_eq( env, layout_ids, @@ -338,19 +329,10 @@ fn build_neq<'a, 'ctx, 'env>( result.into() } - Layout::PhantomEmptyStruct => { - // always equal to itself - env.context.bool_type().const_int(1, false).into() - } - Layout::RecursivePointer => { unreachable!("recursion pointers should never be compared directly") } - Layout::Pointer(_) => { - unreachable!("unused") - } - Layout::FunctionPointer(_, _) | Layout::Closure(_, _, _) => { unreachable!("the type system will guarantee these are never compared") } diff --git a/compiler/gen/src/llvm/convert.rs b/compiler/gen/src/llvm/convert.rs index 29e874c992..c88c12c18b 100644 --- a/compiler/gen/src/llvm/convert.rs +++ b/compiler/gen/src/llvm/convert.rs @@ -112,10 +112,6 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>( let closure_data_layout = closure_layout.runtime_representation(); basic_type_from_layout(env, &closure_data_layout) } - Pointer(layout) => basic_type_from_layout(env, &layout) - .ptr_type(AddressSpace::Generic) - .into(), - PhantomEmptyStruct => env.context.struct_type(&[], false).into(), Struct(sorted_fields) => basic_type_from_record(env, sorted_fields), Union(variant) => { use UnionLayout::*; @@ -174,7 +170,7 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>( Float16 => context.f16_type().as_basic_type_enum(), Dict(_, _) | EmptyDict => 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(), } } diff --git a/compiler/gen/src/llvm/refcounting.rs b/compiler/gen/src/llvm/refcounting.rs index cf0a254163..71c309f8b4 100644 --- a/compiler/gen/src/llvm/refcounting.rs +++ b/compiler/gen/src/llvm/refcounting.rs @@ -15,7 +15,7 @@ use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, Str use inkwell::{AddressSpace, IntPredicate}; use roc_module::symbol::Interns; 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; @@ -469,21 +469,17 @@ fn modify_refcount_builtin<'a, 'ctx, 'env>( use Builtin::*; match builtin { - List(memory_mode, element_layout) => { - if let MemoryMode::Refcounted = memory_mode { - let function = modify_refcount_list( - env, - layout_ids, - mode, - when_recursive, - layout, - element_layout, - ); + List(element_layout) => { + let function = modify_refcount_list( + env, + layout_ids, + mode, + when_recursive, + layout, + element_layout, + ); - Some(function) - } else { - None - } + Some(function) } Set(element_layout) => { let key_layout = &Layout::Struct(&[]); @@ -724,8 +720,6 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>( Some(function) } - PhantomEmptyStruct => None, - Layout::RecursivePointer => match when_recursive { WhenRecursive::Unreachable => { unreachable!("recursion pointers should never be hashed directly") @@ -746,7 +740,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>( } }, - FunctionPointer(_, _) | Pointer(_) => None, + FunctionPointer(_, _) => None, } } @@ -1689,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; 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::RecursivePointer | Layout::Union(_) => env.ptr_bytes as u64, _ => (env.ptr_bytes as u64).max(value_bytes), diff --git a/compiler/mono/src/alias_analysis.rs b/compiler/mono/src/alias_analysis.rs index ebca28d1a5..dd3590e57c 100644 --- a/compiler/mono/src/alias_analysis.rs +++ b/compiler/mono/src/alias_analysis.rs @@ -377,16 +377,6 @@ fn lowlevel_spec( } fn build_variant_types( - builder: &mut FuncDefBuilder, - layout: &Layout, -) -> Option>> { - match layout { - Layout::Union(union_layout) => Some(build_variant_types_help(builder, union_layout)), - _ => None, - } -} - -fn build_variant_types_help( builder: &mut FuncDefBuilder, union_layout: &UnionLayout, ) -> Result> { @@ -435,7 +425,7 @@ fn expr_spec( arguments, } => { let value_id = build_tuple_value(builder, env, block, arguments)?; - let variant_types = build_variant_types(builder, tag_layout).unwrap()?; + let variant_types = build_variant_types(builder, tag_layout)?; builder.add_make_union(block, &variant_types, *tag_id as u32, value_id) } Struct(fields) => build_tuple_value(builder, env, block, fields), @@ -525,16 +515,14 @@ fn layout_spec(builder: &mut FuncDefBuilder, layout: &Layout) -> Result match layout { Builtin(builtin) => builtin_spec(builder, builtin), - PhantomEmptyStruct => todo!(), Struct(fields) => build_tuple_type(builder, fields), Union(union_layout) => { - let variant_types = build_variant_types_help(builder, union_layout)?; + let variant_types = build_variant_types(builder, union_layout)?; builder.add_union_type(&variant_types) } RecursivePointer => todo!(), FunctionPointer(_, _) => todo!(), Closure(_, _, _) => todo!(), - Pointer(_) => todo!(), } } @@ -550,7 +538,7 @@ fn builtin_spec(builder: &mut FuncDefBuilder, builtin: &Builtin) -> Result todo!(), Dict(_, _) => todo!(), Set(_) => todo!(), - List(_, _) => { + List(_) => { // TODO should incorporate the element type into the name Ok(builder.add_named_type(MOD_LIST, TypeName(b"List"))) } diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index b7660b4c61..4bedd2dae6 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -3,8 +3,8 @@ use self::InProgressProc::*; use crate::exhaustive::{Ctor, Guard, RenderAs, TagId}; use crate::layout::{ - Builtin, ClosureRepresentation, LambdaSet, Layout, LayoutCache, LayoutProblem, MemoryMode, - UnionLayout, WrappedVariant, TAG_SIZE, + Builtin, ClosureRepresentation, LambdaSet, Layout, LayoutCache, LayoutProblem, UnionLayout, + WrappedVariant, TAG_SIZE, }; use bumpalo::collections::Vec; use bumpalo::Bump; @@ -1150,7 +1150,7 @@ pub enum Expr<'a> { Call(Call<'a>), Tag { - tag_layout: Layout<'a>, + tag_layout: UnionLayout<'a>, tag_name: TagName, tag_id: u8, union_size: u8, @@ -3371,10 +3371,7 @@ pub fn with_hole<'a>( Stmt::Let( assigned, expr, - Layout::Builtin(Builtin::List( - MemoryMode::Refcounted, - env.arena.alloc(elem_layout), - )), + Layout::Builtin(Builtin::List(env.arena.alloc(elem_layout))), hole, ) } @@ -3406,12 +3403,10 @@ pub fn with_hole<'a>( elems: arg_symbols, }; - let mode = MemoryMode::Refcounted; - let stmt = Stmt::Let( assigned, expr, - Layout::Builtin(Builtin::List(mode, env.arena.alloc(elem_layout))), + Layout::Builtin(Builtin::List(env.arena.alloc(elem_layout))), hole, ); @@ -4140,10 +4135,15 @@ fn construct_closure_data<'a>( tag_symbols.push(tag_id_symbol); tag_symbols.extend(symbols); + let tag_layout = match lambda_set.runtime_representation() { + Layout::Union(inner) => inner, + _ => unreachable!(), + }; + let expr1 = Expr::Literal(Literal::Int(tag_id as i128)); let expr2 = Expr::Tag { tag_id, - tag_layout: lambda_set.runtime_representation(), + tag_layout, union_size, tag_name, arguments: tag_symbols.into_bump_slice(), @@ -4305,17 +4305,17 @@ fn convert_tag_union<'a>( } debug_assert!(layouts.len() > 1); - let layout = Layout::Union(UnionLayout::Recursive(layouts.into_bump_slice())); + let union_layout = UnionLayout::Recursive(layouts.into_bump_slice()); let tag = Expr::Tag { - tag_layout: layout, + tag_layout: union_layout, tag_name, tag_id: tag_id as u8, union_size, arguments: field_symbols, }; - (tag, layout) + (tag, Layout::Union(union_layout)) } NonNullableUnwrapped { fields, @@ -4333,17 +4333,17 @@ fn convert_tag_union<'a>( temp.into_bump_slice() }; - let layout = Layout::Union(UnionLayout::NonNullableUnwrapped(fields)); + let union_layout = UnionLayout::NonNullableUnwrapped(fields); let tag = Expr::Tag { - tag_layout: layout, + tag_layout: union_layout, tag_name, tag_id: tag_id as u8, union_size, arguments: field_symbols, }; - (tag, layout) + (tag, Layout::Union(union_layout)) } NonRecursive { sorted_tag_layouts } => { let tag_id_symbol = env.unique_symbol(); @@ -4365,18 +4365,17 @@ fn convert_tag_union<'a>( layouts.push(arg_layouts); } - let layout = - Layout::Union(UnionLayout::NonRecursive(layouts.into_bump_slice())); + let union_layout = UnionLayout::NonRecursive(layouts.into_bump_slice()); let tag = Expr::Tag { - tag_layout: layout, + tag_layout: union_layout, tag_name, tag_id: tag_id as u8, union_size, arguments: field_symbols, }; - (tag, layout) + (tag, Layout::Union(union_layout)) } NullableWrapped { nullable_id, @@ -4402,20 +4401,20 @@ fn convert_tag_union<'a>( layouts.push(arg_layouts); } - let layout = Layout::Union(UnionLayout::NullableWrapped { + let union_layout = UnionLayout::NullableWrapped { nullable_id, other_tags: layouts.into_bump_slice(), - }); + }; let tag = Expr::Tag { - tag_layout: layout, + tag_layout: union_layout, tag_name, tag_id: tag_id as u8, union_size, arguments: field_symbols, }; - (tag, layout) + (tag, Layout::Union(union_layout)) } NullableUnwrapped { nullable_id, @@ -4437,20 +4436,20 @@ fn convert_tag_union<'a>( temp.into_bump_slice() }; - let layout = Layout::Union(UnionLayout::NullableUnwrapped { + let union_layout = UnionLayout::NullableUnwrapped { nullable_id, other_fields, - }); + }; let tag = Expr::Tag { - tag_layout: layout, + tag_layout: union_layout, tag_name, tag_id: tag_id as u8, union_size, arguments: field_symbols, }; - (tag, layout) + (tag, Layout::Union(union_layout)) } }; diff --git a/compiler/mono/src/layout.rs b/compiler/mono/src/layout.rs index 7afa2efe28..e7af14e26e 100644 --- a/compiler/mono/src/layout.rs +++ b/compiler/mono/src/layout.rs @@ -40,24 +40,19 @@ pub enum Layout<'a> { /// A layout that is empty (turns into the empty struct in LLVM IR /// but for our purposes, not zero-sized, so it does not get dropped from data structures /// this is important for closures that capture zero-sized values - PhantomEmptyStruct, Struct(&'a [Layout<'a>]), Union(UnionLayout<'a>), RecursivePointer, /// A function. The types of its arguments, then the type of its return value. FunctionPointer(&'a [Layout<'a>], &'a Layout<'a>), Closure(&'a [Layout<'a>], LambdaSet<'a>, &'a Layout<'a>), - Pointer(&'a Layout<'a>), } impl<'a> Layout<'a> { pub fn in_place(&self) -> InPlace { match self { Layout::Builtin(Builtin::EmptyList) => InPlace::InPlace, - Layout::Builtin(Builtin::List(memory_mode, _)) => match memory_mode { - MemoryMode::Unique => InPlace::InPlace, - MemoryMode::Refcounted => InPlace::Clone, - }, + Layout::Builtin(Builtin::List(_)) => InPlace::Clone, Layout::Builtin(Builtin::EmptyStr) => InPlace::InPlace, Layout::Builtin(Builtin::Str) => InPlace::Clone, Layout::Builtin(Builtin::Int1) => InPlace::Clone, @@ -337,12 +332,6 @@ impl<'a> LambdaSet<'a> { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy)] -pub enum MemoryMode { - Unique, - Refcounted, -} - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum Builtin<'a> { Int128, @@ -359,7 +348,7 @@ pub enum Builtin<'a> { Str, Dict(&'a Layout<'a>, &'a Layout<'a>), Set(&'a Layout<'a>), - List(MemoryMode, &'a Layout<'a>), + List(&'a Layout<'a>), EmptyStr, EmptyList, EmptyDict, @@ -483,7 +472,6 @@ impl<'a> Layout<'a> { match self { Builtin(builtin) => builtin.safe_to_memcpy(), - PhantomEmptyStruct => true, Struct(fields) => fields .iter() .all(|field_layout| field_layout.safe_to_memcpy()), @@ -508,10 +496,6 @@ impl<'a> Layout<'a> { true } Closure(_, closure_layout, _) => closure_layout.safe_to_memcpy(), - Pointer(_) => { - // We cannot memcpy pointers, because then we would have the same pointer in multiple places! - false - } RecursivePointer => { // We cannot memcpy pointers, because then we would have the same pointer in multiple places! false @@ -523,12 +507,7 @@ impl<'a> Layout<'a> { // For this calculation, we don't need an accurate // stack size, we just need to know whether it's zero, // so it's fine to use a pointer size of 1. - if let Layout::PhantomEmptyStruct = self { - false - } else { - // self.stack_size(1) == 0 - false - } + false } pub fn stack_size(&self, pointer_size: u32) -> u32 { @@ -536,7 +515,6 @@ impl<'a> Layout<'a> { match self { Builtin(builtin) => builtin.stack_size(pointer_size), - PhantomEmptyStruct => 0, Struct(fields) => { let mut sum = 0; @@ -570,7 +548,6 @@ impl<'a> Layout<'a> { Closure(_, lambda_set, _) => lambda_set.stack_size(pointer_size), FunctionPointer(_, _) => pointer_size, RecursivePointer => pointer_size, - Pointer(_) => pointer_size, } } @@ -600,10 +577,8 @@ impl<'a> Layout<'a> { } } Layout::Builtin(builtin) => builtin.alignment_bytes(pointer_size), - Layout::PhantomEmptyStruct => 0, Layout::RecursivePointer => pointer_size, Layout::FunctionPointer(_, _) => pointer_size, - Layout::Pointer(_) => pointer_size, Layout::Closure(_, captured, _) => { pointer_size.max(captured.alignment_bytes(pointer_size)) } @@ -626,7 +601,7 @@ impl<'a> Layout<'a> { RecursivePointer => true, - Builtin(List(MemoryMode::Refcounted, _)) | Builtin(Str) => true, + Builtin(List(_)) | Builtin(Str) => true, _ => false, } @@ -640,7 +615,6 @@ impl<'a> Layout<'a> { match self { Builtin(builtin) => builtin.is_refcounted(), - PhantomEmptyStruct => false, Struct(fields) => fields.iter().any(|f| f.contains_refcounted()), Union(variant) => { use UnionLayout::*; @@ -659,7 +633,7 @@ impl<'a> Layout<'a> { } RecursivePointer => true, Closure(_, closure_layout, _) => closure_layout.contains_refcounted(), - FunctionPointer(_, _) | Pointer(_) => false, + FunctionPointer(_, _) => false, } } @@ -673,7 +647,6 @@ impl<'a> Layout<'a> { match self { Builtin(builtin) => builtin.to_doc(alloc, parens), - PhantomEmptyStruct => alloc.text("{}"), Struct(fields) => { let fields_doc = fields.iter().map(|x| x.to_doc(alloc, parens)); @@ -706,7 +679,6 @@ impl<'a> Layout<'a> { .append(" |} -> ") .append(result.to_doc(alloc, Parens::InFunction)) } - Pointer(_) => todo!(), } } } @@ -878,7 +850,7 @@ impl<'a> Builtin<'a> { Str | EmptyStr => Builtin::STR_WORDS * pointer_size, Dict(_, _) | EmptyDict => Builtin::DICT_WORDS * pointer_size, Set(_) | EmptySet => Builtin::SET_WORDS * pointer_size, - List(_, _) | EmptyList => Builtin::LIST_WORDS * pointer_size, + List(_) | EmptyList => Builtin::LIST_WORDS * pointer_size, } } @@ -904,7 +876,7 @@ impl<'a> Builtin<'a> { Str | EmptyStr => pointer_size, Dict(_, _) | EmptyDict => pointer_size, Set(_) | EmptySet => pointer_size, - List(_, _) | EmptyList => pointer_size, + List(_) | EmptyList => pointer_size, } } @@ -914,7 +886,7 @@ impl<'a> Builtin<'a> { match self { Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Float128 | Float64 | Float32 | Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => true, - Str | Dict(_, _) | Set(_) | List(_, _) => false, + Str | Dict(_, _) | Set(_) | List(_) => false, } } @@ -925,10 +897,7 @@ impl<'a> Builtin<'a> { match self { Int128 | Int64 | Int32 | Int16 | Int8 | Int1 | Usize | Float128 | Float64 | Float32 | Float16 | EmptyStr | EmptyDict | EmptyList | EmptySet => false, - List(mode, element_layout) => match mode { - MemoryMode::Refcounted => true, - MemoryMode::Unique => element_layout.contains_refcounted(), - }, + List(_) => true, Str | Dict(_, _) | Set(_) => true, } @@ -961,7 +930,7 @@ impl<'a> Builtin<'a> { EmptySet => alloc.text("EmptySet"), Str => alloc.text("Str"), - List(_, layout) => alloc + List(layout) => alloc .text("List ") .append(layout.to_doc(alloc, Parens::InTypeParam)), Set(layout) => alloc @@ -1901,11 +1870,7 @@ pub fn list_layout_from_elem<'a>( _ => { let elem_layout = Layout::from_var(env, elem_var)?; - // This is a normal list. - Ok(Layout::Builtin(Builtin::List( - MemoryMode::Refcounted, - env.arena.alloc(elem_layout), - ))) + Ok(Layout::Builtin(Builtin::List(env.arena.alloc(elem_layout)))) } } } @@ -1971,7 +1936,7 @@ impl<'a> std::convert::TryFrom<&Layout<'a>> for ListLayout<'a> { fn try_from(value: &Layout<'a>) -> Result { match value { 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(()), } }