Skip to content

Commit caa0e25

Browse files
authored
cgen: fix struct type dependency sorting, when struct field types, are aliases to struct types from other modules (#13779)
1 parent 71edaa0 commit caa0e25

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

vlib/v/gen/c/cgen.v

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4524,17 +4524,17 @@ fn (mut g Gen) write_builtin_types() {
45244524
// Sort the types, make sure types that are referenced by other types
45254525
// are added before them.
45264526
fn (mut g Gen) write_sorted_types() {
4527+
g.type_definitions.writeln('// #start sorted_symbols')
4528+
defer {
4529+
g.type_definitions.writeln('// #end sorted_symbols')
4530+
}
45274531
mut symbols := []&ast.TypeSymbol{cap: g.table.type_symbols.len} // structs that need to be sorted
45284532
for sym in g.table.type_symbols {
45294533
if sym.name !in c.builtins {
45304534
symbols << sym
45314535
}
45324536
}
4533-
// sort structs
45344537
sorted_symbols := g.sort_structs(symbols)
4535-
// Generate C code
4536-
g.type_definitions.writeln('// builtin types:')
4537-
g.type_definitions.writeln('//------------------ #endbuiltin')
45384538
g.write_types(sorted_symbols)
45394539
}
45404540

@@ -4706,7 +4706,7 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) {
47064706
}
47074707

47084708
// sort structs by dependant fields
4709-
fn (g &Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol {
4709+
fn (mut g Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol {
47104710
util.timing_start(@METHOD)
47114711
defer {
47124712
util.timing_measure(@METHOD)
@@ -4742,12 +4742,23 @@ fn (g &Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol {
47424742
field_deps << dep
47434743
}
47444744
for field in sym.info.fields {
4745-
dep := g.table.sym(field.typ).name
4745+
if field.typ.is_ptr() {
4746+
continue
4747+
}
4748+
fsym := g.table.sym(field.typ)
4749+
dep := fsym.name
47464750
// skip if not in types list or already in deps
4747-
if dep !in type_names || dep in field_deps || field.typ.is_ptr() {
4751+
if dep !in type_names || dep in field_deps {
47484752
continue
47494753
}
47504754
field_deps << dep
4755+
if fsym.info is ast.Alias {
4756+
xdep := g.table.sym(fsym.info.parent_type).name
4757+
if xdep !in type_names || xdep in field_deps {
4758+
continue
4759+
}
4760+
field_deps << xdep
4761+
}
47514762
}
47524763
}
47534764
// ast.Interface {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module alias_to_another_module
2+
3+
import another_module
4+
5+
pub type MyAlias = another_module.SomeStruct
6+
7+
pub fn (m MyAlias) alias_method() int {
8+
return 42
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module another_module
2+
3+
pub struct SomeStruct {
4+
pub mut:
5+
x int
6+
y int
7+
z int
8+
}
9+
10+
pub fn (s SomeStruct) some_method() int {
11+
return 999 + s.x + s.y + s.z
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import alias_to_another_module
2+
3+
struct MyStruct {
4+
myfield alias_to_another_module.MyAlias
5+
}
6+
7+
fn test_using_struct_with_alias() {
8+
m := MyStruct{
9+
myfield: alias_to_another_module.MyAlias{1, 2, 3}
10+
}
11+
dump(m)
12+
assert m.myfield.alias_method() == 42
13+
assert m.myfield.some_method() == 1005
14+
}

0 commit comments

Comments
 (0)