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:
parent
4747e70d9d
commit
bb512f782e
@ -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))
|
||||
|
@ -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
|
||||
//
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user