mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
test_gen works again
This commit is contained in:
parent
5fc629e5b8
commit
c09b3b89f3
11 changed files with 95 additions and 124 deletions
|
@ -270,6 +270,25 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
|
|||
arguments_cast.push(argument);
|
||||
}
|
||||
|
||||
match closure_data_layout {
|
||||
Layout::Struct(&[]) => {
|
||||
// do nothing
|
||||
}
|
||||
other => {
|
||||
let closure_type = basic_type_from_layout(env, &other).ptr_type(AddressSpace::Generic);
|
||||
|
||||
let closure_cast = env
|
||||
.builder
|
||||
.build_bitcast(closure_ptr, closure_type, "load_opaque")
|
||||
.into_pointer_value();
|
||||
|
||||
let closure_data = env.builder.build_load(closure_cast, "load_opaque");
|
||||
|
||||
arguments_cast.push(closure_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
match closure_data_layout {
|
||||
Layout::Closure(_, lambda_set, _) => {
|
||||
if let Layout::Struct(&[]) = lambda_set.runtime_representation() {
|
||||
|
@ -316,6 +335,7 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
|
|||
}
|
||||
other => unreachable!("layout is not valid for a closure: {:?}", other),
|
||||
}
|
||||
*/
|
||||
|
||||
let call = {
|
||||
env.builder
|
||||
|
@ -624,6 +644,7 @@ pub fn build_compare_wrapper<'a, 'ctx, 'env>(
|
|||
|
||||
let default = [value1, value2];
|
||||
|
||||
/*
|
||||
let arguments_cast = match closure_data_layout {
|
||||
Layout::Closure(_, lambda_set, _) => {
|
||||
if let Layout::Struct(&[]) = lambda_set.runtime_representation() {
|
||||
|
@ -646,6 +667,29 @@ pub fn build_compare_wrapper<'a, 'ctx, 'env>(
|
|||
Layout::Struct([]) => &default,
|
||||
other => unreachable!("layout is not valid for a closure: {:?}", other),
|
||||
};
|
||||
*/
|
||||
|
||||
let arguments_cast = match closure_data_layout {
|
||||
Layout::Struct(&[]) => {
|
||||
// do nothing
|
||||
&default
|
||||
}
|
||||
other => {
|
||||
//
|
||||
|
||||
let closure_type =
|
||||
basic_type_from_layout(env, &other).ptr_type(AddressSpace::Generic);
|
||||
|
||||
let closure_cast = env
|
||||
.builder
|
||||
.build_bitcast(closure_ptr, closure_type, "load_opaque")
|
||||
.into_pointer_value();
|
||||
|
||||
let closure_data = env.builder.build_load(closure_cast, "load_opaque");
|
||||
|
||||
env.arena.alloc([value1, value2, closure_data]) as &[_]
|
||||
}
|
||||
};
|
||||
|
||||
let call = env.builder.build_call(
|
||||
roc_function,
|
||||
|
|
|
@ -1082,14 +1082,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
|||
)
|
||||
.unwrap()
|
||||
}
|
||||
(StructValue(argument), Layout::Closure(_, _, _)) => env
|
||||
.builder
|
||||
.build_extract_value(
|
||||
argument,
|
||||
*index as u32,
|
||||
env.arena.alloc(format!("closure_field_access_{}_", index)),
|
||||
)
|
||||
.unwrap(),
|
||||
(
|
||||
PointerValue(argument),
|
||||
Layout::Union(UnionLayout::NonNullableUnwrapped(fields)),
|
||||
|
|
|
@ -88,10 +88,6 @@ fn build_hash_layout<'a, 'ctx, 'env>(
|
|||
)
|
||||
}
|
||||
},
|
||||
|
||||
Layout::Closure(_, _, _) => {
|
||||
unreachable!("the type system will guarantee these are never hashed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -198,10 +198,6 @@ fn build_eq<'a, 'ctx, 'env>(
|
|||
)
|
||||
}
|
||||
},
|
||||
|
||||
Layout::Closure(_, _, _) => {
|
||||
unreachable!("the type system will guarantee these are never compared")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,10 +336,6 @@ fn build_neq<'a, 'ctx, 'env>(
|
|||
Layout::RecursivePointer => {
|
||||
unreachable!("recursion pointers should never be compared directly")
|
||||
}
|
||||
|
||||
Layout::Closure(_, _, _) => {
|
||||
unreachable!("the type system will guarantee these are never compared")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,10 +26,6 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
|
|||
use Layout::*;
|
||||
|
||||
match layout {
|
||||
Closure(_args, closure_layout, _ret_layout) => {
|
||||
let closure_data_layout = closure_layout.runtime_representation();
|
||||
basic_type_from_layout(env, &closure_data_layout)
|
||||
}
|
||||
Struct(sorted_fields) => basic_type_from_record(env, sorted_fields),
|
||||
Union(union_layout) => {
|
||||
use UnionLayout::*;
|
||||
|
|
|
@ -659,23 +659,6 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
|
|||
Some(function)
|
||||
}
|
||||
|
||||
Closure(_, lambda_set, _) => {
|
||||
if lambda_set.contains_refcounted() {
|
||||
let function = modify_refcount_layout_build_function(
|
||||
env,
|
||||
parent,
|
||||
layout_ids,
|
||||
mode,
|
||||
when_recursive,
|
||||
&lambda_set.runtime_representation(),
|
||||
)?;
|
||||
|
||||
Some(function)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
Struct(layouts) => {
|
||||
let function = modify_refcount_struct(env, layout_ids, layouts, mode, when_recursive);
|
||||
|
||||
|
|
|
@ -65,9 +65,6 @@ where
|
|||
|
||||
for layout in argument_layouts {
|
||||
match layout {
|
||||
Layout::Closure(_, lambda_set, _) => {
|
||||
lambda_set.runtime_representation().hash(&mut hasher);
|
||||
}
|
||||
_ => {
|
||||
layout.hash(&mut hasher);
|
||||
}
|
||||
|
@ -75,9 +72,6 @@ where
|
|||
}
|
||||
|
||||
match return_layout {
|
||||
Layout::Closure(_, lambda_set, _) => {
|
||||
lambda_set.runtime_representation().hash(&mut hasher);
|
||||
}
|
||||
_ => {
|
||||
return_layout.hash(&mut hasher);
|
||||
}
|
||||
|
@ -1258,11 +1252,6 @@ fn layout_spec_help(
|
|||
}
|
||||
},
|
||||
},
|
||||
Closure(_, lambda_set, _) => layout_spec_help(
|
||||
builder,
|
||||
&lambda_set.runtime_representation(),
|
||||
when_recursive,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ pub const BORROWED: bool = true;
|
|||
|
||||
fn should_borrow_layout(layout: &Layout) -> bool {
|
||||
match layout {
|
||||
Layout::Closure(_, _, _) => false,
|
||||
_ => layout.is_refcounted(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,11 +165,6 @@ impl<'a, 'i> Env<'a, 'i> {
|
|||
self.constructor_map.insert(symbol, 0);
|
||||
self.layout_map.insert(symbol, Layout::Struct(fields));
|
||||
}
|
||||
Closure(_, lambda_set, _) => {
|
||||
self.constructor_map.insert(symbol, 0);
|
||||
self.layout_map
|
||||
.insert(symbol, lambda_set.runtime_representation());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -244,10 +239,6 @@ fn layout_for_constructor<'a>(
|
|||
debug_assert_eq!(constructor, 0);
|
||||
HasFields(fields)
|
||||
}
|
||||
Closure(_arguments, _lambda_set, _result) => {
|
||||
// HasFields(fields)
|
||||
ConstructorLayout::Unknown
|
||||
}
|
||||
other => unreachable!("weird layout {:?}", other),
|
||||
}
|
||||
}
|
||||
|
@ -374,13 +365,6 @@ pub fn expand_and_cancel_proc<'a>(
|
|||
|
||||
introduced.push(*symbol);
|
||||
}
|
||||
Layout::Closure(_arguments, _lambda_set, _result) => {
|
||||
// TODO can this be improved again?
|
||||
// let fpointer = Layout::FunctionPointer(arguments, result);
|
||||
// let fields = env.arena.alloc([fpointer, *closure_layout.layout]);
|
||||
// env.insert_struct_info(*symbol, fields);
|
||||
// introduced.push(*symbol);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -546,11 +546,11 @@ impl<'a> Procs<'a> {
|
|||
// anonymous functions cannot reference themselves, therefore cannot be tail-recursive
|
||||
let is_self_recursive = false;
|
||||
|
||||
let layout = layout_cache
|
||||
.from_var(env.arena, annotation, env.subs)
|
||||
let raw_layout = layout_cache
|
||||
.raw_from_var(env.arena, annotation, env.subs)
|
||||
.unwrap_or_else(|err| panic!("TODO turn fn_var into a RuntimeError {:?}", err));
|
||||
|
||||
let top_level = ProcLayout::from_layout(env.arena, layout);
|
||||
let top_level = ProcLayout::from_raw(env.arena, raw_layout);
|
||||
|
||||
match patterns_to_when(env, layout_cache, loc_args, ret_var, loc_body) {
|
||||
Ok((_, pattern_symbols, body)) => {
|
||||
|
@ -617,7 +617,11 @@ impl<'a> Procs<'a> {
|
|||
Ok((proc, layout)) => {
|
||||
let top_level = ProcLayout::from_raw(env.arena, layout);
|
||||
|
||||
debug_assert_eq!(outside_layout, top_level);
|
||||
debug_assert_eq!(
|
||||
outside_layout, top_level,
|
||||
"different raw layouts for {:?}",
|
||||
proc.name
|
||||
);
|
||||
|
||||
if self.module_thunks.contains(&proc.name) {
|
||||
debug_assert!(top_level.arguments.is_empty());
|
||||
|
@ -2470,21 +2474,33 @@ fn specialize_solved_type<'a>(
|
|||
let fn_var = introduce_solved_type_to_subs(env, &solved_type);
|
||||
|
||||
// for debugging only
|
||||
let attempted_layout = layout_cache
|
||||
.from_var(env.arena, fn_var, env.subs)
|
||||
let raw = layout_cache
|
||||
.raw_from_var(env.arena, fn_var, env.subs)
|
||||
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
||||
|
||||
let raw = match attempted_layout {
|
||||
Layout::Closure(a, lambda_set, c) => {
|
||||
if procs.module_thunks.contains(&proc_name) {
|
||||
let raw = if procs.module_thunks.contains(&proc_name) {
|
||||
match raw {
|
||||
RawFunctionLayout::Function(_, lambda_set, _) => {
|
||||
RawFunctionLayout::ZeroArgumentThunk(lambda_set.runtime_representation())
|
||||
} else {
|
||||
RawFunctionLayout::Function(a, lambda_set, c)
|
||||
}
|
||||
_ => raw,
|
||||
}
|
||||
_ => RawFunctionLayout::ZeroArgumentThunk(attempted_layout),
|
||||
} else {
|
||||
raw
|
||||
};
|
||||
|
||||
// TODO this module_thunks.contains check will be important
|
||||
// let raw = match attempted_layout {
|
||||
// Layout::Closure(a, lambda_set, c) => {
|
||||
// if procs.module_thunks.contains(&proc_name) {
|
||||
// RawFunctionLayout::ZeroArgumentThunk(lambda_set.runtime_representation())
|
||||
// } else {
|
||||
// RawFunctionLayout::Function(a, lambda_set, c)
|
||||
// }
|
||||
// }
|
||||
// _ => RawFunctionLayout::ZeroArgumentThunk(attempted_layout),
|
||||
// };
|
||||
|
||||
// make sure rigid variables in the annotation are converted to flex variables
|
||||
instantiate_rigids(env.subs, partial_proc.annotation);
|
||||
|
||||
|
@ -2509,12 +2525,12 @@ fn specialize_solved_type<'a>(
|
|||
match specialized {
|
||||
Ok(proc) => {
|
||||
// when successful, the layout after unification should be the layout before unification
|
||||
debug_assert_eq!(
|
||||
attempted_layout,
|
||||
layout_cache
|
||||
.from_var(env.arena, fn_var, env.subs)
|
||||
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err))
|
||||
);
|
||||
// debug_assert_eq!(
|
||||
// attempted_layout,
|
||||
// layout_cache
|
||||
// .from_var(env.arena, fn_var, env.subs)
|
||||
// .unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err))
|
||||
// );
|
||||
|
||||
env.subs.rollback_to(snapshot);
|
||||
layout_cache.rollback_to(cache_snapshot);
|
||||
|
@ -2545,16 +2561,11 @@ impl<'a> ProcLayout<'a> {
|
|||
|
||||
for old in old_arguments {
|
||||
match old {
|
||||
Layout::Closure(_, lambda_set, _) => {
|
||||
let repr = lambda_set.runtime_representation();
|
||||
arguments.push(repr)
|
||||
}
|
||||
other => arguments.push(*other),
|
||||
}
|
||||
}
|
||||
|
||||
let new_result = match result {
|
||||
Layout::Closure(_, lambda_set, _) => lambda_set.runtime_representation(),
|
||||
other => other,
|
||||
};
|
||||
|
||||
|
@ -2563,12 +2574,10 @@ impl<'a> ProcLayout<'a> {
|
|||
result: new_result,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO remove!!!!!
|
||||
pub fn from_layout(arena: &'a Bump, layout: Layout<'a>) -> Self {
|
||||
match layout {
|
||||
Layout::Closure(arguments, lambda_set, result) => {
|
||||
let arguments = lambda_set.extend_argument_list(arena, arguments);
|
||||
ProcLayout::new(arena, arguments, *result)
|
||||
}
|
||||
_ => ProcLayout {
|
||||
arguments: &[],
|
||||
result: layout,
|
||||
|
@ -6048,7 +6057,11 @@ fn reuse_function_symbol<'a>(
|
|||
)
|
||||
} else if procs.module_thunks.contains(&original) {
|
||||
// this is a 0-argument thunk
|
||||
let layout = Layout::Closure(argument_layouts, lambda_set, ret_layout);
|
||||
|
||||
// TODO suspicious
|
||||
// let layout = Layout::Closure(argument_layouts, lambda_set, ret_layout);
|
||||
// panic!("suspicious");
|
||||
let layout = lambda_set.runtime_representation();
|
||||
let top_level = ProcLayout::new(env.arena, &[], layout);
|
||||
procs.insert_passed_by_name(
|
||||
env,
|
||||
|
@ -6654,8 +6667,12 @@ fn call_by_name_module_thunk<'a>(
|
|||
|
||||
match specialize(env, procs, proc_name, layout_cache, pending, partial_proc)
|
||||
{
|
||||
Ok((proc, layout)) => {
|
||||
debug_assert!(layout.is_zero_argument_thunk());
|
||||
Ok((proc, raw_layout)) => {
|
||||
debug_assert!(
|
||||
raw_layout.is_zero_argument_thunk(),
|
||||
"but actually {:?}",
|
||||
raw_layout
|
||||
);
|
||||
|
||||
let was_present =
|
||||
procs.specialized.remove(&(proc_name, top_level_layout));
|
||||
|
|
|
@ -160,9 +160,8 @@ pub enum Layout<'a> {
|
|||
Struct(&'a [Layout<'a>]),
|
||||
Union(UnionLayout<'a>),
|
||||
RecursivePointer,
|
||||
|
||||
/// A function. The types of its arguments, then the type of its return value.
|
||||
Closure(&'a [Layout<'a>], LambdaSet<'a>, &'a Layout<'a>),
|
||||
// /// A function. The types of its arguments, then the type of its return value.
|
||||
// Closure(&'a [Layout<'a>], LambdaSet<'a>, &'a Layout<'a>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
|
@ -743,7 +742,6 @@ impl<'a> Layout<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Closure(_, closure_layout, _) => closure_layout.safe_to_memcpy(),
|
||||
RecursivePointer => {
|
||||
// We cannot memcpy pointers, because then we would have the same pointer in multiple places!
|
||||
false
|
||||
|
@ -808,7 +806,6 @@ impl<'a> Layout<'a> {
|
|||
| NonNullableUnwrapped(_) => pointer_size,
|
||||
}
|
||||
}
|
||||
Closure(_, lambda_set, _) => lambda_set.stack_size(pointer_size),
|
||||
RecursivePointer => pointer_size,
|
||||
}
|
||||
}
|
||||
|
@ -840,9 +837,6 @@ impl<'a> Layout<'a> {
|
|||
}
|
||||
Layout::Builtin(builtin) => builtin.alignment_bytes(pointer_size),
|
||||
Layout::RecursivePointer => pointer_size,
|
||||
Layout::Closure(_, captured, _) => {
|
||||
pointer_size.max(captured.alignment_bytes(pointer_size))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -893,8 +887,6 @@ impl<'a> Layout<'a> {
|
|||
}
|
||||
}
|
||||
RecursivePointer => true,
|
||||
|
||||
Closure(_, closure_layout, _) => closure_layout.contains_refcounted(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -918,20 +910,6 @@ impl<'a> Layout<'a> {
|
|||
}
|
||||
Union(union_layout) => union_layout.to_doc(alloc, parens),
|
||||
RecursivePointer => alloc.text("*self"),
|
||||
Closure(args, closure_layout, result) => {
|
||||
let args_doc = args.iter().map(|x| x.to_doc(alloc, Parens::InFunction));
|
||||
|
||||
let bom = closure_layout
|
||||
.representation
|
||||
.to_doc(alloc, Parens::NotNeeded);
|
||||
|
||||
alloc
|
||||
.intersperse(args_doc, ", ")
|
||||
.append(alloc.text(" {| "))
|
||||
.append(bom)
|
||||
.append(" |} -> ")
|
||||
.append(result.to_doc(alloc, Parens::InFunction))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1257,7 +1235,8 @@ fn layout_from_flat_type<'a>(
|
|||
|
||||
let lambda_set = LambdaSet::from_var(env.arena, env.subs, closure_var)?;
|
||||
|
||||
Ok(Layout::Closure(fn_args, lambda_set, ret))
|
||||
// Ok(Layout::Closure(fn_args, lambda_set, ret))
|
||||
Ok(lambda_set.runtime_representation())
|
||||
}
|
||||
Record(fields, ext_var) => {
|
||||
// extract any values from the ext_var
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue