mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Convert LayoutRepr::Struct into a tuple variant
This commit is contained in:
parent
a6bda6eccf
commit
a67c148be7
24 changed files with 85 additions and 128 deletions
|
@ -1112,7 +1112,7 @@ fn lowlevel_spec<'a>(
|
||||||
|
|
||||||
// depending on the types, the list or value will come first in the struct
|
// depending on the types, the list or value will come first in the struct
|
||||||
let fields = match interner.get(layout).repr {
|
let fields = match interner.get(layout).repr {
|
||||||
LayoutRepr::Struct { field_layouts, .. } => field_layouts,
|
LayoutRepr::Struct(field_layouts) => field_layouts,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1541,9 +1541,7 @@ fn layout_spec_help<'a>(
|
||||||
|
|
||||||
match interner.get(layout).repr {
|
match interner.get(layout).repr {
|
||||||
Builtin(builtin) => builtin_spec(env, builder, interner, &builtin),
|
Builtin(builtin) => builtin_spec(env, builder, interner, &builtin),
|
||||||
Struct { field_layouts, .. } => {
|
Struct(field_layouts) => build_recursive_tuple_type(env, builder, interner, field_layouts),
|
||||||
build_recursive_tuple_type(env, builder, interner, field_layouts)
|
|
||||||
}
|
|
||||||
LambdaSet(lambda_set) => {
|
LambdaSet(lambda_set) => {
|
||||||
layout_spec_help(env, builder, interner, lambda_set.runtime_representation())
|
layout_spec_help(env, builder, interner, lambda_set.runtime_representation())
|
||||||
}
|
}
|
||||||
|
|
|
@ -2261,16 +2261,15 @@ impl<
|
||||||
.storage_manager
|
.storage_manager
|
||||||
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
.claim_stack_area(dst, self.layout_interner.stack_size(*ret_layout));
|
||||||
|
|
||||||
let ret_fields = if let LayoutRepr::Struct { field_layouts, .. } =
|
let ret_fields =
|
||||||
self.layout_interner.get(*ret_layout).repr
|
if let LayoutRepr::Struct(field_layouts) = self.layout_interner.get(*ret_layout).repr {
|
||||||
{
|
field_layouts
|
||||||
field_layouts
|
} else {
|
||||||
} else {
|
internal_error!(
|
||||||
internal_error!(
|
"Expected replace to return a struct instead found: {:?}",
|
||||||
"Expected replace to return a struct instead found: {:?}",
|
ret_layout
|
||||||
ret_layout
|
)
|
||||||
)
|
};
|
||||||
};
|
|
||||||
|
|
||||||
// Only return list and old element.
|
// Only return list and old element.
|
||||||
debug_assert_eq!(ret_fields.len(), 2);
|
debug_assert_eq!(ret_fields.len(), 2);
|
||||||
|
|
|
@ -674,7 +674,7 @@ impl<
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let LayoutRepr::Struct { field_layouts, .. } = layout {
|
if let LayoutRepr::Struct(field_layouts) = layout {
|
||||||
let mut current_offset = base_offset;
|
let mut current_offset = base_offset;
|
||||||
for (field, field_layout) in fields.iter().zip(field_layouts.iter()) {
|
for (field, field_layout) in fields.iter().zip(field_layouts.iter()) {
|
||||||
self.copy_symbol_to_stack_offset(
|
self.copy_symbol_to_stack_offset(
|
||||||
|
|
|
@ -1481,7 +1481,7 @@ trait Backend<'a> {
|
||||||
),
|
),
|
||||||
LowLevel::StrToNum => {
|
LowLevel::StrToNum => {
|
||||||
let number_layout = match self.interner().get(*ret_layout).repr {
|
let number_layout = match self.interner().get(*ret_layout).repr {
|
||||||
LayoutRepr::Struct { field_layouts, .. } => field_layouts[0], // TODO: why is it sometimes a struct?
|
LayoutRepr::Struct(field_layouts) => field_layouts[0], // TODO: why is it sometimes a struct?
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -611,9 +611,7 @@ pub fn build_compare_wrapper<'a, 'ctx>(
|
||||||
let closure_data_repr = closure_data_layout.runtime_representation();
|
let closure_data_repr = closure_data_layout.runtime_representation();
|
||||||
|
|
||||||
let arguments_cast = match layout_interner.get(closure_data_repr).repr {
|
let arguments_cast = match layout_interner.get(closure_data_repr).repr {
|
||||||
LayoutRepr::Struct {
|
LayoutRepr::Struct(&[]) => {
|
||||||
field_layouts: &[], ..
|
|
||||||
} => {
|
|
||||||
// nothing to add
|
// nothing to add
|
||||||
&default
|
&default
|
||||||
}
|
}
|
||||||
|
|
|
@ -1332,7 +1332,7 @@ pub fn build_exp_expr<'a, 'ctx>(
|
||||||
|
|
||||||
// extract field from a record
|
// extract field from a record
|
||||||
match (value, layout_interner.get(layout).repr) {
|
match (value, layout_interner.get(layout).repr) {
|
||||||
(StructValue(argument), LayoutRepr::Struct { field_layouts, .. }) => {
|
(StructValue(argument), LayoutRepr::Struct(field_layouts)) => {
|
||||||
debug_assert!(!field_layouts.is_empty());
|
debug_assert!(!field_layouts.is_empty());
|
||||||
|
|
||||||
let field_value = env
|
let field_value = env
|
||||||
|
|
|
@ -165,7 +165,7 @@ fn build_eq<'a, 'ctx>(
|
||||||
&builtin,
|
&builtin,
|
||||||
),
|
),
|
||||||
|
|
||||||
LayoutRepr::Struct { field_layouts, .. } => build_struct_eq(
|
LayoutRepr::Struct(field_layouts) => build_struct_eq(
|
||||||
env,
|
env,
|
||||||
layout_interner,
|
layout_interner,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
|
@ -353,7 +353,7 @@ fn build_neq<'a, 'ctx>(
|
||||||
&builtin,
|
&builtin,
|
||||||
),
|
),
|
||||||
|
|
||||||
LayoutRepr::Struct { field_layouts, .. } => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
let is_equal = build_struct_eq(
|
let is_equal = build_struct_eq(
|
||||||
env,
|
env,
|
||||||
layout_interner,
|
layout_interner,
|
||||||
|
|
|
@ -37,10 +37,7 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
|
|
||||||
match layout_interner.get(layout).repr {
|
match layout_interner.get(layout).repr {
|
||||||
Struct {
|
Struct(sorted_fields, ..) => basic_type_from_record(env, layout_interner, sorted_fields),
|
||||||
field_layouts: sorted_fields,
|
|
||||||
..
|
|
||||||
} => basic_type_from_record(env, layout_interner, sorted_fields),
|
|
||||||
LambdaSet(lambda_set) => {
|
LambdaSet(lambda_set) => {
|
||||||
basic_type_from_layout(env, layout_interner, lambda_set.runtime_representation())
|
basic_type_from_layout(env, layout_interner, lambda_set.runtime_representation())
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,7 +307,7 @@ fn build_clone<'a, 'ctx>(
|
||||||
builtin,
|
builtin,
|
||||||
),
|
),
|
||||||
|
|
||||||
LayoutRepr::Struct { field_layouts, .. } => build_clone_struct(
|
LayoutRepr::Struct(field_layouts) => build_clone_struct(
|
||||||
env,
|
env,
|
||||||
layout_interner,
|
layout_interner,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
|
|
|
@ -197,7 +197,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
arguments!(string);
|
arguments!(string);
|
||||||
|
|
||||||
let number_layout = match layout_interner.get(layout).repr {
|
let number_layout = match layout_interner.get(layout).repr {
|
||||||
LayoutRepr::Struct { field_layouts, .. } => field_layouts[0], // TODO: why is it sometimes a struct?
|
LayoutRepr::Struct(field_layouts) => field_layouts[0], // TODO: why is it sometimes a struct?
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2013,7 +2013,7 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
// return_layout : Result N [OutOfBounds]* ~ { result: N, out_of_bounds: bool }
|
// return_layout : Result N [OutOfBounds]* ~ { result: N, out_of_bounds: bool }
|
||||||
|
|
||||||
let target_int_width = match layout_interner.get(return_layout).repr {
|
let target_int_width = match layout_interner.get(return_layout).repr {
|
||||||
LayoutRepr::Struct { field_layouts, .. } if field_layouts.len() == 2 => {
|
LayoutRepr::Struct(field_layouts) if field_layouts.len() == 2 => {
|
||||||
debug_assert!(layout_interner.eq_repr(field_layouts[1], Layout::BOOL));
|
debug_assert!(layout_interner.eq_repr(field_layouts[1], Layout::BOOL));
|
||||||
field_layouts[0].to_int_width()
|
field_layouts[0].to_int_width()
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,7 +562,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Struct { field_layouts, .. } => {
|
Struct(field_layouts) => {
|
||||||
let function =
|
let function =
|
||||||
modify_refcount_struct(env, layout_interner, layout_ids, field_layouts, mode);
|
modify_refcount_struct(env, layout_interner, layout_ids, field_layouts, mode);
|
||||||
|
|
||||||
|
|
|
@ -560,10 +560,7 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
// one-element struct.
|
// one-element struct.
|
||||||
let inner_closure_data_layout = match self.layout_interner.get(closure_data_layout).repr
|
let inner_closure_data_layout = match self.layout_interner.get(closure_data_layout).repr
|
||||||
{
|
{
|
||||||
LayoutRepr::Struct {
|
LayoutRepr::Struct([inner]) => inner,
|
||||||
field_layouts: [inner],
|
|
||||||
..
|
|
||||||
} => inner,
|
|
||||||
other => internal_error!(
|
other => internal_error!(
|
||||||
"Expected a boxed layout for wrapped closure data, got {:?}",
|
"Expected a boxed layout for wrapped closure data, got {:?}",
|
||||||
other
|
other
|
||||||
|
|
|
@ -238,7 +238,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
StrGetCapacity => self.load_args_and_call_zig(backend, bitcode::STR_CAPACITY),
|
StrGetCapacity => self.load_args_and_call_zig(backend, bitcode::STR_CAPACITY),
|
||||||
StrToNum => {
|
StrToNum => {
|
||||||
let number_layout = match backend.layout_interner.get(self.ret_layout).repr {
|
let number_layout = match backend.layout_interner.get(self.ret_layout).repr {
|
||||||
LayoutRepr::Struct { field_layouts, .. } => field_layouts[0],
|
LayoutRepr::Struct(field_layouts) => field_layouts[0],
|
||||||
_ => {
|
_ => {
|
||||||
internal_error!("Unexpected mono layout {:?} for StrToNum", self.ret_layout)
|
internal_error!("Unexpected mono layout {:?} for StrToNum", self.ret_layout)
|
||||||
}
|
}
|
||||||
|
@ -390,10 +390,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
// Byte offsets of each field in the return struct
|
// Byte offsets of each field in the return struct
|
||||||
let (ret_list_offset, ret_elem_offset, elem_layout) = match self.ret_layout_raw.repr
|
let (ret_list_offset, ret_elem_offset, elem_layout) = match self.ret_layout_raw.repr
|
||||||
{
|
{
|
||||||
LayoutRepr::Struct {
|
LayoutRepr::Struct(&[f1, f2]) => {
|
||||||
field_layouts: &[f1, f2],
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
let l1 = backend.layout_interner.get(f1);
|
let l1 = backend.layout_interner.get(f1);
|
||||||
let l2 = backend.layout_interner.get(f2);
|
let l2 = backend.layout_interner.get(f2);
|
||||||
match (l1.repr, l2.repr) {
|
match (l1.repr, l2.repr) {
|
||||||
|
@ -693,12 +690,9 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
// The refcount function receives a pointer to an element in the list
|
// The refcount function receives a pointer to an element in the list
|
||||||
// This is the same as a Struct containing the element
|
// This is the same as a Struct containing the element
|
||||||
let in_memory_layout =
|
let in_memory_layout = backend
|
||||||
backend
|
.layout_interner
|
||||||
.layout_interner
|
.insert_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([elem_layout])));
|
||||||
.insert_no_semantic(LayoutRepr::Struct {
|
|
||||||
field_layouts: backend.env.arena.alloc([elem_layout]),
|
|
||||||
});
|
|
||||||
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
||||||
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
||||||
|
|
||||||
|
@ -741,12 +735,9 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
// The refcount function receives a pointer to an element in the list
|
// The refcount function receives a pointer to an element in the list
|
||||||
// This is the same as a Struct containing the element
|
// This is the same as a Struct containing the element
|
||||||
let in_memory_layout =
|
let in_memory_layout = backend
|
||||||
backend
|
.layout_interner
|
||||||
.layout_interner
|
.insert_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([elem_layout])));
|
||||||
.insert_no_semantic(LayoutRepr::Struct {
|
|
||||||
field_layouts: backend.env.arena.alloc([elem_layout]),
|
|
||||||
});
|
|
||||||
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
let dec_fn = backend.get_refcount_fn_index(in_memory_layout, HelperOp::Dec);
|
||||||
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
let dec_fn_ptr = backend.get_fn_ptr(dec_fn);
|
||||||
|
|
||||||
|
@ -1909,10 +1900,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
LayoutRepr::Builtin(Builtin::Int(arg_width)),
|
LayoutRepr::Builtin(Builtin::Int(arg_width)),
|
||||||
LayoutRepr::Struct {
|
LayoutRepr::Struct(&[ret, ..]),
|
||||||
field_layouts: &[ret, ..],
|
|
||||||
..
|
|
||||||
},
|
|
||||||
) => match backend.layout_interner.get(ret).repr {
|
) => match backend.layout_interner.get(ret).repr {
|
||||||
LayoutRepr::Builtin(Builtin::Int(ret_width)) => (arg_width, ret_width),
|
LayoutRepr::Builtin(Builtin::Int(ret_width)) => (arg_width, ret_width),
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -2029,7 +2017,7 @@ impl<'a> LowLevelCall<'a> {
|
||||||
|
|
||||||
// Empty record is always equal to empty record.
|
// Empty record is always equal to empty record.
|
||||||
// There are no runtime arguments to check, so just emit true or false.
|
// There are no runtime arguments to check, so just emit true or false.
|
||||||
LayoutRepr::Struct { field_layouts, .. } if field_layouts.is_empty() => {
|
LayoutRepr::Struct(field_layouts) if field_layouts.is_empty() => {
|
||||||
backend.code_builder.i32_const(!invert_result as i32);
|
backend.code_builder.i32_const(!invert_result as i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2378,9 +2366,7 @@ pub fn call_higher_order_lowlevel<'a>(
|
||||||
(Layout::UNIT, false)
|
(Layout::UNIT, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LayoutRepr::Struct {
|
LayoutRepr::Struct(&[]) => (Layout::UNIT, false),
|
||||||
field_layouts: &[], ..
|
|
||||||
} => (Layout::UNIT, false),
|
|
||||||
x => internal_error!("Closure data has an invalid layout\n{:?}", x),
|
x => internal_error!("Closure data has an invalid layout\n{:?}", x),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2673,9 +2659,7 @@ fn list_map_n<'a>(
|
||||||
// Here we wrap the layout in a Struct to ensure we get the right code gen
|
// Here we wrap the layout in a Struct to ensure we get the right code gen
|
||||||
let el_ptr = backend
|
let el_ptr = backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Struct {
|
.insert_no_semantic(LayoutRepr::Struct(backend.env.arena.alloc([*el])));
|
||||||
field_layouts: backend.env.arena.alloc([*el]),
|
|
||||||
});
|
|
||||||
let idx = backend.get_refcount_fn_index(el_ptr, HelperOp::Dec);
|
let idx = backend.get_refcount_fn_index(el_ptr, HelperOp::Dec);
|
||||||
let ptr = backend.get_fn_ptr(idx);
|
let ptr = backend.get_fn_ptr(idx);
|
||||||
backend.code_builder.i32_const(ptr);
|
backend.code_builder.i32_const(ptr);
|
||||||
|
@ -2714,9 +2698,7 @@ fn ensure_symbol_is_in_memory<'a>(
|
||||||
);
|
);
|
||||||
let in_memory_layout = backend
|
let in_memory_layout = backend
|
||||||
.layout_interner
|
.layout_interner
|
||||||
.insert_no_semantic(LayoutRepr::Struct {
|
.insert_no_semantic(LayoutRepr::Struct(arena.alloc([layout])));
|
||||||
field_layouts: arena.alloc([layout]),
|
|
||||||
});
|
|
||||||
(frame_ptr, offset, in_memory_layout)
|
(frame_ptr, offset, in_memory_layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,7 @@ pub fn eq_generic<'a>(
|
||||||
unreachable!("No generated helper proc for `==` on Str. Use Zig function.")
|
unreachable!("No generated helper proc for `==` on Str. Use Zig function.")
|
||||||
}
|
}
|
||||||
Builtin(List(elem_layout)) => eq_list(root, ident_ids, ctx, layout_interner, elem_layout),
|
Builtin(List(elem_layout)) => eq_list(root, ident_ids, ctx, layout_interner, elem_layout),
|
||||||
Struct { field_layouts, .. } => {
|
Struct(field_layouts) => eq_struct(root, ident_ids, ctx, layout_interner, field_layouts),
|
||||||
eq_struct(root, ident_ids, ctx, layout_interner, field_layouts)
|
|
||||||
}
|
|
||||||
Union(union_layout) => eq_tag_union(root, ident_ids, ctx, layout_interner, union_layout),
|
Union(union_layout) => eq_tag_union(root, ident_ids, ctx, layout_interner, union_layout),
|
||||||
Boxed(inner_layout) => eq_boxed(root, ident_ids, ctx, layout_interner, inner_layout),
|
Boxed(inner_layout) => eq_boxed(root, ident_ids, ctx, layout_interner, inner_layout),
|
||||||
LambdaSet(_) => unreachable!("`==` is not defined on functions"),
|
LambdaSet(_) => unreachable!("`==` is not defined on functions"),
|
||||||
|
|
|
@ -541,14 +541,12 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
|
|
||||||
LayoutRepr::Builtin(_) => return layout,
|
LayoutRepr::Builtin(_) => return layout,
|
||||||
|
|
||||||
LayoutRepr::Struct { field_layouts } => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
let mut new_field_layouts = Vec::with_capacity_in(field_layouts.len(), self.arena);
|
let mut new_field_layouts = Vec::with_capacity_in(field_layouts.len(), self.arena);
|
||||||
for f in field_layouts.iter() {
|
for f in field_layouts.iter() {
|
||||||
new_field_layouts.push(self.replace_rec_ptr(ctx, layout_interner, *f));
|
new_field_layouts.push(self.replace_rec_ptr(ctx, layout_interner, *f));
|
||||||
}
|
}
|
||||||
LayoutRepr::Struct {
|
LayoutRepr::Struct(new_field_layouts.into_bump_slice())
|
||||||
field_layouts: new_field_layouts.into_bump_slice(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutRepr::Union(UnionLayout::NonRecursive(tags)) => {
|
LayoutRepr::Union(UnionLayout::NonRecursive(tags)) => {
|
||||||
|
|
|
@ -199,7 +199,7 @@ pub fn refcount_generic<'a>(
|
||||||
elem_layout,
|
elem_layout,
|
||||||
structure,
|
structure,
|
||||||
),
|
),
|
||||||
LayoutRepr::Struct { field_layouts, .. } => refcount_struct(
|
LayoutRepr::Struct(field_layouts) => refcount_struct(
|
||||||
root,
|
root,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
ctx,
|
ctx,
|
||||||
|
|
|
@ -495,7 +495,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
self.with_sym_layout(structure, |ctx, def_line, layout| {
|
self.with_sym_layout(structure, |ctx, def_line, layout| {
|
||||||
let layout = ctx.resolve(layout);
|
let layout = ctx.resolve(layout);
|
||||||
match ctx.interner.get(layout).repr {
|
match ctx.interner.get(layout).repr {
|
||||||
LayoutRepr::Struct { field_layouts, .. } => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
if index as usize >= field_layouts.len() {
|
if index as usize >= field_layouts.len() {
|
||||||
ctx.problem(ProblemKind::StructIndexOOB {
|
ctx.problem(ProblemKind::StructIndexOOB {
|
||||||
structure,
|
structure,
|
||||||
|
|
|
@ -336,7 +336,7 @@ fn specialize_drops_stmt<'a, 'i>(
|
||||||
|
|
||||||
let new_dec = match runtime_layout.repr {
|
let new_dec = match runtime_layout.repr {
|
||||||
// Layout has children, try to inline them.
|
// Layout has children, try to inline them.
|
||||||
LayoutRepr::Struct { field_layouts, .. } => specialize_struct(
|
LayoutRepr::Struct(field_layouts) => specialize_struct(
|
||||||
arena,
|
arena,
|
||||||
layout_interner,
|
layout_interner,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
|
|
|
@ -4981,7 +4981,7 @@ pub fn with_hole<'a>(
|
||||||
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
||||||
|
|
||||||
let field_layouts = match layout_cache.get_in(record_layout).repr {
|
let field_layouts = match layout_cache.get_in(record_layout).repr {
|
||||||
LayoutRepr::Struct { field_layouts, .. } => field_layouts,
|
LayoutRepr::Struct(field_layouts) => field_layouts,
|
||||||
_ => arena.alloc([record_layout]),
|
_ => arena.alloc([record_layout]),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9061,7 +9061,7 @@ fn match_on_lambda_set<'a>(
|
||||||
env.arena.alloc(result),
|
env.arena.alloc(result),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ClosureCallOptions::Struct { field_layouts } => {
|
ClosureCallOptions::Struct(field_layouts) => {
|
||||||
let function_symbol = match lambda_set.iter_set().next() {
|
let function_symbol = match lambda_set.iter_set().next() {
|
||||||
Some(function_symbol) => function_symbol,
|
Some(function_symbol) => function_symbol,
|
||||||
None => {
|
None => {
|
||||||
|
@ -9726,7 +9726,7 @@ where
|
||||||
| Builtin::Str => { /* do nothing */ }
|
| Builtin::Str => { /* do nothing */ }
|
||||||
Builtin::List(element) => stack.push(layout_interner.get(element)),
|
Builtin::List(element) => stack.push(layout_interner.get(element)),
|
||||||
},
|
},
|
||||||
LayoutRepr::Struct { field_layouts, .. } => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
if field_layouts.iter().any(|l| {
|
if field_layouts.iter().any(|l| {
|
||||||
layout_interner
|
layout_interner
|
||||||
.get(*l)
|
.get(*l)
|
||||||
|
@ -9825,7 +9825,7 @@ where
|
||||||
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
||||||
|
|
||||||
let field_layouts = match layout_interner.get(interned_unboxed_struct_layout).repr {
|
let field_layouts = match layout_interner.get(interned_unboxed_struct_layout).repr {
|
||||||
LayoutRepr::Struct { field_layouts, .. } => field_layouts,
|
LayoutRepr::Struct(field_layouts) => field_layouts,
|
||||||
other => {
|
other => {
|
||||||
unreachable!(
|
unreachable!(
|
||||||
"{:?} {:?}",
|
"{:?} {:?}",
|
||||||
|
|
|
@ -1014,13 +1014,7 @@ fn to_relevant_branch_help<'a>(
|
||||||
// the test matches the constructor of this pattern
|
// the test matches the constructor of this pattern
|
||||||
match layout {
|
match layout {
|
||||||
UnionLayout::NonRecursive([[arg]])
|
UnionLayout::NonRecursive([[arg]])
|
||||||
if matches!(
|
if matches!(interner.get(*arg).repr, LayoutRepr::Struct([_],)) =>
|
||||||
interner.get(*arg).repr,
|
|
||||||
LayoutRepr::Struct {
|
|
||||||
field_layouts: [_],
|
|
||||||
..
|
|
||||||
}
|
|
||||||
) =>
|
|
||||||
{
|
{
|
||||||
// a one-element record equivalent
|
// a one-element record equivalent
|
||||||
// Theory: Unbox doesn't have any value for us
|
// Theory: Unbox doesn't have any value for us
|
||||||
|
@ -1600,7 +1594,7 @@ fn path_to_expr_help<'a>(
|
||||||
layout = inner_layout;
|
layout = inner_layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutRepr::Struct { field_layouts, .. } => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
debug_assert!(field_layouts.len() > 1);
|
debug_assert!(field_layouts.len() > 1);
|
||||||
|
|
||||||
let inner_expr = Expr::StructAtIndex {
|
let inner_expr = Expr::StructAtIndex {
|
||||||
|
|
|
@ -664,7 +664,7 @@ pub struct Layout<'a> {
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub enum LayoutRepr<'a> {
|
pub enum LayoutRepr<'a> {
|
||||||
Builtin(Builtin<'a>),
|
Builtin(Builtin<'a>),
|
||||||
Struct { field_layouts: &'a [InLayout<'a>] },
|
Struct(&'a [InLayout<'a>]),
|
||||||
Boxed(InLayout<'a>),
|
Boxed(InLayout<'a>),
|
||||||
Union(UnionLayout<'a>),
|
Union(UnionLayout<'a>),
|
||||||
LambdaSet(LambdaSet<'a>),
|
LambdaSet(LambdaSet<'a>),
|
||||||
|
@ -1389,7 +1389,7 @@ pub enum ClosureCallOptions<'a> {
|
||||||
/// One of a few capturing functions can be called to
|
/// One of a few capturing functions can be called to
|
||||||
Union(UnionLayout<'a>),
|
Union(UnionLayout<'a>),
|
||||||
/// The closure is one function, whose captures are represented as a struct.
|
/// The closure is one function, whose captures are represented as a struct.
|
||||||
Struct { field_layouts: &'a [InLayout<'a>] },
|
Struct(&'a [InLayout<'a>]),
|
||||||
/// The closure is one function that captures a single identifier, whose value is unwrapped.
|
/// The closure is one function that captures a single identifier, whose value is unwrapped.
|
||||||
UnwrappedCapture(InLayout<'a>),
|
UnwrappedCapture(InLayout<'a>),
|
||||||
/// The closure dispatches to multiple possible functions, none of which capture.
|
/// The closure dispatches to multiple possible functions, none of which capture.
|
||||||
|
@ -1418,9 +1418,7 @@ impl<'a> LambdaSet<'a> {
|
||||||
} else {
|
} else {
|
||||||
let repr = self.representation;
|
let repr = self.representation;
|
||||||
match interner.get(repr).repr {
|
match interner.get(repr).repr {
|
||||||
LayoutRepr::Struct {
|
LayoutRepr::Struct(&[]) => None,
|
||||||
field_layouts: &[], ..
|
|
||||||
} => None,
|
|
||||||
_ => Some(repr),
|
_ => Some(repr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1670,9 +1668,9 @@ impl<'a> LambdaSet<'a> {
|
||||||
}
|
}
|
||||||
ClosureCallOptions::Union(union_layout)
|
ClosureCallOptions::Union(union_layout)
|
||||||
}
|
}
|
||||||
LayoutRepr::Struct { field_layouts } => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
debug_assert_eq!(self.set.len(), 1);
|
debug_assert_eq!(self.set.len(), 1);
|
||||||
ClosureCallOptions::Struct { field_layouts }
|
ClosureCallOptions::Struct(field_layouts)
|
||||||
}
|
}
|
||||||
layout => {
|
layout => {
|
||||||
debug_assert!(self.has_enum_dispatch_repr());
|
debug_assert!(self.has_enum_dispatch_repr());
|
||||||
|
@ -2524,7 +2522,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
pub const OPAQUE_PTR: Self = LayoutRepr::Boxed(Layout::VOID);
|
pub const OPAQUE_PTR: Self = LayoutRepr::Boxed(Layout::VOID);
|
||||||
|
|
||||||
pub const fn struct_(field_layouts: &'a [InLayout<'a>]) -> Self {
|
pub const fn struct_(field_layouts: &'a [InLayout<'a>]) -> Self {
|
||||||
Self::Struct { field_layouts }
|
Self::Struct(field_layouts)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn safe_to_memcpy<I>(&self, interner: &I) -> bool
|
pub fn safe_to_memcpy<I>(&self, interner: &I) -> bool
|
||||||
|
@ -2535,7 +2533,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Builtin(builtin) => builtin.safe_to_memcpy(),
|
Builtin(builtin) => builtin.safe_to_memcpy(),
|
||||||
Struct { field_layouts, .. } => field_layouts
|
Struct(field_layouts) => field_layouts
|
||||||
.iter()
|
.iter()
|
||||||
.all(|field_layout| interner.get(*field_layout).safe_to_memcpy(interner)),
|
.all(|field_layout| interner.get(*field_layout).safe_to_memcpy(interner)),
|
||||||
Union(variant) => {
|
Union(variant) => {
|
||||||
|
@ -2630,7 +2628,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Builtin(builtin) => builtin.stack_size(target_info),
|
Builtin(builtin) => builtin.stack_size(target_info),
|
||||||
Struct { field_layouts, .. } => {
|
Struct(field_layouts) => {
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
|
|
||||||
for field_layout in *field_layouts {
|
for field_layout in *field_layouts {
|
||||||
|
@ -2656,7 +2654,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
{
|
{
|
||||||
use LayoutRepr::*;
|
use LayoutRepr::*;
|
||||||
match self {
|
match self {
|
||||||
Struct { field_layouts, .. } => field_layouts
|
Struct(field_layouts) => field_layouts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| interner.get(*x).alignment_bytes(interner, target_info))
|
.map(|x| interner.get(*x).alignment_bytes(interner, target_info))
|
||||||
.max()
|
.max()
|
||||||
|
@ -2755,7 +2753,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Builtin(builtin) => builtin.is_refcounted(),
|
Builtin(builtin) => builtin.is_refcounted(),
|
||||||
Struct { field_layouts, .. } => field_layouts
|
Struct(field_layouts) => field_layouts
|
||||||
.iter()
|
.iter()
|
||||||
.any(|f| interner.get(*f).contains_refcounted(interner)),
|
.any(|f| interner.get(*f).contains_refcounted(interner)),
|
||||||
Union(variant) => {
|
Union(variant) => {
|
||||||
|
@ -2804,7 +2802,7 @@ impl<'a> LayoutRepr<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If there's any layer of indirection (behind a pointer), then it doesn't vary!
|
// If there's any layer of indirection (behind a pointer), then it doesn't vary!
|
||||||
Struct { field_layouts, .. } => stack.extend(
|
Struct(field_layouts) => stack.extend(
|
||||||
field_layouts
|
field_layouts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|interned| interner.get(*interned).repr),
|
.map(|interned| interner.get(*interned).repr),
|
||||||
|
@ -3244,9 +3242,7 @@ fn layout_from_flat_type<'a>(
|
||||||
} else {
|
} else {
|
||||||
let layouts = Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena);
|
let layouts = Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena);
|
||||||
let struct_layout = Layout {
|
let struct_layout = Layout {
|
||||||
repr: LayoutRepr::Struct {
|
repr: LayoutRepr::Struct(layouts.into_bump_slice()),
|
||||||
field_layouts: layouts.into_bump_slice(),
|
|
||||||
},
|
|
||||||
semantic: SemanticRepr::record(ordered_field_names.into_bump_slice()),
|
semantic: SemanticRepr::record(ordered_field_names.into_bump_slice()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3289,7 +3285,7 @@ fn layout_from_flat_type<'a>(
|
||||||
let field_layouts =
|
let field_layouts =
|
||||||
Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena).into_bump_slice();
|
Vec::from_iter_in(sortables.into_iter().map(|t| t.1), arena).into_bump_slice();
|
||||||
let struct_layout = Layout {
|
let struct_layout = Layout {
|
||||||
repr: LayoutRepr::Struct { field_layouts },
|
repr: LayoutRepr::Struct(field_layouts),
|
||||||
semantic: SemanticRepr::tuple(field_layouts.len()),
|
semantic: SemanticRepr::tuple(field_layouts.len()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ impl<'a> Layout<'a> {
|
||||||
semantic: SemanticRepr::NONE,
|
semantic: SemanticRepr::NONE,
|
||||||
};
|
};
|
||||||
pub(super) const UNIT_NAKED: Self = Layout {
|
pub(super) const UNIT_NAKED: Self = Layout {
|
||||||
repr: LayoutRepr::Struct { field_layouts: &[] },
|
repr: LayoutRepr::Struct(&[]),
|
||||||
semantic: SemanticRepr::EMPTY_RECORD,
|
semantic: SemanticRepr::EMPTY_RECORD,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ pub trait LayoutInterner<'a>: Sized {
|
||||||
|
|
||||||
match self.get(layout).repr {
|
match self.get(layout).repr {
|
||||||
Builtin(builtin) => builtin.to_doc(alloc, self, seen_rec, parens),
|
Builtin(builtin) => builtin.to_doc(alloc, self, seen_rec, parens),
|
||||||
Struct { field_layouts, .. } => {
|
Struct(field_layouts) => {
|
||||||
let fields_doc = field_layouts
|
let fields_doc = field_layouts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| self.to_doc(*x, alloc, seen_rec, parens));
|
.map(|x| self.to_doc(*x, alloc, seen_rec, parens));
|
||||||
|
@ -1050,9 +1050,9 @@ mod reify {
|
||||||
LayoutRepr::Builtin(builtin) => {
|
LayoutRepr::Builtin(builtin) => {
|
||||||
LayoutRepr::Builtin(reify_builtin(arena, interner, slot, builtin))
|
LayoutRepr::Builtin(reify_builtin(arena, interner, slot, builtin))
|
||||||
}
|
}
|
||||||
LayoutRepr::Struct { field_layouts } => LayoutRepr::Struct {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
field_layouts: reify_layout_slice(arena, interner, slot, field_layouts),
|
LayoutRepr::Struct(reify_layout_slice(arena, interner, slot, field_layouts))
|
||||||
},
|
}
|
||||||
LayoutRepr::Boxed(lay) => LayoutRepr::Boxed(reify_layout(arena, interner, slot, lay)),
|
LayoutRepr::Boxed(lay) => LayoutRepr::Boxed(reify_layout(arena, interner, slot, lay)),
|
||||||
LayoutRepr::Union(un) => LayoutRepr::Union(reify_union(arena, interner, slot, un)),
|
LayoutRepr::Union(un) => LayoutRepr::Union(reify_union(arena, interner, slot, un)),
|
||||||
LayoutRepr::LambdaSet(ls) => {
|
LayoutRepr::LambdaSet(ls) => {
|
||||||
|
@ -1258,7 +1258,7 @@ mod equiv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Struct { field_layouts: fl1 }, Struct { field_layouts: fl2 }) => {
|
(Struct(fl1), Struct(fl2)) => {
|
||||||
equiv_fields!(fl1, fl2)
|
equiv_fields!(fl1, fl2)
|
||||||
}
|
}
|
||||||
(Boxed(b1), Boxed(b2)) => stack.push((b1, b2)),
|
(Boxed(b1), Boxed(b2)) => stack.push((b1, b2)),
|
||||||
|
@ -1376,7 +1376,7 @@ pub mod dbg {
|
||||||
.debug_tuple("Builtin")
|
.debug_tuple("Builtin")
|
||||||
.field(&DbgBuiltin(self.0, *b))
|
.field(&DbgBuiltin(self.0, *b))
|
||||||
.finish(),
|
.finish(),
|
||||||
LayoutRepr::Struct { field_layouts } => f
|
LayoutRepr::Struct(field_layouts) => f
|
||||||
.debug_struct("Struct")
|
.debug_struct("Struct")
|
||||||
.field("fields", &DbgFields(self.0, field_layouts))
|
.field("fields", &DbgFields(self.0, field_layouts))
|
||||||
.finish(),
|
.finish(),
|
||||||
|
@ -1622,19 +1622,19 @@ mod insert_recursive_layout {
|
||||||
match interner.chase_recursive(layout).repr {
|
match interner.chase_recursive(layout).repr {
|
||||||
LayoutRepr::Union(UnionLayout::Recursive(&[&[l1], &[l2]])) => {
|
LayoutRepr::Union(UnionLayout::Recursive(&[&[l1], &[l2]])) => {
|
||||||
match (interner.get(l1).repr, interner.get(l2).repr) {
|
match (interner.get(l1).repr, interner.get(l2).repr) {
|
||||||
(
|
(LayoutRepr::Builtin(Builtin::List(l1)), LayoutRepr::Struct(&[l2])) => {
|
||||||
LayoutRepr::Builtin(Builtin::List(l1)),
|
match (interner.get(l1).repr, interner.get(l2).repr) {
|
||||||
LayoutRepr::Struct {
|
(
|
||||||
field_layouts: &[l2],
|
LayoutRepr::RecursivePointer(i1),
|
||||||
},
|
LayoutRepr::RecursivePointer(i2),
|
||||||
) => match (interner.get(l1).repr, interner.get(l2).repr) {
|
) => {
|
||||||
(LayoutRepr::RecursivePointer(i1), LayoutRepr::RecursivePointer(i2)) => {
|
assert_eq!(i1, i2);
|
||||||
assert_eq!(i1, i2);
|
assert_ne!(i1, Layout::VOID);
|
||||||
assert_ne!(i1, Layout::VOID);
|
i1.0
|
||||||
i1.0
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
}
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1691,7 +1691,7 @@ fn add_builtin_type<'a>(
|
||||||
env.subs.get_content_without_compacting(*alias_var),
|
env.subs.get_content_without_compacting(*alias_var),
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
LayoutRepr::Struct { field_layouts, .. },
|
LayoutRepr::Struct(field_layouts),
|
||||||
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, args_subs_slice)),
|
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, args_subs_slice)),
|
||||||
) => {
|
) => {
|
||||||
let (key_var, val_var) = {
|
let (key_var, val_var) = {
|
||||||
|
@ -1741,7 +1741,7 @@ fn add_builtin_type<'a>(
|
||||||
env.subs.get_content_without_compacting(*alias_var),
|
env.subs.get_content_without_compacting(*alias_var),
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
LayoutRepr::Struct { field_layouts, .. },
|
LayoutRepr::Struct(field_layouts),
|
||||||
Alias(Symbol::DICT_DICT, alias_args, _alias_var, AliasKind::Opaque),
|
Alias(Symbol::DICT_DICT, alias_args, _alias_var, AliasKind::Opaque),
|
||||||
) => {
|
) => {
|
||||||
let dict_type_vars = env.subs.get_subs_slice(alias_args.type_variables());
|
let dict_type_vars = env.subs.get_subs_slice(alias_args.type_variables());
|
||||||
|
@ -2058,7 +2058,7 @@ fn tag_union_type_from_layout<'a>(
|
||||||
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
|
||||||
add_int_enumeration(union_tags, subs, &name, int_width)
|
add_int_enumeration(union_tags, subs, &name, int_width)
|
||||||
}
|
}
|
||||||
LayoutRepr::Struct { field_layouts, .. } => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
let (tag_name, payload) =
|
let (tag_name, payload) =
|
||||||
single_tag_payload_fields(env, union_tags, subs, layout, field_layouts, types);
|
single_tag_payload_fields(env, union_tags, subs, layout, field_layouts, types);
|
||||||
|
|
||||||
|
|
|
@ -417,7 +417,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
LayoutRepr::Struct { field_layouts, .. } => {
|
LayoutRepr::Struct(field_layouts) => {
|
||||||
let fields = [Layout::U64, layout];
|
let fields = [Layout::U64, layout];
|
||||||
|
|
||||||
let result_stack_size = LayoutRepr::struct_(env.arena.alloc(fields))
|
let result_stack_size = LayoutRepr::struct_(env.arena.alloc(fields))
|
||||||
|
@ -615,7 +615,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
||||||
let arena_str = env.arena.alloc_str(string);
|
let arena_str = env.arena.alloc_str(string);
|
||||||
Expr::Str(StrLiteral::PlainLine(arena_str))
|
Expr::Str(StrLiteral::PlainLine(arena_str))
|
||||||
}
|
}
|
||||||
(_, LayoutRepr::Struct { field_layouts, .. }) => match raw_content {
|
(_, LayoutRepr::Struct (field_layouts)) => match raw_content {
|
||||||
Content::Structure(FlatType::Record(fields, _)) => {
|
Content::Structure(FlatType::Record(fields, _)) => {
|
||||||
struct_to_ast(env, mem, addr, *fields)
|
struct_to_ast(env, mem, addr, *fields)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue