mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix auto_str for option values (#17910)
This commit is contained in:
parent
220b31bfba
commit
5c439b6621
|
@ -3,6 +3,6 @@
|
|||
[vlib/v/checker/tests/comptime_dump_fields_var_test.vv:13] val.$(field.name): 1
|
||||
[vlib/v/checker/tests/comptime_dump_fields_var_test.vv:13] val.$(field.name): Option(0)
|
||||
[vlib/v/checker/tests/comptime_dump_fields_var_test.vv:13] val.$(field.name): struct {
|
||||
i: 100
|
||||
i: Option(100)
|
||||
}
|
||||
ok
|
||||
|
|
|
@ -192,13 +192,9 @@ fn (mut g Gen) gen_str_for_option(typ ast.Type, styp string, str_fn_name string)
|
|||
} else {
|
||||
g.auto_str_funcs.writeln('\t\tres = ${parent_str_fn_name}(*(${sym.cname}*)it.data);')
|
||||
}
|
||||
g.auto_str_funcs.writeln('\t} else {')
|
||||
|
||||
tmp_str := str_intp_sub('error: %%', 'IError_str(it.err)')
|
||||
g.auto_str_funcs.writeln('\t\tres = ${tmp_str};')
|
||||
g.auto_str_funcs.writeln('\t\treturn ${str_intp_sub('Option(%%)', 'res')};')
|
||||
g.auto_str_funcs.writeln('\t}')
|
||||
|
||||
g.auto_str_funcs.writeln('\treturn ${str_intp_sub('Option(%%)', 'res')};')
|
||||
g.auto_str_funcs.writeln('\treturn _SLIT("Option(none)");')
|
||||
g.auto_str_funcs.writeln('}')
|
||||
}
|
||||
|
||||
|
@ -231,7 +227,7 @@ fn (mut g Gen) gen_str_for_result(typ ast.Type, styp string, str_fn_name string)
|
|||
g.auto_str_funcs.writeln('\t\tres = ${tmp_str};')
|
||||
g.auto_str_funcs.writeln('\t}')
|
||||
|
||||
g.auto_str_funcs.writeln('\treturn ${str_intp_sub('result(%%)', 'res')};')
|
||||
g.auto_str_funcs.writeln('\treturn ${str_intp_sub('Result(%%)', 'res')};')
|
||||
g.auto_str_funcs.writeln('}')
|
||||
}
|
||||
|
||||
|
@ -897,16 +893,19 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, typ_str string,
|
|||
''
|
||||
}
|
||||
base_fmt := g.type_to_fmt(g.unwrap_generic(field.typ))
|
||||
is_opt_field := field.typ.has_flag(.option)
|
||||
|
||||
// manage prefix and quote symbol for the filed
|
||||
mut quote_str := ''
|
||||
mut prefix := ''
|
||||
sym := g.table.sym(g.unwrap_generic(field.typ))
|
||||
if sym.kind == .string {
|
||||
quote_str = "'"
|
||||
} else if field.typ in ast.charptr_types {
|
||||
quote_str = '\\"'
|
||||
prefix = 'C'
|
||||
if !is_opt_field {
|
||||
if sym.kind == .string {
|
||||
quote_str = "'"
|
||||
} else if field.typ in ast.charptr_types {
|
||||
quote_str = '\\"'
|
||||
prefix = 'C'
|
||||
}
|
||||
}
|
||||
|
||||
if is_first {
|
||||
|
@ -937,7 +936,9 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, typ_str string,
|
|||
g.get_str_fn(ftyp_noshared)
|
||||
}
|
||||
// with floats we use always the g representation:
|
||||
if sym.kind !in [.f32, .f64] {
|
||||
if is_opt_field {
|
||||
fn_body.write_string('{_SLIT("${quote_str}"), ${c.si_s_code}, {.d_s=')
|
||||
} else if sym.kind !in [.f32, .f64] {
|
||||
fn_body.write_string('{_SLIT("${quote_str}"), ${int(base_fmt)}, {.${data_str(base_fmt)}=')
|
||||
} else {
|
||||
g_fmt := '0x' + (u32(base_fmt) | u32(0x7F) << 9).hex()
|
||||
|
@ -949,8 +950,11 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, typ_str string,
|
|||
field.name, sym_has_str_method, str_method_expects_ptr)
|
||||
ftyp_nr_muls := field.typ.nr_muls()
|
||||
if ftyp_nr_muls > 1 || field.typ in ast.cptr_types {
|
||||
func = '(voidptr) it.${field.name}'
|
||||
caller_should_free = false
|
||||
if is_opt_field {
|
||||
} else {
|
||||
func = '(voidptr) it.${field.name}'
|
||||
caller_should_free = false
|
||||
}
|
||||
} else if ftyp_noshared.is_ptr() {
|
||||
// reference types can be "nil"
|
||||
if ftyp_noshared.has_flag(.option) {
|
||||
|
@ -1004,7 +1008,7 @@ fn struct_auto_str_func(sym &ast.TypeSymbol, _field_type ast.Type, fn_name strin
|
|||
deref, _ := deref_kind(expects_ptr, field_type.is_ptr(), field_type)
|
||||
if sym.kind == .enum_ {
|
||||
return '${fn_name}(${deref}(it.${c_name(field_name)}))', true
|
||||
} else if should_use_indent_func(sym.kind) {
|
||||
} else if _field_type.has_flag(.option) || should_use_indent_func(sym.kind) {
|
||||
obj := '${deref}it.${c_name(field_name)}${sufix}'
|
||||
if has_custom_str {
|
||||
return '${fn_name}(${obj})', true
|
||||
|
|
10
vlib/v/gen/c/testdata/comptime_option_call.out
vendored
10
vlib/v/gen/c/testdata/comptime_option_call.out
vendored
|
@ -1,10 +1,10 @@
|
|||
0
|
||||
0
|
||||
Option(error: none)
|
||||
Option(error: none)
|
||||
Option(error: none)
|
||||
Option(error: none)
|
||||
Option(none)
|
||||
Option(none)
|
||||
Option(none)
|
||||
Option(none)
|
||||
1
|
||||
1
|
||||
println(NIL)
|
||||
Option(error: none)
|
||||
Option(none)
|
||||
|
|
18
vlib/v/slow_tests/inout/struct_dump_option_fields.out
Normal file
18
vlib/v/slow_tests/inout/struct_dump_option_fields.out
Normal file
|
@ -0,0 +1,18 @@
|
|||
Test{
|
||||
a: Option(none)
|
||||
b: Option(none)
|
||||
c: Option(none)
|
||||
d: &Option(none)
|
||||
e: Option(none)
|
||||
f: Option(none)
|
||||
g: Option(none)
|
||||
h: &Option(none)
|
||||
i: Option(none)
|
||||
j: Option(none)
|
||||
k: []
|
||||
l: []
|
||||
m: []
|
||||
n: Option(Other{
|
||||
a: Option(none)
|
||||
})
|
||||
}
|
35
vlib/v/slow_tests/inout/struct_dump_option_fields.vv
Normal file
35
vlib/v/slow_tests/inout/struct_dump_option_fields.vv
Normal file
|
@ -0,0 +1,35 @@
|
|||
type Alias = int
|
||||
|
||||
type SumType = int | string
|
||||
|
||||
enum Abc {
|
||||
a
|
||||
b
|
||||
c
|
||||
}
|
||||
|
||||
struct Other {
|
||||
a ?int
|
||||
}
|
||||
|
||||
struct Test {
|
||||
a ?int
|
||||
b ?string
|
||||
c ?[]int
|
||||
d ?&int
|
||||
e ?Alias
|
||||
f ?SumType
|
||||
g ?Other
|
||||
h ?&&int
|
||||
i ?Abc
|
||||
j ?fn (int)
|
||||
k []?int
|
||||
l []?string
|
||||
m []?Other
|
||||
n ?Other = Other{}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
t := Test{}
|
||||
println(t)
|
||||
}
|
|
@ -16,11 +16,11 @@
|
|||
none
|
||||
3
|
||||
Foo{
|
||||
bar: 3
|
||||
baz: 0
|
||||
bar: Option(3)
|
||||
baz: Option(none)
|
||||
}
|
||||
[vlib/v/slow_tests/inout/struct_field_option.vv:61] f: Foo{
|
||||
bar: 3
|
||||
baz: 0
|
||||
bar: Option(3)
|
||||
baz: Option(none)
|
||||
}
|
||||
1
|
||||
1
|
||||
|
|
|
@ -24,7 +24,7 @@ fn f_arr2(args ?[3]f64) ?[]f64 {
|
|||
|
||||
fn test_simple() {
|
||||
mut arr := ?[3]int(none)
|
||||
println(arr) // Option(error: none)
|
||||
println(arr) // Option(none)
|
||||
}
|
||||
|
||||
fn test_simple_assign() {
|
||||
|
|
|
@ -15,6 +15,6 @@ fn test_main() {
|
|||
}
|
||||
assert a.str() == 'MyStruct2{
|
||||
valuea: 1
|
||||
valueb: Option(error: none)
|
||||
valueb: Option(none)
|
||||
}'
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ fn test_return_err_var() {
|
|||
}
|
||||
|
||||
fn test_str() {
|
||||
assert '${foo()}' == 'result(1)'
|
||||
assert '${foo()}' == 'Result(1)'
|
||||
}
|
||||
|
||||
fn result_void(err bool) ! {
|
||||
|
|
|
@ -328,12 +328,12 @@ fn test_multi_generic_struct() {
|
|||
assert x.str() == 'MultiGenericStruct[TestStruct, TestStruct]{\n t: TestStruct{\n x: 0\n }\n x: TestStruct{\n x: 0\n }\n}'
|
||||
}
|
||||
|
||||
fn create_option_err() ?string {
|
||||
fn create_option_err() !string {
|
||||
return error('this is an error')
|
||||
}
|
||||
|
||||
fn test_option_err() {
|
||||
assert '${create_option_err()}' == 'Option(error: this is an error)'
|
||||
fn test_result_err() {
|
||||
assert '${create_option_err()}' == 'Result(error: this is an error)'
|
||||
}
|
||||
|
||||
fn create_option_none() ?string {
|
||||
|
@ -341,7 +341,7 @@ fn create_option_none() ?string {
|
|||
}
|
||||
|
||||
fn test_option_none() {
|
||||
assert '${create_option_none()}' == 'Option(error: none)'
|
||||
assert '${create_option_none()}' == 'Option(none)'
|
||||
}
|
||||
|
||||
fn create_option_string() ?string {
|
||||
|
|
|
@ -155,7 +155,7 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
|
|||
mut i := 0
|
||||
mut fields_len := 0
|
||||
$for field in U.fields {
|
||||
if val.$(field.name).str() != 'Option(error: none)' {
|
||||
if val.$(field.name).str() != 'Option(none)' {
|
||||
fields_len++
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
|
|||
}
|
||||
|
||||
$if field.is_option {
|
||||
is_none := value.str() == 'Option(error: none)'
|
||||
is_none := value.str() == 'Option(none)'
|
||||
|
||||
if !is_none {
|
||||
e.encode_newline(level, mut wr)!
|
||||
|
|
Loading…
Reference in New Issue
Block a user