From eb7e1b4712f652dd4871c13d03400cc5fb0bce5a Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 12 Feb 2023 03:54:09 -0300 Subject: [PATCH] cgen: fix cast with comptime var (#17286) --- vlib/v/gen/c/cgen.v | 12 +++++--- vlib/v/tests/cast_comptime_test.v | 50 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 vlib/v/tests/cast_comptime_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index a1f035e80a..4b3ebe2ef7 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4208,9 +4208,13 @@ fn (mut g Gen) ident(node ast.Ident) { 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) { + expr_type = g.unwrap_generic(g.comptime_for_field_type) + } if sym.kind in [.sum_type, .interface_] { - g.expr_with_cast(node.expr, node.expr_type, node_typ) + g.expr_with_cast(node.expr, expr_type, node_typ) } else if sym.kind == .struct_ && !node.typ.is_ptr() && !(sym.info as ast.Struct).is_typedef { // deprecated, replaced by Struct{...exr} styp := g.typ(node.typ) @@ -4222,7 +4226,7 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) { g.write('(${g.typ(node.expr.typ)})') } g.expr(node.expr) - } else if node.expr_type == ast.bool_type && node.typ.is_int() { + } else if expr_type == ast.bool_type && node.typ.is_int() { styp := g.typ(node_typ) g.write('(${styp}[]){(') g.expr(node.expr) @@ -4241,7 +4245,7 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) { mut cast_label := '' // `ast.string_type` is done for MSVC's bug if sym.kind != .alias - || (sym.info as ast.Alias).parent_type !in [node.expr_type, ast.string_type] { + || (sym.info as ast.Alias).parent_type !in [expr_type, ast.string_type] { cast_label = '(${styp})' } if node.typ.has_flag(.option) && node.expr is ast.None { @@ -4249,7 +4253,7 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) { } else { g.write('(${cast_label}(') if sym.kind == .alias && g.table.final_sym(node.typ).kind == .string { - ptr_cnt := node.typ.nr_muls() - node.expr_type.nr_muls() + ptr_cnt := node.typ.nr_muls() - expr_type.nr_muls() if ptr_cnt > 0 { g.write('&'.repeat(ptr_cnt)) } diff --git a/vlib/v/tests/cast_comptime_test.v b/vlib/v/tests/cast_comptime_test.v new file mode 100644 index 0000000000..cbfa2505ff --- /dev/null +++ b/vlib/v/tests/cast_comptime_test.v @@ -0,0 +1,50 @@ +struct Document0 { + a int + b f64 + c string + d bool + e u8 + f u32 +} + +type Any = []Any + | bool + | f32 + | f64 + | i16 + | i64 + | i8 + | int + | map[string]Any + | string + | u16 + | u32 + | u64 + | u8 + +fn raw_encode[T](data T) !map[string]Any { + mut res := map[string]Any{} + $for field in T.fields { + x := data.$(field.name) + res[field.name] = Any(x) + } + return res +} + +fn test_main() { + d := Document0{ + a: 1 + b: 1.1 + c: 'qwerty' + d: false + e: u8(0) + f: u32(0) + } + map_data := raw_encode(d)! + assert map_data['a']! as int == d.a + assert map_data['b']! as f64 == d.b + assert map_data['c']! as string == d.c + assert map_data['d']! as bool == d.d + assert map_data['e']! as u8 == d.e + assert map_data['f']! as u32 == d.f +}