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

ast: fix generics with nested generic type parameter (fix #13077) (#13088)

This commit is contained in:
yuyi 2022-01-09 01:19:45 +08:00 committed by GitHub
parent 64028eedb8
commit 64c8fb061d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 0 deletions

View File

@ -1540,6 +1540,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concrete_types []Type) Type { pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concrete_types []Type) Type {
mut final_concrete_types := []Type{} mut final_concrete_types := []Type{}
mut fields := []StructField{} mut fields := []StructField{}
mut needs_unwrap_types := []Type{}
mut nrt := '' mut nrt := ''
mut c_nrt := '' mut c_nrt := ''
ts := t.sym(typ) ts := t.sym(typ)
@ -1627,6 +1628,20 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
} }
if final_concrete_types.len > 0 { if final_concrete_types.len > 0 {
for method in ts.methods { for method in ts.methods {
for i in 1 .. method.params.len {
if method.params[i].typ.has_flag(.generic)
&& method.params[i].typ != method.params[0].typ {
if method.params[i].typ !in needs_unwrap_types {
needs_unwrap_types << method.params[i].typ
}
}
if method.return_type.has_flag(.generic)
&& method.return_type != method.params[0].typ {
if method.return_type !in needs_unwrap_types {
needs_unwrap_types << method.return_type
}
}
}
t.register_fn_concrete_types(method.fkey(), final_concrete_types) t.register_fn_concrete_types(method.fkey(), final_concrete_types)
} }
} }
@ -1648,6 +1663,9 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
mod: ts.mod mod: ts.mod
info: info info: info
) )
for typ_ in needs_unwrap_types {
t.unwrap_generic_type(typ_, generic_names, concrete_types)
}
return new_type(new_idx).derive(typ).clear_flag(.generic) return new_type(new_idx).derive(typ).clear_flag(.generic)
} }
Interface { Interface {

View File

@ -0,0 +1,20 @@
module main
pub struct Randomizer<T> {
}
pub struct Element<T> {
}
fn test_generics_with_nested_generic_type_parameter() {
a := new_randomizer<int>()
println(a)
assert '$a' == '&Randomizer<int>{}'
}
pub fn new_randomizer<T>() &Randomizer<T> {
return &Randomizer<T>{}
}
pub fn (mut r Randomizer<T>) add_multiple(elements []Element<T>) {
}