Support guards on lists with rest

This commit is contained in:
JRI98 2024-04-30 13:08:57 +01:00
parent db97e3ed22
commit eebd4b21c3
No known key found for this signature in database
GPG key ID: F83B29916FF13F24
4 changed files with 189 additions and 1 deletions

View file

@ -185,6 +185,7 @@ impl<'r, 'a> Iterator for PatternBindingIter<'r, 'a> {
List {
element_layout,
elements,
opt_rest,
..
} => {
let stack = elements
@ -193,7 +194,11 @@ impl<'r, 'a> Iterator for PatternBindingIter<'r, 'a> {
.rev()
.collect();
*self = Stack(stack);
self.next()
match opt_rest {
Some((_, Some(rest_sym))) => (*rest_sym, layout).into(),
_ => self.next(),
}
}
IntLiteral(_, _)
| FloatLiteral(_, _)
@ -236,11 +241,16 @@ impl<'r, 'a> Iterator for PatternBindingIter<'r, 'a> {
List {
element_layout,
elements,
opt_rest,
..
} => {
stack.extend(
elements.iter().map(|p| (Pat(p), *element_layout)).rev(),
);
if let Some((_, Some(rest_sym))) = opt_rest {
return (*rest_sym, layout).into();
}
}
IntLiteral(_, _)
| FloatLiteral(_, _)

View file

@ -0,0 +1,63 @@
procedure Bool.1 ():
let Bool.24 : Int1 = false;
ret Bool.24;
procedure Test.1 (Test.4):
dec Test.4;
let Test.9 : I64 = 0i64;
ret Test.9;
procedure Test.0 ():
joinpoint Test.7 Test.2:
ret Test.2;
in
let Test.6 : List [] = Array [];
joinpoint Test.14:
let Test.11 : I64 = 2i64;
jump Test.7 Test.11;
in
joinpoint Test.13 Test.12:
let Test.8 : I64 = CallByName Test.1 Test.12;
jump Test.7 Test.8;
in
let Test.32 : U64 = lowlevel ListLenUsize Test.6;
let Test.33 : U64 = 0i64;
let Test.34 : Int1 = lowlevel Eq Test.32 Test.33;
if Test.34 then
let Test.18 : U64 = 0i64;
let Test.19 : U64 = lowlevel ListLenU64 Test.6;
let Test.20 : U64 = lowlevel NumSub Test.19 Test.18;
let Test.21 : U64 = 0i64;
let Test.3 : List [] = lowlevel ListSublist Test.6 Test.21 Test.20;
joinpoint Test.16 Test.15:
if Test.15 then
jump Test.13 Test.3;
else
dec Test.3;
let Test.10 : I64 = 1i64;
jump Test.7 Test.10;
in
let Test.17 : Int1 = CallByName Bool.1;
jump Test.16 Test.17;
else
let Test.29 : U64 = lowlevel ListLenUsize Test.6;
let Test.30 : U64 = 0i64;
let Test.31 : Int1 = lowlevel NumGte Test.29 Test.30;
if Test.31 then
let Test.25 : U64 = 0i64;
let Test.26 : U64 = lowlevel ListLenU64 Test.6;
let Test.27 : U64 = lowlevel NumSub Test.26 Test.25;
let Test.28 : U64 = 0i64;
let Test.3 : List [] = lowlevel ListSublist Test.6 Test.28 Test.27;
joinpoint Test.23 Test.22:
if Test.22 then
jump Test.13 Test.3;
else
dec Test.3;
jump Test.14;
in
let Test.24 : Int1 = CallByName Bool.1;
jump Test.23 Test.24;
else
dec Test.6;
jump Test.14;

View file

@ -0,0 +1,81 @@
procedure Bool.1 ():
let Bool.24 : Int1 = false;
ret Bool.24;
procedure Test.1 (Test.4):
dec Test.4;
let Test.9 : I64 = 0i64;
ret Test.9;
procedure Test.0 ():
joinpoint Test.7 Test.2:
ret Test.2;
in
let Test.6 : List List [] = Array [];
joinpoint Test.15:
let Test.11 : I64 = 2i64;
jump Test.7 Test.11;
in
joinpoint Test.13 Test.12:
let Test.8 : I64 = CallByName Test.1 Test.12;
jump Test.7 Test.8;
in
let Test.44 : U64 = lowlevel ListLenUsize Test.6;
let Test.45 : U64 = 1i64;
let Test.46 : Int1 = lowlevel Eq Test.44 Test.45;
if Test.46 then
let Test.39 : U64 = 0i64;
let Test.40 : List [] = lowlevel ListGetUnsafe Test.6 Test.39;
let Test.41 : U64 = lowlevel ListLenUsize Test.40;
let Test.42 : U64 = 1i64;
let Test.43 : Int1 = lowlevel Eq Test.41 Test.42;
if Test.43 then
let Test.24 : U64 = 0i64;
let Test.19 : List [] = lowlevel ListGetUnsafe Test.6 Test.24;
decref Test.6;
let Test.20 : U64 = 0i64;
let Test.21 : U64 = lowlevel ListLenU64 Test.19;
let Test.22 : U64 = lowlevel NumSub Test.21 Test.20;
let Test.23 : U64 = 0i64;
let Test.3 : List [] = lowlevel ListSublist Test.19 Test.23 Test.22;
joinpoint Test.17 Test.16:
if Test.16 then
jump Test.13 Test.3;
else
dec Test.3;
let Test.10 : I64 = 1i64;
jump Test.7 Test.10;
in
let Test.18 : Int1 = CallByName Bool.1;
jump Test.17 Test.18;
else
let Test.34 : U64 = 0i64;
let Test.35 : List [] = lowlevel ListGetUnsafe Test.6 Test.34;
let Test.36 : U64 = lowlevel ListLenUsize Test.35;
let Test.37 : U64 = 0i64;
let Test.38 : Int1 = lowlevel NumGte Test.36 Test.37;
if Test.38 then
let Test.33 : U64 = 0i64;
let Test.28 : List [] = lowlevel ListGetUnsafe Test.6 Test.33;
decref Test.6;
let Test.29 : U64 = 0i64;
let Test.30 : U64 = lowlevel ListLenU64 Test.28;
let Test.31 : U64 = lowlevel NumSub Test.30 Test.29;
let Test.32 : U64 = 0i64;
let Test.3 : List [] = lowlevel ListSublist Test.28 Test.32 Test.31;
joinpoint Test.26 Test.25:
if Test.25 then
jump Test.13 Test.3;
else
dec Test.3;
jump Test.15;
in
let Test.27 : Int1 = CallByName Bool.1;
jump Test.26 Test.27;
else
dec Test.40;
decref Test.6;
jump Test.15;
else
dec Test.6;
jump Test.15;

View file

@ -3500,3 +3500,37 @@ fn issue_6174() {
"
)
}
#[mono_test]
fn issue_6606_1() {
indoc!(
r"
foo = \_ -> 0
f =
when [] is
[.. as rest] if Bool.false -> foo rest
[] -> 1
_ -> 2
f
"
)
}
#[mono_test]
fn issue_6606_2() {
indoc!(
r"
foo = \_ -> 0
f =
when [] is
[[.. as rest]] if Bool.false -> foo rest
[[_]] -> 1
_ -> 2
f
"
)
}