diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index c4b4e69fff..a887afd1b5 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -1276,7 +1276,15 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) { p.error_with_token_index( 'incompatible types: $p.assigned_type != $p.expected_type', errtok) } p.cgen.resetln('memcpy( (& $left), ($etype{$expr}), sizeof( $left ) );') - } + } + else if tok == .left_shift_assign || tok == .righ_shift_assign { + if !is_integer_type(p.assigned_type) { + p.error_with_token_index( 'cannot use shift operator on non-integer type `$p.assigned_type`', errtok) + } + if !is_integer_type(expr_type) { + p.error_with_token_index( 'cannot use non-integer type `$expr_type` as shift argument', errtok) + } + } else if !p.builtin_mod && !p.check_types_no_throw(expr_type, p.assigned_type) { p.error_with_token_index( 'cannot use type `$expr_type` as type `$p.assigned_type` in assignment', errtok) } @@ -2409,6 +2417,9 @@ fn (p mut Parser) expression() string { return 'void' } else { + if !is_integer_type(typ) { + p.error('cannot use shift operator on non-integer type `$typ`') + } p.next() p.gen(' << ') p.check_types(p.expression(), 'integer') @@ -2416,6 +2427,9 @@ fn (p mut Parser) expression() string { } } if p.tok == .righ_shift { + if !is_integer_type(typ) { + p.error('cannot use shift operator on non-integer type `$typ`') + } p.next() p.gen(' >> ') p.check_types(p.expression(), 'integer') diff --git a/vlib/compiler/tests/shift_test.v b/vlib/compiler/tests/shift_test.v index 5d3460afdd..3438784c03 100644 --- a/vlib/compiler/tests/shift_test.v +++ b/vlib/compiler/tests/shift_test.v @@ -30,4 +30,40 @@ fn test_shift_operators() { d := u64(1) c = d << i8(63) assert c == 9223372036854775808 + + // check that shift-assign works with all types + // of integers on the right-hand side + mut e := 1 + e <<= i8(i) + assert e == b + e >>= i8(i) + assert e == a + e <<= i16(i) + assert e == b + e >>= i16(i) + assert e == a + e <<= int(i) + assert e == b + e >>= int(i) + assert e == a + e <<= i64(i) + assert e == b + e >>= i64(i) + assert e == a + e <<= byte(i) + assert e == b + e >>= byte(i) + assert e == a + e <<= u16(i) + assert e == b + e >>= u16(i) + assert e == a + e <<= u32(i) + assert e == b + e >>= u32(i) + assert e == a + e <<= u64(i) + assert e == b + e >>= u64(i) + assert e == a } \ No newline at end of file