mirror of
https://github.com/vlang/v.git
synced 2025-09-14 01:47:30 -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()
|
||||
for i in 0 .. fields.len {
|
||||
if fields[i].typ.has_flag(.generic) {
|
||||
orig_type := fields[i].typ
|
||||
sym := t.sym(fields[i].typ)
|
||||
if sym.kind == .struct_ && fields[i].typ.idx() != typ.idx() {
|
||||
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
|
||||
}
|
||||
}
|
||||
// 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
|
||||
|
@ -2,11 +2,28 @@ struct Foo[T] {
|
||||
field T
|
||||
}
|
||||
|
||||
struct MainStruct[T] {
|
||||
struct Bar[T] {
|
||||
Foo[T]
|
||||
}
|
||||
|
||||
struct Baz[T] {
|
||||
Bar[T]
|
||||
}
|
||||
|
||||
struct OneLevelEmbed[T] {
|
||||
Foo[T]
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user