Merge pull request #1699 from rtfeldman/effect-after

Fix closures only monomorphizing once
This commit is contained in:
Richard Feldman 2021-09-13 19:50:50 -04:00 committed by GitHub
commit f619932255
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 113 additions and 47 deletions

View file

@ -1164,8 +1164,16 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
StructAtIndex {
index, structure, ..
} => {
let (value, layout) = load_symbol_and_layout(scope, structure);
let layout = if let Layout::LambdaSet(lambda_set) = layout {
lambda_set.runtime_representation()
} else {
*layout
};
// extract field from a record
match load_symbol_and_layout(scope, structure) {
match (value, layout) {
(StructValue(argument), Layout::Struct(fields)) => {
debug_assert!(!fields.is_empty());
env.builder
@ -4100,6 +4108,11 @@ fn roc_function_call<'a, 'ctx, 'env>(
) -> RocFunctionCall<'ctx> {
use crate::llvm::bitcode::{build_inc_n_wrapper, build_transform_caller};
let closure_data_layout = match closure_data_layout {
Layout::LambdaSet(lambda_set) => lambda_set.runtime_representation(),
_ => panic!("closure argument is not a lambda set!"),
};
let closure_data_ptr = env
.builder
.build_alloca(closure_data.get_type(), "closure_data_ptr");
@ -4503,8 +4516,13 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let argument_layouts = &[**element_layout, **element_layout];
let closure_data_layout = match closure_layout {
Layout::LambdaSet(lambda_set) => lambda_set.runtime_representation(),
_ => panic!("closure argument is not a lambda set!"),
};
let compare_wrapper =
build_compare_wrapper(env, function, *closure_layout, element_layout)
build_compare_wrapper(env, function, closure_data_layout, element_layout)
.as_global_value()
.as_pointer_value();

View file

@ -59,6 +59,15 @@ fn build_hash_layout<'a, 'ctx, 'env>(
val.into_struct_value(),
),
Layout::LambdaSet(lambda_set) => build_hash_layout(
env,
layout_ids,
seed,
val,
&lambda_set.runtime_representation(),
when_recursive,
),
Layout::Union(union_layout) => {
build_hash_tag(env, layout_ids, layout, union_layout, seed, val)
}

View file

@ -156,6 +156,8 @@ fn build_eq<'a, 'ctx, 'env>(
rhs_val.into_struct_value(),
),
Layout::LambdaSet(_) => unreachable!("cannot compare closures"),
Layout::Union(union_layout) => build_tag_eq(
env,
layout_ids,
@ -336,6 +338,7 @@ fn build_neq<'a, 'ctx, 'env>(
Layout::RecursivePointer => {
unreachable!("recursion pointers should never be compared directly")
}
Layout::LambdaSet(_) => unreachable!("cannot compare closure"),
}
}

View file

@ -27,6 +27,7 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
match layout {
Struct(sorted_fields) => basic_type_from_record(env, sorted_fields),
LambdaSet(lambda_set) => basic_type_from_layout(env, &lambda_set.runtime_representation()),
Union(union_layout) => {
use UnionLayout::*;

View file

@ -626,6 +626,14 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
Some(function)
}
},
LambdaSet(lambda_set) => modify_refcount_layout_build_function(
env,
parent,
layout_ids,
mode,
when_recursive,
&lambda_set.runtime_representation(),
),
}
}