mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: fix comptime selector evaluate when checked against type of array (#18774)
This commit is contained in:
parent
838d0e8960
commit
578264c815
@ -742,11 +742,9 @@ fn (mut c Checker) comptime_if_branch(cond ast.Expr, pos token.Pos) ComptimeBran
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_in, .not_in {
|
.key_in, .not_in {
|
||||||
if cond.left is ast.Ident {
|
|
||||||
c.expr(cond.left)
|
|
||||||
}
|
|
||||||
if cond.left in [ast.TypeNode, ast.SelectorExpr, ast.Ident]
|
if cond.left in [ast.TypeNode, ast.SelectorExpr, ast.Ident]
|
||||||
&& cond.right is ast.ArrayInit {
|
&& cond.right is ast.ArrayInit {
|
||||||
|
c.expr(cond.left)
|
||||||
for expr in cond.right.exprs {
|
for expr in cond.right.exprs {
|
||||||
if expr !in [ast.ComptimeType, ast.TypeNode] {
|
if expr !in [ast.ComptimeType, ast.TypeNode] {
|
||||||
c.error('invalid `\$if` condition, only types are allowed',
|
c.error('invalid `\$if` condition, only types are allowed',
|
||||||
|
@ -796,6 +796,11 @@ fn (mut g Gen) get_comptime_var_type(node ast.Expr) ast.Type {
|
|||||||
fn (mut g Gen) resolve_comptime_type(node ast.Expr, default_type ast.Type) ast.Type {
|
fn (mut g Gen) resolve_comptime_type(node ast.Expr, default_type ast.Type) ast.Type {
|
||||||
if (node is ast.Ident && g.is_comptime_var(node)) || node is ast.ComptimeSelector {
|
if (node is ast.Ident && g.is_comptime_var(node)) || node is ast.ComptimeSelector {
|
||||||
return g.get_comptime_var_type(node)
|
return g.get_comptime_var_type(node)
|
||||||
|
} else if node is ast.SelectorExpr {
|
||||||
|
sym := g.table.sym(g.unwrap_generic(node.expr_type))
|
||||||
|
if f := g.table.find_field_with_embeds(sym, node.field_name) {
|
||||||
|
return f.typ
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return default_type
|
return default_type
|
||||||
}
|
}
|
||||||
|
24
vlib/v/tests/comptime_arr_type_test.v
Normal file
24
vlib/v/tests/comptime_arr_type_test.v
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
struct TestStruct {
|
||||||
|
test string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test[T](val T) string {
|
||||||
|
$if T is $struct {
|
||||||
|
$for attribute in T.fields {
|
||||||
|
$if attribute.name == 'test' {
|
||||||
|
$if val.test in [u32, i32, $int] {
|
||||||
|
return 'struct field ${typeof(val.test).name}'
|
||||||
|
} $else {
|
||||||
|
return 'got type: ${typeof(val.test).name}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'no test field in struct'
|
||||||
|
} $else {
|
||||||
|
return 'empty'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
assert test(TestStruct{'7'}) == 'got type: string'
|
||||||
|
}
|
36
vlib/v/tests/comptime_selector_member_test.v
Normal file
36
vlib/v/tests/comptime_selector_member_test.v
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
struct OtherStruct {
|
||||||
|
test string
|
||||||
|
}
|
||||||
|
|
||||||
|
struct I32Struct {
|
||||||
|
test i32
|
||||||
|
}
|
||||||
|
|
||||||
|
struct U32Struct {
|
||||||
|
test u32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test[T](val T) string {
|
||||||
|
$if val is $struct {
|
||||||
|
println(T.name)
|
||||||
|
$for attribute in T.fields {
|
||||||
|
$if attribute.name == 'test' {
|
||||||
|
$if val.test in [u32, i32] {
|
||||||
|
return 'struct field ${typeof(val.test).name}'
|
||||||
|
} $else {
|
||||||
|
return 'not u32 or i32 struct field, got type: ${typeof(val.test).name}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'no test field in struct'
|
||||||
|
} $else {
|
||||||
|
return 'else block'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
assert test(u32(7)) == 'else block'
|
||||||
|
assert test(OtherStruct{'7'}) == 'struct field string'
|
||||||
|
assert test(I32Struct{-7}) == 'struct field i32'
|
||||||
|
assert test(U32Struct{7}) == 'struct field u32'
|
||||||
|
}
|
@ -16,7 +16,7 @@ fn test_nested_sumtype_selector() {
|
|||||||
pos: 1
|
pos: 1
|
||||||
}))}
|
}))}
|
||||||
for c.node is Expr {
|
for c.node is Expr {
|
||||||
assert typeof(c.node).name == 'Expr'
|
assert typeof(c.node).name == 'Node'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user