1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen, checker: fix comptime assigning to sumtype or indexexpr (#18240)

This commit is contained in:
Felipe Pena 2023-05-23 09:42:53 -03:00 committed by GitHub
parent e2f18fc9cc
commit 37618c9465
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 116 additions and 6 deletions

View File

@ -336,8 +336,10 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
}
}
if right is ast.ComptimeSelector {
left.obj.ct_type_var = .field_var
left.obj.typ = c.comptime_fields_default_type
if is_decl {
left.obj.ct_type_var = .field_var
left.obj.typ = c.comptime_fields_default_type
}
} else if right is ast.Ident
&& (right as ast.Ident).obj is ast.Var && (right as ast.Ident).or_expr.kind == .absent {
if ((right as ast.Ident).obj as ast.Var).ct_type_var != .no_comptime {

View File

@ -238,9 +238,13 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
} else if val is ast.ComptimeSelector {
key_str := g.get_comptime_selector_key_type(val)
if key_str != '' {
var_type = g.comptime_var_type_map[key_str] or { var_type }
val_type = var_type
left.obj.typ = var_type
if is_decl {
var_type = g.comptime_var_type_map[key_str] or { var_type }
val_type = var_type
left.obj.typ = var_type
} else {
val_type = g.comptime_var_type_map[key_str] or { var_type }
}
}
} else if val is ast.ComptimeCall {
key_str := '${val.method_name}.return_type'
@ -283,6 +287,11 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
val_type = g.comptime_var_type_map[key_str_right] or { var_type }
}
}
} else if mut left is ast.IndexExpr && val is ast.ComptimeSelector {
key_str := g.get_comptime_selector_key_type(val)
if key_str != '' {
val_type = g.comptime_var_type_map[key_str] or { var_type }
}
}
mut styp := g.typ(var_type)
mut is_fixed_array_init := false

View File

@ -4263,7 +4263,7 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
node_typ := g.unwrap_generic(node.typ)
mut expr_type := node.expr_type
sym := g.table.sym(node_typ)
if node.expr is ast.Ident && g.is_comptime_var(node.expr) {
if (node.expr is ast.Ident && g.is_comptime_var(node.expr)) || node.expr is ast.ComptimeSelector {
expr_type = g.unwrap_generic(g.get_comptime_var_type(node.expr))
}
if sym.kind in [.sum_type, .interface_] {

View File

@ -0,0 +1,38 @@
pub type Any = bool | int | map[string]Any | string
struct StructType[T] {
mut:
val T
}
fn map_from[T](t T) Any {
mut value := Any{}
$if T is $struct {
$for field in T.fields {
println(t.$(field.name))
value = t.$(field.name)
value = Any(t.$(field.name))
}
}
return value
}
fn test_generic_struct_with_sumtype() {
struct_type := StructType[string]{
val: 'true'
}
struct_type2 := StructType[int]{
val: 1
}
array_of_struct := [struct_type, struct_type]
for variable in array_of_struct {
assert map_from(variable) == Any('true')
}
array_of_struct2 := [struct_type2, struct_type2]
for variable in array_of_struct2 {
assert map_from(variable) == Any(1)
}
}

View File

@ -0,0 +1,61 @@
pub type Any = bool | int | map[string]Any | string
struct StructType[T] {
mut:
val T
}
fn map_from[T](t T) map[string]Any {
mut m := map[string]Any{}
$if T is $struct {
$for field in T.fields {
key := field.name
m[key] = t.$(field.name)
}
}
return m
}
fn test_struct_to_map_string() {
array_of_struct := [StructType[string]{
val: 'true'
}, StructType[string]{
val: 'false'
}]
mut array_of_map := []Any{}
for variable in array_of_struct {
array_of_map << map_from(variable)
}
println(array_of_map)
assert array_of_map[0] == Any({
'val': Any('true')
})
assert array_of_map[1] == Any({
'val': Any('false')
})
}
fn test_struct_to_map_bool() {
array_of_struct := [StructType[bool]{
val: true
}, StructType[bool]{
val: false
}]
mut array_of_map := []Any{}
for variable in array_of_struct {
array_of_map << map_from(variable)
}
println(array_of_map)
assert array_of_map[0] == Any({
'val': Any(true)
})
assert array_of_map[1] == Any({
'val': Any(false)
})
}