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 {
|
if typ == 0 {
|
||||||
return none
|
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 {
|
match mut sym.info {
|
||||||
Array {
|
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) {
|
if typ := t.resolve_generic_to_concrete(elem_type, generic_names, concrete_types) {
|
||||||
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_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 {
|
ArrayFixed {
|
||||||
@ -1451,7 +1459,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
|||||||
concrete_types)
|
concrete_types)
|
||||||
{
|
{
|
||||||
idx := t.find_or_register_array_fixed(typ, sym.info.size, None{})
|
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 {
|
Chan {
|
||||||
@ -1459,16 +1471,24 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
|||||||
concrete_types)
|
concrete_types)
|
||||||
{
|
{
|
||||||
idx := t.find_or_register_chan(typ, typ.nr_muls() > 0)
|
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 {
|
FnType {
|
||||||
mut func := sym.info.func
|
mut func := sym.info.func
|
||||||
|
mut has_generic := false
|
||||||
if func.return_type.has_flag(.generic) {
|
if func.return_type.has_flag(.generic) {
|
||||||
if typ := t.resolve_generic_to_concrete(func.return_type, generic_names,
|
if typ := t.resolve_generic_to_concrete(func.return_type, generic_names,
|
||||||
concrete_types)
|
concrete_types)
|
||||||
{
|
{
|
||||||
func.return_type = typ
|
func.return_type = typ
|
||||||
|
if typ.has_flag(.generic) {
|
||||||
|
has_generic = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func.params = func.params.clone()
|
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)
|
concrete_types)
|
||||||
{
|
{
|
||||||
param.typ = typ
|
param.typ = typ
|
||||||
|
if typ.has_flag(.generic) {
|
||||||
|
has_generic = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func.name = ''
|
func.name = ''
|
||||||
idx := t.find_or_register_fn_type('', func, true, false)
|
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 {
|
MultiReturn {
|
||||||
mut types := []Type{}
|
mut types := []Type{}
|
||||||
@ -1498,7 +1525,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
|||||||
}
|
}
|
||||||
if type_changed {
|
if type_changed {
|
||||||
idx := t.find_or_register_multi_return(types)
|
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 {
|
Map {
|
||||||
@ -1519,7 +1550,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
|||||||
}
|
}
|
||||||
if type_changed {
|
if type_changed {
|
||||||
idx := t.find_or_register_map(unwrapped_key_type, unwrapped_value_type)
|
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 {
|
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 func.generic_names.len > 0 {
|
||||||
if has_generic {
|
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
|
return node.return_type
|
||||||
} else if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names,
|
} else if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names,
|
||||||
concrete_types)
|
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