From 71e8fc8b387c36493107ed60947a52c51acb9acc Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 14 Jan 2023 10:06:38 -0300 Subject: [PATCH] checker: fix comptime if branch checking (#16938) --- vlib/v/checker/if.v | 3 ++- vlib/v/checker/return.v | 4 +++- ...ching_working_with_a_custom_compile_error.out | 7 +++++++ ...nching_working_with_a_custom_compile_error.vv | 16 ++++++++++++++++ ...ranching_working_without_compile_error_test.v | 16 ++++++++++++++++ 5 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/comptime_branching_working_with_a_custom_compile_error.out create mode 100644 vlib/v/checker/tests/comptime_branching_working_with_a_custom_compile_error.vv create mode 100644 vlib/v/tests/comptime_branching_working_without_compile_error_test.v diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index 2fc65f35de..bb76022b07 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -131,8 +131,9 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } else if skip_state == .skip { c.skip_flags = true skip_state = .unknown // Reset the value of `skip_state` for the next branch - } else if !is_comptime_type_is_expr && skip_state == .eval { + } else if skip_state == .eval { found_branch = true // If a branch wasn't skipped, the rest must be + c.skip_flags = skip_state == .skip } if c.fn_level == 0 && c.pref.output_cross_c { // do not skip any of the branches for top level `$if OS {` diff --git a/vlib/v/checker/return.v b/vlib/v/checker/return.v index 2a19338132..5f853a18bc 100644 --- a/vlib/v/checker/return.v +++ b/vlib/v/checker/return.v @@ -270,7 +270,9 @@ fn has_top_return(stmts []ast.Stmt) bool { } ast.ExprStmt { if stmt.expr is ast.CallExpr { - if stmt.expr.is_noreturn { + // do not ignore panic() calls on non checked stmts + if stmt.expr.is_noreturn + || (stmt.expr.is_method == false && stmt.expr.name == 'panic') { return true } } diff --git a/vlib/v/checker/tests/comptime_branching_working_with_a_custom_compile_error.out b/vlib/v/checker/tests/comptime_branching_working_with_a_custom_compile_error.out new file mode 100644 index 0000000000..108dd4d618 --- /dev/null +++ b/vlib/v/checker/tests/comptime_branching_working_with_a_custom_compile_error.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/comptime_branching_working_with_a_custom_compile_error.vv:8:3: error: 11 + 6 | return Value(val) + 7 | } $else { + 8 | $compile_error('11') + | ~~~~~~~~~~~~~~~~~~~~ + 9 | println('not bool ${val}') + 10 | } diff --git a/vlib/v/checker/tests/comptime_branching_working_with_a_custom_compile_error.vv b/vlib/v/checker/tests/comptime_branching_working_with_a_custom_compile_error.vv new file mode 100644 index 0000000000..8310eb7a8d --- /dev/null +++ b/vlib/v/checker/tests/comptime_branching_working_with_a_custom_compile_error.vv @@ -0,0 +1,16 @@ +type Value = bool | voidptr + +pub fn create[T](val T) Value { + $if T is bool { + println('bool ${val}') + return Value(val) + } $else { + $compile_error('11') + println('not bool ${val}') + } + return Value(voidptr(123)) +} + +fn main() { + println(create(123)) +} diff --git a/vlib/v/tests/comptime_branching_working_without_compile_error_test.v b/vlib/v/tests/comptime_branching_working_without_compile_error_test.v new file mode 100644 index 0000000000..cf507bd74d --- /dev/null +++ b/vlib/v/tests/comptime_branching_working_without_compile_error_test.v @@ -0,0 +1,16 @@ +type Value = bool | voidptr + +pub fn create[T](val T) Value { + $if T is bool { + println('bool ${val}') + return Value(val) + } $else { + $compile_error('11') + println('not bool ${val}') + } + return Value(voidptr(123)) +} + +fn test_calling_generic_function_that_has_inside_a_comptime_compile_error_directive() { + assert create(true) == Value(true) +}