From ac442abc11ed15d33299d2bae69c15441212a054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=C3=A4schle?= Date: Sun, 29 Aug 2021 10:57:11 +0200 Subject: [PATCH] checker: allow noreturn in match expr (#11126) --- vlib/v/checker/checker.v | 3 ++- vlib/v/gen/c/cgen.v | 15 ++++++++++++++- vlib/v/tests/match_test.v | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 467b00b4ad..cac3a24fb3 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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()) } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index d1035ca052..152d84de82 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -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 - g.write('$tmp_var = ') + 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(';') diff --git a/vlib/v/tests/match_test.v b/vlib/v/tests/match_test.v index 32a77b6b1c..25d96e13a7 100644 --- a/vlib/v/tests/match_test.v +++ b/vlib/v/tests/match_test.v @@ -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) + } + } +}