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

cgen: fix cast with comptime var (#17286)

This commit is contained in:
Felipe Pena 2023-02-12 03:54:09 -03:00 committed by GitHub
parent 6883561d6d
commit eb7e1b4712
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 4 deletions

View File

@ -4208,9 +4208,13 @@ fn (mut g Gen) ident(node ast.Ident) {
fn (mut g Gen) cast_expr(node ast.CastExpr) { fn (mut g Gen) cast_expr(node ast.CastExpr) {
node_typ := g.unwrap_generic(node.typ) node_typ := g.unwrap_generic(node.typ)
mut expr_type := node.expr_type
sym := g.table.sym(node_typ) 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_] { 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 { } else if sym.kind == .struct_ && !node.typ.is_ptr() && !(sym.info as ast.Struct).is_typedef {
// deprecated, replaced by Struct{...exr} // deprecated, replaced by Struct{...exr}
styp := g.typ(node.typ) 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.write('(${g.typ(node.expr.typ)})')
} }
g.expr(node.expr) 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) styp := g.typ(node_typ)
g.write('(${styp}[]){(') g.write('(${styp}[]){(')
g.expr(node.expr) g.expr(node.expr)
@ -4241,7 +4245,7 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
mut cast_label := '' mut cast_label := ''
// `ast.string_type` is done for MSVC's bug // `ast.string_type` is done for MSVC's bug
if sym.kind != .alias 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})' cast_label = '(${styp})'
} }
if node.typ.has_flag(.option) && node.expr is ast.None { 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 { } else {
g.write('(${cast_label}(') g.write('(${cast_label}(')
if sym.kind == .alias && g.table.final_sym(node.typ).kind == .string { 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 { if ptr_cnt > 0 {
g.write('&'.repeat(ptr_cnt)) g.write('&'.repeat(ptr_cnt))
} }

View File

@ -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
}