checker: fix invalid cast warning for flag enums (#12848)
parent
11d2b8b354
commit
65f12f3217
|
@ -3592,24 +3592,30 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
|
||||||
|
|
||||||
if enum_decl := c.table.enum_decls[to_type_sym.name] {
|
if enum_decl := c.table.enum_decls[to_type_sym.name] {
|
||||||
mut in_range := false
|
mut in_range := false
|
||||||
mut enum_val := 0
|
if enum_decl.is_flag {
|
||||||
|
// if a flag enum has 4 variants, the maximum possible value would have all 4 flags set (0b1111)
|
||||||
|
max_val := (1 << enum_decl.fields.len) - 1
|
||||||
|
in_range = node_val >= 0 && node_val <= max_val
|
||||||
|
} else {
|
||||||
|
mut enum_val := 0
|
||||||
|
|
||||||
for enum_field in enum_decl.fields {
|
for enum_field in enum_decl.fields {
|
||||||
// check if the field of the enum value is an integer literal
|
// check if the field of the enum value is an integer literal
|
||||||
if enum_field.expr is ast.IntegerLiteral {
|
if enum_field.expr is ast.IntegerLiteral {
|
||||||
enum_val = enum_field.expr.val.int()
|
enum_val = enum_field.expr.val.int()
|
||||||
|
}
|
||||||
|
|
||||||
|
if node_val == enum_val {
|
||||||
|
in_range = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
enum_val += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if node_val == enum_val {
|
|
||||||
in_range = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
enum_val += 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !in_range {
|
if !in_range {
|
||||||
c.warn('$node_val does not represents a value of enum $enum_typ_name',
|
c.warn('$node_val does not represent a value of enum $enum_typ_name',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
vlib/v/checker/tests/enum_cast.vv:6:13: error: 12 does not represents a value of enum Color
|
vlib/v/checker/tests/enum_cast.vv:9:13: error: 12 does not represent a value of enum Color
|
||||||
4 | println(Color(0))
|
7 | println(Color(0))
|
||||||
5 | println(Color(10))
|
8 | println(Color(10))
|
||||||
6 | println(Color(12))
|
9 | println(Color(12))
|
||||||
| ~~~~~~~~~
|
| ~~~~~~~~~
|
||||||
7 | }
|
10 | println(Color(-10))
|
||||||
|
11 |
|
||||||
|
vlib/v/checker/tests/enum_cast.vv:10:13: error: -10 does not represent a value of enum Color
|
||||||
|
8 | println(Color(10))
|
||||||
|
9 | println(Color(12))
|
||||||
|
10 | println(Color(-10))
|
||||||
|
| ~~~~~~~~~~
|
||||||
|
11 |
|
||||||
|
12 | println(Permissions(0b101))
|
||||||
|
vlib/v/checker/tests/enum_cast.vv:13:13: error: 10 does not represent a value of enum Permissions
|
||||||
|
11 |
|
||||||
|
12 | println(Permissions(0b101))
|
||||||
|
13 | println(Permissions(0b1010))
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~
|
||||||
|
14 | println(Permissions(-1))
|
||||||
|
15 | }
|
||||||
|
vlib/v/checker/tests/enum_cast.vv:14:13: error: -1 does not represent a value of enum Permissions
|
||||||
|
12 | println(Permissions(0b101))
|
||||||
|
13 | println(Permissions(0b1010))
|
||||||
|
14 | println(Permissions(-1))
|
||||||
|
| ~~~~~~~~~~~~~~~
|
||||||
|
15 | }
|
||||||
|
|
|
@ -1,7 +1,15 @@
|
||||||
enum Color { red green = 10 blue }
|
enum Color { red green = 10 blue }
|
||||||
|
|
||||||
|
[flag]
|
||||||
|
enum Permissions { read write execute }
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println(Color(0))
|
println(Color(0))
|
||||||
println(Color(10))
|
println(Color(10))
|
||||||
println(Color(12))
|
println(Color(12))
|
||||||
}
|
println(Color(-10))
|
||||||
|
|
||||||
|
println(Permissions(0b101))
|
||||||
|
println(Permissions(0b1010))
|
||||||
|
println(Permissions(-1))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue