mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
Add a Newtype variant to LayoutWrapper
This commit is contained in:
parent
dd94d6ba16
commit
5274dbcd00
22 changed files with 348 additions and 265 deletions
|
@ -403,7 +403,7 @@ fn build_entry_point<'a>(
|
|||
|
||||
let block = builder.add_block();
|
||||
|
||||
let struct_layout = interner.insert_no_semantic(LayoutRepr::struct_(layouts));
|
||||
let struct_layout = interner.insert_direct_no_semantic(LayoutRepr::struct_(layouts));
|
||||
let type_id = layout_spec(env, &mut builder, interner, struct_layout)?;
|
||||
|
||||
let argument = builder.add_unknown_with(block, &[], type_id)?;
|
||||
|
@ -461,7 +461,7 @@ fn proc_spec<'a>(
|
|||
|
||||
let root = BlockExpr(block, value_id);
|
||||
let args_struct_layout =
|
||||
interner.insert_no_semantic(LayoutRepr::struct_(argument_layouts.into_bump_slice()));
|
||||
interner.insert_direct_no_semantic(LayoutRepr::struct_(argument_layouts.into_bump_slice()));
|
||||
let arg_type_id = layout_spec(&mut env, &mut builder, interner, args_struct_layout)?;
|
||||
let ret_type_id = layout_spec(&mut env, &mut builder, interner, proc.ret_layout)?;
|
||||
|
||||
|
@ -851,8 +851,9 @@ fn call_spec<'a>(
|
|||
|
||||
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
||||
|
||||
let state_layout = interner
|
||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*return_layout)));
|
||||
let state_layout = interner.insert_direct_no_semantic(LayoutRepr::Builtin(
|
||||
Builtin::List(*return_layout),
|
||||
));
|
||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||
|
||||
let init_state = new_list(builder, block, output_element_type)?;
|
||||
|
@ -880,7 +881,7 @@ fn call_spec<'a>(
|
|||
let arg0_layout = argument_layouts[0];
|
||||
|
||||
let state_layout = interner
|
||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(arg0_layout)));
|
||||
.insert_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(arg0_layout)));
|
||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||
let init_state = list;
|
||||
|
||||
|
@ -907,8 +908,9 @@ fn call_spec<'a>(
|
|||
|
||||
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
||||
|
||||
let state_layout = interner
|
||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*return_layout)));
|
||||
let state_layout = interner.insert_direct_no_semantic(LayoutRepr::Builtin(
|
||||
Builtin::List(*return_layout),
|
||||
));
|
||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||
|
||||
let init_state = new_list(builder, block, output_element_type)?;
|
||||
|
@ -941,8 +943,9 @@ fn call_spec<'a>(
|
|||
|
||||
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
||||
|
||||
let state_layout = interner
|
||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*return_layout)));
|
||||
let state_layout = interner.insert_direct_no_semantic(LayoutRepr::Builtin(
|
||||
Builtin::List(*return_layout),
|
||||
));
|
||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||
|
||||
let init_state = new_list(builder, block, output_element_type)?;
|
||||
|
@ -981,8 +984,9 @@ fn call_spec<'a>(
|
|||
|
||||
let output_element_type = layout_spec(env, builder, interner, *return_layout)?;
|
||||
|
||||
let state_layout = interner
|
||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*return_layout)));
|
||||
let state_layout = interner.insert_direct_no_semantic(LayoutRepr::Builtin(
|
||||
Builtin::List(*return_layout),
|
||||
));
|
||||
let state_type = layout_spec(env, builder, interner, state_layout)?;
|
||||
|
||||
let init_state = new_list(builder, block, output_element_type)?;
|
||||
|
|
|
@ -1850,8 +1850,9 @@ impl<
|
|||
let new_element_layout = higher_order.passed_function.return_layout;
|
||||
|
||||
let input_list_layout = LayoutRepr::Builtin(Builtin::List(old_element_layout));
|
||||
let input_list_in_layout =
|
||||
self.layout_interner.insert_no_semantic(input_list_layout);
|
||||
let input_list_in_layout = self
|
||||
.layout_interner
|
||||
.insert_direct_no_semantic(input_list_layout);
|
||||
|
||||
let caller = self.debug_symbol("caller");
|
||||
let data = self.debug_symbol("data");
|
||||
|
@ -2677,7 +2678,7 @@ impl<
|
|||
_ => {
|
||||
let union_in_layout = self
|
||||
.layout_interner
|
||||
.insert_no_semantic(LayoutRepr::Union(*union_layout));
|
||||
.insert_direct_no_semantic(LayoutRepr::Union(*union_layout));
|
||||
todo!(
|
||||
"loading from union type: {:?}",
|
||||
self.layout_interner.dbg(union_in_layout)
|
||||
|
|
|
@ -384,7 +384,7 @@ trait Backend<'a> {
|
|||
fn increment_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
|
||||
let box_layout = self
|
||||
.interner_mut()
|
||||
.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||
|
||||
let element_increment = self.debug_symbol("element_increment");
|
||||
let element_increment_symbol = self.build_indirect_inc(layout);
|
||||
|
@ -404,7 +404,7 @@ trait Backend<'a> {
|
|||
fn decrement_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
|
||||
let box_layout = self
|
||||
.interner_mut()
|
||||
.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||
|
||||
let element_decrement = self.debug_symbol("element_decrement");
|
||||
let element_decrement_symbol = self.build_indirect_dec(layout);
|
||||
|
|
|
@ -464,7 +464,7 @@ fn build_exposed_generic_proc<'a, B: Backend<'a>>(backend: &mut B, proc: &Proc<'
|
|||
|
||||
let box_layout = backend
|
||||
.interner_mut()
|
||||
.insert_no_semantic(roc_mono::layout::LayoutRepr::Boxed(proc.ret_layout));
|
||||
.insert_direct_no_semantic(roc_mono::layout::LayoutRepr::Boxed(proc.ret_layout));
|
||||
|
||||
let mut args = bumpalo::collections::Vec::new_in(arena);
|
||||
args.extend(proc.args);
|
||||
|
|
|
@ -1385,8 +1385,8 @@ pub fn build_exp_expr<'a, 'ctx>(
|
|||
|
||||
let field_layouts = tag_layouts[*tag_id as usize];
|
||||
|
||||
let struct_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let struct_layout = layout_interner
|
||||
.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let struct_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
||||
|
||||
let opaque_data_ptr = env
|
||||
|
@ -1442,8 +1442,8 @@ pub fn build_exp_expr<'a, 'ctx>(
|
|||
)
|
||||
}
|
||||
UnionLayout::NonNullableUnwrapped(field_layouts) => {
|
||||
let struct_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let struct_layout = layout_interner
|
||||
.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
|
||||
let struct_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
||||
let target_loaded_type = basic_type_from_layout(env, layout_interner, layout);
|
||||
|
@ -1493,8 +1493,8 @@ pub fn build_exp_expr<'a, 'ctx>(
|
|||
debug_assert_ne!(*tag_id != 0, *nullable_id);
|
||||
|
||||
let field_layouts = other_fields;
|
||||
let struct_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let struct_layout = layout_interner
|
||||
.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
|
||||
let struct_type = basic_type_from_layout(env, layout_interner, struct_layout);
|
||||
let target_loaded_type = basic_type_from_layout(env, layout_interner, layout);
|
||||
|
@ -1696,7 +1696,10 @@ fn build_struct<'a, 'ctx>(
|
|||
// Zero-sized fields have no runtime representation.
|
||||
// The layout of the struct expects them to be dropped!
|
||||
let (field_expr, field_layout) = load_symbol_and_layout(scope, symbol);
|
||||
if !layout_interner.get(field_layout).is_dropped_because_empty() {
|
||||
if !layout_interner
|
||||
.get_repr(field_layout)
|
||||
.is_dropped_because_empty()
|
||||
{
|
||||
let field_type = basic_type_from_layout(env, layout_interner, field_layout);
|
||||
field_types.push(field_type);
|
||||
|
||||
|
@ -1780,8 +1783,8 @@ fn build_tag<'a, 'ctx>(
|
|||
use std::cmp::Ordering::*;
|
||||
match tag_id.cmp(&(*nullable_id as _)) {
|
||||
Equal => {
|
||||
let layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Union(*union_layout));
|
||||
let layout = layout_interner
|
||||
.insert_direct_no_semantic(LayoutRepr::Union(*union_layout));
|
||||
|
||||
return basic_type_from_layout(env, layout_interner, layout)
|
||||
.into_pointer_type()
|
||||
|
@ -2133,7 +2136,8 @@ fn lookup_at_index_ptr2<'a, 'ctx>(
|
|||
) -> BasicValueEnum<'ctx> {
|
||||
let builder = env.builder;
|
||||
|
||||
let struct_layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let struct_layout =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let struct_type =
|
||||
basic_type_from_layout(env, layout_interner, struct_layout).into_struct_type();
|
||||
|
||||
|
@ -2850,7 +2854,7 @@ pub fn build_exp_stmt<'a, 'ctx>(
|
|||
LayoutRepr::Builtin(Builtin::Str) => todo!(),
|
||||
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
|
||||
debug_assert!(value.is_struct_value());
|
||||
let element_layout = layout_interner.get(element_layout);
|
||||
let element_layout = layout_interner.get_repr(element_layout);
|
||||
let alignment =
|
||||
element_layout.alignment_bytes(layout_interner, env.target_info);
|
||||
|
||||
|
@ -3764,7 +3768,7 @@ fn expose_function_to_host_help_c_abi_generic<'a, 'ctx>(
|
|||
|
||||
builder.position_at_end(entry);
|
||||
|
||||
let wrapped_layout = layout_interner.insert_no_semantic(roc_call_result_layout(
|
||||
let wrapped_layout = layout_interner.insert_direct_no_semantic(roc_call_result_layout(
|
||||
env.arena,
|
||||
return_layout,
|
||||
env.target_info,
|
||||
|
@ -3905,7 +3909,7 @@ fn expose_function_to_host_help_c_abi_gen_test<'a, 'ctx>(
|
|||
|
||||
builder.position_at_end(last_block);
|
||||
|
||||
let wrapper_result = layout_interner.insert_no_semantic(LayoutRepr::struct_(
|
||||
let wrapper_result = layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(
|
||||
env.arena.alloc([Layout::U64, return_layout]),
|
||||
));
|
||||
|
||||
|
|
|
@ -973,7 +973,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
|||
env.builder.position_at_end(block);
|
||||
|
||||
let struct_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
|
||||
let answer = eq_ptr_to_struct(
|
||||
env,
|
||||
|
@ -1046,7 +1046,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
|||
env.builder.position_at_end(block);
|
||||
|
||||
let struct_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
|
||||
let answer = eq_ptr_to_struct(
|
||||
env,
|
||||
|
@ -1109,7 +1109,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
|||
env.builder.position_at_end(compare_other);
|
||||
|
||||
let struct_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(other_fields));
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(other_fields));
|
||||
|
||||
let answer = eq_ptr_to_struct(
|
||||
env,
|
||||
|
@ -1214,7 +1214,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
|||
env.builder.position_at_end(block);
|
||||
|
||||
let struct_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
|
||||
let answer = eq_ptr_to_struct(
|
||||
env,
|
||||
|
@ -1255,7 +1255,7 @@ fn build_tag_eq_help<'a, 'ctx>(
|
|||
env.builder.position_at_end(compare_fields);
|
||||
|
||||
let struct_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
|
||||
let answer = eq_ptr_to_struct(
|
||||
env,
|
||||
|
|
|
@ -476,7 +476,7 @@ fn build_clone_tag<'a, 'ctx>(
|
|||
value: BasicValueEnum<'ctx>,
|
||||
union_layout: UnionLayout<'a>,
|
||||
) -> IntValue<'ctx> {
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let layout_id = layout_ids.get(Symbol::CLONE, &layout);
|
||||
let fn_name = layout_id.to_symbol_string(Symbol::CLONE, &env.interns);
|
||||
|
||||
|
@ -690,7 +690,7 @@ fn build_clone_tag_help<'a, 'ctx>(
|
|||
|
||||
// load the tag payload (if any)
|
||||
let payload_layout = LayoutRepr::struct_(field_layouts);
|
||||
let payload_in_layout = layout_interner.insert_no_semantic(payload_layout);
|
||||
let payload_in_layout = layout_interner.insert_direct_no_semantic(payload_layout);
|
||||
|
||||
let opaque_payload_ptr = env
|
||||
.builder
|
||||
|
@ -748,11 +748,12 @@ fn build_clone_tag_help<'a, 'ctx>(
|
|||
|
||||
let tag_value = tag_pointer_clear_tag_id(env, tag_value.into_pointer_value());
|
||||
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let layout =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let layout = if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
||||
layout
|
||||
} else {
|
||||
layout_interner.insert_no_semantic(LayoutRepr::struct_(
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(
|
||||
env.arena.alloc([layout, union_layout.tag_id_layout()]),
|
||||
))
|
||||
};
|
||||
|
@ -797,7 +798,7 @@ fn build_clone_tag_help<'a, 'ctx>(
|
|||
|
||||
build_copy(env, ptr, offset, extra_offset.into());
|
||||
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(fields));
|
||||
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(fields));
|
||||
let basic_type = basic_type_from_layout(env, layout_interner, layout);
|
||||
|
||||
let (width, _) = union_layout.data_size_and_alignment(layout_interner, env.target_info);
|
||||
|
@ -853,7 +854,8 @@ fn build_clone_tag_help<'a, 'ctx>(
|
|||
other_tags[i]
|
||||
};
|
||||
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(fields));
|
||||
let layout =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(fields));
|
||||
let basic_type = basic_type_from_layout(env, layout_interner, layout);
|
||||
|
||||
let (width, _) =
|
||||
|
@ -928,7 +930,8 @@ fn build_clone_tag_help<'a, 'ctx>(
|
|||
// write the "pointer" af the current offset
|
||||
build_copy(env, ptr, offset, extra_offset.into());
|
||||
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(other_fields));
|
||||
let layout =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(other_fields));
|
||||
let basic_type = basic_type_from_layout(env, layout_interner, layout);
|
||||
|
||||
let cursors = Cursors {
|
||||
|
|
|
@ -267,7 +267,7 @@ fn modify_refcount_struct<'a, 'ctx>(
|
|||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::struct_(layouts));
|
||||
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(layouts));
|
||||
|
||||
let (_, fn_name) = function_name_from_mode(
|
||||
layout_ids,
|
||||
|
@ -609,8 +609,8 @@ fn modify_refcount_list<'a, 'ctx>(
|
|||
element_layout
|
||||
};
|
||||
|
||||
let list_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(element_layout)));
|
||||
let list_layout = layout_interner
|
||||
.insert_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(element_layout)));
|
||||
let (_, fn_name) = function_name_from_mode(
|
||||
layout_ids,
|
||||
&env.interns,
|
||||
|
@ -859,7 +859,7 @@ fn modify_refcount_boxed<'a, 'ctx>(
|
|||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
||||
let boxed_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(inner_layout));
|
||||
let boxed_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(inner_layout));
|
||||
|
||||
let (_, fn_name) = function_name_from_mode(
|
||||
layout_ids,
|
||||
|
@ -921,7 +921,7 @@ fn modify_refcount_box_help<'a, 'ctx>(
|
|||
let boxed = arg_val.into_pointer_value();
|
||||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, boxed);
|
||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||
let boxed_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(inner_layout));
|
||||
let boxed_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(inner_layout));
|
||||
|
||||
match mode {
|
||||
Mode::Inc => {
|
||||
|
@ -1065,7 +1065,7 @@ fn build_rec_union<'a, 'ctx>(
|
|||
mode: Mode,
|
||||
union_layout: UnionLayout<'a>,
|
||||
) -> FunctionValue<'ctx> {
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
|
||||
let (_, fn_name) = function_name_from_mode(
|
||||
layout_ids,
|
||||
|
@ -1168,7 +1168,7 @@ fn build_rec_union_help<'a, 'ctx>(
|
|||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, value_ptr);
|
||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
|
||||
match mode {
|
||||
Mode::Inc => {
|
||||
|
@ -1223,7 +1223,7 @@ enum DecOrReuse {
|
|||
|
||||
fn fields_need_no_refcounting(interner: &STLayoutInterner, field_layouts: &[InLayout]) -> bool {
|
||||
!field_layouts.iter().any(|x| {
|
||||
let x = interner.get(*x);
|
||||
let x = interner.get_repr(*x);
|
||||
x.is_refcounted() || x.contains_refcounted(interner)
|
||||
})
|
||||
}
|
||||
|
@ -1274,7 +1274,8 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
|||
|
||||
env.builder.position_at_end(block);
|
||||
|
||||
let fields_struct = layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let fields_struct =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let wrapper_type = basic_type_from_layout(env, layout_interner, fields_struct);
|
||||
|
||||
// cast the opaque pointer to a pointer of the correct shape
|
||||
|
@ -1312,7 +1313,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
|||
|
||||
// therefore we must cast it to our desired type
|
||||
let union_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let union_type = basic_type_from_layout(env, layout_interner, union_layout);
|
||||
let recursive_field_ptr = cast_basic_basic(env.builder, ptr_as_i64_ptr, union_type);
|
||||
|
||||
|
@ -1351,7 +1352,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
|||
DecOrReuse::Reuse => {}
|
||||
DecOrReuse::Dec => {
|
||||
let union_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
refcount_ptr.modify(call_mode, union_layout, env, layout_interner);
|
||||
}
|
||||
}
|
||||
|
@ -1410,7 +1411,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx>(
|
|||
// increment/decrement the cons-cell itself
|
||||
if let DecOrReuse::Dec = decrement_or_reuse {
|
||||
let union_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
refcount_ptr.modify(call_mode, union_layout, env, layout_interner);
|
||||
}
|
||||
}
|
||||
|
@ -1470,7 +1471,8 @@ pub fn build_reset<'a, 'ctx>(
|
|||
) -> FunctionValue<'ctx> {
|
||||
let mode = Mode::Dec;
|
||||
|
||||
let union_layout_in = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let union_layout_in =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let layout_id = layout_ids.get(Symbol::DEC, &union_layout_in);
|
||||
let fn_name = layout_id.to_symbol_string(Symbol::DEC, &env.interns);
|
||||
let fn_name = format!("{}_reset", fn_name);
|
||||
|
@ -1566,7 +1568,7 @@ fn build_reuse_rec_union_help<'a, 'ctx>(
|
|||
|
||||
env.builder.position_at_end(should_recurse_block);
|
||||
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
|
||||
let do_recurse_block = env.context.append_basic_block(parent, "do_recurse");
|
||||
let no_recurse_block = env.context.append_basic_block(parent, "no_recurse");
|
||||
|
@ -1628,7 +1630,7 @@ fn modify_refcount_nonrecursive<'a, 'ctx>(
|
|||
fields: &'a [&'a [InLayout<'a>]],
|
||||
) -> FunctionValue<'ctx> {
|
||||
let union_layout = UnionLayout::NonRecursive(fields);
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
|
||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
let di_location = env.builder.get_current_debug_location().unwrap();
|
||||
|
@ -1698,7 +1700,7 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
|||
let before_block = env.builder.get_insert_block().expect("to be in a function");
|
||||
|
||||
let union_layout = UnionLayout::NonRecursive(tags);
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let union_struct_type = basic_type_from_layout(env, layout_interner, layout).into_struct_type();
|
||||
|
||||
// read the tag_id
|
||||
|
@ -1735,7 +1737,7 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
|||
for (tag_id, field_layouts) in tags.iter().enumerate() {
|
||||
// if none of the fields are or contain anything refcounted, just move on
|
||||
if !field_layouts.iter().any(|x| {
|
||||
let x = layout_interner.get(*x);
|
||||
let x = layout_interner.get_repr(*x);
|
||||
x.is_refcounted() || x.contains_refcounted(layout_interner)
|
||||
}) {
|
||||
continue;
|
||||
|
@ -1744,7 +1746,8 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
|
|||
let block = env.context.append_basic_block(parent, "tag_id_modify");
|
||||
env.builder.position_at_end(block);
|
||||
|
||||
let fields_struct = layout_interner.insert_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let fields_struct =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::struct_(field_layouts));
|
||||
let data_struct_type = basic_type_from_layout(env, layout_interner, fields_struct);
|
||||
|
||||
debug_assert!(data_struct_type.is_struct_type());
|
||||
|
|
|
@ -467,7 +467,7 @@ impl<'a> LowLevelCall<'a> {
|
|||
|
||||
let capacity: Symbol = self.arguments[0];
|
||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
||||
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||
let (elem_width, elem_align) =
|
||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||
|
||||
|
@ -506,7 +506,7 @@ impl<'a> LowLevelCall<'a> {
|
|||
|
||||
// Load monomorphization constants
|
||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
||||
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||
let (elem_width, elem_align) =
|
||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||
backend.code_builder.i32_const(elem_align as i32);
|
||||
|
@ -522,7 +522,7 @@ impl<'a> LowLevelCall<'a> {
|
|||
let spare: Symbol = self.arguments[1];
|
||||
|
||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
||||
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||
let (elem_width, elem_align) =
|
||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||
|
||||
|
@ -563,7 +563,7 @@ impl<'a> LowLevelCall<'a> {
|
|||
let list: Symbol = self.arguments[0];
|
||||
|
||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout_raw);
|
||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
||||
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||
let (elem_width, elem_align) =
|
||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||
|
||||
|
@ -690,9 +690,12 @@ impl<'a> LowLevelCall<'a> {
|
|||
|
||||
// The refcount function receives a pointer to an element in the list
|
||||
// This is the same as a Struct containing the element
|
||||
let in_memory_layout = backend
|
||||
.layout_interner
|
||||
.insert_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([elem_layout])));
|
||||
let in_memory_layout =
|
||||
backend
|
||||
.layout_interner
|
||||
.insert_direct_no_semantic(LayoutRepr::Struct(
|
||||
backend.env.arena.alloc([elem_layout]),
|
||||
));
|
||||
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
||||
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
||||
|
||||
|
@ -735,9 +738,12 @@ impl<'a> LowLevelCall<'a> {
|
|||
|
||||
// The refcount function receives a pointer to an element in the list
|
||||
// This is the same as a Struct containing the element
|
||||
let in_memory_layout = backend
|
||||
.layout_interner
|
||||
.insert_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([elem_layout])));
|
||||
let in_memory_layout =
|
||||
backend
|
||||
.layout_interner
|
||||
.insert_direct_no_semantic(LayoutRepr::Struct(
|
||||
backend.env.arena.alloc([elem_layout]),
|
||||
));
|
||||
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
||||
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
||||
|
||||
|
@ -2375,7 +2381,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
|||
let wrapped_captures_layout =
|
||||
backend
|
||||
.layout_interner
|
||||
.insert_no_semantic(LayoutRepr::struct_(
|
||||
.insert_direct_no_semantic(LayoutRepr::struct_(
|
||||
backend.env.arena.alloc([closure_data_layout]),
|
||||
));
|
||||
|
||||
|
@ -2450,7 +2456,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
|||
argument_layouts.iter().take(n_non_closure_args).map(|lay| {
|
||||
backend
|
||||
.layout_interner
|
||||
.insert_no_semantic(LayoutRepr::Boxed(*lay))
|
||||
.insert_direct_no_semantic(LayoutRepr::Boxed(*lay))
|
||||
});
|
||||
|
||||
wrapper_arg_layouts.push(wrapped_captures_layout);
|
||||
|
@ -2462,7 +2468,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
|||
wrapper_arg_layouts.push(
|
||||
backend
|
||||
.layout_interner
|
||||
.insert_no_semantic(LayoutRepr::Boxed(*result_layout)),
|
||||
.insert_direct_no_semantic(LayoutRepr::Boxed(*result_layout)),
|
||||
);
|
||||
ProcLayout {
|
||||
arguments: wrapper_arg_layouts.into_bump_slice(),
|
||||
|
@ -2554,7 +2560,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
|||
.layout_interner
|
||||
.get_repr(backend.storage.symbol_layouts[xs]),
|
||||
);
|
||||
let elem_layout = backend.layout_interner.get(elem_layout);
|
||||
let elem_layout = backend.layout_interner.get_repr(elem_layout);
|
||||
let (element_width, alignment) =
|
||||
elem_layout.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||
|
||||
|
@ -2623,7 +2629,7 @@ fn list_map_n<'a>(
|
|||
);
|
||||
|
||||
let elem_ret = unwrap_list_elem_layout(backend.layout_interner.get_repr(return_layout));
|
||||
let elem_ret = backend.layout_interner.get(elem_ret);
|
||||
let elem_ret = backend.layout_interner.get_repr(elem_ret);
|
||||
let (elem_ret_size, elem_ret_align) =
|
||||
elem_ret.stack_size_and_alignment(backend.layout_interner, TARGET_INFO);
|
||||
|
||||
|
@ -2657,7 +2663,7 @@ fn list_map_n<'a>(
|
|||
// Here we wrap the layout in a Struct to ensure we get the right code gen
|
||||
let el_ptr = backend
|
||||
.layout_interner
|
||||
.insert_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([*el])));
|
||||
.insert_direct_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([*el])));
|
||||
let idx = backend.get_refcount_fn_index(el_ptr, HelperOp::Dec);
|
||||
let ptr = backend.get_fn_ptr(idx);
|
||||
backend.code_builder.i32_const(ptr);
|
||||
|
@ -2696,7 +2702,7 @@ fn ensure_symbol_is_in_memory<'a>(
|
|||
);
|
||||
let in_memory_layout = backend
|
||||
.layout_interner
|
||||
.insert_no_semantic(LayoutRepr::Struct(arena.alloc([layout])));
|
||||
.insert_direct_no_semantic(LayoutRepr::Struct(arena.alloc([layout])));
|
||||
(frame_ptr, offset, in_memory_layout)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::hash::Hash;
|
|||
use crate::ir::{
|
||||
Expr, HigherOrderLowLevel, JoinPointId, Param, PassedFunction, Proc, ProcLayout, Stmt,
|
||||
};
|
||||
use crate::layout::{InLayout, Layout, LayoutInterner, STLayoutInterner};
|
||||
use crate::layout::{InLayout, LayoutInterner, LayoutRepr, STLayoutInterner};
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
|
@ -29,7 +29,7 @@ impl Ownership {
|
|||
|
||||
/// For reference-counted types (lists, (big) strings, recursive tags), owning a value
|
||||
/// means incrementing its reference count. Hence, we prefer borrowing for these types
|
||||
fn from_layout(layout: &Layout) -> Self {
|
||||
fn from_layout(layout: &LayoutRepr) -> Self {
|
||||
match layout.is_refcounted() {
|
||||
true => Ownership::Borrowed,
|
||||
false => Ownership::Owned,
|
||||
|
@ -265,7 +265,7 @@ impl<'a> ParamMap<'a> {
|
|||
) -> &'a [Param<'a>] {
|
||||
Vec::from_iter_in(
|
||||
ps.iter().map(|p| Param {
|
||||
ownership: Ownership::from_layout(&interner.get(p.layout)),
|
||||
ownership: Ownership::from_layout(&interner.get_repr(p.layout)),
|
||||
layout: p.layout,
|
||||
symbol: p.symbol,
|
||||
}),
|
||||
|
@ -281,7 +281,7 @@ impl<'a> ParamMap<'a> {
|
|||
) -> &'a [Param<'a>] {
|
||||
Vec::from_iter_in(
|
||||
ps.iter().map(|(layout, symbol)| Param {
|
||||
ownership: Ownership::from_layout(&interner.get(*layout)),
|
||||
ownership: Ownership::from_layout(&interner.get_repr(*layout)),
|
||||
layout: *layout,
|
||||
symbol: *symbol,
|
||||
}),
|
||||
|
|
|
@ -434,7 +434,8 @@ fn eq_tag_union_help<'a>(
|
|||
if is_non_recursive {
|
||||
compare_ptr_or_value
|
||||
} else {
|
||||
let union_layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let union_layout =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let loop_params_iter = operands.iter().map(|arg| Param {
|
||||
symbol: *arg,
|
||||
ownership: Ownership::Borrowed,
|
||||
|
@ -657,7 +658,7 @@ fn eq_list<'a>(
|
|||
let arena = root.arena;
|
||||
|
||||
// A "Box" layout (heap pointer to a single list element)
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(elem_layout));
|
||||
let box_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(elem_layout));
|
||||
|
||||
// Compare lengths
|
||||
|
||||
|
@ -703,7 +704,7 @@ fn eq_list<'a>(
|
|||
let size = root.create_symbol(ident_ids, "size");
|
||||
let size_expr = Expr::Literal(Literal::Int(
|
||||
(layout_interner
|
||||
.get(elem_layout)
|
||||
.get_repr(elem_layout)
|
||||
.stack_size(layout_interner, root.target_info) as i128)
|
||||
.to_ne_bytes(),
|
||||
));
|
||||
|
|
|
@ -10,8 +10,8 @@ use crate::ir::{
|
|||
Proc, ProcLayout, SelfRecursive, Stmt, UpdateModeId,
|
||||
};
|
||||
use crate::layout::{
|
||||
Builtin, InLayout, LambdaName, Layout, LayoutInterner, LayoutRepr, Niche, STLayoutInterner,
|
||||
UnionLayout,
|
||||
Builtin, InLayout, LambdaName, Layout, LayoutInterner, LayoutRepr, LayoutWrapper, Niche,
|
||||
STLayoutInterner, UnionLayout,
|
||||
};
|
||||
|
||||
mod equality;
|
||||
|
@ -290,7 +290,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
LayoutRepr::RecursivePointer(_)
|
||||
) {
|
||||
let union_layout = ctx.recursive_union.unwrap();
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout))
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout))
|
||||
} else {
|
||||
called_layout
|
||||
};
|
||||
|
@ -301,7 +301,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
|
||||
let (ret_layout, arg_layouts): (InLayout<'a>, &'a [InLayout<'a>]) = {
|
||||
let arg = self.replace_rec_ptr(ctx, layout_interner, layout);
|
||||
let box_arg = layout_interner.insert_no_semantic(LayoutRepr::Boxed(arg));
|
||||
let box_arg = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(arg));
|
||||
|
||||
match ctx.op {
|
||||
Dec | DecRef(_) => (LAYOUT_UNIT, self.arena.alloc([arg])),
|
||||
|
@ -430,12 +430,14 @@ impl<'a> CodeGenHelp<'a> {
|
|||
}
|
||||
Dec | DecRef(_) | Reset | ResetRef => self.arena.alloc([roc_value]),
|
||||
IndirectInc => {
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
let box_layout =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||
let inc_amount = (self.layout_isize, ARG_2);
|
||||
self.arena.alloc([(box_layout, ARG_1), inc_amount])
|
||||
}
|
||||
IndirectDec => {
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
let box_layout =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||
self.arena.alloc([(box_layout, ARG_1)])
|
||||
}
|
||||
Eq => self.arena.alloc([roc_value, (layout, ARG_2)]),
|
||||
|
@ -483,7 +485,8 @@ impl<'a> CodeGenHelp<'a> {
|
|||
niche: Niche::NONE,
|
||||
},
|
||||
HelperOp::IndirectInc => {
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
let box_layout =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||
|
||||
ProcLayout {
|
||||
arguments: self.arena.alloc([box_layout, self.layout_isize]),
|
||||
|
@ -492,7 +495,8 @@ impl<'a> CodeGenHelp<'a> {
|
|||
}
|
||||
}
|
||||
HelperOp::IndirectDec => {
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
let box_layout =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
|
||||
|
||||
ProcLayout {
|
||||
arguments: self.arena.alloc([box_layout]),
|
||||
|
@ -581,7 +585,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
LayoutRepr::RecursivePointer(_) => LayoutRepr::Union(ctx.recursive_union.unwrap()),
|
||||
};
|
||||
|
||||
layout_interner.insert(Layout::new(repr, semantic))
|
||||
layout_interner.insert(Layout::new(LayoutWrapper::Direct(repr), semantic))
|
||||
}
|
||||
|
||||
fn union_tail_recursion_fields(
|
||||
|
@ -665,16 +669,16 @@ impl<'a> CallerProc<'a> {
|
|||
};
|
||||
|
||||
let box_capture_layout = if let Some(capture_layout) = capture_layout {
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Boxed(capture_layout))
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(capture_layout))
|
||||
} else {
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Boxed(Layout::UNIT))
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(Layout::UNIT))
|
||||
};
|
||||
|
||||
let box_argument_layout = layout_interner
|
||||
.insert_no_semantic(LayoutRepr::Boxed(passed_function.argument_layouts[0]));
|
||||
.insert_direct_no_semantic(LayoutRepr::Boxed(passed_function.argument_layouts[0]));
|
||||
|
||||
let box_return_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Boxed(passed_function.return_layout));
|
||||
let box_return_layout = layout_interner
|
||||
.insert_direct_no_semantic(LayoutRepr::Boxed(passed_function.return_layout));
|
||||
|
||||
let proc_layout = ProcLayout {
|
||||
arguments: arena.alloc([box_capture_layout, box_argument_layout, box_return_layout]),
|
||||
|
|
|
@ -309,7 +309,8 @@ pub fn refcount_reset_proc_body<'a>(
|
|||
// Whenever we recurse into a child layout we will want to Decrement
|
||||
ctx.op = HelperOp::Dec;
|
||||
ctx.recursive_union = Some(union_layout);
|
||||
let recursion_ptr = layout_interner.insert_no_semantic(LayoutRepr::RecursivePointer(layout));
|
||||
let recursion_ptr =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::RecursivePointer(layout));
|
||||
|
||||
// Reset structure is unique. Decrement its children and return a pointer to the allocation.
|
||||
let then_stmt = {
|
||||
|
@ -491,7 +492,8 @@ pub fn refcount_resetref_proc_body<'a>(
|
|||
// Whenever we recurse into a child layout we will want to Decrement
|
||||
ctx.op = HelperOp::Dec;
|
||||
ctx.recursive_union = Some(union_layout);
|
||||
let recursion_ptr = layout_interner.insert_no_semantic(LayoutRepr::RecursivePointer(layout));
|
||||
let recursion_ptr =
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::RecursivePointer(layout));
|
||||
|
||||
// Reset structure is unique. Return a pointer to the allocation.
|
||||
let then_stmt = Stmt::Ret(addr);
|
||||
|
@ -979,7 +981,7 @@ fn refcount_list<'a>(
|
|||
let arena = root.arena;
|
||||
|
||||
// A "Box" layout (heap pointer to a single list element)
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(elem_layout));
|
||||
let box_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(elem_layout));
|
||||
|
||||
//
|
||||
// Check if the list is empty
|
||||
|
@ -1106,7 +1108,7 @@ fn refcount_list<'a>(
|
|||
|
||||
let is_relevant_op = ctx.op.is_dec() || ctx.op.is_inc();
|
||||
let modify_elems_and_list =
|
||||
if is_relevant_op && layout_interner.get(elem_layout).is_refcounted() {
|
||||
if is_relevant_op && layout_interner.get_repr(elem_layout).is_refcounted() {
|
||||
refcount_list_elems(
|
||||
root,
|
||||
ident_ids,
|
||||
|
@ -1742,7 +1744,7 @@ fn refcount_union_tailrec<'a>(
|
|||
let tailrec_loop = JoinPointId(root.create_symbol(ident_ids, "tailrec_loop"));
|
||||
let current = root.create_symbol(ident_ids, "current");
|
||||
let next_ptr = root.create_symbol(ident_ids, "next_ptr");
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
|
||||
let tag_id_layout = union_layout.tag_id_layout();
|
||||
|
||||
|
@ -1887,7 +1889,7 @@ fn refcount_union_tailrec<'a>(
|
|||
let jump_with_null_ptr = Stmt::Let(
|
||||
null_pointer,
|
||||
Expr::NullPointer,
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout)),
|
||||
layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout)),
|
||||
root.arena.alloc(Stmt::Jump(
|
||||
jp_modify_union,
|
||||
root.arena.alloc([null_pointer]),
|
||||
|
@ -1931,7 +1933,7 @@ fn refcount_union_tailrec<'a>(
|
|||
));
|
||||
|
||||
let loop_init = Stmt::Jump(tailrec_loop, root.arena.alloc([initial_structure]));
|
||||
let union_layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let union_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let loop_param = Param {
|
||||
symbol: current,
|
||||
ownership: Ownership::Borrowed,
|
||||
|
|
|
@ -400,7 +400,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
} => {
|
||||
let interned_layout = self
|
||||
.interner
|
||||
.insert_no_semantic(LayoutRepr::Union(tag_layout));
|
||||
.insert_direct_no_semantic(LayoutRepr::Union(tag_layout));
|
||||
self.check_tag_expr(interned_layout, tag_layout, tag_id, arguments);
|
||||
Some(interned_layout)
|
||||
}
|
||||
|
@ -440,7 +440,9 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
}
|
||||
Some(
|
||||
self.interner
|
||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*elem_layout))),
|
||||
.insert_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(
|
||||
*elem_layout,
|
||||
))),
|
||||
)
|
||||
}
|
||||
Expr::EmptyArray => {
|
||||
|
@ -449,7 +451,10 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
}
|
||||
&Expr::ExprBox { symbol } => self.with_sym_layout(symbol, |ctx, _def_line, layout| {
|
||||
let inner = layout;
|
||||
Some(ctx.interner.insert_no_semantic(LayoutRepr::Boxed(inner)))
|
||||
Some(
|
||||
ctx.interner
|
||||
.insert_direct_no_semantic(LayoutRepr::Boxed(inner)),
|
||||
)
|
||||
}),
|
||||
&Expr::ExprUnbox { symbol } => self.with_sym_layout(symbol, |ctx, def_line, layout| {
|
||||
let layout = ctx.resolve(layout);
|
||||
|
@ -471,7 +476,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
} => {
|
||||
let union = self
|
||||
.interner
|
||||
.insert_no_semantic(LayoutRepr::Union(tag_layout));
|
||||
.insert_direct_no_semantic(LayoutRepr::Union(tag_layout));
|
||||
self.check_sym_layout(symbol, union, UseKind::TagReuse);
|
||||
// TODO also check update arguments
|
||||
Some(union)
|
||||
|
@ -529,7 +534,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
) -> Option<InLayout<'a>> {
|
||||
let union = self
|
||||
.interner
|
||||
.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
.insert_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
self.with_sym_layout(structure, |ctx, def_line, _layout| {
|
||||
ctx.check_sym_layout(structure, union, UseKind::TagExpr);
|
||||
|
||||
|
|
|
@ -3509,10 +3509,10 @@ fn specialize_proc_help<'a>(
|
|||
|
||||
combined.sort_by(|(_, layout1), (_, layout2)| {
|
||||
let size1 = layout_cache
|
||||
.get_in(**layout1)
|
||||
.get_repr(**layout1)
|
||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||
let size2 = layout_cache
|
||||
.get_in(**layout2)
|
||||
.get_repr(**layout2)
|
||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||
|
||||
size2.cmp(&size1)
|
||||
|
@ -3557,10 +3557,10 @@ fn specialize_proc_help<'a>(
|
|||
|
||||
combined.sort_by(|(_, layout1), (_, layout2)| {
|
||||
let size1 = layout_cache
|
||||
.get_in(**layout1)
|
||||
.get_repr(**layout1)
|
||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||
let size2 = layout_cache
|
||||
.get_in(**layout2)
|
||||
.get_repr(**layout2)
|
||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||
|
||||
size2.cmp(&size1)
|
||||
|
@ -4627,13 +4627,14 @@ pub fn with_hole<'a>(
|
|||
Ok(elem_layout) => {
|
||||
let expr = Expr::EmptyArray;
|
||||
let list_layout = layout_cache
|
||||
.put_in_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
||||
.put_in_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
||||
Stmt::Let(assigned, expr, list_layout, hole)
|
||||
}
|
||||
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
|
||||
let expr = Expr::EmptyArray;
|
||||
let list_layout = layout_cache
|
||||
.put_in_no_semantic(LayoutRepr::Builtin(Builtin::List(Layout::VOID)));
|
||||
let list_layout = layout_cache.put_in_direct_no_semantic(LayoutRepr::Builtin(
|
||||
Builtin::List(Layout::VOID),
|
||||
));
|
||||
Stmt::Let(assigned, expr, list_layout, hole)
|
||||
}
|
||||
Err(LayoutProblem::Erroneous) => panic!("list element is error type"),
|
||||
|
@ -4679,8 +4680,8 @@ pub fn with_hole<'a>(
|
|||
elems: elements.into_bump_slice(),
|
||||
};
|
||||
|
||||
let list_layout =
|
||||
layout_cache.put_in_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
||||
let list_layout = layout_cache
|
||||
.put_in_direct_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
||||
|
||||
let stmt = Stmt::Let(assigned, expr, list_layout, hole);
|
||||
|
||||
|
@ -5917,10 +5918,10 @@ where
|
|||
|
||||
combined.sort_by(|(_, layout1), (_, layout2)| {
|
||||
let size1 = layout_cache
|
||||
.get_in(**layout1)
|
||||
.get_repr(**layout1)
|
||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||
let size2 = layout_cache
|
||||
.get_in(**layout2)
|
||||
.get_repr(**layout2)
|
||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||
|
||||
size2.cmp(&size1)
|
||||
|
@ -5951,10 +5952,10 @@ where
|
|||
|
||||
combined.sort_by(|(_, layout1), (_, layout2)| {
|
||||
let size1 = layout_cache
|
||||
.get_in(**layout1)
|
||||
.get_repr(**layout1)
|
||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||
let size2 = layout_cache
|
||||
.get_in(**layout2)
|
||||
.get_repr(**layout2)
|
||||
.alignment_bytes(&layout_cache.interner, ptr_bytes);
|
||||
|
||||
size2.cmp(&size1)
|
||||
|
@ -6299,7 +6300,8 @@ fn convert_tag_union<'a>(
|
|||
}
|
||||
};
|
||||
|
||||
let union_layout = layout_cache.put_in_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let union_layout =
|
||||
layout_cache.put_in_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
|
||||
let stmt = Stmt::Let(assigned, tag, union_layout, hole);
|
||||
let iter = field_symbols_temp
|
||||
|
@ -6438,7 +6440,7 @@ fn sorted_field_symbols<'a>(
|
|||
};
|
||||
|
||||
let alignment = layout_cache
|
||||
.get_in(layout)
|
||||
.get_repr(layout)
|
||||
.alignment_bytes(&layout_cache.interner, env.target_info);
|
||||
|
||||
let symbol = possible_reuse_symbol_or_specialize(env, procs, layout_cache, &arg.value, var);
|
||||
|
@ -7885,7 +7887,7 @@ fn specialize_symbol<'a>(
|
|||
let layout = match raw {
|
||||
RawFunctionLayout::ZeroArgumentThunk(layout) => layout,
|
||||
RawFunctionLayout::Function(_, lambda_set, _) => layout_cache
|
||||
.put_in_no_semantic(LayoutRepr::LambdaSet(lambda_set)),
|
||||
.put_in_direct_no_semantic(LayoutRepr::LambdaSet(lambda_set)),
|
||||
};
|
||||
|
||||
let raw = RawFunctionLayout::ZeroArgumentThunk(layout);
|
||||
|
@ -9762,7 +9764,7 @@ where
|
|||
($tag_id:expr, $layout:expr, $union_layout:expr, $field_layouts: expr) => {{
|
||||
if $field_layouts.iter().any(|l| {
|
||||
layout_interner
|
||||
.get(*l)
|
||||
.get_repr(*l)
|
||||
.has_varying_stack_size(layout_interner, arena)
|
||||
}) {
|
||||
let procs = generate_glue_procs_for_tag_fields(
|
||||
|
@ -9799,7 +9801,7 @@ where
|
|||
LayoutRepr::Struct(field_layouts) => {
|
||||
if field_layouts.iter().any(|l| {
|
||||
layout_interner
|
||||
.get(*l)
|
||||
.get_repr(*l)
|
||||
.has_varying_stack_size(layout_interner, arena)
|
||||
}) {
|
||||
let procs = generate_glue_procs_for_struct_fields(
|
||||
|
@ -9890,7 +9892,7 @@ where
|
|||
{
|
||||
let interned_unboxed_struct_layout = layout_interner.insert(*unboxed_struct_layout);
|
||||
let boxed_struct_layout =
|
||||
Layout::no_semantic(LayoutRepr::Boxed(interned_unboxed_struct_layout));
|
||||
Layout::no_semantic(LayoutRepr::Boxed(interned_unboxed_struct_layout).direct());
|
||||
let boxed_struct_layout = layout_interner.insert(boxed_struct_layout);
|
||||
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
||||
|
||||
|
@ -10001,7 +10003,7 @@ where
|
|||
I: LayoutInterner<'a>,
|
||||
{
|
||||
let interned = layout_interner.insert(*unboxed_struct_layout);
|
||||
let boxed_struct_layout = Layout::no_semantic(LayoutRepr::Boxed(interned));
|
||||
let boxed_struct_layout = Layout::no_semantic(LayoutRepr::Boxed(interned).direct());
|
||||
let boxed_struct_layout = layout_interner.insert(boxed_struct_layout);
|
||||
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
||||
|
||||
|
|
|
@ -1206,8 +1206,8 @@ fn store_pattern_help<'a>(
|
|||
let mut fields = Vec::with_capacity_in(arguments.len(), env.arena);
|
||||
fields.extend(arguments.iter().map(|x| x.1));
|
||||
|
||||
let layout =
|
||||
layout_cache.put_in_no_semantic(LayoutRepr::struct_(fields.into_bump_slice()));
|
||||
let layout = layout_cache
|
||||
.put_in_direct_no_semantic(LayoutRepr::struct_(fields.into_bump_slice()));
|
||||
|
||||
return store_newtype_pattern(
|
||||
env,
|
||||
|
@ -1553,7 +1553,7 @@ fn store_tag_pattern<'a>(
|
|||
|
||||
if let LayoutRepr::RecursivePointer(_) = layout_cache.get_repr(arg_layout) {
|
||||
// TODO(recursive-layouts): fix after disjoint rec ptrs
|
||||
arg_layout = layout_cache.put_in_no_semantic(LayoutRepr::Union(union_layout));
|
||||
arg_layout = layout_cache.put_in_direct_no_semantic(LayoutRepr::Union(union_layout));
|
||||
}
|
||||
|
||||
let load = Expr::UnionAtIndex {
|
||||
|
|
|
@ -335,8 +335,8 @@ impl<'a> LayoutCache<'a> {
|
|||
pub fn put_in(&mut self, layout: Layout<'a>) -> InLayout<'a> {
|
||||
self.interner.insert(layout)
|
||||
}
|
||||
pub fn put_in_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
||||
self.interner.insert_no_semantic(repr)
|
||||
pub(crate) fn put_in_direct_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
||||
self.interner.insert_direct_no_semantic(repr)
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -659,10 +659,17 @@ impl<'a> RawFunctionLayout<'a> {
|
|||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Layout<'a> {
|
||||
repr: LayoutRepr<'a>,
|
||||
repr: LayoutWrapper<'a>,
|
||||
semantic: SemanticRepr<'a>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub(crate) enum LayoutWrapper<'a> {
|
||||
Direct(LayoutRepr<'a>),
|
||||
#[allow(unused)] // for now
|
||||
Newtype(InLayout<'a>),
|
||||
}
|
||||
|
||||
/// Types for code gen must be monomorphic. No type variables allowed!
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum LayoutRepr<'a> {
|
||||
|
@ -877,7 +884,7 @@ impl<'a> UnionLayout<'a> {
|
|||
|
||||
// TODO(recursive-layouts): simplify after we have disjoint recursive pointers
|
||||
if let LayoutRepr::RecursivePointer(_) = interner.get_repr(result) {
|
||||
interner.insert_no_semantic(LayoutRepr::Union(self))
|
||||
interner.insert_direct_no_semantic(LayoutRepr::Union(self))
|
||||
} else {
|
||||
result
|
||||
}
|
||||
|
@ -1926,7 +1933,7 @@ impl<'a> LambdaSet<'a> {
|
|||
I: LayoutInterner<'a>,
|
||||
{
|
||||
interner
|
||||
.get(self.representation)
|
||||
.get_repr(self.representation)
|
||||
.stack_size(interner, target_info)
|
||||
}
|
||||
pub fn contains_refcounted<I>(&self, interner: &I) -> bool
|
||||
|
@ -1934,14 +1941,16 @@ impl<'a> LambdaSet<'a> {
|
|||
I: LayoutInterner<'a>,
|
||||
{
|
||||
interner
|
||||
.get(self.representation)
|
||||
.get_repr(self.representation)
|
||||
.contains_refcounted(interner)
|
||||
}
|
||||
pub fn safe_to_memcpy<I>(&self, interner: &I) -> bool
|
||||
where
|
||||
I: LayoutInterner<'a>,
|
||||
{
|
||||
interner.get(self.representation).safe_to_memcpy(interner)
|
||||
interner
|
||||
.get_repr(self.representation)
|
||||
.safe_to_memcpy(interner)
|
||||
}
|
||||
|
||||
pub fn alignment_bytes<I>(&self, interner: &I, target_info: TargetInfo) -> u32
|
||||
|
@ -1949,7 +1958,7 @@ impl<'a> LambdaSet<'a> {
|
|||
I: LayoutInterner<'a>,
|
||||
{
|
||||
interner
|
||||
.get(self.representation)
|
||||
.get_repr(self.representation)
|
||||
.alignment_bytes(interner, target_info)
|
||||
}
|
||||
}
|
||||
|
@ -2329,22 +2338,30 @@ pub fn is_any_float_range(subs: &Subs, var: Variable) -> bool {
|
|||
}
|
||||
|
||||
impl<'a> Layout<'a> {
|
||||
pub const fn new(repr: LayoutRepr<'a>, semantic: SemanticRepr<'a>) -> Self {
|
||||
pub(crate) const fn new(repr: LayoutWrapper<'a>, semantic: SemanticRepr<'a>) -> Self {
|
||||
Self { repr, semantic }
|
||||
}
|
||||
|
||||
pub const fn no_semantic(repr: LayoutRepr<'a>) -> Self {
|
||||
pub(crate) const fn no_semantic(repr: LayoutWrapper<'a>) -> Self {
|
||||
Self {
|
||||
repr,
|
||||
semantic: SemanticRepr::NONE,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn repr<I>(&self, _interner: &I) -> LayoutRepr<'a>
|
||||
pub(crate) fn repr<I>(&self, interner: &I) -> LayoutRepr<'a>
|
||||
where
|
||||
I: LayoutInterner<'a>,
|
||||
{
|
||||
self.repr
|
||||
let mut lay = *self;
|
||||
loop {
|
||||
match lay.repr {
|
||||
LayoutWrapper::Direct(repr) => return repr,
|
||||
LayoutWrapper::Newtype(real) => {
|
||||
lay = interner.get(real);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn new_help<'b>(
|
||||
|
@ -2463,7 +2480,7 @@ impl<'a> Layout<'a> {
|
|||
let mut total = 0;
|
||||
for layout in tag.iter() {
|
||||
let (stack_size, alignment) = interner
|
||||
.get(*layout)
|
||||
.get_repr(*layout)
|
||||
.stack_size_and_alignment(interner, target_info);
|
||||
total += stack_size;
|
||||
data_align = data_align.max(alignment);
|
||||
|
@ -2482,7 +2499,7 @@ impl<'a> Layout<'a> {
|
|||
I: LayoutInterner<'a>,
|
||||
{
|
||||
use LayoutRepr::*;
|
||||
match self.repr {
|
||||
match self.repr(interner) {
|
||||
LambdaSet(lambda_set) => interner.get(lambda_set.runtime_representation()),
|
||||
_ => *self,
|
||||
}
|
||||
|
@ -2500,14 +2517,6 @@ impl<'a> Layout<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> std::ops::Deref for Layout<'a> {
|
||||
type Target = LayoutRepr<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.repr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> LayoutRepr<'a> {
|
||||
pub const UNIT: Self = LayoutRepr::struct_(&[]);
|
||||
pub const BOOL: Self = LayoutRepr::Builtin(Builtin::Bool);
|
||||
|
@ -2531,6 +2540,10 @@ impl<'a> LayoutRepr<'a> {
|
|||
Self::Struct(field_layouts)
|
||||
}
|
||||
|
||||
pub(crate) const fn direct(self) -> LayoutWrapper<'a> {
|
||||
LayoutWrapper::Direct(self)
|
||||
}
|
||||
|
||||
pub fn safe_to_memcpy<I>(&self, interner: &I) -> bool
|
||||
where
|
||||
I: LayoutInterner<'a>,
|
||||
|
@ -2541,7 +2554,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
Builtin(builtin) => builtin.safe_to_memcpy(),
|
||||
Struct(field_layouts) => field_layouts
|
||||
.iter()
|
||||
.all(|field_layout| interner.get(*field_layout).safe_to_memcpy(interner)),
|
||||
.all(|field_layout| interner.get_repr(*field_layout).safe_to_memcpy(interner)),
|
||||
Union(variant) => {
|
||||
use UnionLayout::*;
|
||||
|
||||
|
@ -2549,7 +2562,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
NonRecursive(tags) => tags.iter().all(|tag_layout| {
|
||||
tag_layout
|
||||
.iter()
|
||||
.all(|field| interner.get(*field).safe_to_memcpy(interner))
|
||||
.all(|field| interner.get_repr(*field).safe_to_memcpy(interner))
|
||||
}),
|
||||
Recursive(_)
|
||||
| NullableWrapped { .. }
|
||||
|
@ -2561,7 +2574,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
}
|
||||
}
|
||||
LambdaSet(lambda_set) => interner
|
||||
.get(lambda_set.runtime_representation())
|
||||
.get_repr(lambda_set.runtime_representation())
|
||||
.safe_to_memcpy(interner),
|
||||
Boxed(_) | RecursivePointer(_) => {
|
||||
// We cannot memcpy pointers, because then we would have the same pointer in multiple places!
|
||||
|
@ -2598,7 +2611,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
}
|
||||
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => true,
|
||||
LayoutRepr::LambdaSet(lambda_set) => interner
|
||||
.get(lambda_set.runtime_representation())
|
||||
.get_repr(lambda_set.runtime_representation())
|
||||
.is_passed_by_reference(interner, target_info),
|
||||
_ => false,
|
||||
}
|
||||
|
@ -2639,7 +2652,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
|
||||
for field_layout in *field_layouts {
|
||||
sum += interner
|
||||
.get(*field_layout)
|
||||
.get_repr(*field_layout)
|
||||
.stack_size(interner, target_info);
|
||||
}
|
||||
|
||||
|
@ -2647,7 +2660,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
}
|
||||
Union(variant) => variant.stack_size_without_alignment(interner, target_info),
|
||||
LambdaSet(lambda_set) => interner
|
||||
.get(lambda_set.runtime_representation())
|
||||
.get_repr(lambda_set.runtime_representation())
|
||||
.stack_size_without_alignment(interner, target_info),
|
||||
RecursivePointer(_) => target_info.ptr_width() as u32,
|
||||
Boxed(_) => target_info.ptr_width() as u32,
|
||||
|
@ -2662,7 +2675,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
match self {
|
||||
Struct(field_layouts) => field_layouts
|
||||
.iter()
|
||||
.map(|x| interner.get(*x).alignment_bytes(interner, target_info))
|
||||
.map(|x| interner.get_repr(*x).alignment_bytes(interner, target_info))
|
||||
.max()
|
||||
.unwrap_or(0),
|
||||
|
||||
|
@ -2675,7 +2688,9 @@ impl<'a> LayoutRepr<'a> {
|
|||
.iter()
|
||||
.flat_map(|layouts| {
|
||||
layouts.iter().map(|layout| {
|
||||
interner.get(*layout).alignment_bytes(interner, target_info)
|
||||
interner
|
||||
.get_repr(*layout)
|
||||
.alignment_bytes(interner, target_info)
|
||||
})
|
||||
})
|
||||
.max();
|
||||
|
@ -2699,7 +2714,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
}
|
||||
}
|
||||
LambdaSet(lambda_set) => interner
|
||||
.get(lambda_set.runtime_representation())
|
||||
.get_repr(lambda_set.runtime_representation())
|
||||
.alignment_bytes(interner, target_info),
|
||||
Builtin(builtin) => builtin.alignment_bytes(target_info),
|
||||
RecursivePointer(_) => target_info.ptr_width() as u32,
|
||||
|
@ -2719,14 +2734,16 @@ impl<'a> LayoutRepr<'a> {
|
|||
Struct { .. } => self.alignment_bytes(interner, target_info).max(ptr_width),
|
||||
Union(union_layout) => union_layout.allocation_alignment_bytes(interner, target_info),
|
||||
LambdaSet(lambda_set) => interner
|
||||
.get(lambda_set.runtime_representation())
|
||||
.get_repr(lambda_set.runtime_representation())
|
||||
.allocation_alignment_bytes(interner, target_info),
|
||||
RecursivePointer(_) => {
|
||||
unreachable!("should be looked up to get an actual layout")
|
||||
}
|
||||
Boxed(inner) => Ord::max(
|
||||
ptr_width,
|
||||
interner.get(*inner).alignment_bytes(interner, target_info),
|
||||
interner
|
||||
.get_repr(*inner)
|
||||
.alignment_bytes(interner, target_info),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -2761,7 +2778,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
Builtin(builtin) => builtin.is_refcounted(),
|
||||
Struct(field_layouts) => field_layouts
|
||||
.iter()
|
||||
.any(|f| interner.get(*f).contains_refcounted(interner)),
|
||||
.any(|f| interner.get_repr(*f).contains_refcounted(interner)),
|
||||
Union(variant) => {
|
||||
use UnionLayout::*;
|
||||
|
||||
|
@ -2769,7 +2786,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
NonRecursive(fields) => fields
|
||||
.iter()
|
||||
.flat_map(|ls| ls.iter())
|
||||
.any(|f| interner.get(*f).contains_refcounted(interner)),
|
||||
.any(|f| interner.get_repr(*f).contains_refcounted(interner)),
|
||||
Recursive(_)
|
||||
| NullableWrapped { .. }
|
||||
| NullableUnwrapped { .. }
|
||||
|
@ -2777,7 +2794,7 @@ impl<'a> LayoutRepr<'a> {
|
|||
}
|
||||
}
|
||||
LambdaSet(lambda_set) => interner
|
||||
.get(lambda_set.runtime_representation())
|
||||
.get_repr(lambda_set.runtime_representation())
|
||||
.contains_refcounted(interner),
|
||||
RecursivePointer(_) => true,
|
||||
Boxed(_) => true,
|
||||
|
@ -2900,9 +2917,12 @@ impl<'a> Layout<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_recursive_tag_union(self) -> bool {
|
||||
pub fn is_recursive_tag_union<I>(self, interner: &I) -> bool
|
||||
where
|
||||
I: LayoutInterner<'a>,
|
||||
{
|
||||
matches!(
|
||||
self.repr,
|
||||
self.repr(interner),
|
||||
LayoutRepr::Union(
|
||||
UnionLayout::NullableUnwrapped { .. }
|
||||
| UnionLayout::Recursive(_)
|
||||
|
@ -3050,7 +3070,7 @@ impl<'a> Builtin<'a> {
|
|||
let allocation = match self {
|
||||
Builtin::Str => ptr_width,
|
||||
Builtin::List(e) => {
|
||||
let e = interner.get(*e);
|
||||
let e = interner.get_repr(*e);
|
||||
e.alignment_bytes(interner, target_info).max(ptr_width)
|
||||
}
|
||||
// The following are usually not heap-allocated, but they might be when inside a Box.
|
||||
|
@ -3163,7 +3183,7 @@ fn layout_from_flat_type<'a>(
|
|||
let inner_layout =
|
||||
cached!(Layout::from_var(env, inner_var), criteria, env.subs);
|
||||
let boxed_layout = env.cache.put_in(Layout {
|
||||
repr: LayoutRepr::Boxed(inner_layout),
|
||||
repr: LayoutRepr::Boxed(inner_layout).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
});
|
||||
|
||||
|
@ -3248,7 +3268,7 @@ fn layout_from_flat_type<'a>(
|
|||
} else {
|
||||
let layouts = Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena);
|
||||
let struct_layout = Layout {
|
||||
repr: LayoutRepr::Struct(layouts.into_bump_slice()),
|
||||
repr: LayoutRepr::Struct(layouts.into_bump_slice()).direct(),
|
||||
semantic: SemanticRepr::record(ordered_field_names.into_bump_slice()),
|
||||
};
|
||||
|
||||
|
@ -3291,7 +3311,7 @@ fn layout_from_flat_type<'a>(
|
|||
let field_layouts =
|
||||
Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena).into_bump_slice();
|
||||
let struct_layout = Layout {
|
||||
repr: LayoutRepr::Struct(field_layouts),
|
||||
repr: LayoutRepr::Struct(field_layouts).direct(),
|
||||
semantic: SemanticRepr::tuple(field_layouts.len()),
|
||||
};
|
||||
|
||||
|
@ -3726,11 +3746,11 @@ where
|
|||
layouts.sort_by(|layout1, layout2| {
|
||||
let size1 = env
|
||||
.cache
|
||||
.get_in(*layout1)
|
||||
.get_repr(*layout1)
|
||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||
let size2 = env
|
||||
.cache
|
||||
.get_in(*layout2)
|
||||
.get_repr(*layout2)
|
||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||
|
||||
size2.cmp(&size1)
|
||||
|
@ -3788,11 +3808,11 @@ where
|
|||
arg_layouts.sort_by(|layout1, layout2| {
|
||||
let size1 = env
|
||||
.cache
|
||||
.get_in(*layout1)
|
||||
.get_repr(*layout1)
|
||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||
let size2 = env
|
||||
.cache
|
||||
.get_in(*layout2)
|
||||
.get_repr(*layout2)
|
||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||
|
||||
size2.cmp(&size1)
|
||||
|
@ -3970,7 +3990,7 @@ where
|
|||
== env
|
||||
.subs
|
||||
.get_root_key_without_compacting(opt_rec_var.unwrap())
|
||||
&& layout.is_recursive_tag_union();
|
||||
&& layout.is_recursive_tag_union(&env.cache.interner);
|
||||
|
||||
let arg_layout = if self_recursion {
|
||||
Layout::NAKED_RECURSIVE_PTR
|
||||
|
@ -4000,11 +4020,11 @@ where
|
|||
arg_layouts.sort_by(|layout1, layout2| {
|
||||
let size1 = env
|
||||
.cache
|
||||
.get_in(*layout1)
|
||||
.get_repr(*layout1)
|
||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||
let size2 = env
|
||||
.cache
|
||||
.get_in(*layout2)
|
||||
.get_repr(*layout2)
|
||||
.alignment_bytes(&env.cache.interner, env.target_info);
|
||||
|
||||
size2.cmp(&size1)
|
||||
|
@ -4139,13 +4159,13 @@ where
|
|||
Never => Layout::VOID,
|
||||
Unit => env
|
||||
.cache
|
||||
.put_in(Layout::new(LayoutRepr::UNIT, compute_semantic())),
|
||||
.put_in(Layout::new(LayoutRepr::UNIT.direct(), compute_semantic())),
|
||||
BoolUnion { .. } => env
|
||||
.cache
|
||||
.put_in(Layout::new(LayoutRepr::BOOL, compute_semantic())),
|
||||
.put_in(Layout::new(LayoutRepr::BOOL.direct(), compute_semantic())),
|
||||
ByteUnion(_) => env
|
||||
.cache
|
||||
.put_in(Layout::new(LayoutRepr::U8, compute_semantic())),
|
||||
.put_in(Layout::new(LayoutRepr::U8.direct(), compute_semantic())),
|
||||
Newtype {
|
||||
arguments: field_layouts,
|
||||
..
|
||||
|
@ -4154,7 +4174,7 @@ where
|
|||
field_layouts[0]
|
||||
} else {
|
||||
env.cache
|
||||
.put_in_no_semantic(LayoutRepr::struct_(field_layouts.into_bump_slice()))
|
||||
.put_in_direct_no_semantic(LayoutRepr::struct_(field_layouts.into_bump_slice()))
|
||||
};
|
||||
|
||||
answer1
|
||||
|
@ -4165,8 +4185,9 @@ where
|
|||
if data_tag_arguments.len() == 1 {
|
||||
data_tag_arguments[0]
|
||||
} else {
|
||||
env.cache
|
||||
.put_in_no_semantic(LayoutRepr::struct_(data_tag_arguments.into_bump_slice()))
|
||||
env.cache.put_in_direct_no_semantic(LayoutRepr::struct_(
|
||||
data_tag_arguments.into_bump_slice(),
|
||||
))
|
||||
}
|
||||
}
|
||||
Wrapped(variant) => {
|
||||
|
@ -4182,7 +4203,8 @@ where
|
|||
let layout = Layout {
|
||||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(
|
||||
tag_layouts.into_bump_slice(),
|
||||
)),
|
||||
))
|
||||
.direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
};
|
||||
env.cache.put_in(layout)
|
||||
|
@ -4298,14 +4320,14 @@ where
|
|||
env.cache.interner.insert_recursive(
|
||||
env.arena,
|
||||
Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
repr: LayoutRepr::Union(union_layout).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
// There are no naked recursion pointers, so we can insert the layout as-is.
|
||||
env.cache.interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
repr: LayoutRepr::Union(union_layout).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
})
|
||||
};
|
||||
|
@ -4441,7 +4463,7 @@ pub(crate) fn list_layout_from_elem<'a>(
|
|||
};
|
||||
|
||||
let list_layout = env.cache.put_in(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::List(element_layout)),
|
||||
repr: LayoutRepr::Builtin(Builtin::List(element_layout)).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
});
|
||||
|
||||
|
@ -4595,8 +4617,12 @@ pub fn cmp_fields<'a, L: Ord, I>(
|
|||
where
|
||||
I: LayoutInterner<'a>,
|
||||
{
|
||||
let size1 = interner.get(layout1).alignment_bytes(interner, target_info);
|
||||
let size2 = interner.get(layout2).alignment_bytes(interner, target_info);
|
||||
let size1 = interner
|
||||
.get_repr(layout1)
|
||||
.alignment_bytes(interner, target_info);
|
||||
let size2 = interner
|
||||
.get_repr(layout2)
|
||||
.alignment_bytes(interner, target_info);
|
||||
|
||||
size2.cmp(&size1).then(label1.cmp(label2))
|
||||
}
|
||||
|
@ -4619,19 +4645,16 @@ mod test {
|
|||
|
||||
let a = &[Layout::UNIT] as &[_];
|
||||
let b = &[interner.insert(Layout {
|
||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
||||
repr: LayoutRepr::LambdaSet(lambda_set).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
})] as &[_];
|
||||
let tt = [a, b];
|
||||
|
||||
let layout = Layout {
|
||||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(&tt)),
|
||||
semantic: SemanticRepr::NONE,
|
||||
};
|
||||
let repr = LayoutRepr::Union(UnionLayout::NonRecursive(&tt));
|
||||
|
||||
let target_info = TargetInfo::default_x86_64();
|
||||
assert_eq!(layout.stack_size(&interner, target_info), 1);
|
||||
assert_eq!(layout.alignment_bytes(&interner, target_info), 1);
|
||||
assert_eq!(repr.stack_size(&interner, target_info), 1);
|
||||
assert_eq!(repr.alignment_bytes(&interner, target_info), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -4639,29 +4662,28 @@ mod test {
|
|||
let mut interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
||||
|
||||
let ok_tag = &[interner.insert(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U32)),
|
||||
repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U32)).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
})];
|
||||
let err_tag = &[Layout::UNIT];
|
||||
let tags = [ok_tag as &[_], err_tag as &[_]];
|
||||
let union_layout = UnionLayout::NonRecursive(&tags as &[_]);
|
||||
let layout = Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
semantic: SemanticRepr::NONE,
|
||||
};
|
||||
let repr = LayoutRepr::Union(union_layout);
|
||||
|
||||
let target_info = TargetInfo::default_x86_64();
|
||||
assert_eq!(
|
||||
layout.stack_size_without_alignment(&interner, target_info),
|
||||
8
|
||||
);
|
||||
assert_eq!(repr.stack_size_without_alignment(&interner, target_info), 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn void_stack_size() {
|
||||
let interner = STLayoutInterner::with_capacity(4, TargetInfo::default_x86_64());
|
||||
let target_info = TargetInfo::default_x86_64();
|
||||
assert_eq!(Layout::VOID_NAKED.stack_size(&interner, target_info), 0);
|
||||
assert_eq!(
|
||||
Layout::VOID_NAKED
|
||||
.repr(&interner)
|
||||
.stack_size(&interner, target_info),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -14,7 +14,7 @@ use roc_target::TargetInfo;
|
|||
|
||||
use crate::layout::LayoutRepr;
|
||||
|
||||
use super::{LambdaSet, Layout, SeenRecPtrs, SemanticRepr, UnionLayout};
|
||||
use super::{LambdaSet, Layout, LayoutWrapper, SeenRecPtrs, SemanticRepr, UnionLayout};
|
||||
|
||||
macro_rules! cache_interned_layouts {
|
||||
($($i:literal, $name:ident, $vis:vis, $layout:expr)*; $total_constants:literal) => {
|
||||
|
@ -50,7 +50,7 @@ macro_rules! cache_interned_layouts {
|
|||
macro_rules! nosema {
|
||||
($r:expr) => {
|
||||
Layout {
|
||||
repr: $r,
|
||||
repr: $r.direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
}
|
||||
};
|
||||
|
@ -119,11 +119,11 @@ impl_to_from_int_width! {
|
|||
|
||||
impl<'a> Layout<'a> {
|
||||
pub(super) const VOID_NAKED: Self = Layout {
|
||||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(&[])),
|
||||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(&[])).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
};
|
||||
pub(super) const UNIT_NAKED: Self = Layout {
|
||||
repr: LayoutRepr::Struct(&[]),
|
||||
repr: LayoutRepr::Struct(&[]).direct(),
|
||||
semantic: SemanticRepr::EMPTY_RECORD,
|
||||
};
|
||||
|
||||
|
@ -154,8 +154,8 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
|
||||
/// Interns a value with no semantic representation, returning its interned representation.
|
||||
/// If the value has been interned before, the old interned representation will be re-used.
|
||||
fn insert_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
||||
self.insert(Layout::no_semantic(repr))
|
||||
fn insert_direct_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
||||
self.insert(Layout::no_semantic(repr.direct()))
|
||||
}
|
||||
|
||||
/// Creates a [LambdaSet], including caching the [LayoutRepr::LambdaSet] representation of the
|
||||
|
@ -181,8 +181,13 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
//
|
||||
// Convenience methods
|
||||
|
||||
fn get_repr(&self, key: InLayout<'a>) -> LayoutRepr<'a> {
|
||||
self.get(key).repr
|
||||
fn get_repr(&self, mut key: InLayout<'a>) -> LayoutRepr<'a> {
|
||||
loop {
|
||||
match self.get(key).repr {
|
||||
LayoutWrapper::Direct(repr) => return repr,
|
||||
LayoutWrapper::Newtype(inner) => key = inner,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_semantic(&self, key: InLayout<'a>) -> SemanticRepr<'a> {
|
||||
|
@ -196,38 +201,39 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
fn target_info(&self) -> TargetInfo;
|
||||
|
||||
fn alignment_bytes(&self, layout: InLayout<'a>) -> u32 {
|
||||
self.get(layout).alignment_bytes(self, self.target_info())
|
||||
self.get_repr(layout)
|
||||
.alignment_bytes(self, self.target_info())
|
||||
}
|
||||
|
||||
fn allocation_alignment_bytes(&self, layout: InLayout<'a>) -> u32 {
|
||||
self.get(layout)
|
||||
self.get_repr(layout)
|
||||
.allocation_alignment_bytes(self, self.target_info())
|
||||
}
|
||||
|
||||
fn stack_size(&self, layout: InLayout<'a>) -> u32 {
|
||||
self.get(layout).stack_size(self, self.target_info())
|
||||
self.get_repr(layout).stack_size(self, self.target_info())
|
||||
}
|
||||
|
||||
fn stack_size_and_alignment(&self, layout: InLayout<'a>) -> (u32, u32) {
|
||||
self.get(layout)
|
||||
self.get_repr(layout)
|
||||
.stack_size_and_alignment(self, self.target_info())
|
||||
}
|
||||
|
||||
fn stack_size_without_alignment(&self, layout: InLayout<'a>) -> u32 {
|
||||
self.get(layout)
|
||||
self.get_repr(layout)
|
||||
.stack_size_without_alignment(self, self.target_info())
|
||||
}
|
||||
|
||||
fn contains_refcounted(&self, layout: InLayout<'a>) -> bool {
|
||||
self.get(layout).contains_refcounted(self)
|
||||
self.get_repr(layout).contains_refcounted(self)
|
||||
}
|
||||
|
||||
fn is_refcounted(&self, layout: InLayout<'a>) -> bool {
|
||||
self.get(layout).is_refcounted()
|
||||
self.get_repr(layout).is_refcounted()
|
||||
}
|
||||
|
||||
fn is_passed_by_reference(&self, layout: InLayout<'a>) -> bool {
|
||||
self.get(layout)
|
||||
self.get_repr(layout)
|
||||
.is_passed_by_reference(self, self.target_info())
|
||||
}
|
||||
|
||||
|
@ -239,6 +245,10 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
Layout::runtime_representation_in(layout, self)
|
||||
}
|
||||
|
||||
fn has_varying_stack_size(&self, layout: InLayout<'a>, arena: &'a Bump) -> bool {
|
||||
self.get_repr(layout).has_varying_stack_size(self, arena)
|
||||
}
|
||||
|
||||
fn chase_recursive(&self, mut layout: InLayout<'a>) -> LayoutRepr<'a> {
|
||||
loop {
|
||||
let lay = self.get_repr(layout);
|
||||
|
@ -251,7 +261,7 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
|
||||
fn chase_recursive_in(&self, mut layout: InLayout<'a>) -> InLayout<'a> {
|
||||
loop {
|
||||
match self.get(layout).repr {
|
||||
match self.get_repr(layout) {
|
||||
LayoutRepr::RecursivePointer(l) => layout = l,
|
||||
_ => return layout,
|
||||
}
|
||||
|
@ -259,7 +269,7 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
}
|
||||
|
||||
fn safe_to_memcpy(&self, layout: InLayout<'a>) -> bool {
|
||||
self.get(layout).safe_to_memcpy(self)
|
||||
self.get_repr(layout).safe_to_memcpy(self)
|
||||
}
|
||||
|
||||
/// Checks if two layouts are equivalent up to isomorphism.
|
||||
|
@ -306,7 +316,7 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
{
|
||||
use LayoutRepr::*;
|
||||
|
||||
match self.get(layout).repr {
|
||||
match self.get_repr(layout) {
|
||||
Builtin(builtin) => builtin.to_doc(alloc, self, seen_rec, parens),
|
||||
Struct(field_layouts) => {
|
||||
let fields_doc = field_layouts
|
||||
|
@ -673,7 +683,7 @@ impl<'a> GlobalLayoutInterner<'a> {
|
|||
..normalized
|
||||
};
|
||||
let lambda_set_layout = Layout {
|
||||
repr: LayoutRepr::LambdaSet(full_lambda_set),
|
||||
repr: LayoutRepr::LambdaSet(full_lambda_set).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
};
|
||||
|
||||
|
@ -982,7 +992,7 @@ macro_rules! st_impl {
|
|||
full_layout: slot,
|
||||
};
|
||||
let lay = Layout {
|
||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
||||
repr: LayoutRepr::LambdaSet(lambda_set).direct(),
|
||||
semantic: SemanticRepr::NONE
|
||||
};
|
||||
self.vec[slot.0] = lay;
|
||||
|
@ -1054,7 +1064,8 @@ mod reify {
|
|||
slot: InLayout<'a>,
|
||||
normalized_layout: Layout<'a>,
|
||||
) -> Layout<'a> {
|
||||
let repr = match normalized_layout.repr {
|
||||
// TODO: what if the layout repr is a newtype - should we preserve all the links?
|
||||
let repr = match normalized_layout.repr(interner) {
|
||||
LayoutRepr::Builtin(builtin) => {
|
||||
LayoutRepr::Builtin(reify_builtin(arena, interner, slot, builtin))
|
||||
}
|
||||
|
@ -1073,7 +1084,7 @@ mod reify {
|
|||
}
|
||||
};
|
||||
Layout {
|
||||
repr,
|
||||
repr: repr.direct(),
|
||||
semantic: normalized_layout.semantic,
|
||||
}
|
||||
}
|
||||
|
@ -1252,7 +1263,7 @@ mod equiv {
|
|||
continue;
|
||||
}
|
||||
use LayoutRepr::*;
|
||||
match (interner.get(l1).repr, interner.get(l2).repr) {
|
||||
match (interner.get_repr(l1), interner.get_repr(l2)) {
|
||||
(RecursivePointer(rec), _) => stack.push((rec, l2)),
|
||||
(_, RecursivePointer(rec)) => stack.push((l1, rec)),
|
||||
(Builtin(b1), Builtin(b2)) => {
|
||||
|
@ -1348,7 +1359,7 @@ mod equiv {
|
|||
pub mod dbg {
|
||||
use roc_module::symbol::Symbol;
|
||||
|
||||
use crate::layout::{Builtin, LambdaSet, Layout, LayoutRepr, UnionLayout};
|
||||
use crate::layout::{Builtin, LambdaSet, LayoutRepr, UnionLayout};
|
||||
|
||||
use super::{InLayout, LayoutInterner};
|
||||
|
||||
|
@ -1356,7 +1367,8 @@ pub mod dbg {
|
|||
|
||||
impl<'a, 'r, I: LayoutInterner<'a>> std::fmt::Debug for Dbg<'a, 'r, I> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Layout { repr, semantic } = self.0.get(self.1);
|
||||
let repr = self.0.get_repr(self.1);
|
||||
let semantic = self.0.get_semantic(self.1);
|
||||
|
||||
f.debug_struct("Layout")
|
||||
.field("repr", &DbgRepr(self.0, &repr))
|
||||
|
@ -1552,7 +1564,7 @@ mod insert_lambda_set {
|
|||
let lambda_set =
|
||||
interner.insert_lambda_set(arena, TEST_ARGS, TEST_RET, TEST_SET, FIXUP, Layout::UNIT);
|
||||
let lambda_set_layout_in = interner.insert(Layout {
|
||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
||||
repr: LayoutRepr::LambdaSet(lambda_set).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
});
|
||||
assert_eq!(lambda_set.full_layout, lambda_set_layout_in);
|
||||
|
@ -1611,15 +1623,16 @@ mod insert_recursive_layout {
|
|||
|
||||
fn make_layout<'a>(arena: &'a Bump, interner: &mut impl LayoutInterner<'a>) -> Layout<'a> {
|
||||
let list_rec = Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::List(Layout::NAKED_RECURSIVE_PTR)),
|
||||
repr: LayoutRepr::Builtin(Builtin::List(Layout::NAKED_RECURSIVE_PTR)).direct(),
|
||||
semantic: SemanticRepr::NONE,
|
||||
};
|
||||
let repr = LayoutRepr::Union(UnionLayout::Recursive(&*arena.alloc([
|
||||
&*arena.alloc([interner.insert(list_rec)]),
|
||||
&*arena.alloc_slice_fill_iter([interner.insert_no_semantic(LayoutRepr::struct_(
|
||||
&*arena.alloc([Layout::NAKED_RECURSIVE_PTR]),
|
||||
))]),
|
||||
])));
|
||||
&*arena.alloc_slice_fill_iter([interner.insert_direct_no_semantic(
|
||||
LayoutRepr::struct_(&*arena.alloc([Layout::NAKED_RECURSIVE_PTR])),
|
||||
)]),
|
||||
])))
|
||||
.direct();
|
||||
Layout {
|
||||
repr,
|
||||
semantic: SemanticRepr::NONE,
|
||||
|
@ -1629,9 +1642,9 @@ mod insert_recursive_layout {
|
|||
fn get_rec_ptr_index<'a>(interner: &impl LayoutInterner<'a>, layout: InLayout<'a>) -> usize {
|
||||
match interner.chase_recursive(layout) {
|
||||
LayoutRepr::Union(UnionLayout::Recursive(&[&[l1], &[l2]])) => {
|
||||
match (interner.get(l1).repr, interner.get(l2).repr) {
|
||||
match (interner.get_repr(l1), interner.get_repr(l2)) {
|
||||
(LayoutRepr::Builtin(Builtin::List(l1)), LayoutRepr::Struct(&[l2])) => {
|
||||
match (interner.get(l1).repr, interner.get(l2).repr) {
|
||||
match (interner.get_repr(l1), interner.get_repr(l2)) {
|
||||
(
|
||||
LayoutRepr::RecursivePointer(i1),
|
||||
LayoutRepr::RecursivePointer(i2),
|
||||
|
|
|
@ -25,7 +25,7 @@ fn width_and_alignment_u8_u8() {
|
|||
let t = &[Layout::U8] as &[_];
|
||||
let tt = [t, t];
|
||||
|
||||
let layout = Layout::no_semantic(LayoutRepr::Union(UnionLayout::NonRecursive(&tt)));
|
||||
let layout = LayoutRepr::Union(UnionLayout::NonRecursive(&tt));
|
||||
|
||||
assert_eq!(layout.alignment_bytes(&interner, target_info), 1);
|
||||
assert_eq!(layout.stack_size(&interner, target_info), 2);
|
||||
|
|
|
@ -416,7 +416,10 @@ pub fn load_types(
|
|||
|
||||
let layout = layout_cache.interner.get(in_layout);
|
||||
|
||||
if layout.has_varying_stack_size(&layout_cache.interner, arena) {
|
||||
if layout_cache
|
||||
.interner
|
||||
.has_varying_stack_size(in_layout, arena)
|
||||
{
|
||||
let ident_ids = interns.all_ident_ids.get_mut(&home).unwrap();
|
||||
let answer = generate_glue_procs(
|
||||
home,
|
||||
|
|
|
@ -1840,7 +1840,10 @@ where
|
|||
let layout = env.layout_cache.interner.get(in_layout);
|
||||
let struct_fields = match env.glue_procs_by_layout.get(&layout) {
|
||||
Some(&glue_procs) => {
|
||||
debug_assert!(layout.has_varying_stack_size(&env.layout_cache.interner, arena));
|
||||
debug_assert!(env
|
||||
.layout_cache
|
||||
.interner
|
||||
.has_varying_stack_size(in_layout, arena));
|
||||
|
||||
let fields: Vec<(String, TypeId, Accessors)> = sortables
|
||||
.into_iter()
|
||||
|
@ -2226,7 +2229,9 @@ fn single_tag_payload_fields<'a, 'b>(
|
|||
// anyway just so we have some warning in case that relationship somehow didn't hold!
|
||||
debug_assert_eq!(
|
||||
env.glue_procs_by_layout.get(&layout).is_some(),
|
||||
layout.has_varying_stack_size(&env.layout_cache.interner, env.arena)
|
||||
env.layout_cache
|
||||
.interner
|
||||
.has_varying_stack_size(in_layout, env.arena)
|
||||
);
|
||||
|
||||
let (tag_name, payload_vars) = single_tag_payload(union_tags, subs);
|
||||
|
@ -2307,7 +2312,7 @@ fn struct_fields_needed<I: IntoIterator<Item = Variable>>(env: &mut Env<'_>, var
|
|||
vars.into_iter().fold(0, |count, var| {
|
||||
let layout = env.layout_cache.from_var(arena, var, subs).unwrap();
|
||||
|
||||
if env.layout_cache.get_in(layout).is_dropped_because_empty() {
|
||||
if env.layout_cache.get_repr(layout).is_dropped_because_empty() {
|
||||
count
|
||||
} else {
|
||||
count + 1
|
||||
|
|
|
@ -475,7 +475,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
|||
env,
|
||||
mem,
|
||||
addr,
|
||||
layout,
|
||||
env.layout_cache.get_repr(layout),
|
||||
WhenRecursive::Unreachable,
|
||||
env.subs.get_root_key_without_compacting(raw_var),
|
||||
)
|
||||
|
@ -496,7 +496,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
|||
env,
|
||||
mem,
|
||||
addr,
|
||||
layout,
|
||||
env.layout_cache.get_repr(layout),
|
||||
WhenRecursive::Loop(layout),
|
||||
env.subs.get_root_key_without_compacting(raw_var),
|
||||
)
|
||||
|
@ -515,7 +515,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
|||
env,
|
||||
mem,
|
||||
addr,
|
||||
layout,
|
||||
env.layout_cache.get_repr(layout),
|
||||
WhenRecursive::Unreachable,
|
||||
env.subs.get_root_key_without_compacting(raw_var),
|
||||
)
|
||||
|
@ -542,7 +542,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
env: &mut Env<'a, '_>,
|
||||
mem: &'a M,
|
||||
addr: usize,
|
||||
layout: InLayout<'a>,
|
||||
layout: LayoutRepr<'a>,
|
||||
when_recursive: WhenRecursive<'a>,
|
||||
var: Variable,
|
||||
) -> Expr<'a> {
|
||||
|
@ -557,7 +557,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
let (newtype_containers, _alias_content, raw_var) = unroll_newtypes_and_aliases(env, var);
|
||||
let raw_content = env.subs.get_content_without_compacting(raw_var);
|
||||
|
||||
let expr = match (raw_content, env.layout_cache.get_repr(layout)) {
|
||||
let expr = match (raw_content, layout) {
|
||||
(Content::Structure(FlatType::Func(_, _, _)), _) | (_, LayoutRepr::LambdaSet(_)) => {
|
||||
OPAQUE_FUNCTION
|
||||
}
|
||||
|
@ -650,7 +650,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
},
|
||||
WhenRecursive::Loop(union_layout),
|
||||
) => {
|
||||
addr_to_ast(env, mem, addr, union_layout, when_recursive, *structure)
|
||||
addr_to_ast(env, mem, addr, env.layout_cache.get_repr(union_layout), when_recursive, *structure)
|
||||
}
|
||||
|
||||
(
|
||||
|
@ -667,7 +667,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
.expect("no layout for structure");
|
||||
debug_assert!(matches!(env.layout_cache.get_repr(union_layout), LayoutRepr::Union(..)));
|
||||
let when_recursive = WhenRecursive::Loop(union_layout);
|
||||
addr_to_ast(env, mem, addr, union_layout, when_recursive, *structure)
|
||||
addr_to_ast(env, mem, addr, env.layout_cache.get_repr(union_layout), when_recursive, *structure)
|
||||
}
|
||||
other => unreachable!("Something had a RecursivePointer layout, but instead of being a RecursionVar and having a known recursive layout, I found {:?}", other),
|
||||
},
|
||||
|
@ -873,7 +873,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
env,
|
||||
mem,
|
||||
addr_of_inner,
|
||||
inner_layout,
|
||||
env.layout_cache.get_repr(inner_layout),
|
||||
WhenRecursive::Unreachable,
|
||||
inner_var,
|
||||
);
|
||||
|
@ -930,7 +930,7 @@ fn list_to_ast<'a, M: ReplAppMemory>(
|
|||
env,
|
||||
mem,
|
||||
elem_addr,
|
||||
elem_layout,
|
||||
env.layout_cache.get_repr(elem_layout),
|
||||
WhenRecursive::Unreachable,
|
||||
elem_content,
|
||||
);
|
||||
|
@ -993,7 +993,14 @@ where
|
|||
let mut field_addr = addr;
|
||||
|
||||
for (var, layout) in sequence {
|
||||
let expr = addr_to_ast(env, mem, field_addr, *layout, when_recursive, var);
|
||||
let expr = addr_to_ast(
|
||||
env,
|
||||
mem,
|
||||
field_addr,
|
||||
env.layout_cache.get_repr(*layout),
|
||||
when_recursive,
|
||||
var,
|
||||
);
|
||||
let loc_expr = Loc::at_zero(expr);
|
||||
|
||||
output.push(&*arena.alloc(loc_expr));
|
||||
|
@ -1029,9 +1036,7 @@ fn struct_to_ast<'a, M: ReplAppMemory>(
|
|||
.unwrap();
|
||||
let inner_layouts = arena.alloc([field_layout]);
|
||||
|
||||
let struct_layout = env
|
||||
.layout_cache
|
||||
.put_in_no_semantic(LayoutRepr::struct_(inner_layouts));
|
||||
let struct_layout = LayoutRepr::struct_(inner_layouts);
|
||||
let loc_expr = &*arena.alloc(Loc {
|
||||
value: addr_to_ast(
|
||||
env,
|
||||
|
@ -1094,7 +1099,7 @@ fn struct_to_ast<'a, M: ReplAppMemory>(
|
|||
env,
|
||||
mem,
|
||||
field_addr,
|
||||
field_layout,
|
||||
env.layout_cache.get_repr(field_layout),
|
||||
WhenRecursive::Unreachable,
|
||||
field_var,
|
||||
),
|
||||
|
@ -1175,7 +1180,7 @@ fn struct_to_ast_tuple<'a, M: ReplAppMemory>(
|
|||
env,
|
||||
mem,
|
||||
field_addr,
|
||||
elem_layout,
|
||||
env.layout_cache.get_repr(elem_layout),
|
||||
WhenRecursive::Unreachable,
|
||||
elem_var,
|
||||
),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue