checker: fix generics that return multi generics struct (#9852)
parent
c026d8b6f3
commit
8e455495b2
|
@ -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 {}
|
||||
|
|
|
@ -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'
|
||||
}
|
Loading…
Reference in New Issue