walk the chain till we find a tag union to make recursive

This commit is contained in:
Folkert 2021-12-31 14:26:23 +01:00
parent 4c62e335e5
commit 2c97c840fc
2 changed files with 58 additions and 1 deletions

View File

@ -3138,3 +3138,49 @@ fn alias_defined_out_of_order() {
RocStr
);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
fn recursively_build_effect() {
assert_evals_to!(
indoc!(
r#"
app "test" provides [ main ] to "./platform"
greeting =
hi = "Hello"
name = "World"
"\(hi), \(name)!"
main =
when nestHelp 4 is
_ -> greeting
nestHelp : I64 -> XEffect {}
nestHelp = \m ->
when m is
0 ->
always {}
_ ->
always {} |> after \_ -> nestHelp (m - 1)
XEffect a : [ @XEffect ({} -> a) ]
always : a -> XEffect a
always = \x -> @XEffect (\{} -> x)
after : XEffect a, (a -> XEffect b) -> XEffect b
after = \(@XEffect e), toB ->
@XEffect \{} ->
when toB (e {}) is
@XEffect e2 ->
e2 {}
"#
),
RocStr::from_slice(b"Hello, World!"),
RocStr
);
}

View File

@ -833,10 +833,21 @@ enum OtherTags2 {
}
fn maybe_mark_tag_union_recursive(subs: &mut Subs, tag_union_var: Variable) {
while let Err((recursive, _chain)) = subs.occurs(tag_union_var) {
'outer: while let Err((recursive, chain)) = subs.occurs(tag_union_var) {
let description = subs.get(recursive);
if let Content::Structure(FlatType::TagUnion(tags, ext_var)) = description.content {
subs.mark_tag_union_recursive(recursive, tags, ext_var);
} else {
// walk the chain till we find a tag union
for v in &chain[..chain.len() - 1] {
let description = subs.get(*v);
if let Content::Structure(FlatType::TagUnion(tags, ext_var)) = description.content {
subs.mark_tag_union_recursive(*v, tags, ext_var);
continue 'outer;
}
}
panic!("recursive loop does not contain a tag union")
}
}
}