mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
set correct closure tag_id
This commit is contained in:
parent
752a2200fd
commit
539f173472
3 changed files with 23 additions and 8 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue