From 0c174104fc094ea8937d2131fc72e58e4c4c55d3 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 4 Oct 2020 15:29:05 +0300 Subject: [PATCH] checker: allow &=,|=,^=,%= on an integer number type aliases --- vlib/v/checker/checker.v | 12 ++++--- .../assign_bitops_with_type_aliases_test.v | 18 +++++++++++ vlib/v/tests/cast_to_byte_test.v | 32 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 vlib/v/tests/assign_bitops_with_type_aliases_test.v create mode 100644 vlib/v/tests/cast_to_byte_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 750ac33190..ee7c121f74 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2022,19 +2022,23 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { } } .mult_assign, .div_assign { - if !left_sym.is_number() { + if !left_sym.is_number() && + !c.table.get_final_type_symbol(left_type_unwrapped).is_int() { c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.source_name`', left.position()) - } else if !right_sym.is_number() { + } else if !right_sym.is_number() && + !c.table.get_final_type_symbol(left_type_unwrapped).is_int() { c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.source_name`', right.position()) } } .and_assign, .or_assign, .xor_assign, .mod_assign, .left_shift_assign, .right_shift_assign { - if !left_sym.is_int() { + if !left_sym.is_int() && + !c.table.get_final_type_symbol(left_type_unwrapped).is_int() { c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.source_name`', left.position()) - } else if !right_sym.is_int() { + } else if !right_sym.is_int() && + !c.table.get_final_type_symbol(right_type_unwrapped).is_int() { c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.source_name`', right.position()) } diff --git a/vlib/v/tests/assign_bitops_with_type_aliases_test.v b/vlib/v/tests/assign_bitops_with_type_aliases_test.v new file mode 100644 index 0000000000..9e7860de6e --- /dev/null +++ b/vlib/v/tests/assign_bitops_with_type_aliases_test.v @@ -0,0 +1,18 @@ +// see https://discordapp.com/channels/592103645835821068/592114487759470596/762271917293043762 +const ( + steamid_id_shift = 2 + steamid_id_mask = 0x04 +) + +type SteamId = u64 + +fn (mut s SteamId) set_id(i u32) { + (*s) &= ~steamid_id_mask + (*s) |= ((u64(i) << steamid_id_shift) & steamid_id_mask) +} + +fn test_bitops_work_with_type_aliases() { + mut x := SteamId(123) + x.set_id(5) + assert 'x: $x' == 'x: 127' +} diff --git a/vlib/v/tests/cast_to_byte_test.v b/vlib/v/tests/cast_to_byte_test.v new file mode 100644 index 0000000000..5147f81ad9 --- /dev/null +++ b/vlib/v/tests/cast_to_byte_test.v @@ -0,0 +1,32 @@ +// see: https://discordapp.com/channels/592103645835821068/592114487759470596/762270244566728704 +enum WireType { + varint = 0 + _64bit = 1 + length_prefixed = 2 + _32bit = 5 +} + +fn pack_wire_type(w WireType) byte { + return byte(w) +} + +fn test_casting_an_enum_to_byte() { + x := WireType.length_prefixed + y := pack_wire_type(x) + assert 'x: $x' == 'x: length_prefixed' + assert 'y: $y.hex()' == 'y: 02' +} + +// + +fn test_casting_a_float_to_byte() { + x := 1.23 + b := byte(x) + assert 'x: $x | b: $b.hex()' == 'x: 1.23 | b: 01' +} + +fn test_casting_an_int_to_byte() { + x := 12 + b := byte(x) + assert 'x: $x | b: $b.hex()' == 'x: 12 | b: 0c' +}