diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 9cd2c2f031..543702a82a 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -4,6 +4,7 @@ module checker import v.table +import v.token pub fn (c &Checker) check_types(got, expected table.Type) bool { t := c.table @@ -126,6 +127,18 @@ pub fn (c &Checker) check_types(got, expected table.Type) bool { return false } +[inline] +fn (c &Checker) check_shift(left_type, right_type table.Type, left_pos, right_pos token.Position) table.Type { + if !left_type.is_int() { + c.error('cannot shift type ${c.table.get_type_symbol(right_type).name} into non-integer type ${c.table.get_type_symbol(left_type).name}', left_pos) + return table.void_type + } else if !right_type.is_int() { + c.error('cannot shift non-integer type ${c.table.get_type_symbol(right_type).name} into type ${c.table.get_type_symbol(left_type).name}', right_pos) + return table.void_type + } + return left_type +} + pub fn (c &Checker) promote(left_type, right_type table.Type) table.Type { if left_type.is_ptr() || left_type.is_pointer() { if right_type.is_int() { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 17ed93ec4c..fbb36af427 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -524,14 +524,13 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { s := left.name.replace('array_', '[]') c.error('cannot append `$right.name` to `$s`', right_pos) return table.void_type - } else if !left.is_int() { - c.error('cannot shift type $right.name into non-integer type $left.name', left_pos) - return table.void_type - } else if !right.is_int() { - c.error('cannot shift non-integer type $right.name into type $left.name', right_pos) - return table.void_type + } else { + return c.check_shift(left_type, right_type, left_pos, right_pos) } } + .right_shift { + return c.check_shift(left_type, right_type, left_pos, right_pos) + } .key_is { type_expr := infix_expr.right as ast.Type typ_sym := c.table.get_type_symbol(type_expr.typ) diff --git a/vlib/v/checker/tests/rshift_op_wrong_left_type_err.out b/vlib/v/checker/tests/rshift_op_wrong_left_type_err.out new file mode 100644 index 0000000000..761219a2a8 --- /dev/null +++ b/vlib/v/checker/tests/rshift_op_wrong_left_type_err.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/rshift_op_wrong_left_type_err.v:2:2: error: cannot shift type any_int into non-integer type any_float + 1 | fn main() { + 2 | 0.5 >> 1 + | ~~~ + 3 | } diff --git a/vlib/v/checker/tests/rshift_op_wrong_left_type_err.vv b/vlib/v/checker/tests/rshift_op_wrong_left_type_err.vv new file mode 100644 index 0000000000..5e4a471809 --- /dev/null +++ b/vlib/v/checker/tests/rshift_op_wrong_left_type_err.vv @@ -0,0 +1,3 @@ +fn main() { + 0.5 >> 1 +} diff --git a/vlib/v/checker/tests/rshift_op_wrong_right_type_err.out b/vlib/v/checker/tests/rshift_op_wrong_right_type_err.out new file mode 100644 index 0000000000..a7103b8582 --- /dev/null +++ b/vlib/v/checker/tests/rshift_op_wrong_right_type_err.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/rshift_op_wrong_right_type_err.v:2:7: error: cannot shift non-integer type any_float into type any_int + 1 | fn main() { + 2 | 1 >> 0.5 + | ~~~ + 3 | } diff --git a/vlib/v/checker/tests/rshift_op_wrong_right_type_err.vv b/vlib/v/checker/tests/rshift_op_wrong_right_type_err.vv new file mode 100644 index 0000000000..22abd553d3 --- /dev/null +++ b/vlib/v/checker/tests/rshift_op_wrong_right_type_err.vv @@ -0,0 +1,3 @@ +fn main() { + 1 >> 0.5 +}