checker: only allow `!=` and `==` for enum (#7985)

pull/7976/head^2
Swastik Baranwal 2021-01-10 15:56:31 +05:30 committed by GitHub
parent 1f5255c2bb
commit 0081e5740d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 34 additions and 8 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 {

View File

@ -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 | }

View File

@ -0,0 +1,10 @@
enum Color {
red
blue
green
}
fn main() {
println(Color.red > Color.green)
println(Color.red + Color.green)
}

View File

@ -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)

View File

@ -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)