mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: allow casted enum val
and const
as fixed array size (#18321)
This commit is contained in:
@@ -372,6 +372,43 @@ pub fn (t &Table) find_method_with_embeds(sym &TypeSymbol, method_name string) !
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find_enum_field_val finds the int value from the enum name and enum field
|
||||||
|
pub fn (t &Table) find_enum_field_val(name string, field_ string) i64 {
|
||||||
|
mut val := i64(0)
|
||||||
|
enum_decl := t.enum_decls[name]
|
||||||
|
mut enum_vals := []i64{}
|
||||||
|
for field in enum_decl.fields {
|
||||||
|
if field.name == field_ {
|
||||||
|
if field.has_expr {
|
||||||
|
if field.expr is IntegerLiteral {
|
||||||
|
val = field.expr.val.i64()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if enum_vals.len > 0 {
|
||||||
|
val = enum_vals.last() + 1
|
||||||
|
} else {
|
||||||
|
val = 0
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if field.has_expr {
|
||||||
|
if field.expr is IntegerLiteral {
|
||||||
|
enum_vals << field.expr.val.i64()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if enum_vals.len > 0 {
|
||||||
|
enum_vals << enum_vals.last() + 1
|
||||||
|
} else {
|
||||||
|
enum_vals << 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (t &Table) get_embed_methods(sym &TypeSymbol) []Fn {
|
pub fn (t &Table) get_embed_methods(sym &TypeSymbol) []Fn {
|
||||||
mut methods := []Fn{}
|
mut methods := []Fn{}
|
||||||
if sym.info is Struct {
|
if sym.info is Struct {
|
||||||
|
@@ -270,10 +270,9 @@ fn (mut c Checker) eval_comptime_const_expr(expr ast.Expr, nlevel int) ?ast.Comp
|
|||||||
ast.ParExpr {
|
ast.ParExpr {
|
||||||
return c.eval_comptime_const_expr(expr.expr, nlevel + 1)
|
return c.eval_comptime_const_expr(expr.expr, nlevel + 1)
|
||||||
}
|
}
|
||||||
// ast.EnumVal {
|
ast.EnumVal {
|
||||||
// c.note('>>>>>>>> expr: $expr', expr.pos)
|
return c.table.find_enum_field_val(expr.enum_name, expr.val)
|
||||||
// return expr.val.i64()
|
}
|
||||||
// }
|
|
||||||
ast.SizeOf {
|
ast.SizeOf {
|
||||||
s, _ := c.table.type_size(expr.typ)
|
s, _ := c.table.type_size(expr.typ)
|
||||||
return s
|
return s
|
||||||
|
@@ -241,8 +241,36 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
|
|||||||
ast.IntegerLiteral {
|
ast.IntegerLiteral {
|
||||||
fixed_size = init_expr.val.int()
|
fixed_size = init_expr.val.int()
|
||||||
}
|
}
|
||||||
|
ast.CastExpr {
|
||||||
|
if !init_expr.typ.is_pure_int() {
|
||||||
|
c.error('only integer types are allowed', init_expr.pos)
|
||||||
|
}
|
||||||
|
match init_expr.expr {
|
||||||
|
ast.IntegerLiteral {
|
||||||
|
fixed_size = init_expr.expr.val.int()
|
||||||
|
}
|
||||||
|
ast.EnumVal {
|
||||||
|
fixed_size = c.table.find_enum_field_val(init_expr.expr.enum_name,
|
||||||
|
init_expr.expr.val)
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast.EnumVal {
|
||||||
|
c.error('${init_expr.enum_name}.${init_expr.val} has to be casted to integer to be used as size',
|
||||||
|
init_expr.pos)
|
||||||
|
}
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
if init_expr.obj is ast.ConstField {
|
if init_expr.obj is ast.ConstField {
|
||||||
|
if init_expr.obj.expr is ast.EnumVal {
|
||||||
|
c.error('${init_expr.obj.expr.enum_name}.${init_expr.obj.expr.val} has to be casted to integer to be used as size',
|
||||||
|
init_expr.pos)
|
||||||
|
}
|
||||||
|
if init_expr.obj.expr is ast.CastExpr {
|
||||||
|
if !init_expr.obj.expr.typ.is_pure_int() {
|
||||||
|
c.error('only integer types are allowed', init_expr.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
if comptime_value := c.eval_comptime_const_expr(init_expr.obj.expr,
|
if comptime_value := c.eval_comptime_const_expr(init_expr.obj.expr,
|
||||||
0)
|
0)
|
||||||
{
|
{
|
||||||
|
@@ -0,0 +1,13 @@
|
|||||||
|
vlib/v/checker/tests/uncasted_enum_val_as_size_for_fixed_array_err.vv:10:7: error: Foo.first has to be casted to integer to be used as size
|
||||||
|
8 | }
|
||||||
|
9 |
|
||||||
|
10 | a := [b]int{}
|
||||||
|
| ^
|
||||||
|
11 | println(a)
|
||||||
|
12 |
|
||||||
|
vlib/v/checker/tests/uncasted_enum_val_as_size_for_fixed_array_err.vv:13:7: error: Foo.second has to be casted to integer to be used as size
|
||||||
|
11 | println(a)
|
||||||
|
12 |
|
||||||
|
13 | c := [Foo.second]int{}
|
||||||
|
| ~~~~~~~~~~
|
||||||
|
14 | println(c)
|
@@ -0,0 +1,14 @@
|
|||||||
|
const b = Foo.first
|
||||||
|
|
||||||
|
enum Foo {
|
||||||
|
first = 5
|
||||||
|
second
|
||||||
|
|
||||||
|
_end = 9
|
||||||
|
}
|
||||||
|
|
||||||
|
a := [b]int{}
|
||||||
|
println(a)
|
||||||
|
|
||||||
|
c := [Foo.second]int{}
|
||||||
|
println(c)
|
@@ -0,0 +1,13 @@
|
|||||||
|
vlib/v/checker/tests/wrong_type_casted_fixed_array_size_err.vv:10:7: error: only integer types are allowed
|
||||||
|
8 | }
|
||||||
|
9 |
|
||||||
|
10 | a := [b]int{}
|
||||||
|
| ^
|
||||||
|
11 | println(a)
|
||||||
|
12 |
|
||||||
|
vlib/v/checker/tests/wrong_type_casted_fixed_array_size_err.vv:13:7: error: only integer types are allowed
|
||||||
|
11 | println(a)
|
||||||
|
12 |
|
||||||
|
13 | c := [f32(Foo.first)]int{}
|
||||||
|
| ~~~~~~~~~~~~~~
|
||||||
|
14 | println(c)
|
@@ -0,0 +1,14 @@
|
|||||||
|
const b = f32(3)
|
||||||
|
|
||||||
|
enum Foo {
|
||||||
|
first = 5
|
||||||
|
second
|
||||||
|
|
||||||
|
_end = 9
|
||||||
|
}
|
||||||
|
|
||||||
|
a := [b]int{}
|
||||||
|
println(a)
|
||||||
|
|
||||||
|
c := [f32(Foo.first)]int{}
|
||||||
|
println(c)
|
@@ -1,3 +1,26 @@
|
|||||||
|
enum Foo {
|
||||||
|
zero
|
||||||
|
first = 1
|
||||||
|
third = 3
|
||||||
|
fourth
|
||||||
|
}
|
||||||
|
|
||||||
|
const enum_size = int(Foo.third)
|
||||||
|
|
||||||
|
fn test_enum_val_as_fixed_array_size() {
|
||||||
|
arr1 := [int(Foo.first)]int{}
|
||||||
|
assert arr1 == [0]!
|
||||||
|
|
||||||
|
// TODO check why it fails on MSVC
|
||||||
|
$if !msvc {
|
||||||
|
arr2 := [enum_size]int{}
|
||||||
|
assert arr2 == [0, 0, 0]!
|
||||||
|
}
|
||||||
|
|
||||||
|
arr3 := [int(Foo.fourth)]int{}
|
||||||
|
assert arr3 == [0, 0, 0, 0]!
|
||||||
|
}
|
||||||
|
|
||||||
fn test_for_in_array_named_array() {
|
fn test_for_in_array_named_array() {
|
||||||
mut array := [1]
|
mut array := [1]
|
||||||
for elem in array {
|
for elem in array {
|
||||||
|
Reference in New Issue
Block a user