Open yorickpeterse opened 3 hours ago
The test failure that reveals this in turn seems to be caused by the incremental compilation changes (as in, a test fails with main
but not with 0.16.0). Oddly enough this happens with --opt=none
as well, suggesting it's not the inliner itself but some other change in the commit that broke things.
This appears to be due to a bug in pattern matching. inko-markdown has the following code:
fn mut text_line -> String {
let mut buffer = ByteArray.new
loop {
match next_token {
case Some({ @kind = SoftBreak or EmptyLine }) -> break
case Some({ @offset = offset, @size = size }) -> {
buffer.append(@lexer.input.slice(offset, size))
}
case _ -> break
}
}
buffer.into_string
}
Even when encountering a SoftBreak
node, it seems the second case
wins which is wrong. Similarly, the following program hangs indefinitely:
import std.stdio (Stdout)
class enum Letter {
case A
case B
case C
}
class Thing {
let @letter: Letter
let @number: Int
}
class async Main {
fn async main {
let out = Stdout.new
let thing = Thing(letter: Letter.C, number: 42)
match thing {
case { @letter = C } -> out.print('A or C')
case { @number = _ } -> out.print('wtf')
}
}
}
It seems that with the above code snippet, switch
instructions are miscompiled. These are the interesting blocks in question when using 0.16.0:
And when using main
:
Note how block b4
lists the destination for case 2
as b7
instead of b8
.
I'm guessing that the unreachable block removal code isn't entirely correct, resulting in these miscompilations.
Please describe the bug
I'm seeing this with inko-markdown when the tests fail: the line numbers reported aren't correct. This isn't the case when using
inko test --opt=none
.Operating system
Fedora
Inko version
main