@@ -1441,62 +1441,93 @@ pub fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_re
14411441 return
14421442 }
14431443 last_stmt := node.stmts[stmts_len - 1 ]
1444+ c.check_or_last_stmt (last_stmt, ret_type, expr_return_type)
1445+ }
1446+
1447+ fn (mut c Checker) check_or_last_stmt (stmt ast.Stmt, ret_type ast.Type, expr_return_type ast.Type) {
14441448 if ret_type != ast.void_type {
1445- match last_stmt {
1449+ match stmt {
14461450 ast.ExprStmt {
14471451 c.expected_type = ret_type
14481452 c.expected_or_type = ret_type.clear_flag (.optional)
1449- last_stmt_typ := c.expr (last_stmt .expr)
1453+ last_stmt_typ := c.expr (stmt .expr)
14501454 c.expected_or_type = ast.void_type
14511455 type_fits := c.check_types (last_stmt_typ, ret_type)
14521456 && last_stmt_typ.nr_muls () == ret_type.nr_muls ()
1453- is_noreturn := is_noreturn_callexpr (last_stmt .expr)
1457+ is_noreturn := is_noreturn_callexpr (stmt .expr)
14541458 if type_fits || is_noreturn {
14551459 return
14561460 }
14571461 expected_type_name := c.table.type_to_str (ret_type.clear_flag (.optional))
1458- if last_stmt.typ == ast.void_type {
1462+ if stmt.typ == ast.void_type {
1463+ if stmt.expr is ast.IfExpr {
1464+ for branch in stmt.expr.branches {
1465+ last_stmt := branch.stmts[branch.stmts.len - 1 ]
1466+ c.check_or_last_stmt (last_stmt, ret_type, expr_return_type)
1467+ }
1468+ return
1469+ } else if stmt.expr is ast.MatchExpr {
1470+ for branch in stmt.expr.branches {
1471+ last_stmt := branch.stmts[branch.stmts.len - 1 ]
1472+ c.check_or_last_stmt (last_stmt, ret_type, expr_return_type)
1473+ }
1474+ return
1475+ }
14591476 c.error ('`or` block must provide a default value of type `$expected_type_name `, or return/continue/break or call a [noreturn] function like panic(err) or exit(1)' ,
1460- last_stmt. pos)
1477+ stmt.expr. pos () )
14611478 } else {
14621479 type_name := c.table.type_to_str (last_stmt_typ)
14631480 c.error ('wrong return type `$type_name ` in the `or {}` block, expected `$expected_type_name `' ,
1464- last_stmt. pos)
1481+ stmt.expr. pos () )
14651482 }
1466- return
14671483 }
14681484 ast.BranchStmt {
1469- if last_stmt .kind ! in [.key_continue, .key_break] {
1485+ if stmt .kind ! in [.key_continue, .key_break] {
14701486 c.error ('only break/continue is allowed as a branch statement in the end of an `or {}` block' ,
1471- last_stmt .pos)
1487+ stmt .pos)
14721488 return
14731489 }
14741490 }
14751491 ast.Return {}
14761492 else {
14771493 expected_type_name := c.table.type_to_str (ret_type.clear_flag (.optional))
14781494 c.error ('last statement in the `or {}` block should be an expression of type `$expected_type_name ` or exit parent scope' ,
1479- node.pos)
1480- return
1495+ stmt.pos)
14811496 }
14821497 }
14831498 } else {
1484- match last_stmt {
1499+ match stmt {
14851500 ast.ExprStmt {
1486- if last_stmt.typ == ast.void_type {
1487- return
1488- }
1489- if is_noreturn_callexpr (last_stmt.expr) {
1490- return
1491- }
1492- if c.check_types (last_stmt.typ, expr_return_type) {
1493- return
1501+ match stmt.expr {
1502+ ast.IfExpr {
1503+ for branch in stmt.expr.branches {
1504+ last_stmt := branch.stmts[branch.stmts.len - 1 ]
1505+ c.check_or_last_stmt (last_stmt, ret_type, expr_return_type)
1506+ }
1507+ }
1508+ ast.MatchExpr {
1509+ for branch in stmt.expr.branches {
1510+ last_stmt := branch.stmts[branch.stmts.len - 1 ]
1511+ c.check_or_last_stmt (last_stmt, ret_type, expr_return_type)
1512+ }
1513+ }
1514+ else {
1515+ if stmt.typ == ast.void_type {
1516+ return
1517+ }
1518+ if is_noreturn_callexpr (stmt.expr) {
1519+ return
1520+ }
1521+ if c.check_types (stmt.typ, expr_return_type) {
1522+ return
1523+ }
1524+ // opt_returning_string() or { ... 123 }
1525+ type_name := c.table.type_to_str (stmt.typ)
1526+ expr_return_type_name := c.table.type_to_str (expr_return_type)
1527+ c.error ('the default expression type in the `or` block should be `$expr_return_type_name `, instead you gave a value of type `$type_name `' ,
1528+ stmt.expr.pos ())
1529+ }
14941530 }
1495- // opt_returning_string() or { ... 123 }
1496- type_name := c.table.type_to_str (last_stmt.typ)
1497- expr_return_type_name := c.table.type_to_str (expr_return_type)
1498- c.error ('the default expression type in the `or` block should be `$expr_return_type_name `, instead you gave a value of type `$type_name `' ,
1499- last_stmt.expr.pos ())
15001531 }
15011532 else {}
15021533 }
0 commit comments