checker: fix generics that return multi generics struct (#9852)

pull/9853/head
yuyi 2021-04-23 16:19:16 +08:00 committed by GitHub
parent c026d8b6f3
commit 8e455495b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 3 deletions

View File

@ -1434,9 +1434,18 @@ fn (mut c Checker) check_return_generics_struct(return_type ast.Type, mut call_e
rts := c.table.get_type_symbol(return_type)
if rts.info is ast.Struct {
if rts.info.generic_types.len > 0 {
gts := c.table.get_type_symbol(call_expr.generic_types[0])
nrt := '$rts.name<$gts.name>'
c_nrt := '${rts.name}_T_$gts.name'
mut nrt := '$rts.name<'
mut c_nrt := '${rts.name}_T_'
for i in 0 .. call_expr.generic_types.len {
gts := c.table.get_type_symbol(call_expr.generic_types[i])
nrt += gts.name
c_nrt += gts.name
if i != call_expr.generic_types.len - 1 {
nrt += ','
c_nrt += '_'
}
}
nrt += '>'
idx := c.table.type_idxs[nrt]
if idx != 0 {
c.ensure_type_exists(idx, call_expr.pos) or {}

View File

@ -0,0 +1,38 @@
struct Foo<A, B> {
mut:
a A
b B
}
fn new_foo<A, B>(a A, b B) Foo<A, B> {
return {
a: a
b: b
}
}
fn get_a<A, B>(opt Foo<A, B>) A {
return opt.a
}
fn get_b<A, B>(opt Foo<A, B>) B {
return opt.b
}
fn set<A, B>(mut opt Foo<A, B>, a A, b B) {
opt.a = a
opt.b = b
}
fn test_generics_return_multiple_generics_struct() {
mut o := new_foo<int, string>(23, 'aaa')
println(get_a<int, string>(o))
assert get_a<int, string>(o) == 23
println(get_b<int, string>(o))
assert get_b<int, string>(o) == 'aaa'
set<int, string>(mut o, 42, 'bbb')
println(get_a<int, string>(o))
assert get_a<int, string>(o) == 42
println(get_b<int, string>(o))
assert get_b<int, string>(o) == 'bbb'
}