mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
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:
parent
fdba8b26d4
commit
2079a64cb7
2 changed files with 26 additions and 13 deletions
|
@ -573,7 +573,8 @@ fn build_recursive_tuple_type(
|
||||||
let mut field_types = Vec::new();
|
let mut field_types = Vec::new();
|
||||||
|
|
||||||
for field in layouts.iter() {
|
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)
|
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_bytes = recursive_tag_union_name_bytes(union_layout).as_bytes();
|
||||||
let type_name = TypeName(&type_name_bytes);
|
let type_name = TypeName(&type_name_bytes);
|
||||||
|
|
||||||
// a tuple ( cell, union { ... } )
|
// the unwrapped recursive tag variant
|
||||||
let union_id = builder.add_unwrap_named(block, MOD_APP, type_name, tag_value_id)?;
|
let variant_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)?;
|
|
||||||
|
|
||||||
builder.add_get_tuple_field(block, variant_id, index)
|
builder.add_get_tuple_field(block, variant_id, index)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1703,3 +1703,24 @@ fn issue_2900_unreachable_pattern() {
|
||||||
true // ignore type errors
|
true // ignore type errors
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
|
fn issue_3261_non_nullable_unwrapped_recursive_union_at_index() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
Named : [Named Str (List Named)]
|
||||||
|
|
||||||
|
foo : Named
|
||||||
|
foo = Named "outer" [Named "inner" []]
|
||||||
|
|
||||||
|
Named name outerList = foo
|
||||||
|
|
||||||
|
{name, outerList}.name
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
RocStr::from("outer"),
|
||||||
|
RocStr
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue