parent
b88b17aca5
commit
69f31d8d5c
|
@ -35,6 +35,7 @@ pub mut:
|
|||
cur_fn &FnDecl = 0 // previously stored in Checker.cur_fn and Gen.cur_fn
|
||||
cur_concrete_types []Type // current concrete types, e.g. <int, string>
|
||||
gostmts int // how many `go` statements there were in the parsed files.
|
||||
enum_decls map[string]EnumDecl
|
||||
// When table.gostmts > 0, __VTHREADS__ is defined, which can be checked with `$if threads {`
|
||||
}
|
||||
|
||||
|
@ -657,6 +658,11 @@ pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int {
|
|||
return typ_idx
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (mut t Table) register_enum_decl(enum_decl EnumDecl) {
|
||||
t.enum_decls[enum_decl.name] = enum_decl
|
||||
}
|
||||
|
||||
pub fn (t &Table) known_type(name string) bool {
|
||||
return t.find_type_idx(name) != 0
|
||||
}
|
||||
|
|
|
@ -5607,6 +5607,41 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
|
|||
if node.has_arg {
|
||||
c.expr(node.arg)
|
||||
}
|
||||
|
||||
// checks on int literal to enum cast if the value represents a value on the enum
|
||||
if to_type_sym.kind == .enum_ {
|
||||
if node.expr is ast.IntegerLiteral {
|
||||
enum_typ_name := c.table.get_type_name(node.typ)
|
||||
node_val := (node.expr as ast.IntegerLiteral).val.int()
|
||||
|
||||
if enum_decl := c.table.enum_decls[to_type_sym.name] {
|
||||
mut in_range := false
|
||||
mut enum_val := 0
|
||||
|
||||
for enum_field in enum_decl.fields {
|
||||
// check if the field of the enum value is an integer literal
|
||||
if enum_field.expr is ast.IntegerLiteral {
|
||||
enum_val = enum_field.expr.val.int()
|
||||
}
|
||||
|
||||
if node_val == enum_val {
|
||||
in_range = true
|
||||
break
|
||||
}
|
||||
|
||||
enum_val += 1
|
||||
}
|
||||
|
||||
if !in_range {
|
||||
c.warn('$node_val does not represents a value of enum $enum_typ_name',
|
||||
node.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node.typname = c.table.get_type_symbol(node.typ).name
|
||||
|
||||
return node.typ
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
vlib/v/checker/tests/enum_cast.vv:6:13: error: 12 does not represents a value of enum Color
|
||||
4 | println(Color(0))
|
||||
5 | println(Color(10))
|
||||
6 | println(Color(12))
|
||||
| ~~~~~~~~~
|
||||
7 | }
|
|
@ -0,0 +1,7 @@
|
|||
enum Color { red green = 10 blue }
|
||||
|
||||
fn main() {
|
||||
println(Color(0))
|
||||
println(Color(10))
|
||||
println(Color(12))
|
||||
}
|
|
@ -3097,7 +3097,8 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
|
|||
p.error_with_pos('cannot register enum `$name`, another type with this name exists',
|
||||
end_pos)
|
||||
}
|
||||
return ast.EnumDecl{
|
||||
|
||||
enum_decl := ast.EnumDecl{
|
||||
name: name
|
||||
is_pub: is_pub
|
||||
is_flag: is_flag
|
||||
|
@ -3107,6 +3108,10 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
|
|||
attrs: p.attrs
|
||||
comments: enum_decl_comments
|
||||
}
|
||||
|
||||
p.table.register_enum_decl(enum_decl)
|
||||
|
||||
return enum_decl
|
||||
}
|
||||
|
||||
fn (mut p Parser) type_decl() ast.TypeDecl {
|
||||
|
|
Loading…
Reference in New Issue