From cf07375d1b8db31dbd9ee4dbf25a846f9d9e1987 Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 26 May 2021 00:51:55 +0800 Subject: [PATCH] checker: fix multi types generic struct init (#10201) --- vlib/v/checker/checker.v | 9 +++- .../generics_multi_types_struct_init_test.v | 41 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/generics_multi_types_struct_init_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 1bca2d3b8d..e35b737148 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3241,7 +3241,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { } return } - // + is_decl := assign_stmt.op == .decl_assign for i, left in assign_stmt.left { if left is ast.CallExpr { @@ -3283,6 +3283,13 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { right := if i < assign_stmt.right.len { assign_stmt.right[i] } else { assign_stmt.right[0] } mut right_type := assign_stmt.right_types[i] if is_decl { + // check generic struct init and return unwrap generic struct type + if right is ast.StructInit { + if right.typ.has_flag(.generic) { + c.expr(right) + right_type = right.typ + } + } if right.is_auto_deref_var() { left_type = c.table.mktyp(right_type.deref()) } else { diff --git a/vlib/v/tests/generics_multi_types_struct_init_test.v b/vlib/v/tests/generics_multi_types_struct_init_test.v new file mode 100644 index 0000000000..36c06ce588 --- /dev/null +++ b/vlib/v/tests/generics_multi_types_struct_init_test.v @@ -0,0 +1,41 @@ +struct Response { + result T +} + +pub fn send(res T) string { + msg := Response{ + result: res + } + return '$msg' +} + +struct Foo {} + +struct Bar {} + +fn test_generics_multi_types_struct_init() { + mut ret := send(Foo{}) + println(ret) + assert ret.contains('Response{') + assert ret.contains('result: Foo{}') + + ret = send(Bar{}) + println(ret) + assert ret.contains('Response{') + assert ret.contains('result: Bar{}') + + ret = send(123) + println(ret) + assert ret.contains('Response{') + assert ret.contains('result: 123') + + ret = send('abc') + println(ret) + assert ret.contains('Response{') + assert ret.contains("result: 'abc'") + + ret = send(2.22) + println(ret) + assert ret.contains('Response{') + assert ret.contains('result: 2.22') +}