checker: fix generics return generic struct (#9663)

pull/9667/head
yuyi 2021-04-10 19:00:01 +08:00 committed by GitHub
parent 1bcc45f914
commit cf64001474
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 10 deletions

View File

@ -1446,6 +1446,8 @@ fn (mut c Checker) check_return_generics_struct(return_type ast.Type, mut call_e
} }
mut info := rts.info mut info := rts.info
info.generic_types = [] info.generic_types = []
info.concrete_types = generic_types.clone()
info.parent_type = return_type
info.fields = fields info.fields = fields
stru_idx := c.table.register_type_symbol(ast.TypeSymbol{ stru_idx := c.table.register_type_symbol(ast.TypeSymbol{
kind: .struct_ kind: .struct_

View File

@ -2,11 +2,14 @@
pub struct Optional<T> { pub struct Optional<T> {
mut: mut:
value T value T
some bool some bool
} }
pub fn new_some<T>(value T) Optional<T> { pub fn new_some<T>(value T) Optional<T> {
return {value: value, some: true} return {
value: value
some: true
}
} }
pub fn some<T>(opt Optional<T>) bool { pub fn some<T>(opt Optional<T>) bool {
@ -36,19 +39,22 @@ pub struct Foo {
foo int foo int
} }
pub fn (f Foo)new_some<T>(value T) Optional<T> { pub fn (f Foo) new_some<T>(value T) Optional<T> {
return {value: value, some: true} return {
value: value
some: true
}
} }
pub fn (f Foo)some<T>(opt Optional<T>) bool { pub fn (f Foo) some<T>(opt Optional<T>) bool {
return opt.some return opt.some
} }
pub fn (f Foo)get<T>(opt Optional<T>) T { pub fn (f Foo) get<T>(opt Optional<T>) T {
return opt.value return opt.value
} }
pub fn (f Foo)set<T>(mut opt Optional<T>, value T) { pub fn (f Foo) set<T>(mut opt Optional<T>, value T) {
opt.value = value opt.value = value
opt.some = true opt.some = true
} }
@ -71,11 +77,14 @@ mut:
} }
pub fn iter<T>(arr []T) ArrayIterator<T> { pub fn iter<T>(arr []T) ArrayIterator<T> {
return ArrayIterator{data: arr, index: 11} return ArrayIterator{
data: arr
index: 11
}
} }
fn test_generics_with_generics_struct_string() { fn test_generics_with_generics_struct_string() {
data := ['foo' 'bar'] data := ['foo', 'bar']
it := iter<string>(data) it := iter<string>(data)
println(it) println(it)
ret := '$it' ret := '$it'
@ -86,7 +95,7 @@ fn test_generics_with_generics_struct_string() {
fn test_generics_struct_insts_to_concrete() { fn test_generics_struct_insts_to_concrete() {
ai := ArrayIterator<int>{ ai := ArrayIterator<int>{
data: [11, 22], data: [11, 22]
index: 22 index: 22
} }
println(ai) println(ai)
@ -95,3 +104,23 @@ fn test_generics_struct_insts_to_concrete() {
assert ret.contains('data: [11, 22]') assert ret.contains('data: [11, 22]')
assert ret.contains('index: 22') assert ret.contains('index: 22')
} }
struct Iterator<T> {
data []T
}
pub fn (mut i Iterator<T>) next<T>() ?T {
return i.data[0]
}
pub fn iter_data<T>(data []T) Iterator<T> {
return Iterator{
data: data
}
}
fn test_generics_return_generic_struct_from_fn() {
mut it := iter_data<int>([1, 2, 3])
println(it.next())
assert '$it.next()' == 'Option(1)'
}