Skip to content

Commit 64c8fb0

Browse files
authored
ast: fix generics with nested generic type parameter (fix #13077) (#13088)
1 parent 64028ee commit 64c8fb0

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

vlib/v/ast/table.v

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
15401540
pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concrete_types []Type) Type {
15411541
mut final_concrete_types := []Type{}
15421542
mut fields := []StructField{}
1543+
mut needs_unwrap_types := []Type{}
15431544
mut nrt := ''
15441545
mut c_nrt := ''
15451546
ts := t.sym(typ)
@@ -1627,6 +1628,20 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
16271628
}
16281629
if final_concrete_types.len > 0 {
16291630
for method in ts.methods {
1631+
for i in 1 .. method.params.len {
1632+
if method.params[i].typ.has_flag(.generic)
1633+
&& method.params[i].typ != method.params[0].typ {
1634+
if method.params[i].typ !in needs_unwrap_types {
1635+
needs_unwrap_types << method.params[i].typ
1636+
}
1637+
}
1638+
if method.return_type.has_flag(.generic)
1639+
&& method.return_type != method.params[0].typ {
1640+
if method.return_type !in needs_unwrap_types {
1641+
needs_unwrap_types << method.return_type
1642+
}
1643+
}
1644+
}
16301645
t.register_fn_concrete_types(method.fkey(), final_concrete_types)
16311646
}
16321647
}
@@ -1648,6 +1663,9 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
16481663
mod: ts.mod
16491664
info: info
16501665
)
1666+
for typ_ in needs_unwrap_types {
1667+
t.unwrap_generic_type(typ_, generic_names, concrete_types)
1668+
}
16511669
return new_type(new_idx).derive(typ).clear_flag(.generic)
16521670
}
16531671
Interface {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module main
2+
3+
pub struct Randomizer<T> {
4+
}
5+
6+
pub struct Element<T> {
7+
}
8+
9+
fn test_generics_with_nested_generic_type_parameter() {
10+
a := new_randomizer<int>()
11+
println(a)
12+
assert '$a' == '&Randomizer<int>{}'
13+
}
14+
15+
pub fn new_randomizer<T>() &Randomizer<T> {
16+
return &Randomizer<T>{}
17+
}
18+
19+
pub fn (mut r Randomizer<T>) add_multiple(elements []Element<T>) {
20+
}

0 commit comments

Comments
 (0)