checker: allow noreturn in if expr (#12462)

pull/12499/head
zakuro 2021-11-15 17:29:58 +09:00 committed by GitHub
parent d8479f107f
commit 5e75c89b71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 0 deletions

View File

@ -6870,6 +6870,10 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
&& c.table.get_type_symbol(former_expected_type).kind == .sum_type {
continue
}
if is_noreturn_callexpr(last_expr.expr) {
continue
}
c.error('mismatched types `${c.table.type_to_str(node.typ)}` and `${c.table.type_to_str(last_expr.typ)}`',
node.pos)
}

View File

@ -5159,6 +5159,9 @@ fn (mut g Gen) need_tmp_var_in_if(node ast.IfExpr) bool {
if branch.stmts.len == 1 {
if branch.stmts[0] is ast.ExprStmt {
stmt := branch.stmts[0] as ast.ExprStmt
if is_noreturn_callexpr(stmt.expr) {
return true
}
if stmt.expr is ast.CallExpr {
if stmt.expr.is_method {
left_sym := g.table.get_type_symbol(stmt.expr.receiver_type)

View File

@ -234,3 +234,32 @@ fn test_if_expr_with_or_block() {
a := if arr.len == 0 || arr[0] == '-' { 123 } else { return_optional() or { -1 } }
assert a == 1
}
type Num = f32 | f64 | i64 | int
[noreturn]
fn assert_false_noreturn() {
assert false
exit(1)
}
fn test_noreturn() {
n := Num(int(0))
_ := if n is int {
n
} else if n is f32 {
int(n)
} else {
exit(1)
}
_ := if 1 == 0 {
0
} else if 1 == 1 {
1
} else if 1 == 2 {
panic('err')
} else {
assert_false_noreturn()
}
}