From cf64001474af9f7fc67d43845fcd20e83b6d3301 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 10 Apr 2021 19:00:01 +0800 Subject: [PATCH] checker: fix generics return generic struct (#9663) --- vlib/v/checker/checker.v | 2 + .../generics_return_generics_struct_test.v | 49 +++++++++++++++---- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 41af16f87c..6e0873b7a3 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1446,6 +1446,8 @@ fn (mut c Checker) check_return_generics_struct(return_type ast.Type, mut call_e } mut info := rts.info info.generic_types = [] + info.concrete_types = generic_types.clone() + info.parent_type = return_type info.fields = fields stru_idx := c.table.register_type_symbol(ast.TypeSymbol{ kind: .struct_ diff --git a/vlib/v/tests/generics_return_generics_struct_test.v b/vlib/v/tests/generics_return_generics_struct_test.v index 8005f33812..0252bf0517 100644 --- a/vlib/v/tests/generics_return_generics_struct_test.v +++ b/vlib/v/tests/generics_return_generics_struct_test.v @@ -2,11 +2,14 @@ pub struct Optional { mut: value T - some bool + some bool } pub fn new_some(value T) Optional { - return {value: value, some: true} + return { + value: value + some: true + } } pub fn some(opt Optional) bool { @@ -36,19 +39,22 @@ pub struct Foo { foo int } -pub fn (f Foo)new_some(value T) Optional { - return {value: value, some: true} +pub fn (f Foo) new_some(value T) Optional { + return { + value: value + some: true + } } -pub fn (f Foo)some(opt Optional) bool { +pub fn (f Foo) some(opt Optional) bool { return opt.some } -pub fn (f Foo)get(opt Optional) T { +pub fn (f Foo) get(opt Optional) T { return opt.value } -pub fn (f Foo)set(mut opt Optional, value T) { +pub fn (f Foo) set(mut opt Optional, value T) { opt.value = value opt.some = true } @@ -71,11 +77,14 @@ mut: } pub fn iter(arr []T) ArrayIterator { - return ArrayIterator{data: arr, index: 11} + return ArrayIterator{ + data: arr + index: 11 + } } fn test_generics_with_generics_struct_string() { - data := ['foo' 'bar'] + data := ['foo', 'bar'] it := iter(data) println(it) ret := '$it' @@ -86,7 +95,7 @@ fn test_generics_with_generics_struct_string() { fn test_generics_struct_insts_to_concrete() { ai := ArrayIterator{ - data: [11, 22], + data: [11, 22] index: 22 } println(ai) @@ -95,3 +104,23 @@ fn test_generics_struct_insts_to_concrete() { assert ret.contains('data: [11, 22]') assert ret.contains('index: 22') } + +struct Iterator { + data []T +} + +pub fn (mut i Iterator) next() ?T { + return i.data[0] +} + +pub fn iter_data(data []T) Iterator { + return Iterator{ + data: data + } +} + +fn test_generics_return_generic_struct_from_fn() { + mut it := iter_data([1, 2, 3]) + println(it.next()) + assert '$it.next()' == 'Option(1)' +}