From ae5bf7ef79dad076473168e4460e581d79e8aa66 Mon Sep 17 00:00:00 2001 From: CreeperFace <165158232+dy-tea@users.noreply.github.com> Date: Thu, 13 Nov 2025 22:08:39 +0000 Subject: [PATCH] checker: unwrap for base type if ft.typ and inferred_typ are both opt (fix #25517) (#25728) --- vlib/v/checker/check_types.v | 7 +++++- .../json_optional_both_type_field_test.v | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 vlib/x/json2/tests/json_optional_both_type_field_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 9dccd0e2e..bce0b0874 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -845,7 +845,12 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit) if field_sym.name == gt_name { for t in node.init_fields { if ft.name == t.name && t.typ != 0 { - concrete_types << ast.mktyp(t.typ) + // unwrap to get base type for T if both are options + mut inferred_typ := ast.mktyp(t.typ) + if ft.typ.has_flag(.option) && inferred_typ.has_flag(.option) { + inferred_typ = inferred_typ.clear_flag(.option) + } + concrete_types << inferred_typ continue gname } } diff --git a/vlib/x/json2/tests/json_optional_both_type_field_test.v b/vlib/x/json2/tests/json_optional_both_type_field_test.v new file mode 100644 index 000000000..fa666f9a6 --- /dev/null +++ b/vlib/x/json2/tests/json_optional_both_type_field_test.v @@ -0,0 +1,23 @@ +struct Response[T] { + code int + msg string + data ?T +} + +struct UserInfo { + name string + age int +} + +fn g[T](x T) string { + return 'abc' +} + +fn response_to_string[T](response Response[T]) string { + return g(response) +} + +fn test_main() { + res := response_to_string(Response{1, 'success', ?UserInfo{'Jay Chou', 46}}) + assert res == 'abc' +} -- 2.39.5