mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
This commit is contained in:
parent
a2d23306c2
commit
cc443e50bb
5 changed files with 70 additions and 32 deletions
|
@ -4317,8 +4317,14 @@ fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
|
|||
}
|
||||
}
|
||||
}
|
||||
if node.op == .bit_not && !right_sym.is_int() && !c.pref.translated && !c.file.is_translated {
|
||||
c.type_error_for_operator('~', 'integer', right_sym.name, node.pos)
|
||||
if node.op == .bit_not && !c.pref.translated && !c.file.is_translated {
|
||||
if right_sym.info is ast.Enum && !right_sym.info.is_flag {
|
||||
c.error('operator `~` can only be used with `@[flag]` tagged enums', node.pos)
|
||||
}
|
||||
// Only check for int not enum as it is done above
|
||||
if !right_sym.is_int() && right_sym.info !is ast.Enum {
|
||||
c.type_error_for_operator('~', 'integer', right_sym.name, node.pos)
|
||||
}
|
||||
}
|
||||
if node.op == .not && right_sym.kind != .bool && !c.pref.translated && !c.file.is_translated {
|
||||
c.type_error_for_operator('!', 'bool', right_sym.name, node.pos)
|
||||
|
|
|
@ -750,9 +750,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
|||
left_enum := left_sym.info as ast.Enum
|
||||
right_enum := right_sym.info as ast.Enum
|
||||
if left_enum.is_flag && right_enum.is_flag {
|
||||
// `[flag]` tagged enums are a special case that allow also `|` and `&` binary operators
|
||||
if node.op !in [.pipe, .amp] {
|
||||
c.error('only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed',
|
||||
// `@[flag]` tagged enums are a special case that allow also `|` and `&` binary operators
|
||||
if node.op !in [.pipe, .amp, .xor, .bit_not] {
|
||||
c.error('only `==`, `!=`, `|`, `&`, `^` and `~` are defined on `@[flag]` tagged `enum`, use an explicit cast to `int` if needed',
|
||||
node.pos)
|
||||
}
|
||||
} else if !c.pref.translated && !c.file.is_translated && !left_type.has_flag(.generic)
|
||||
|
|
|
@ -1,32 +1,48 @@
|
|||
vlib/v/checker/tests/enum_op_flag_err.vv:9:24: error: only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed
|
||||
7 |
|
||||
8 | fn main() {
|
||||
9 | println(FilePerm.read > FilePerm.write)
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:16:24: error: only `==`, `!=`, `|`, `&`, `^` and `~` are defined on `@[flag]` tagged `enum`, use an explicit cast to `int` if needed
|
||||
14 |
|
||||
15 | fn main() {
|
||||
16 | println(FilePerm.read > FilePerm.write)
|
||||
| ^
|
||||
10 | println(FilePerm.write + FilePerm.exec)
|
||||
11 | println(FilePerm.write && FilePerm.exec)
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:10:25: error: only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed
|
||||
8 | fn main() {
|
||||
9 | println(FilePerm.read > FilePerm.write)
|
||||
10 | println(FilePerm.write + FilePerm.exec)
|
||||
17 | println(FilePerm.write + FilePerm.exec)
|
||||
18 | println(FilePerm.write && FilePerm.exec)
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:17:25: error: only `==`, `!=`, `|`, `&`, `^` and `~` are defined on `@[flag]` tagged `enum`, use an explicit cast to `int` if needed
|
||||
15 | fn main() {
|
||||
16 | println(FilePerm.read > FilePerm.write)
|
||||
17 | println(FilePerm.write + FilePerm.exec)
|
||||
| ^
|
||||
11 | println(FilePerm.write && FilePerm.exec)
|
||||
12 | }
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:11:10: error: left operand for `&&` is not a boolean
|
||||
9 | println(FilePerm.read > FilePerm.write)
|
||||
10 | println(FilePerm.write + FilePerm.exec)
|
||||
11 | println(FilePerm.write && FilePerm.exec)
|
||||
18 | println(FilePerm.write && FilePerm.exec)
|
||||
19 |
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:18:10: error: left operand for `&&` is not a boolean
|
||||
16 | println(FilePerm.read > FilePerm.write)
|
||||
17 | println(FilePerm.write + FilePerm.exec)
|
||||
18 | println(FilePerm.write && FilePerm.exec)
|
||||
| ~~~~~~~~~~~~~~
|
||||
12 | }
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:11:28: error: right operand for `&&` is not a boolean
|
||||
9 | println(FilePerm.read > FilePerm.write)
|
||||
10 | println(FilePerm.write + FilePerm.exec)
|
||||
11 | println(FilePerm.write && FilePerm.exec)
|
||||
19 |
|
||||
20 | f := Flags.bit0 | Flags.bit1
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:18:28: error: right operand for `&&` is not a boolean
|
||||
16 | println(FilePerm.read > FilePerm.write)
|
||||
17 | println(FilePerm.write + FilePerm.exec)
|
||||
18 | println(FilePerm.write && FilePerm.exec)
|
||||
| ~~~~~~~~~~~~~
|
||||
12 | }
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:11:25: error: only `==`, `!=`, `|` and `&` are defined on `[flag]` tagged `enum`, use an explicit cast to `int` if needed
|
||||
9 | println(FilePerm.read > FilePerm.write)
|
||||
10 | println(FilePerm.write + FilePerm.exec)
|
||||
11 | println(FilePerm.write && FilePerm.exec)
|
||||
19 |
|
||||
20 | f := Flags.bit0 | Flags.bit1
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:18:25: error: only `==`, `!=`, `|`, `&`, `^` and `~` are defined on `@[flag]` tagged `enum`, use an explicit cast to `int` if needed
|
||||
16 | println(FilePerm.read > FilePerm.write)
|
||||
17 | println(FilePerm.write + FilePerm.exec)
|
||||
18 | println(FilePerm.write && FilePerm.exec)
|
||||
| ~~
|
||||
12 | }
|
||||
19 |
|
||||
20 | f := Flags.bit0 | Flags.bit1
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:20:18: error: only `==` and `!=` are defined on `enum`, use an explicit cast to `int` if needed
|
||||
18 | println(FilePerm.write && FilePerm.exec)
|
||||
19 |
|
||||
20 | f := Flags.bit0 | Flags.bit1
|
||||
| ^
|
||||
21 | println(~f)
|
||||
22 | }
|
||||
vlib/v/checker/tests/enum_op_flag_err.vv:21:10: error: operator `~` can only be used with `@[flag]` tagged enums
|
||||
19 |
|
||||
20 | f := Flags.bit0 | Flags.bit1
|
||||
21 | println(~f)
|
||||
| ^
|
||||
22 | }
|
||||
|
|
|
@ -5,8 +5,18 @@ enum FilePerm {
|
|||
exec
|
||||
}
|
||||
|
||||
enum Flags {
|
||||
bit0
|
||||
bit1
|
||||
bit2
|
||||
bit3
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println(FilePerm.read > FilePerm.write)
|
||||
println(FilePerm.write + FilePerm.exec)
|
||||
println(FilePerm.write && FilePerm.exec)
|
||||
|
||||
f := Flags.bit0 | Flags.bit1
|
||||
println(~f)
|
||||
}
|
||||
|
|
|
@ -15,10 +15,16 @@ const abc = Foo.a | Foo.b | Foo.c
|
|||
|
||||
const abc2 = Foo.a | .b | .c
|
||||
|
||||
const abc3 = Foo.a ^ .b
|
||||
|
||||
const abc4 = ~Foo.a
|
||||
|
||||
fn test_main() {
|
||||
assert dump(a) == Foo.a
|
||||
assert dump(ab) == Foo.a | Foo.b
|
||||
assert dump(ab2) == Foo.a | .b
|
||||
assert dump(abc) == Foo.a | Foo.b | Foo.c
|
||||
assert dump(abc2) == Foo.a | .b | .c
|
||||
assert dump(abc3) == Foo.a ^ .b
|
||||
assert dump(abc4) == ~Foo.a
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue