1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

table, checker, cgen: implement generic fn infering fixed array (#10352)

This commit is contained in:
yuyi 2021-06-06 06:11:08 +08:00 committed by GitHub
parent c2981de4d5
commit 329a6c974e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 1 deletions

View File

@ -1144,6 +1144,14 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
idx := t.find_or_register_array_with_dims(typ, dims) idx := t.find_or_register_array_with_dims(typ, dims)
return new_type(idx).derive(generic_type).clear_flag(.generic) return new_type(idx).derive(generic_type).clear_flag(.generic)
} }
} else if sym.kind == .array_fixed {
info := sym.info as ArrayFixed
if typ := t.resolve_generic_to_concrete(info.elem_type, generic_names, concrete_types,
is_inst)
{
idx := t.find_or_register_array_fixed(typ, info.size, None{})
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
} else if mut sym.info is Chan { } else if mut sym.info is Chan {
if typ := t.resolve_generic_to_concrete(sym.info.elem_type, generic_names, concrete_types, if typ := t.resolve_generic_to_concrete(sym.info.elem_type, generic_names, concrete_types,
is_inst) is_inst)

View File

@ -568,6 +568,23 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
break break
} }
} }
} else if arg_sym.kind == .array_fixed && param_type_sym.kind == .array_fixed {
mut arg_elem_info := arg_sym.info as ast.ArrayFixed
mut param_elem_info := param_type_sym.info as ast.ArrayFixed
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_fixed && param_elem_sym.kind == .array_fixed
&& param_elem_sym.name !in c.table.cur_fn.generic_names {
arg_elem_info = arg_elem_sym.info as ast.ArrayFixed
arg_elem_sym = c.table.get_type_symbol(arg_elem_info.elem_type)
param_elem_info = param_elem_sym.info as ast.ArrayFixed
param_elem_sym = c.table.get_type_symbol(param_elem_info.elem_type)
} else {
to_set = arg_elem_info.elem_type
break
}
}
} else if param.typ.has_flag(.variadic) { } else if param.typ.has_flag(.variadic) {
to_set = c.table.mktyp(arg.typ) to_set = c.table.mktyp(arg.typ)
} else if arg_sym.kind == .struct_ && param.typ.has_flag(.generic) { } else if arg_sym.kind == .struct_ && param.typ.has_flag(.generic) {

View File

@ -5734,7 +5734,7 @@ fn (mut g Gen) write_types(types []ast.TypeSymbol) {
} }
ast.ArrayFixed { ast.ArrayFixed {
elem_sym := g.table.get_type_symbol(typ.info.elem_type) elem_sym := g.table.get_type_symbol(typ.info.elem_type)
if !elem_sym.is_builtin() { if !elem_sym.is_builtin() && !typ.info.elem_type.has_flag(.generic) {
// .array_fixed { // .array_fixed {
styp := typ.cname styp := typ.cname
// array_fixed_char_300 => char x[300] // array_fixed_char_300 => char x[300]

View File

@ -0,0 +1,30 @@
fn get_element<T>(arr [3]T) string {
return '${arr[1]}'
}
fn test_generic_fn_infer_fixed_array() {
a := [1, 2, 3]!
mut ret := get_element(a)
println(ret)
assert ret == '2'
b := ['a', 'b', 'c']!
ret = get_element(b)
println(ret)
assert ret == 'b'
c := [1.1, 2.2, 3.3]!
ret = get_element(c)
println(ret)
assert ret == '2.2'
d := [`a`, `b`, `c`]!
ret = get_element(d)
println(ret)
assert ret == 'b'
e := [true, false, true]!
ret = get_element(e)
println(ret)
assert ret == 'false'
}