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:
parent
c2981de4d5
commit
329a6c974e
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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]
|
||||||
|
30
vlib/v/tests/generic_fn_infer_fixed_array_test.v
Normal file
30
vlib/v/tests/generic_fn_infer_fixed_array_test.v
Normal 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'
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user