mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix typeof with comptime var (#16816)
This commit is contained in:
parent
15c9153f1d
commit
5daf39bc6a
@ -3549,6 +3549,22 @@ fn (mut g Gen) typeof_expr(node ast.TypeOf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) comptime_typeof(node ast.TypeOf, default_type ast.Type) ast.Type {
|
||||||
|
if node.expr is ast.ComptimeSelector {
|
||||||
|
if node.expr.field_expr is ast.SelectorExpr {
|
||||||
|
if node.expr.field_expr.expr is ast.Ident {
|
||||||
|
key_str := '${node.expr.field_expr.expr.name}.typ'
|
||||||
|
return g.comptime_var_type_map[key_str] or { default_type }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if g.inside_comptime_for_field && node.expr is ast.Ident
|
||||||
|
&& (node.expr as ast.Ident).obj is ast.Var && ((node.expr as ast.Ident).obj as ast.Var).is_comptime_field == true {
|
||||||
|
// typeof(var) from T.fields
|
||||||
|
return g.comptime_for_field_type
|
||||||
|
}
|
||||||
|
return default_type
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
||||||
prevent_sum_type_unwrapping_once := g.prevent_sum_type_unwrapping_once
|
prevent_sum_type_unwrapping_once := g.prevent_sum_type_unwrapping_once
|
||||||
g.prevent_sum_type_unwrapping_once = false
|
g.prevent_sum_type_unwrapping_once = false
|
||||||
@ -3568,20 +3584,17 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
|||||||
// typeof(expr).name
|
// typeof(expr).name
|
||||||
mut name_type := node.name_type
|
mut name_type := node.name_type
|
||||||
if node.expr is ast.TypeOf {
|
if node.expr is ast.TypeOf {
|
||||||
if node.expr.expr is ast.ComptimeSelector {
|
name_type = g.comptime_typeof(node.expr, name_type)
|
||||||
if node.expr.expr.field_expr is ast.SelectorExpr {
|
|
||||||
if node.expr.expr.field_expr.expr is ast.Ident {
|
|
||||||
key_str := '${node.expr.expr.field_expr.expr.name}.typ'
|
|
||||||
name_type = g.comptime_var_type_map[key_str] or { name_type }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
g.type_name(name_type)
|
g.type_name(name_type)
|
||||||
return
|
return
|
||||||
} else if node.field_name == 'idx' {
|
} else if node.field_name == 'idx' {
|
||||||
|
mut name_type := node.name_type
|
||||||
|
if node.expr is ast.TypeOf {
|
||||||
|
name_type = g.comptime_typeof(node.expr, name_type)
|
||||||
|
}
|
||||||
// `typeof(expr).idx`
|
// `typeof(expr).idx`
|
||||||
g.write(int(g.unwrap_generic(node.name_type)).str())
|
g.write(int(g.unwrap_generic(name_type)).str())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.error('unknown generic field', node.pos)
|
g.error('unknown generic field', node.pos)
|
||||||
|
41
vlib/v/tests/comptime_for_in_field_typeof_test.v
Normal file
41
vlib/v/tests/comptime_for_in_field_typeof_test.v
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
struct Ab {
|
||||||
|
a []int
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ComplexStruct {
|
||||||
|
a int
|
||||||
|
b []Ab
|
||||||
|
c string
|
||||||
|
d map[string]int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_typeof_in_comptime_for_in_fields() {
|
||||||
|
out := encode_struct(ComplexStruct{})
|
||||||
|
dump(out)
|
||||||
|
assert out[0] == 'a'
|
||||||
|
assert out[1] == typeof[int]().idx.str()
|
||||||
|
assert out[2] == 'int'
|
||||||
|
|
||||||
|
assert out[3] == 'b'
|
||||||
|
assert out[4] == typeof[[]Ab]().idx.str()
|
||||||
|
assert out[5] == '[]Ab'
|
||||||
|
|
||||||
|
assert out[6] == 'c'
|
||||||
|
assert out[7] == typeof[string]().idx.str()
|
||||||
|
assert out[8] == 'string'
|
||||||
|
|
||||||
|
assert out[9] == 'd'
|
||||||
|
assert out[10] == typeof[map[string]int]().idx.str()
|
||||||
|
assert out[11] == 'map[string]int'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn encode_struct[T](val T) []string {
|
||||||
|
mut out := []string{}
|
||||||
|
$for field in T.fields {
|
||||||
|
value := val.$(field.name)
|
||||||
|
out << field.name
|
||||||
|
out << typeof(value).idx.str()
|
||||||
|
out << typeof(value).name
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user