diff --git a/vlib/v/checker/tests/comptime_dump_fields_var_test.out b/vlib/v/checker/tests/comptime_dump_fields_var_test.out index deb2106f1f..fa7fa704d3 100644 --- a/vlib/v/checker/tests/comptime_dump_fields_var_test.out +++ b/vlib/v/checker/tests/comptime_dump_fields_var_test.out @@ -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 diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index 6a0d36c30a..b78d4e87cf 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -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 diff --git a/vlib/v/gen/c/testdata/comptime_option_call.out b/vlib/v/gen/c/testdata/comptime_option_call.out index f6b3ef5efa..5e83e8918b 100644 --- a/vlib/v/gen/c/testdata/comptime_option_call.out +++ b/vlib/v/gen/c/testdata/comptime_option_call.out @@ -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) diff --git a/vlib/v/slow_tests/inout/struct_dump_option_fields.out b/vlib/v/slow_tests/inout/struct_dump_option_fields.out new file mode 100644 index 0000000000..8d200d5226 --- /dev/null +++ b/vlib/v/slow_tests/inout/struct_dump_option_fields.out @@ -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) + }) +} diff --git a/vlib/v/slow_tests/inout/struct_dump_option_fields.vv b/vlib/v/slow_tests/inout/struct_dump_option_fields.vv new file mode 100644 index 0000000000..8f79a42cb5 --- /dev/null +++ b/vlib/v/slow_tests/inout/struct_dump_option_fields.vv @@ -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) +} \ No newline at end of file diff --git a/vlib/v/slow_tests/inout/struct_field_option.out b/vlib/v/slow_tests/inout/struct_field_option.out index eb650f4afb..8ea5cedcf3 100644 --- a/vlib/v/slow_tests/inout/struct_field_option.out +++ b/vlib/v/slow_tests/inout/struct_field_option.out @@ -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 \ No newline at end of file +1 diff --git a/vlib/v/tests/option_fixed_array_test.v b/vlib/v/tests/option_fixed_array_test.v index 60fb765720..816398728f 100644 --- a/vlib/v/tests/option_fixed_array_test.v +++ b/vlib/v/tests/option_fixed_array_test.v @@ -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() { diff --git a/vlib/v/tests/option_struct_init_test.v b/vlib/v/tests/option_struct_init_test.v index 52d8884db6..8cd4dc2de2 100644 --- a/vlib/v/tests/option_struct_init_test.v +++ b/vlib/v/tests/option_struct_init_test.v @@ -15,6 +15,6 @@ fn test_main() { } assert a.str() == 'MyStruct2{ valuea: 1 - valueb: Option(error: none) + valueb: Option(none) }' } diff --git a/vlib/v/tests/results_test.v b/vlib/v/tests/results_test.v index c70e4349ac..b9f5a651ac 100644 --- a/vlib/v/tests/results_test.v +++ b/vlib/v/tests/results_test.v @@ -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) ! { diff --git a/vlib/v/tests/str_gen_test.v b/vlib/v/tests/str_gen_test.v index 21f49f87cd..048049c569 100644 --- a/vlib/v/tests/str_gen_test.v +++ b/vlib/v/tests/str_gen_test.v @@ -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 { diff --git a/vlib/x/json2/encoder.v b/vlib/x/json2/encoder.v index ec3c6c2884..2b200e172e 100644 --- a/vlib/x/json2/encoder.v +++ b/vlib/x/json2/encoder.v @@ -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)!