parent
7533ffa48f
commit
46d311dcc4
|
@ -427,13 +427,24 @@ pub fn (mut c Checker) infer_fn_types(f table.Fn, mut call_expr ast.CallExpr) {
|
|||
arg_sym := c.table.get_type_symbol(arg.typ)
|
||||
param_type_sym := c.table.get_type_symbol(param.typ)
|
||||
if arg_sym.kind == .array && param_type_sym.kind == .array {
|
||||
param_info := param_type_sym.info as table.Array
|
||||
if param_info.elem_type.has_flag(.generic) {
|
||||
arg_info := arg_sym.info as table.Array
|
||||
typ = arg_info.elem_type
|
||||
mut arg_elem_info := arg_sym.info as table.Array
|
||||
mut param_elem_info := param_type_sym.info as table.Array
|
||||
mut arg_elem_sym := c.table.get_type_symbol(arg_elem_info.elem_type)
|
||||
mut param_elem_sym := c.table.get_type_symbol(param_elem_info.elem_type)
|
||||
for {
|
||||
if arg_elem_sym.kind == .array &&
|
||||
param_elem_sym.kind == .array && param_elem_sym.name != 'T' {
|
||||
arg_elem_info = arg_elem_sym.info as table.Array
|
||||
arg_elem_sym = c.table.get_type_symbol(arg_elem_info.elem_type)
|
||||
param_elem_info = param_elem_sym.info as table.Array
|
||||
param_elem_sym = c.table.get_type_symbol(param_elem_info.elem_type)
|
||||
} else {
|
||||
typ = arg_elem_info.elem_type
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if typ == table.void_type {
|
||||
c.error('could not infer generic type `$gt_name` in call to `$f.name`', call_expr.pos)
|
||||
|
|
|
@ -1766,14 +1766,24 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
|||
}
|
||||
call_expr.return_type = typ
|
||||
return typ
|
||||
} else if return_sym.kind == .array {
|
||||
elem_info := return_sym.info as table.Array
|
||||
elem_sym := c.table.get_type_symbol(elem_info.elem_type)
|
||||
if elem_sym.name == 'T' {
|
||||
idx := c.table.find_or_register_array(call_expr.generic_type, 1)
|
||||
return table.new_type(idx)
|
||||
} else if return_sym.kind == .array && return_sym.name.contains('T') {
|
||||
mut info := return_sym.info as table.Array
|
||||
mut sym := c.table.get_type_symbol(info.elem_type)
|
||||
mut dims := 1
|
||||
for {
|
||||
if sym.kind == .array {
|
||||
info = sym.info as table.Array
|
||||
sym = c.table.get_type_symbol(info.elem_type)
|
||||
dims++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
idx := c.table.find_or_register_array(call_expr.generic_type, dims)
|
||||
typ := table.new_type(idx)
|
||||
call_expr.return_type = typ
|
||||
return typ
|
||||
}
|
||||
}
|
||||
if call_expr.generic_type.is_full() && !f.is_generic {
|
||||
c.error('a non generic function called like a generic one', call_expr.generic_list_pos)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
fn example1<T>(data []T) [][]T {
|
||||
return [data]
|
||||
}
|
||||
|
||||
fn example2<T>(data [][]T) [][][]T {
|
||||
return [data]
|
||||
}
|
||||
|
||||
fn example3<T>(data [][][]T) [][][][]T {
|
||||
return [data]
|
||||
}
|
||||
|
||||
fn test_generic_return_multi_array() {
|
||||
d1 := [1, 2, 3]
|
||||
d2 := example1(d1)
|
||||
assert d2 == [[1, 2, 3]]
|
||||
|
||||
d11 := [[1, 2, 3]]
|
||||
d22 := example2(d11)
|
||||
assert d22 == [[[1, 2, 3]]]
|
||||
|
||||
d111 := [[[1, 2, 3]]]
|
||||
d222 := example3(d111)
|
||||
assert d222 == [[[[1, 2, 3]]]]
|
||||
}
|
Loading…
Reference in New Issue