mirror of
https://github.com/vlang/v.git
synced 2025-09-14 09:56:16 -04:00
ast: fix generic structs with multiple levels of generic embedding (#20042)
This commit is contained in:
parent
0c4abf0c19
commit
c19b13e165
@ -1936,6 +1936,7 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
|
|||||||
fields = ts.info.fields.clone()
|
fields = ts.info.fields.clone()
|
||||||
for i in 0 .. fields.len {
|
for i in 0 .. fields.len {
|
||||||
if fields[i].typ.has_flag(.generic) {
|
if fields[i].typ.has_flag(.generic) {
|
||||||
|
orig_type := fields[i].typ
|
||||||
sym := t.sym(fields[i].typ)
|
sym := t.sym(fields[i].typ)
|
||||||
if sym.kind == .struct_ && fields[i].typ.idx() != typ.idx() {
|
if sym.kind == .struct_ && fields[i].typ.idx() != typ.idx() {
|
||||||
fields[i].typ = t.unwrap_generic_type(fields[i].typ, t_generic_names,
|
fields[i].typ = t.unwrap_generic_type(fields[i].typ, t_generic_names,
|
||||||
@ -1947,6 +1948,19 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
|
|||||||
fields[i].typ = t_typ
|
fields[i].typ = t_typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Update type in `info.embeds`, if it's embed
|
||||||
|
if fields[i].name.len > 1 && fields[i].name[0].is_capital() {
|
||||||
|
mut parent_sym := t.sym(typ)
|
||||||
|
mut parent_info := parent_sym.info
|
||||||
|
if mut parent_info is Struct {
|
||||||
|
for mut embed in parent_info.embeds {
|
||||||
|
if embed == orig_type {
|
||||||
|
embed = fields[i].typ.set_flag(.generic)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// update concrete types
|
// update concrete types
|
||||||
|
@ -2,11 +2,28 @@ struct Foo[T] {
|
|||||||
field T
|
field T
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MainStruct[T] {
|
struct Bar[T] {
|
||||||
|
Foo[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Baz[T] {
|
||||||
|
Bar[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OneLevelEmbed[T] {
|
||||||
Foo[T]
|
Foo[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_main() {
|
fn test_main() {
|
||||||
m := MainStruct[int]{}
|
m := OneLevelEmbed[int]{}
|
||||||
|
assert m.field == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MultiLevelEmbed[T] {
|
||||||
|
Baz[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_multi_level() {
|
||||||
|
m := MultiLevelEmbed[int]{}
|
||||||
assert m.field == 0
|
assert m.field == 0
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user