From efb78cea35bb24711fbbb47571e92fd80363a61c Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 15 Apr 2026 04:51:55 +0300 Subject: [PATCH] checker: fix cannot convert struct to struct pointer in generics (fixes #21835) --- vlib/v/checker/check_types.v | 13 +++++++++++- ...ort_struct_init_reference_inference_test.v | 21 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/generics/generic_fn_short_struct_init_reference_inference_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 1f8d1e24f..24b47628a 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -1142,9 +1142,20 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit) if ft.name == t.name && t.typ != 0 { // 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) { + mut field_typ := ft.typ + if field_typ.has_flag(.option) && inferred_typ.has_flag(.option) { + field_typ = field_typ.clear_flag(.option) inferred_typ = inferred_typ.clear_flag(.option) } + if field_typ.nr_muls() > 0 && inferred_typ.nr_muls() > 0 { + field_muls := field_typ.nr_muls() + inferred_muls := inferred_typ.nr_muls() + inferred_typ = if inferred_muls >= field_muls { + inferred_typ.set_nr_muls(inferred_muls - field_muls) + } else { + inferred_typ.set_nr_muls(0) + } + } concrete_types << inferred_typ continue gname } diff --git a/vlib/v/tests/generics/generic_fn_short_struct_init_reference_inference_test.v b/vlib/v/tests/generics/generic_fn_short_struct_init_reference_inference_test.v new file mode 100644 index 000000000..f921e88b5 --- /dev/null +++ b/vlib/v/tests/generics/generic_fn_short_struct_init_reference_inference_test.v @@ -0,0 +1,21 @@ +import json + +@[heap] +struct Logger {} + +struct SaveParams[T] { + object &T +} + +fn (mut l Logger) save[T](p SaveParams[T]) string { + return json.encode(p.object) +} + +struct Object { + s1 string = 'a string' +} + +fn test_generic_fn_short_struct_init_reference_inference() { + mut logger := &Logger{} + assert logger.save(object: &Object{}) == '{"s1":"a string"}' +} -- 2.39.5