mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
46a096b95d
commit
b34860e39b
@ -1428,7 +1428,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
||||
if typ == 0 {
|
||||
return none
|
||||
}
|
||||
return typ.derive_add_muls(generic_type).clear_flag(.generic)
|
||||
if typ.has_flag(.generic) {
|
||||
return typ.derive_add_muls(generic_type).set_flag(.generic)
|
||||
} else {
|
||||
return typ.derive_add_muls(generic_type).clear_flag(.generic)
|
||||
}
|
||||
}
|
||||
match mut sym.info {
|
||||
Array {
|
||||
@ -1443,7 +1447,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
||||
}
|
||||
if typ := t.resolve_generic_to_concrete(elem_type, generic_names, concrete_types) {
|
||||
idx := t.find_or_register_array_with_dims(typ, dims)
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
if typ.has_flag(.generic) {
|
||||
return new_type(idx).derive_add_muls(generic_type).set_flag(.generic)
|
||||
} else {
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
}
|
||||
}
|
||||
}
|
||||
ArrayFixed {
|
||||
@ -1451,7 +1459,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
||||
concrete_types)
|
||||
{
|
||||
idx := t.find_or_register_array_fixed(typ, sym.info.size, None{})
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
if typ.has_flag(.generic) {
|
||||
return new_type(idx).derive_add_muls(generic_type).set_flag(.generic)
|
||||
} else {
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
}
|
||||
}
|
||||
}
|
||||
Chan {
|
||||
@ -1459,16 +1471,24 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
||||
concrete_types)
|
||||
{
|
||||
idx := t.find_or_register_chan(typ, typ.nr_muls() > 0)
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
if typ.has_flag(.generic) {
|
||||
return new_type(idx).derive_add_muls(generic_type).set_flag(.generic)
|
||||
} else {
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
}
|
||||
}
|
||||
}
|
||||
FnType {
|
||||
mut func := sym.info.func
|
||||
mut has_generic := false
|
||||
if func.return_type.has_flag(.generic) {
|
||||
if typ := t.resolve_generic_to_concrete(func.return_type, generic_names,
|
||||
concrete_types)
|
||||
{
|
||||
func.return_type = typ
|
||||
if typ.has_flag(.generic) {
|
||||
has_generic = true
|
||||
}
|
||||
}
|
||||
}
|
||||
func.params = func.params.clone()
|
||||
@ -1478,12 +1498,19 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
||||
concrete_types)
|
||||
{
|
||||
param.typ = typ
|
||||
if typ.has_flag(.generic) {
|
||||
has_generic = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func.name = ''
|
||||
idx := t.find_or_register_fn_type('', func, true, false)
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
if has_generic {
|
||||
return new_type(idx).derive_add_muls(generic_type).set_flag(.generic)
|
||||
} else {
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
}
|
||||
}
|
||||
MultiReturn {
|
||||
mut types := []Type{}
|
||||
@ -1498,7 +1525,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
||||
}
|
||||
if type_changed {
|
||||
idx := t.find_or_register_multi_return(types)
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
if types.any(it.has_flag(.generic)) {
|
||||
return new_type(idx).derive_add_muls(generic_type).set_flag(.generic)
|
||||
} else {
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
}
|
||||
}
|
||||
}
|
||||
Map {
|
||||
@ -1519,7 +1550,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
||||
}
|
||||
if type_changed {
|
||||
idx := t.find_or_register_map(unwrapped_key_type, unwrapped_value_type)
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
if unwrapped_key_type.has_flag(.generic) || unwrapped_value_type.has_flag(.generic) {
|
||||
return new_type(idx).derive_add_muls(generic_type).set_flag(.generic)
|
||||
} else {
|
||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||
}
|
||||
}
|
||||
}
|
||||
Struct, Interface, SumType {
|
||||
|
@ -963,6 +963,13 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||
}
|
||||
if func.generic_names.len > 0 {
|
||||
if has_generic {
|
||||
if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names,
|
||||
node.concrete_types)
|
||||
{
|
||||
if typ.has_flag(.generic) {
|
||||
node.return_type = typ
|
||||
}
|
||||
}
|
||||
return node.return_type
|
||||
} else if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names,
|
||||
concrete_types)
|
||||
|
@ -0,0 +1,26 @@
|
||||
fn test_generics_with_complex_nested_generics_type() {
|
||||
mut buf := []byte{}
|
||||
initial<string, u64>(buf)
|
||||
}
|
||||
|
||||
fn initial<K, V>(buf []byte) map[K]V {
|
||||
mut ret := map[K]V{}
|
||||
for _ in 0 .. 3 {
|
||||
k := get<K>(buf)
|
||||
v := get<V>(buf)
|
||||
ret[k] = v
|
||||
}
|
||||
println(ret)
|
||||
assert '$ret' == "{'get': 22}"
|
||||
return ret
|
||||
}
|
||||
|
||||
fn get<T>(buf []byte) T {
|
||||
$if T is string {
|
||||
return buf.bytestr() + 'get'
|
||||
} $else $if T is u64 {
|
||||
return u64(22)
|
||||
} $else {
|
||||
panic('oops!')
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user