set correct closure tag_id

This commit is contained in:
Folkert 2020-12-11 20:25:15 +01:00
parent 752a2200fd
commit 539f173472
3 changed files with 23 additions and 8 deletions

View file

@ -36,6 +36,7 @@ use inkwell::OptimizationLevel;
use inkwell::{AddressSpace, IntPredicate}; use inkwell::{AddressSpace, IntPredicate};
use roc_builtins::bitcode; use roc_builtins::bitcode;
use roc_collections::all::{ImMap, MutSet}; use roc_collections::all::{ImMap, MutSet};
use roc_module::ident::TagName;
use roc_module::low_level::LowLevel; use roc_module::low_level::LowLevel;
use roc_module::symbol::{Interns, ModuleId, Symbol}; use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_mono::ir::{JoinPointId, Wrapped}; use roc_mono::ir::{JoinPointId, Wrapped};
@ -811,6 +812,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
tag_layout: Layout::Union(fields), tag_layout: Layout::Union(fields),
union_size, union_size,
tag_id, tag_id,
tag_name,
.. ..
} => { } => {
let tag_layout = Layout::Union(fields); let tag_layout = Layout::Union(fields);
@ -826,12 +828,15 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
let mut field_types = Vec::with_capacity_in(num_fields, env.arena); let mut field_types = Vec::with_capacity_in(num_fields, env.arena);
let mut field_vals = Vec::with_capacity_in(num_fields, env.arena); let mut field_vals = Vec::with_capacity_in(num_fields, env.arena);
let tag_field_layouts = fields[*tag_id as usize]; let tag_field_layouts = if let TagName::Closure(_) = tag_name {
for (field_symbol, tag_field_layout) in arguments.iter().zip(tag_field_layouts.iter()) { // closures ignore (and do not store) the discriminant
let (val, _val_layout) = load_symbol_and_layout(env, scope, field_symbol); &fields[*tag_id as usize][1..]
} else {
&fields[*tag_id as usize]
};
// this check fails for recursive tag unions, but can be helpful while debugging for (field_symbol, tag_field_layout) in arguments.iter().zip(tag_field_layouts.iter()) {
// debug_assert_eq!(tag_field_layout, val_layout); let (val, val_layout) = load_symbol_and_layout(env, scope, field_symbol);
// Zero-sized fields have no runtime representation. // Zero-sized fields have no runtime representation.
// The layout of the struct expects them to be dropped! // The layout of the struct expects them to be dropped!
@ -852,6 +857,9 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
field_vals.push(ptr); field_vals.push(ptr);
} else { } else {
// this check fails for recursive tag unions, but can be helpful while debugging
debug_assert_eq!(tag_field_layout, val_layout);
field_vals.push(val); field_vals.push(val);
} }
} }

View file

@ -260,10 +260,17 @@ impl<'a> ClosureLayout<'a> {
Layout::Union(tags) => { Layout::Union(tags) => {
// NOTE it's very important that this Union consists of Closure tags // NOTE it's very important that this Union consists of Closure tags
// and is not an unpacked 1-element record // and is not an unpacked 1-element record
let tag_id = self
.captured
.iter()
.position(|(tn, _)| *tn == TagName::Closure(original))
.unwrap() as _;
let expr = Expr::Tag { let expr = Expr::Tag {
tag_layout: Layout::Union(tags), tag_layout: Layout::Union(tags),
tag_name: TagName::Closure(original), tag_name: TagName::Closure(original),
tag_id: 0, tag_id,
union_size: tags.len() as u8, union_size: tags.len() as u8,
arguments: symbols, arguments: symbols,
}; };

View file

@ -5,5 +5,5 @@ app "effect-example"
main : Task.Task {} F64 main : Task.Task {} F64
main = main =
# Task.after (Task.putLine "foo") \{} -> Task.putLine "bar" # Task.after (Task.always "foo") (\_ -> Task.always {})
Task.after (Task.always "foo") (\_ -> Task.always {}) Task.after (Task.putLine "foo") \{} -> Task.putLine "bar"