Skip to content

Commit 0081e57

Browse files
authored
checker: only allow != and == for enum (vlang#7985)
1 parent 1f5255c commit 0081e57

7 files changed

Lines changed: 34 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
- Smart cast in for loops: `for mut x is string {}`.
99
- `[noinit]` struct attribute to disallow direct struct initialization with `Foo{}`.
1010
- Array decompose: `[1, 2, 3]...` is now `...[1, 2, 3]`
11-
- Treating `enum` as `int` is removed for strict type checking.
11+
- Treating `enum` as `int` and operations on `enum` except `==` and `!=` are removed for strict type checking.
1212
- Support `[manualfree] fn f1(){}` and `[manualfree] module m1`, for functions doing their own memory management.
1313

1414
## V 0.2.1

vlib/log/log.v

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fn (mut l Log) send_output(s &string, level Level) {
128128

129129
// fatal logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.fatal` category.
130130
pub fn (mut l Log) fatal(s string) {
131-
if l.level < .fatal {
131+
if int(l.level) < int(Level.fatal) {
132132
return
133133
}
134134
l.send_output(s, .fatal)
@@ -138,31 +138,31 @@ pub fn (mut l Log) fatal(s string) {
138138

139139
// error logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.error` category.
140140
pub fn (mut l Log) error(s string) {
141-
if l.level < .error {
141+
if int(l.level) < int(Level.error) {
142142
return
143143
}
144144
l.send_output(s, .error)
145145
}
146146

147147
// warn logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.warn` category.
148148
pub fn (mut l Log) warn(s string) {
149-
if l.level < .warn {
149+
if int(l.level) < int(Level.warn) {
150150
return
151151
}
152152
l.send_output(s, .warn)
153153
}
154154

155155
// info logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.info` category.
156156
pub fn (mut l Log) info(s string) {
157-
if l.level < .info {
157+
if int(l.level) < int(Level.info) {
158158
return
159159
}
160160
l.send_output(s, .info)
161161
}
162162

163163
// debug logs line `s` via `send_output` if `Log.level` is greater than or equal to the `Level.debug` category.
164164
pub fn (mut l Log) debug(s string) {
165-
if l.level < .debug {
165+
if int(l.level) < int(Level.debug) {
166166
return
167167
}
168168
l.send_output(s, .debug)

vlib/v/checker/checker.v

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,9 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
952952
// TODO broken !in
953953
c.error('string types only have the following operators defined: `==`, `!=`, `<`, `>`, `<=`, `>=`, and `+`',
954954
infix_expr.pos)
955+
} else if left.kind == .enum_ && right.kind == .enum_ && infix_expr.op !in [.ne, .eq] {
956+
c.error('only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed',
957+
infix_expr.pos)
955958
}
956959
// sum types can't have any infix operation except of "is", is is checked before and doesn't reach this
957960
if c.table.type_kind(left_type) == .sum_type {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
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
2+
6 |
3+
7 | fn main() {
4+
8 | println(Color.red > Color.green)
5+
| ^
6+
9 | println(Color.red + Color.green)
7+
10 | }
8+
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
9+
7 | fn main() {
10+
8 | println(Color.red > Color.green)
11+
9 | println(Color.red + Color.green)
12+
| ^
13+
10 | }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
enum Color {
2+
red
3+
blue
4+
green
5+
}
6+
7+
fn main() {
8+
println(Color.red > Color.green)
9+
println(Color.red + Color.green)
10+
}

vlib/v/gen/x64/gen.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ pub fn (mut g Gen) ret() {
371371
}
372372

373373
pub fn (mut g Gen) push(reg Register) {
374-
if reg < .r8 {
374+
if int(reg) < int(Register.r8) {
375375
g.write8(0x50 + int(reg))
376376
} else {
377377
g.write8(0x41)

vlib/v/tests/enum_bitfield_test.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn test_enum_bitfield() {
2626
assert a.perm.has(.execute)
2727
assert !a.perm.has(.write)
2828
assert !a.perm.has(.other)
29-
mut b := BfPermission.read | BfPermission.execute
29+
mut b := BfPermission(int(BfPermission.read) | int(BfPermission.execute))
3030
assert int(b) == 1 + 0 + 4 + 0
3131
assert b.has(.read)
3232
assert b.has(.execute)

0 commit comments

Comments
 (0)