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)
|
arg_sym := c.table.get_type_symbol(arg.typ)
|
||||||
param_type_sym := c.table.get_type_symbol(param.typ)
|
param_type_sym := c.table.get_type_symbol(param.typ)
|
||||||
if arg_sym.kind == .array && param_type_sym.kind == .array {
|
if arg_sym.kind == .array && param_type_sym.kind == .array {
|
||||||
param_info := param_type_sym.info as table.Array
|
mut arg_elem_info := arg_sym.info as table.Array
|
||||||
if param_info.elem_type.has_flag(.generic) {
|
mut param_elem_info := param_type_sym.info as table.Array
|
||||||
arg_info := arg_sym.info as table.Array
|
mut arg_elem_sym := c.table.get_type_symbol(arg_elem_info.elem_type)
|
||||||
typ = arg_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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if typ == table.void_type {
|
if typ == table.void_type {
|
||||||
c.error('could not infer generic type `$gt_name` in call to `$f.name`', call_expr.pos)
|
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
|
call_expr.return_type = typ
|
||||||
return typ
|
return typ
|
||||||
} else if return_sym.kind == .array {
|
} else if return_sym.kind == .array && return_sym.name.contains('T') {
|
||||||
elem_info := return_sym.info as table.Array
|
mut info := return_sym.info as table.Array
|
||||||
elem_sym := c.table.get_type_symbol(elem_info.elem_type)
|
mut sym := c.table.get_type_symbol(info.elem_type)
|
||||||
if elem_sym.name == 'T' {
|
mut dims := 1
|
||||||
idx := c.table.find_or_register_array(call_expr.generic_type, 1)
|
for {
|
||||||
return table.new_type(idx)
|
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 {
|
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)
|
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