checker: allow noreturn in match expr (#11126)

pull/11335/head
Daniel Däschle 2021-08-29 10:57:11 +02:00 committed by GitHub
parent 4ce9ad6a56
commit ac442abc11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 2 deletions

View File

@ -6124,7 +6124,8 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
if !c.check_types(ret_type, expr_type)
&& !c.check_types(expr_type, ret_type) {
ret_sym := c.table.get_type_symbol(ret_type)
if !(node.is_expr && ret_sym.kind == .sum_type) {
is_noreturn := is_noreturn_callexpr(stmt.expr)
if !(node.is_expr && ret_sym.kind == .sum_type) && !is_noreturn {
c.error('return type mismatch, it should be `$ret_sym.name`',
stmt.expr.position())
}

View File

@ -1084,6 +1084,13 @@ fn (mut g Gen) stmts(stmts []ast.Stmt) {
g.stmts_with_tmp_var(stmts, '')
}
fn is_noreturn_callexpr(expr ast.Expr) bool {
if expr is ast.CallExpr {
return expr.is_noreturn
}
return false
}
// tmp_var is used in `if` expressions only
fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) {
g.indent++
@ -1119,7 +1126,13 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) {
} else {
g.stmt_path_pos << g.out.len
g.skip_stmt_pos = true
mut is_noreturn := false
if stmt is ast.ExprStmt {
is_noreturn = is_noreturn_callexpr(stmt.expr)
}
if !is_noreturn {
g.write('$tmp_var = ')
}
g.stmt(stmt)
if !g.out.last_n(2).contains(';') {
g.writeln(';')

View File

@ -287,3 +287,17 @@ fn test_match_expression_add() {
} + 3
assert a == 4
}
type LeType = int | string
fn test_noreturn() {
t := LeType(3)
_ := match t {
int {
'test'
}
string {
exit(0)
}
}
}