checker: fix generic fn infer variadic parameter with arrays (#11324)

pull/11328/head
yuyi 2021-08-28 15:32:51 +08:00 committed by GitHub
parent f731060caf
commit e90a624738
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 17 deletions

View File

@ -633,7 +633,9 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
} }
} else if param.typ.has_flag(.generic) { } else if param.typ.has_flag(.generic) {
arg_sym := c.table.get_type_symbol(arg.typ) arg_sym := c.table.get_type_symbol(arg.typ)
if arg_sym.kind == .array && param_type_sym.kind == .array { if param.typ.has_flag(.variadic) {
to_set = c.table.mktyp(arg.typ)
} else if arg_sym.kind == .array && param_type_sym.kind == .array {
mut arg_elem_info := arg_sym.info as ast.Array mut arg_elem_info := arg_sym.info as ast.Array
mut param_elem_info := param_type_sym.info as ast.Array mut param_elem_info := param_type_sym.info as ast.Array
mut arg_elem_sym := c.table.get_type_symbol(arg_elem_info.elem_type) mut arg_elem_sym := c.table.get_type_symbol(arg_elem_info.elem_type)
@ -678,8 +680,6 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
&& c.table.get_type_symbol(param_map_info.value_type).name == gt_name { && c.table.get_type_symbol(param_map_info.value_type).name == gt_name {
typ = arg_map_info.value_type typ = arg_map_info.value_type
} }
} else if param.typ.has_flag(.variadic) {
to_set = c.table.mktyp(arg.typ)
} else if arg_sym.kind in [.struct_, .interface_, .sum_type] { } else if arg_sym.kind in [.struct_, .interface_, .sum_type] {
mut generic_types := []ast.Type{} mut generic_types := []ast.Type{}
mut concrete_types := []ast.Type{} mut concrete_types := []ast.Type{}

View File

@ -1,14 +1,7 @@
vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.vv:12:11: error: cannot use `[]int` as `int` in argument 1 to `max` vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.vv:12:16: error: cannot use `[]int` as `int` in argument 1 to `max`
10 | 10 |
11 | fn main() { 11 | fn main() {
12 | a := max([1, 2, 3, 4]) 12 | b := max<int>([1, 2, 3, 4])
| ~~~~~~~~~~~~
13 | println(a)
14 |
vlib/v/checker/tests/generics_fn_called_variadic_arg_mismatch.vv:15:16: error: cannot use `[]int` as `int` in argument 1 to `max`
13 | println(a)
14 |
15 | b := max<int>([1, 2, 3, 4])
| ~~~~~~~~~~~~ | ~~~~~~~~~~~~
16 | println(b) 13 | println(b)
17 | } 14 | }

View File

@ -9,9 +9,6 @@ fn max<T>(a ...T) T {
} }
fn main() { fn main() {
a := max([1, 2, 3, 4])
println(a)
b := max<int>([1, 2, 3, 4]) b := max<int>([1, 2, 3, 4])
println(b) println(b)
} }

View File

@ -0,0 +1,17 @@
fn generic<T>(items ...T) string {
return '$items'
}
fn test_generic_fn_infer_variadic() {
ret1 := generic([1, 2, 3], [4, 5, 6])
println(ret1)
assert ret1 == '[[1, 2, 3], [4, 5, 6]]'
ret2 := generic(['a', 'b'], ['c', 'd'])
println(ret2)
assert ret2 == "[['a', 'b'], ['c', 'd']]"
ret3 := generic(1.1, 2.2, 3.3)
println(ret3)
assert ret3 == '[1.1, 2.2, 3.3]'
}