From bb512f782e836ba555b8c9fc832e35ad07df0423 Mon Sep 17 00:00:00 2001 From: l-m Date: Sun, 29 Jan 2023 19:06:05 +0000 Subject: [PATCH] checker, ast: add field `promoted_type` for `InfixExpr`, filled in by the checker, to save duplicate work in the backends (#17158) --- cmd/tools/vast/vast.v | 1 + vlib/v/ast/ast.v | 13 +++++++------ vlib/v/checker/infix.v | 18 ++++++++++++++---- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/cmd/tools/vast/vast.v b/cmd/tools/vast/vast.v index 9482bfa689..4e20a02b24 100644 --- a/cmd/tools/vast/vast.v +++ b/cmd/tools/vast/vast.v @@ -1350,6 +1350,7 @@ fn (t Tree) infix_expr(node ast.InfixExpr) &Node { obj.add_terse('left_type', t.type_node(node.left_type)) obj.add_terse('right', t.expr(node.right)) obj.add_terse('right_type', t.type_node(node.right_type)) + obj.add_terse('promoted_type', t.type_node(node.promoted_type)) obj.add('auto_locked', t.string_node(node.auto_locked)) obj.add_terse('or_block', t.or_expr(node.or_block)) obj.add_terse('is_stmt', t.bool_node(node.is_stmt)) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index d3885bb668..c3d5add4db 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -866,12 +866,13 @@ pub: pos token.Pos is_stmt bool pub mut: - left Expr - right Expr - left_type Type - right_type Type - auto_locked string - or_block OrExpr + left Expr + right Expr + left_type Type + right_type Type + promoted_type Type = void_type + auto_locked string + or_block OrExpr // ct_left_value_evaled bool ct_left_value ComptTimeConstValue = empty_comptime_const_expr() diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index d0279fcf2b..315ceabb1d 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -23,6 +23,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { 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) + node.promoted_type = ast.bool_type return ast.bool_type } node.right_type = right_type @@ -188,6 +189,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { node.pos) } } + node.promoted_type = ast.bool_type return ast.bool_type } .plus, .minus, .mul, .div, .mod, .xor, .amp, .pipe { @@ -367,6 +369,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { c.error('only `==` and `!=` are defined on arrays', node.pos) } else if left_sym.kind == .struct_ && (left_sym.info as ast.Struct).generic_types.len > 0 { + node.promoted_type = ast.bool_type return ast.bool_type } else if left_sym.kind == .struct_ && right_sym.kind == .struct_ && node.op in [.eq, .lt] { @@ -489,11 +492,13 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { c.error('cannot append `${right_sym.name}` to `${left_sym.name}`', right_pos) return ast.void_type } else { - return c.check_shift(mut node, left_type, right_type) + node.promoted_type = c.check_shift(mut node, left_type, right_type) + return node.promoted_type } } .right_shift { - return c.check_shift(mut node, left_type, right_type) + node.promoted_type = c.check_shift(mut node, left_type, right_type) + return node.promoted_type } .unsigned_right_shift { modified_left_type := if !left_type.is_int() { @@ -538,7 +543,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { or_block: node.or_block } - return c.check_shift(mut node, left_type, right_type) + node.promoted_type = c.check_shift(mut node, left_type, right_type) + + return node.promoted_type } .key_is, .not_is { right_expr := node.right @@ -579,6 +586,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { } } } + node.promoted_type = ast.bool_type return ast.bool_type } .arrow { // `chan <- elem` @@ -677,6 +685,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { } if left_type.nr_muls() > 0 && right_type.is_int() { // pointer arithmetic is fine, it is checked in other places + node.promoted_type = return_type return return_type } c.error('infix expr: cannot use `${right_sym.name}` (right expression) as `${left_sym.name}`', @@ -698,7 +707,8 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { c.warn('`++` and `--` are statements, not expressions', node.pos) } */ - return if node.op.is_relational() { ast.bool_type } else { return_type } + node.promoted_type = if node.op.is_relational() { ast.bool_type } else { return_type } + return node.promoted_type } fn (mut c Checker) check_div_mod_by_zero(expr ast.Expr, op_kind token.Kind) {