From f10ff0353e50004cdea340229072e31c9ec17c03 Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 19 Aug 2022 14:50:46 +0800 Subject: [PATCH] checker, fmt: check infix_expr with 'and' op (#15466) --- vlib/v/checker/infix.v | 5 +++++ vlib/v/checker/tests/infix_and_op_expr_err.out | 7 +++++++ vlib/v/checker/tests/infix_and_op_expr_err.vv | 5 +++++ vlib/v/fmt/fmt.v | 5 +++++ vlib/v/fmt/tests/infix_expr_and_op_expected.vv | 5 +++++ vlib/v/fmt/tests/infix_expr_and_op_input.vv | 5 +++++ 6 files changed, 32 insertions(+) create mode 100644 vlib/v/checker/tests/infix_and_op_expr_err.out create mode 100644 vlib/v/checker/tests/infix_and_op_expr_err.vv create mode 100644 vlib/v/fmt/tests/infix_expr_and_op_expected.vv create mode 100644 vlib/v/fmt/tests/infix_expr_and_op_input.vv diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 479e69e523..cddd41b3aa 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -20,6 +20,11 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { if node.op == .key_is { c.inside_x_is_type = false } + if node.op == .amp && left_type.is_bool() && right_type.is_bool() && right_type.is_ptr() { + pos := node.pos.extend(node.right.pos()) + c.error('the right expression should be separated from the `&&` by a space', pos) + return ast.bool_type + } node.right_type = right_type if left_type.is_number() && !left_type.is_ptr() && right_type in [ast.int_literal_type, ast.float_literal_type] { diff --git a/vlib/v/checker/tests/infix_and_op_expr_err.out b/vlib/v/checker/tests/infix_and_op_expr_err.out new file mode 100644 index 0000000000..c01732b8e0 --- /dev/null +++ b/vlib/v/checker/tests/infix_and_op_expr_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/infix_and_op_expr_err.vv:3:17: error: the right expression should be separated from the `&&` by a space + 1 | fn main() { + 2 | ok1 := true + 3 | ok2 := false&&ok1 + | ~~ + 4 | println(ok2) + 5 | } diff --git a/vlib/v/checker/tests/infix_and_op_expr_err.vv b/vlib/v/checker/tests/infix_and_op_expr_err.vv new file mode 100644 index 0000000000..ac44021dd0 --- /dev/null +++ b/vlib/v/checker/tests/infix_and_op_expr_err.vv @@ -0,0 +1,5 @@ +fn main() { + ok1 := true + ok2 := false&&ok1 + println(ok2) +} diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index fc6cdf0995..43a8898049 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -2055,16 +2055,21 @@ pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) { f.expr(node.left) is_one_val_array_init := node.op in [.key_in, .not_in] && node.right is ast.ArrayInit && (node.right as ast.ArrayInit).exprs.len == 1 + is_and := node.op == .amp && f.node_str(node.right).starts_with('&') if is_one_val_array_init { // `var in [val]` => `var == val` op := if node.op == .key_in { ' == ' } else { ' != ' } f.write(op) + } else if is_and { + f.write(' && ') } else { f.write(' $node.op.str() ') } if is_one_val_array_init { // `var in [val]` => `var == val` f.expr((node.right as ast.ArrayInit).exprs[0]) + } else if is_and { + f.write(f.node_str(node.right).trim_string_left('&')) } else { f.expr(node.right) } diff --git a/vlib/v/fmt/tests/infix_expr_and_op_expected.vv b/vlib/v/fmt/tests/infix_expr_and_op_expected.vv new file mode 100644 index 0000000000..450dfd6c35 --- /dev/null +++ b/vlib/v/fmt/tests/infix_expr_and_op_expected.vv @@ -0,0 +1,5 @@ +fn main() { + ok1 := true + ok2 := false && ok1 + println(ok2) +} diff --git a/vlib/v/fmt/tests/infix_expr_and_op_input.vv b/vlib/v/fmt/tests/infix_expr_and_op_input.vv new file mode 100644 index 0000000000..ac44021dd0 --- /dev/null +++ b/vlib/v/fmt/tests/infix_expr_and_op_input.vv @@ -0,0 +1,5 @@ +fn main() { + ok1 := true + ok2 := false&&ok1 + println(ok2) +}