From ef37f59bc27295f4dcfbc29b251edd81dad6cb13 Mon Sep 17 00:00:00 2001 From: timbasel Date: Wed, 9 Mar 2022 09:53:54 +0100 Subject: [PATCH] fix comptime `$else` `[noreturn]` function --- vlib/v/checker/return.v | 18 ++++++++++++++---- vlib/v/tests/comptime_no_return.v | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 vlib/v/tests/comptime_no_return.v diff --git a/vlib/v/checker/return.v b/vlib/v/checker/return.v index 82ac175db0..9417249984 100644 --- a/vlib/v/checker/return.v +++ b/vlib/v/checker/return.v @@ -178,6 +178,7 @@ pub fn (mut c Checker) find_unreachable_statements_after_noreturn_calls(stmts [] // Note: has_top_return/1 should be called on *already checked* stmts, // which do have their stmt.expr.is_noreturn set properly: fn has_top_return(stmts []ast.Stmt) bool { + mut has_return := false for stmt in stmts { match stmt { ast.Return { @@ -189,16 +190,25 @@ fn has_top_return(stmts []ast.Stmt) bool { } } ast.ExprStmt { - if stmt.expr is ast.CallExpr { - if stmt.expr.is_noreturn { - return true + match stmt.expr { + ast.CallExpr { + if stmt.expr.is_noreturn { + return true + } } + ast.IfExpr { + if stmt.expr.is_comptime && stmt.expr.has_else { + has_return = stmt.expr.branches.all(!it.pkg_exist + || has_top_return(it.stmts)) // `.pkg_exist` is set to `false` when the compile-time branch is skipped (and therefore does not identify `noreturn` function calls) + } + } + else {} } } else {} } } - return false + return has_return } fn (mut c Checker) check_noreturn_fn_decl(mut node ast.FnDecl) { diff --git a/vlib/v/tests/comptime_no_return.v b/vlib/v/tests/comptime_no_return.v new file mode 100644 index 0000000000..3fa1b1fb80 --- /dev/null +++ b/vlib/v/tests/comptime_no_return.v @@ -0,0 +1,16 @@ +[noreturn] +fn no_return() { + exit(0) +} + +fn abc() bool { + $if x64 { + no_return() + } $else { + no_return() + } +} + +fn main() { + abc() +}