compiler: fix non exhaustive conditions in inlined functions bug#65
compiler: fix non exhaustive conditions in inlined functions bug#65
Conversation
|
Super cool that you attacked this bug, it's not a simple one. I tried to play a bit with the tests and this program compiles but there is an error at runtime: let program = r#"
fn main() {
b = doesnt_work(1);
print(b);
return;
}
fn doesnt_work(x) inline -> 1 {
if x == 1 {
if x == 0 {
return 100;
}
}
return 200;
}
"#;
compile_and_run(program, &[], &[], false);Do you have an idea of the issue? I will try to have a look at your code when I find some time |
Let me check I had hard time dealing with the tests when some of them are passing but when I imagined new configs, it doesn't always pass, let me check this precise one. |
|
@TomWambsgans Let me know if this last commit fixes the problem or if you find another edge config where the test fails? |
let program = r#"
fn main() {
b = doesnt_work(1);
print(b);
return;
}
fn doesnt_work(x) inline -> 1 {
if x == 1 {
if x == 0 {
return 100;
}
if x == 1 {
return 200;
}
}
return 300;
}
"#;
compile_and_run(program, &[], &[], false); |
|
I'm investigating a bit more, can't find in a simple way why this is failing, I've these tests that should pass for the implementation to be correct (I've added a bunch of them to prevent us finding some strange edge case after merging a fix that us thinkint this is the right one): #[test]
fn test_inline_multiple_returns() {
let program = r#"
fn main() {
result = conditional_return(5);
print(result);
return;
}
fn conditional_return(x) inline -> 1 {
if x == 5 {
return 100;
} else {
if x == 3 {
return 200;
} else {
return 300;
}
}
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_inline_complex_multiple_returns() {
let program = r#"
fn main() {
result1 = complex_return(1, 2);
result2 = complex_return(3, 4);
print(result1);
print(result2);
return;
}
fn complex_return(a, b) inline -> 1 {
sum = a + b;
if sum == 3 {
return 100;
} else {
if sum == 7 {
return 200;
} else {
if a == 1 {
return 150;
} else {
return 300;
}
}
}
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_inline_non_exhaustive_conditions() {
let program = r#"
fn main() {
result1 = works(0);
result2 = works(1);
result3 = should_work(0);
result4 = should_work(1);
print(result1);
print(result2);
print(result3);
print(result4);
return;
}
fn works(x) inline -> 1 {
if x == 0 {
return 0;
} else {
return 1;
}
}
fn should_work(x) inline -> 1 {
if x == 0 {
return 0;
}
return 1;
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_inline_edge_cases() {
let program = r#"
fn main() {
b = should_work(1);
print(b);
return;
}
fn should_work(x) inline -> 1 {
if x == 1 {
if x == 0 {
return 100;
}
}
return 200;
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_inline_edge_cases1() {
let program = r#"
fn main() {
b = doesnt_work(1);
print(b);
return;
}
fn doesnt_work(x) inline -> 1 {
if x == 1 {
if x == 0 {
return 100;
}
if x == 1 {
return 200;
}
}
return 300;
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_simple_exhaustive() {
let program = r#"
fn main() {
result = simple(1);
print(result);
return;
}
fn simple(x) inline -> 1 {
if x == 0 {
return 100;
} else {
return 200;
}
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_simple_non_exhaustive() {
let program = r#"
fn main() {
result = simple(1);
print(result);
return;
}
fn simple(x) inline -> 1 {
if x == 0 {
return 100;
}
return 200;
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_nested_exhaustive() {
let program = r#"
fn main() {
result = nested(1);
print(result);
return;
}
fn nested(x) inline -> 1 {
if x == 1 {
if x == 0 {
return 100;
} else {
return 200;
}
} else {
return 300;
}
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_nested_non_exhaustive_simple() {
let program = r#"
fn main() {
result = nested(1);
print(result);
return;
}
fn nested(x) inline -> 1 {
if x == 1 {
if x == 0 {
return 100;
}
}
return 200;
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_nested_non_exhaustive_complex() {
let program = r#"
fn main() {
result = nested(1);
print(result);
return;
}
fn nested(x) inline -> 1 {
if x == 1 {
if x == 0 {
return 100;
}
if x == 1 {
return 200;
}
}
return 300;
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_triple_nested() {
let program = r#"
fn main() {
result = triple(1);
print(result);
return;
}
fn triple(x) inline -> 1 {
if x == 1 {
if x == 2 {
if x == 3 {
return 100;
}
return 200;
}
if x == 1 {
return 300;
}
}
return 400;
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_multiple_conditions_same_level() {
let program = r#"
fn main() {
result = multiple(2);
print(result);
return;
}
fn multiple(x) inline -> 1 {
if x == 1 {
return 100;
}
if x == 2 {
return 200;
}
if x == 3 {
return 300;
}
return 400;
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_mixed_patterns() {
let program = r#"
fn main() {
result1 = mixed(0);
result2 = mixed(1);
result3 = mixed(2);
print(result1);
print(result2);
print(result3);
return;
}
fn mixed(x) inline -> 1 {
if x == 0 {
return 100;
} else {
if x == 1 {
if x == 2 {
return 200;
}
return 300;
}
}
return 400;
}
"#;
compile_and_run(program, &[], &[], false);
}
#[test]
fn test_all_cases_comprehensive() {
let program = r#"
fn main() {
// Test all different input values
for i in 0..4 {
result = comprehensive(i);
print(result);
}
return;
}
fn comprehensive(x) inline -> 1 {
if x == 0 {
return 1000;
}
if x == 1 {
if x == 2 {
return 2000;
}
if x == 1 {
return 3000;
}
}
if x == 2 {
if x == 0 {
return 4000;
} else {
return 5000;
}
}
return 6000;
}
"#;
compile_and_run(program, &[], &[], false);
} |
6283fa4 to
4b0ae0a
Compare
Should close #54