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 {
|
if node.op == .bit_not && !c.pref.translated && !c.file.is_translated {
|
||||||
c.type_error_for_operator('~', 'integer', right_sym.name, node.pos)
|
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 {
|
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)
|
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
|
left_enum := left_sym.info as ast.Enum
|
||||||
right_enum := right_sym.info as ast.Enum
|
right_enum := right_sym.info as ast.Enum
|
||||||
if left_enum.is_flag && right_enum.is_flag {
|
if left_enum.is_flag && right_enum.is_flag {
|
||||||
// `[flag]` tagged enums are a special case that allow also `|` and `&` binary operators
|
// `@[flag]` tagged enums are a special case that allow also `|` and `&` binary operators
|
||||||
if node.op !in [.pipe, .amp] {
|
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',
|
c.error('only `==`, `!=`, `|`, `&`, `^` and `~` are defined on `@[flag]` tagged `enum`, use an explicit cast to `int` if needed',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
} else if !c.pref.translated && !c.file.is_translated && !left_type.has_flag(.generic)
|
} 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
|
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
|
||||||
7 |
|
14 |
|
||||||
8 | fn main() {
|
15 | fn main() {
|
||||||
9 | println(FilePerm.read > FilePerm.write)
|
16 | println(FilePerm.read > FilePerm.write)
|
||||||
| ^
|
| ^
|
||||||
10 | println(FilePerm.write + FilePerm.exec)
|
17 | println(FilePerm.write + FilePerm.exec)
|
||||||
11 | println(FilePerm.write && FilePerm.exec)
|
18 | 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
|
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
|
||||||
8 | fn main() {
|
15 | fn main() {
|
||||||
9 | println(FilePerm.read > FilePerm.write)
|
16 | println(FilePerm.read > FilePerm.write)
|
||||||
10 | println(FilePerm.write + FilePerm.exec)
|
17 | println(FilePerm.write + FilePerm.exec)
|
||||||
| ^
|
| ^
|
||||||
11 | println(FilePerm.write && FilePerm.exec)
|
18 | println(FilePerm.write && FilePerm.exec)
|
||||||
12 | }
|
19 |
|
||||||
vlib/v/checker/tests/enum_op_flag_err.vv:11:10: error: left operand for `&&` is not a boolean
|
vlib/v/checker/tests/enum_op_flag_err.vv:18:10: error: left operand for `&&` is not a boolean
|
||||||
9 | println(FilePerm.read > FilePerm.write)
|
16 | println(FilePerm.read > FilePerm.write)
|
||||||
10 | println(FilePerm.write + FilePerm.exec)
|
17 | println(FilePerm.write + FilePerm.exec)
|
||||||
11 | println(FilePerm.write && FilePerm.exec)
|
18 | println(FilePerm.write && FilePerm.exec)
|
||||||
| ~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~
|
||||||
12 | }
|
19 |
|
||||||
vlib/v/checker/tests/enum_op_flag_err.vv:11:28: error: right operand for `&&` is not a boolean
|
20 | f := Flags.bit0 | Flags.bit1
|
||||||
9 | println(FilePerm.read > FilePerm.write)
|
vlib/v/checker/tests/enum_op_flag_err.vv:18:28: error: right operand for `&&` is not a boolean
|
||||||
10 | println(FilePerm.write + FilePerm.exec)
|
16 | println(FilePerm.read > FilePerm.write)
|
||||||
11 | println(FilePerm.write && FilePerm.exec)
|
17 | println(FilePerm.write + FilePerm.exec)
|
||||||
|
18 | println(FilePerm.write && FilePerm.exec)
|
||||||
| ~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~
|
||||||
12 | }
|
19 |
|
||||||
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
|
20 | f := Flags.bit0 | Flags.bit1
|
||||||
9 | println(FilePerm.read > FilePerm.write)
|
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
|
||||||
10 | println(FilePerm.write + FilePerm.exec)
|
16 | println(FilePerm.read > FilePerm.write)
|
||||||
11 | println(FilePerm.write && FilePerm.exec)
|
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
|
exec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Flags {
|
||||||
|
bit0
|
||||||
|
bit1
|
||||||
|
bit2
|
||||||
|
bit3
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println(FilePerm.read > FilePerm.write)
|
println(FilePerm.read > FilePerm.write)
|
||||||
println(FilePerm.write + FilePerm.exec)
|
println(FilePerm.write + FilePerm.exec)
|
||||||
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 abc2 = Foo.a | .b | .c
|
||||||
|
|
||||||
|
const abc3 = Foo.a ^ .b
|
||||||
|
|
||||||
|
const abc4 = ~Foo.a
|
||||||
|
|
||||||
fn test_main() {
|
fn test_main() {
|
||||||
assert dump(a) == Foo.a
|
assert dump(a) == Foo.a
|
||||||
assert dump(ab) == Foo.a | Foo.b
|
assert dump(ab) == Foo.a | Foo.b
|
||||||
assert dump(ab2) == Foo.a | .b
|
assert dump(ab2) == Foo.a | .b
|
||||||
assert dump(abc) == Foo.a | Foo.b | Foo.c
|
assert dump(abc) == Foo.a | Foo.b | Foo.c
|
||||||
assert dump(abc2) == Foo.a | .b | .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