diff --git a/CHANGELOG.md b/CHANGELOG.md index 16f6f5e69e..3a8ff79c2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ - Smart cast in for loops: `for mut x is string {}`. - `[noinit]` struct attribute to disallow direct struct initialization with `Foo{}`. - Array decompose: `[1, 2, 3]...` is now `...[1, 2, 3]` -- Treating `enum` as `int` is removed for strict type checking. +- Treating `enum` as `int` and operations on `enum` except `==` and `!=` are removed for strict type checking. - Support `[manualfree] fn f1(){}` and `[manualfree] module m1`, for functions doing their own memory management. ## V 0.2.1 diff --git a/vlib/log/log.v b/vlib/log/log.v index 67ca7bdd03..fe864a7f5a 100644 --- a/vlib/log/log.v +++ b/vlib/log/log.v @@ -128,7 +128,7 @@ fn (mut l Log) send_output(s &string, level Level) { // fatal logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.fatal` category. pub fn (mut l Log) fatal(s string) { - if l.level < .fatal { + if int(l.level) < int(Level.fatal) { return } l.send_output(s, .fatal) @@ -138,7 +138,7 @@ pub fn (mut l Log) fatal(s string) { // error logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.error` category. pub fn (mut l Log) error(s string) { - if l.level < .error { + if int(l.level) < int(Level.error) { return } l.send_output(s, .error) @@ -146,7 +146,7 @@ pub fn (mut l Log) error(s string) { // warn logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.warn` category. pub fn (mut l Log) warn(s string) { - if l.level < .warn { + if int(l.level) < int(Level.warn) { return } l.send_output(s, .warn) @@ -154,7 +154,7 @@ pub fn (mut l Log) warn(s string) { // info logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.info` category. pub fn (mut l Log) info(s string) { - if l.level < .info { + if int(l.level) < int(Level.info) { return } l.send_output(s, .info) @@ -162,7 +162,7 @@ pub fn (mut l Log) info(s string) { // debug logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.debug` category. pub fn (mut l Log) debug(s string) { - if l.level < .debug { + if int(l.level) < int(Level.debug) { return } l.send_output(s, .debug) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index fd4c427825..71d21280f0 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -952,6 +952,9 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { // TODO broken !in c.error('string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`', infix_expr.pos) + } else if left.kind == .enum_ && right.kind == .enum_ && infix_expr.op !in [.ne, .eq] { + c.error('only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed', + infix_expr.pos) } // sum types can't have any infix operation except of "is", is is checked before and doesn't reach this if c.table.type_kind(left_type) == .sum_type { diff --git a/vlib/v/checker/tests/enum_op_err.out b/vlib/v/checker/tests/enum_op_err.out new file mode 100644 index 0000000000..c28e1c9f19 --- /dev/null +++ b/vlib/v/checker/tests/enum_op_err.out @@ -0,0 +1,13 @@ +vlib/v/checker/tests/enum_op_err.vv:8:20: error: only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed + 6 | + 7 | fn main() { + 8 | println(Color.red > Color.green) + | ^ + 9 | println(Color.red + Color.green) + 10 | } +vlib/v/checker/tests/enum_op_err.vv:9:20: error: only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed + 7 | fn main() { + 8 | println(Color.red > Color.green) + 9 | println(Color.red + Color.green) + | ^ + 10 | } diff --git a/vlib/v/checker/tests/enum_op_err.vv b/vlib/v/checker/tests/enum_op_err.vv new file mode 100644 index 0000000000..485391077d --- /dev/null +++ b/vlib/v/checker/tests/enum_op_err.vv @@ -0,0 +1,10 @@ +enum Color { + red + blue + green +} + +fn main() { + println(Color.red > Color.green) + println(Color.red + Color.green) +} diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index afce35f180..5035f210d3 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -371,7 +371,7 @@ pub fn (mut g Gen) ret() { } pub fn (mut g Gen) push(reg Register) { - if reg < .r8 { + if int(reg) < int(Register.r8) { g.write8(0x50 + int(reg)) } else { g.write8(0x41) diff --git a/vlib/v/tests/enum_bitfield_test.v b/vlib/v/tests/enum_bitfield_test.v index 34af9c5298..81a1507b96 100644 --- a/vlib/v/tests/enum_bitfield_test.v +++ b/vlib/v/tests/enum_bitfield_test.v @@ -26,7 +26,7 @@ fn test_enum_bitfield() { assert a.perm.has(.execute) assert !a.perm.has(.write) assert !a.perm.has(.other) - mut b := BfPermission.read | BfPermission.execute + mut b := BfPermission(int(BfPermission.read) | int(BfPermission.execute)) assert int(b) == 1 + 0 + 4 + 0 assert b.has(.read) assert b.has(.execute)