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

cgen: fix code generated for optional comptime var (#16854)

This commit is contained in:
Felipe Pena
2023-01-05 05:54:51 -03:00
committed by GitHub
parent 19c9633896
commit e3aee748ac
3 changed files with 110 additions and 0 deletions

View File

@ -4247,6 +4247,22 @@ fn (mut g Gen) ident(node ast.Ident) {
}
mut is_auto_heap := false
if node.info is ast.IdentVar {
if node.obj is ast.Var {
if !g.is_assign_lhs && node.obj.is_comptime_field {
if g.comptime_for_field_type.has_flag(.optional) {
if g.inside_opt_or_res {
g.write('${name}')
} else {
g.write('/*opt*/')
styp := g.base_type(g.comptime_for_field_type)
g.write('(*(${styp}*)${name}.data)')
}
} else {
g.write('${name}')
}
return
}
}
// x ?int
// `x = 10` => `x.data = 10` (g.right_is_opt == false)
// `x = new_opt()` => `x = new_opt()` (g.right_is_opt == true)

View File

@ -0,0 +1,34 @@
struct FixedStruct1 {
a int
b string
}
struct FixedStruct2 {
c ?int
d ?string
}
struct Writer {}
fn write1[T](val T) {
println(val)
}
fn (wr &Writer) write2[T](val T) {
println(val)
}
fn encode_struct[T](val T) bool {
wr := Writer{}
$for field in T.fields {
value := val.$(field.name)
write1(value)
wr.write2(value)
}
return true
}
fn test_main() {
assert encode_struct(FixedStruct1{}) == true
assert encode_struct(FixedStruct2{}) == true
}

View File

@ -0,0 +1,60 @@
struct FixedStruct1 {
a int
b ?int
c ?int = 4
}
// struct FixedStruct2 {
// b ?int
// }
struct Encoder {}
struct Writer {}
fn write1[T](val T) {
println(val)
}
fn (wr &Writer) write2[T](val T) {
println(val)
}
fn encode_struct[T](val T) map[string][]string {
wr := Writer{}
mut out := map[string][]string{}
$if T is $Struct {
$for field in T.fields {
value := val.$(field.name)
$if field.typ is ?int {
// work if comment lines 27 and 28
write1(value)
wr.write2(value)
out[field.name] << '${value}'
} $else {
write1(value)
wr.write2(value)
out[field.name] << value.str()
}
// This work well
$if field.is_optional {
write1(value)
wr.write2(value)
out[field.name] << '${value}'
} $else {
write1(value)
wr.write2(value)
out[field.name] << value.str()
}
}
}
return out
}
fn test_main() {
// cgen error: cannot convert 'struct _option_int' to 'int'
out := encode_struct(FixedStruct1{})
assert out['a'] == ['0', '0']
assert out['b'] == ['0', '0']
assert out['c'] == ['4', '4']
}