Make sure to unwrap non-nullable unwrapped unions directly in alias analysis

Non-nullable unwrapped tag unions are represented directly as the type
of their singleton variant in morphic. Other recursive tag unions are
something like `(heap_cell, union [A, B (<rec>)])` for recursive union
`[A, B (<rec>)]`, but a non-nullable unwrapped tag union `[ Foo Str <rec> ]`
is represented directly as the tuple `(Str <rec>)`. Make sure we don't
try to unwrap a non-existent heap cell and union data for such type
representations.

Closes #3261
This commit is contained in:
Ayaz Hafiz 2022-06-22 12:36:37 -04:00
parent fdba8b26d4
commit 2079a64cb7
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
2 changed files with 26 additions and 13 deletions

View file

@ -573,7 +573,8 @@ fn build_recursive_tuple_type(
let mut field_types = Vec::new();
for field in layouts.iter() {
field_types.push(layout_spec_help(builder, field, when_recursive)?);
let type_id = layout_spec_help(builder, field, when_recursive)?;
field_types.push(type_id);
}
builder.add_tuple_type(&field_types)
@ -1617,18 +1618,9 @@ fn expr_spec<'a>(
let type_name_bytes = recursive_tag_union_name_bytes(union_layout).as_bytes();
let type_name = TypeName(&type_name_bytes);
// a tuple ( cell, union { ... } )
let union_id = builder.add_unwrap_named(block, MOD_APP, type_name, tag_value_id)?;
// decompose
let heap_cell = builder.add_get_tuple_field(block, union_id, TAG_CELL_INDEX)?;
let union_data = builder.add_get_tuple_field(block, union_id, TAG_DATA_INDEX)?;
// we're reading from this value, so touch the heap cell
builder.add_touch(block, heap_cell)?;
// next, unwrap the union at the tag id that we've got
let variant_id = builder.add_unwrap_union(block, union_data, *tag_id as u32)?;
// the unwrapped recursive tag variant
let variant_id =
builder.add_unwrap_named(block, MOD_APP, type_name, tag_value_id)?;
builder.add_get_tuple_field(block, variant_id, index)
}