From a28249c119caf700c06495013ac0f92aea6ec120 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 24 Feb 2022 16:48:52 +0800 Subject: [PATCH] ast: fix for in iterator of generic struct (fix #13579) (#13585) --- vlib/v/ast/types.v | 14 +++++--- ...or_in_iterator_of_generic_struct_1_test.v} | 0 ...for_in_iterator_of_generic_struct_2_test.v | 35 +++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) rename vlib/v/tests/{for_in_iterator_of_generic_struct_test.v => for_in_iterator_of_generic_struct_1_test.v} (100%) create mode 100644 vlib/v/tests/for_in_iterator_of_generic_struct_2_test.v diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 159c9ff93f..11e9d3938a 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -1266,10 +1266,16 @@ pub fn (t &TypeSymbol) find_method_with_generic_parent(name string) ?Fn { Struct, Interface, SumType { mut method := x generic_names := parent_sym.info.generic_types.map(table.sym(it).name) - if rt := table.resolve_generic_to_concrete(method.return_type, - generic_names, t.info.concrete_types) - { - method.return_type = rt + return_sym := table.sym(method.return_type) + if return_sym.kind == .struct_ { + method.return_type = table.unwrap_generic_type(method.return_type, + generic_names, t.info.concrete_types) + } else { + if rt := table.resolve_generic_to_concrete(method.return_type, + generic_names, t.info.concrete_types) + { + method.return_type = rt + } } method.params = method.params.clone() for mut param in method.params { diff --git a/vlib/v/tests/for_in_iterator_of_generic_struct_test.v b/vlib/v/tests/for_in_iterator_of_generic_struct_1_test.v similarity index 100% rename from vlib/v/tests/for_in_iterator_of_generic_struct_test.v rename to vlib/v/tests/for_in_iterator_of_generic_struct_1_test.v diff --git a/vlib/v/tests/for_in_iterator_of_generic_struct_2_test.v b/vlib/v/tests/for_in_iterator_of_generic_struct_2_test.v new file mode 100644 index 0000000000..511f4f39f7 --- /dev/null +++ b/vlib/v/tests/for_in_iterator_of_generic_struct_2_test.v @@ -0,0 +1,35 @@ +pub struct Item { +pub: + value V +} + +pub struct Iter { + arr []V +mut: + ix int +} + +pub fn (mut iter Iter) next() ?Item { + if iter.ix >= iter.arr.len { + return none + } + + val := iter.arr[iter.ix] + iter.ix += 1 + return Item{val} +} + +fn iterator(arr []V) Iter { + return Iter{arr, 0} +} + +fn test_for_in_iterator_of_generic_struct() { + mut ret := []int{} + mut x := iterator([1, 2, 3, 4, 5]) + for item in x { + println(item.value) + ret << item.value + } + println(ret) + assert ret == [1, 2, 3, 4, 5] +}