1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker, ast: add field promoted_type for InfixExpr, filled in by the checker, to save duplicate work in the backends (#17158)

This commit is contained in:
l-m 2023-01-29 19:06:05 +00:00 committed by GitHub
parent 4747e70d9d
commit bb512f782e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 10 deletions

View File

@ -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))

View File

@ -870,6 +870,7 @@ pub mut:
right Expr
left_type Type
right_type Type
promoted_type Type = void_type
auto_locked string
or_block OrExpr
//

View File

@ -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) {