remove dict/set layout

This commit is contained in:
Folkert 2022-07-13 11:41:19 +02:00
parent 5aef349f09
commit 4d55b756bb
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
16 changed files with 8 additions and 321 deletions

View file

@ -638,30 +638,6 @@ fn add_builtin_type<'a>(
(Builtin::Decimal, _) => types.add(RocType::Num(RocNum::Dec), layout), (Builtin::Decimal, _) => types.add(RocType::Num(RocNum::Dec), layout),
(Builtin::Bool, _) => types.add(RocType::Bool, layout), (Builtin::Bool, _) => types.add(RocType::Bool, layout),
(Builtin::Str, _) => types.add(RocType::RocStr, layout), (Builtin::Str, _) => types.add(RocType::RocStr, layout),
(Builtin::Dict(key_layout, val_layout), Structure(Apply(Symbol::DICT_DICT, args))) => {
let args = env.subs.get_subs_slice(*args);
debug_assert_eq!(args.len(), 2);
let key_id = add_type_help(env, *key_layout, args[0], opt_name, types);
let val_id = add_type_help(env, *val_layout, args[1], opt_name, types);
let dict_id = types.add(RocType::RocDict(key_id, val_id), layout);
types.depends(dict_id, key_id);
types.depends(dict_id, val_id);
dict_id
}
(Builtin::Set(elem_layout), Structure(Apply(Symbol::SET_SET, args))) => {
let args = env.subs.get_subs_slice(*args);
debug_assert_eq!(args.len(), 1);
let elem_id = add_type_help(env, *elem_layout, args[0], opt_name, types);
let set_id = types.add(RocType::RocSet(elem_id), layout);
types.depends(set_id, elem_id);
set_id
}
(Builtin::List(elem_layout), Structure(Apply(Symbol::LIST_LIST, args))) => { (Builtin::List(elem_layout), Structure(Apply(Symbol::LIST_LIST, args))) => {
let args = env.subs.get_subs_slice(*args); let args = env.subs.get_subs_slice(*args);
debug_assert_eq!(args.len(), 1); debug_assert_eq!(args.len(), 1);

View file

@ -1446,19 +1446,9 @@ fn builtin_spec(
use Builtin::*; use Builtin::*;
match builtin { match builtin {
Dict(_, _) => todo!(),
Int(_) | Bool => builder.add_tuple_type(&[]), Int(_) | Bool => builder.add_tuple_type(&[]),
Decimal | Float(_) => builder.add_tuple_type(&[]), Decimal | Float(_) => builder.add_tuple_type(&[]),
Str => str_type(builder), Str => str_type(builder),
Set(key_layout) => {
let value_type = builder.add_tuple_type(&[])?;
let key_type = layout_spec_help(builder, key_layout, when_recursive)?;
let element_type = builder.add_tuple_type(&[key_type, value_type])?;
let cell = builder.add_heap_cell_type();
let bag = builder.add_bag_type(element_type)?;
builder.add_tuple_type(&[cell, bag])
}
List(element_layout) => { List(element_layout) => {
let element_type = layout_spec_help(builder, element_layout, when_recursive)?; let element_type = layout_spec_help(builder, element_layout, when_recursive)?;

View file

@ -2810,12 +2810,6 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
build_list::decref(env, value.into_struct_value(), alignment); build_list::decref(env, value.into_struct_value(), alignment);
} }
Layout::Builtin(Builtin::Dict(key_layout, value_layout)) => {
todo!()
}
Layout::Builtin(Builtin::Set(key_layout)) => {
todo!()
}
_ if layout.is_refcounted() => { _ if layout.is_refcounted() => {
if value.is_pointer_value() { if value.is_pointer_value() {
@ -6146,10 +6140,6 @@ fn to_cc_type_builtin<'a, 'ctx, 'env>(
struct_type.ptr_type(address_space).into() struct_type.ptr_type(address_space).into()
} }
Builtin::Dict(_, _) | Builtin::Set(_) => {
// TODO verify this is what actually happens
basic_type_from_builtin(env, builtin)
}
} }
} }

View file

@ -58,25 +58,7 @@ pub fn dict_len<'a, 'ctx, 'env>(
let (_, dict_layout) = load_symbol_and_layout(scope, &dict_symbol); let (_, dict_layout) = load_symbol_and_layout(scope, &dict_symbol);
match dict_layout { match dict_layout {
Layout::Builtin(Builtin::Dict(_, _)) => { Layout::Builtin(Builtin::Dict(_, _)) =>
// let dict_as_int = dict_symbol_to_i128(env, scope, dict_symbol);
let dict_as_zig_dict = dict_symbol_to_zig_dict(env, scope, dict_symbol);
let length_i64 = call_bitcode_fn(
env,
&[pass_dict_c_abi(env, dict_as_zig_dict.into())],
bitcode::DICT_LEN,
);
env.builder
.build_int_cast_sign_flag(
length_i64.into_int_value(),
env.ptr_int(),
false,
"to_usize",
)
.into()
}
_ => unreachable!("Invalid layout given to Dict.len : {:?}", dict_layout), _ => unreachable!("Invalid layout given to Dict.len : {:?}", dict_layout),
} }
} }

View file

@ -130,12 +130,6 @@ fn hash_builtin<'a, 'ctx, 'env>(
call_bitcode_fn(env, &[seed.into(), val], bitcode::DICT_HASH_STR).into_int_value() call_bitcode_fn(env, &[seed.into(), val], bitcode::DICT_HASH_STR).into_int_value()
} }
Builtin::Dict(_, _) => {
todo!("Implement hash for Dict")
}
Builtin::Set(_) => {
todo!("Implement Hash for Set")
}
Builtin::List(element_layout) => build_hash_list( Builtin::List(element_layout) => build_hash_list(
env, env,
layout_ids, layout_ids,

View file

@ -135,8 +135,6 @@ fn build_eq_builtin<'a, 'ctx, 'env>(
rhs_val.into_struct_value(), rhs_val.into_struct_value(),
when_recursive, when_recursive,
), ),
Builtin::Set(_elem) => todo!("equality on Set"),
Builtin::Dict(_key, _value) => todo!("equality on Dict"),
} }
} }
@ -312,8 +310,6 @@ fn build_neq_builtin<'a, 'ctx, 'env>(
result.into() result.into()
} }
Builtin::Set(_elem) => todo!("equality on Set"),
Builtin::Dict(_key, _value) => todo!("equality on Dict"),
} }
} }

View file

@ -103,8 +103,6 @@ pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
Float(float_width) => float_type_from_float_width(env, *float_width).as_basic_type_enum(), Float(float_width) => float_type_from_float_width(env, *float_width).as_basic_type_enum(),
Bool => context.bool_type().as_basic_type_enum(), Bool => context.bool_type().as_basic_type_enum(),
Decimal => context.i128_type().as_basic_type_enum(), Decimal => context.i128_type().as_basic_type_enum(),
Dict(_, _) => zig_dict_type(env).into(),
Set(_) => zig_dict_type(env).into(),
List(_) => zig_list_type(env).into(), List(_) => zig_list_type(env).into(),
Str => zig_str_type(env).into(), Str => zig_str_type(env).into(),
} }
@ -260,10 +258,6 @@ pub fn str_list_int(ctx: &Context, target_info: TargetInfo) -> IntType<'_> {
} }
} }
pub fn zig_dict_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> {
env.module.get_struct_type("dict.RocDict").unwrap()
}
pub fn zig_list_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> { pub fn zig_list_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> {
env.module.get_struct_type("list.RocList").unwrap() env.module.get_struct_type("list.RocList").unwrap()
} }

View file

@ -1,6 +1,5 @@
pub mod bitcode; pub mod bitcode;
pub mod build; pub mod build;
pub mod build_dict;
pub mod build_hash; pub mod build_hash;
pub mod build_list; pub mod build_list;
pub mod build_str; pub mod build_str;

View file

@ -423,35 +423,6 @@ fn modify_refcount_builtin<'a, 'ctx, 'env>(
Some(function) Some(function)
} }
Set(element_layout) => {
let key_layout = element_layout;
let value_layout = &Layout::UNIT;
let function = modify_refcount_dict(
env,
layout_ids,
mode,
when_recursive,
layout,
key_layout,
value_layout,
);
Some(function)
}
Dict(key_layout, value_layout) => {
let function = modify_refcount_dict(
env,
layout_ids,
mode,
when_recursive,
layout,
key_layout,
value_layout,
);
Some(function)
}
Str => Some(modify_refcount_str(env, layout_ids, mode, layout)), Str => Some(modify_refcount_str(env, layout_ids, mode, layout)),
@ -960,141 +931,6 @@ fn modify_refcount_box_help<'a, 'ctx, 'env>(
builder.build_return(None); builder.build_return(None);
} }
#[allow(clippy::too_many_arguments)]
fn modify_refcount_dict<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>,
mode: Mode,
when_recursive: &WhenRecursive<'a>,
layout: &Layout<'a>,
key_layout: &Layout<'a>,
value_layout: &Layout<'a>,
) -> FunctionValue<'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 (_, fn_name) = function_name_from_mode(
layout_ids,
&env.interns,
"increment_dict",
"decrement_dict",
layout,
mode,
);
let function = match env.module.get_function(fn_name.as_str()) {
Some(function_value) => function_value,
None => {
let basic_type = basic_type_from_layout(env, layout);
let function_value = build_header(env, basic_type, mode, &fn_name);
modify_refcount_dict_help(
env,
layout_ids,
mode,
when_recursive,
layout,
key_layout,
value_layout,
function_value,
);
function_value
}
};
env.builder.position_at_end(block);
env.builder
.set_current_debug_location(env.context, di_location);
function
}
#[allow(clippy::too_many_arguments)]
fn modify_refcount_dict_help<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
layout_ids: &mut LayoutIds<'a>,
mode: Mode,
when_recursive: &WhenRecursive<'a>,
layout: &Layout<'a>,
key_layout: &Layout<'a>,
value_layout: &Layout<'a>,
fn_val: FunctionValue<'ctx>,
) {
debug_assert_eq!(
when_recursive,
&WhenRecursive::Unreachable,
"TODO pipe when_recursive through the dict key/value inc/dec"
);
let builder = env.builder;
let ctx = env.context;
// Add a basic block for the entry point
let entry = ctx.append_basic_block(fn_val, "entry");
builder.position_at_end(entry);
debug_info_init!(env, fn_val);
// Add args to scope
let arg_symbol = Symbol::ARG_1;
let arg_val = fn_val.get_param_iter().next().unwrap();
arg_val.set_name(arg_symbol.as_str(&env.interns));
let parent = fn_val;
let wrapper_struct = arg_val.into_struct_value();
let len = builder
.build_extract_value(wrapper_struct, 1, "read_dict_len")
.unwrap()
.into_int_value();
// the block we'll always jump to when we're done
let cont_block = ctx.append_basic_block(parent, "modify_rc_dict_cont");
let modification_block = ctx.append_basic_block(parent, "modify_rc");
let is_non_empty = builder.build_int_compare(
IntPredicate::SGT,
len,
env.ptr_int().const_zero(),
"is_non_empty",
);
builder.build_conditional_branch(is_non_empty, modification_block, cont_block);
builder.position_at_end(modification_block);
if key_layout.contains_refcounted() || value_layout.contains_refcounted() {
crate::llvm::build_dict::dict_elements_rc(
env,
layout_ids,
wrapper_struct.into(),
key_layout,
value_layout,
mode,
);
}
let data_ptr = env
.builder
.build_extract_value(wrapper_struct, 0, "get_data_ptr")
.unwrap()
.into_pointer_value();
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, data_ptr);
let call_mode = mode_to_call_mode(fn_val, mode);
refcount_ptr.modify(call_mode, layout, env);
builder.build_unconditional_branch(cont_block);
builder.position_at_end(cont_block);
// this function returns void
builder.build_return(None);
}
/// Build an increment or decrement function for a specific layout /// Build an increment or decrement function for a specific layout
fn build_header<'a, 'ctx, 'env>( fn build_header<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,

View file

@ -18,7 +18,7 @@ pub enum ReturnMethod {
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StackMemoryFormat { pub enum StackMemoryFormat {
/// Record, Str, List, Dict, etc. /// Record, Str, List, etc.
DataStructure, DataStructure,
Int128, Int128,
Float128, Float128,
@ -87,7 +87,7 @@ impl WasmLayout {
Layout::LambdaSet(lambda_set) => WasmLayout::new(&lambda_set.runtime_representation()), Layout::LambdaSet(lambda_set) => WasmLayout::new(&lambda_set.runtime_representation()),
Layout::Builtin(Str | Dict(_, _) | Set(_) | List(_)) Layout::Builtin(Str | List(_))
| Layout::Struct { .. } | Layout::Struct { .. }
| Layout::Union(NonRecursive(_)) => Self::StackMemory { | Layout::Union(NonRecursive(_)) => Self::StackMemory {
size, size,

View file

@ -1824,7 +1824,7 @@ impl<'a> LowLevelCall<'a> {
backend.code_builder.i32_const(!invert_result as i32); backend.code_builder.i32_const(!invert_result as i32);
} }
Layout::Builtin(Builtin::Dict(_, _) | Builtin::Set(_) | Builtin::List(_)) Layout::Builtin(Builtin::List(_))
| Layout::Struct { .. } | Layout::Struct { .. }
| Layout::Union(_) | Layout::Union(_)
| Layout::LambdaSet(_) | Layout::LambdaSet(_)

View file

@ -30,7 +30,6 @@ pub fn eq_generic<'a>(
Layout::Builtin(Builtin::Str) => { Layout::Builtin(Builtin::Str) => {
unreachable!("No generated helper proc for `==` on Str. Use Zig function.") unreachable!("No generated helper proc for `==` on Str. Use Zig function.")
} }
Layout::Builtin(Builtin::Dict(_, _) | Builtin::Set(_)) => eq_todo(),
Layout::Builtin(Builtin::List(elem_layout)) => eq_list(root, ident_ids, ctx, elem_layout), Layout::Builtin(Builtin::List(elem_layout)) => eq_list(root, ident_ids, ctx, elem_layout),
Layout::Struct { field_layouts, .. } => eq_struct(root, ident_ids, ctx, field_layouts), Layout::Struct { field_layouts, .. } => eq_struct(root, ident_ids, ctx, field_layouts),
Layout::Union(union_layout) => eq_tag_union(root, ident_ids, ctx, union_layout), Layout::Union(union_layout) => eq_tag_union(root, ident_ids, ctx, union_layout),

View file

@ -410,15 +410,6 @@ impl<'a> CodeGenHelp<'a> {
// needs *two* specializations for `List(RecursivePointer)`, not just one. // needs *two* specializations for `List(RecursivePointer)`, not just one.
fn replace_rec_ptr(&self, ctx: &Context<'a>, layout: Layout<'a>) -> Layout<'a> { fn replace_rec_ptr(&self, ctx: &Context<'a>, layout: Layout<'a>) -> Layout<'a> {
match layout { match layout {
Layout::Builtin(Builtin::Dict(k, v)) => Layout::Builtin(Builtin::Dict(
self.arena.alloc(self.replace_rec_ptr(ctx, *k)),
self.arena.alloc(self.replace_rec_ptr(ctx, *v)),
)),
Layout::Builtin(Builtin::Set(k)) => Layout::Builtin(Builtin::Set(
self.arena.alloc(self.replace_rec_ptr(ctx, *k)),
)),
Layout::Builtin(Builtin::List(v)) => Layout::Builtin(Builtin::List( Layout::Builtin(Builtin::List(v)) => Layout::Builtin(Builtin::List(
self.arena.alloc(self.replace_rec_ptr(ctx, *v)), self.arena.alloc(self.replace_rec_ptr(ctx, *v)),
)), )),
@ -543,7 +534,7 @@ fn layout_needs_helper_proc(layout: &Layout, op: HelperOp) -> bool {
// Both are fine, they were just developed at different times. // Both are fine, they were just developed at different times.
matches!(op, HelperOp::Inc | HelperOp::Dec | HelperOp::DecRef(_)) matches!(op, HelperOp::Inc | HelperOp::Dec | HelperOp::DecRef(_))
} }
Layout::Builtin(Builtin::Dict(_, _) | Builtin::Set(_) | Builtin::List(_)) => true, Layout::Builtin(Builtin::List(_)) => true,
Layout::Struct { .. } => true, // note: we do generate a helper for Unit, with just a Stmt::Ret Layout::Struct { .. } => true, // note: we do generate a helper for Unit, with just a Stmt::Ret
Layout::Union(UnionLayout::NonRecursive(tags)) => !tags.is_empty(), Layout::Union(UnionLayout::NonRecursive(tags)) => !tags.is_empty(),
Layout::Union(_) => true, Layout::Union(_) => true,

View file

@ -115,7 +115,6 @@ pub fn refcount_generic<'a>(
Layout::Builtin(Builtin::List(elem_layout)) => { Layout::Builtin(Builtin::List(elem_layout)) => {
refcount_list(root, ident_ids, ctx, &layout, elem_layout, structure) refcount_list(root, ident_ids, ctx, &layout, elem_layout, structure)
} }
Layout::Builtin(Builtin::Dict(_, _) | Builtin::Set(_)) => rc_todo(),
Layout::Struct { field_layouts, .. } => { Layout::Struct { field_layouts, .. } => {
refcount_struct(root, ident_ids, ctx, field_layouts, structure) refcount_struct(root, ident_ids, ctx, field_layouts, structure)
} }
@ -322,7 +321,6 @@ pub fn is_rc_implemented_yet(layout: &Layout) -> bool {
use UnionLayout::*; use UnionLayout::*;
match layout { match layout {
Layout::Builtin(Builtin::Dict(..) | Builtin::Set(_)) => false,
Layout::Builtin(Builtin::List(elem_layout)) => is_rc_implemented_yet(elem_layout), Layout::Builtin(Builtin::List(elem_layout)) => is_rc_implemented_yet(elem_layout),
Layout::Builtin(_) => true, Layout::Builtin(_) => true,
Layout::Struct { field_layouts, .. } => field_layouts.iter().all(is_rc_implemented_yet), Layout::Struct { field_layouts, .. } => field_layouts.iter().all(is_rc_implemented_yet),

View file

@ -32,7 +32,7 @@ roc_error_macros::assert_sizeof_wasm!(Layout, 6 * 4);
roc_error_macros::assert_sizeof_wasm!(UnionLayout, 3 * 4); roc_error_macros::assert_sizeof_wasm!(UnionLayout, 3 * 4);
roc_error_macros::assert_sizeof_wasm!(LambdaSet, 3 * 4); roc_error_macros::assert_sizeof_wasm!(LambdaSet, 3 * 4);
roc_error_macros::assert_sizeof_default!(Builtin, 3 * 8); roc_error_macros::assert_sizeof_default!(Builtin, 2 * 8);
roc_error_macros::assert_sizeof_default!(Layout, 4 * 8); roc_error_macros::assert_sizeof_default!(Layout, 4 * 8);
roc_error_macros::assert_sizeof_default!(UnionLayout, 3 * 8); roc_error_macros::assert_sizeof_default!(UnionLayout, 3 * 8);
roc_error_macros::assert_sizeof_default!(LambdaSet, 3 * 8); roc_error_macros::assert_sizeof_default!(LambdaSet, 3 * 8);
@ -1155,8 +1155,6 @@ pub enum Builtin<'a> {
Bool, Bool,
Decimal, Decimal,
Str, Str,
Dict(&'a Layout<'a>, &'a Layout<'a>),
Set(&'a Layout<'a>),
List(&'a Layout<'a>), List(&'a Layout<'a>),
} }
@ -1809,8 +1807,6 @@ impl<'a> Builtin<'a> {
/// Number of machine words in an empty one of these /// Number of machine words in an empty one of these
pub const STR_WORDS: u32 = 3; pub const STR_WORDS: u32 = 3;
pub const DICT_WORDS: u32 = 3;
pub const SET_WORDS: u32 = Builtin::DICT_WORDS; // Set is an alias for Dict with {} for value
pub const LIST_WORDS: u32 = 3; pub const LIST_WORDS: u32 = 3;
/// Layout of collection wrapper for List and Str - a struct of (pointer, length, capacity). /// Layout of collection wrapper for List and Str - a struct of (pointer, length, capacity).
@ -1829,8 +1825,6 @@ impl<'a> Builtin<'a> {
Bool => Builtin::I1_SIZE, Bool => Builtin::I1_SIZE,
Decimal => Builtin::DECIMAL_SIZE, Decimal => Builtin::DECIMAL_SIZE,
Str => Builtin::STR_WORDS * ptr_width, Str => Builtin::STR_WORDS * ptr_width,
Dict(_, _) => Builtin::DICT_WORDS * ptr_width,
Set(_) => Builtin::SET_WORDS * ptr_width,
List(_) => Builtin::LIST_WORDS * ptr_width, List(_) => Builtin::LIST_WORDS * ptr_width,
} }
} }
@ -1849,8 +1843,6 @@ impl<'a> Builtin<'a> {
Float(float_width) => float_width.alignment_bytes(target_info), Float(float_width) => float_width.alignment_bytes(target_info),
Bool => align_of::<bool>() as u32, Bool => align_of::<bool>() as u32,
Decimal => IntWidth::I128.alignment_bytes(target_info), Decimal => IntWidth::I128.alignment_bytes(target_info),
Dict(_, _) => ptr_width,
Set(_) => ptr_width,
// we often treat these as i128 (64-bit systems) // we often treat these as i128 (64-bit systems)
// or i64 (32-bit systems). // or i64 (32-bit systems).
// //
@ -1867,7 +1859,7 @@ impl<'a> Builtin<'a> {
match self { match self {
Int(_) | Float(_) | Bool | Decimal => true, Int(_) | Float(_) | Bool | Decimal => true,
Str | Dict(_, _) | Set(_) | List(_) => false, Str | List(_) => false,
} }
} }
@ -1878,8 +1870,7 @@ impl<'a> Builtin<'a> {
match self { match self {
Int(_) | Float(_) | Bool | Decimal => false, Int(_) | Float(_) | Bool | Decimal => false,
List(_) => true, List(_) => true,
Str => true,
Str | Dict(_, _) | Set(_) => true,
} }
} }
@ -1926,14 +1917,6 @@ impl<'a> Builtin<'a> {
List(layout) => alloc List(layout) => alloc
.text("List ") .text("List ")
.append(layout.to_doc(alloc, Parens::InTypeParam)), .append(layout.to_doc(alloc, Parens::InTypeParam)),
Set(layout) => alloc
.text("Set ")
.append(layout.to_doc(alloc, Parens::InTypeParam)),
Dict(key_layout, value_layout) => alloc
.text("Dict ")
.append(key_layout.to_doc(alloc, Parens::InTypeParam))
.append(" ")
.append(value_layout.to_doc(alloc, Parens::InTypeParam)),
} }
} }
@ -1942,11 +1925,6 @@ impl<'a> Builtin<'a> {
let allocation = match self { let allocation = match self {
Builtin::Str => ptr_width, Builtin::Str => ptr_width,
Builtin::Dict(k, v) => k
.alignment_bytes(target_info)
.max(v.alignment_bytes(target_info))
.max(ptr_width),
Builtin::Set(k) => k.alignment_bytes(target_info).max(ptr_width),
Builtin::List(e) => e.alignment_bytes(target_info).max(ptr_width), Builtin::List(e) => e.alignment_bytes(target_info).max(ptr_width),
// The following are usually not heap-allocated, but they might be when inside a Box. // The following are usually not heap-allocated, but they might be when inside a Box.
Builtin::Int(int_width) => int_width.alignment_bytes(target_info).max(ptr_width), Builtin::Int(int_width) => int_width.alignment_bytes(target_info).max(ptr_width),
@ -3122,39 +3100,6 @@ fn layout_from_num_content<'a>(
} }
} }
fn dict_layout_from_key_value<'a>(
env: &mut Env<'a, '_>,
key_var: Variable,
value_var: Variable,
) -> Result<Layout<'a>, LayoutProblem> {
let is_variable = |content| matches!(content, &Content::FlexVar(_) | &Content::RigidVar(_));
let key_content = env.subs.get_content_without_compacting(key_var);
let value_content = env.subs.get_content_without_compacting(value_var);
let key_layout = if is_variable(key_content) {
Layout::VOID
} else {
// NOTE: cannot re-use Content, because it may be recursive
// then some state is not correctly kept, we have to go through from_var
Layout::from_var(env, key_var)?
};
let value_layout = if is_variable(value_content) {
Layout::VOID
} else {
// NOTE: cannot re-use Content, because it may be recursive
// then some state is not correctly kept, we have to go through from_var
Layout::from_var(env, value_var)?
};
// This is a normal list.
Ok(Layout::Builtin(Builtin::Dict(
env.arena.alloc(key_layout),
env.arena.alloc(value_layout),
)))
}
pub fn list_layout_from_elem<'a>( pub fn list_layout_from_elem<'a>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
element_var: Variable, element_var: Variable,

View file

@ -341,9 +341,6 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
list_to_ast(env, mem, addr, len, elem_layout, raw_content) list_to_ast(env, mem, addr, len, elem_layout, raw_content)
}, },
)), )),
Layout::Builtin(other) => {
todo!("add support for rendering builtin {:?} to the REPL", other)
}
Layout::Struct { field_layouts, .. } => { Layout::Struct { field_layouts, .. } => {
let struct_addr_to_ast = |mem: &'a A::Memory, addr: usize| match raw_content { let struct_addr_to_ast = |mem: &'a A::Memory, addr: usize| match raw_content {
Content::Structure(FlatType::Record(fields, _)) => { Content::Structure(FlatType::Record(fields, _)) => {