cgen: fix struct type dependency sorting, when struct field types, are aliases to struct types from other modules (#13779)
parent
71edaa071a
commit
caa0e25939
|
@ -4524,17 +4524,17 @@ fn (mut g Gen) write_builtin_types() {
|
|||
// Sort the types, make sure types that are referenced by other types
|
||||
// are added before them.
|
||||
fn (mut g Gen) write_sorted_types() {
|
||||
g.type_definitions.writeln('// #start sorted_symbols')
|
||||
defer {
|
||||
g.type_definitions.writeln('// #end sorted_symbols')
|
||||
}
|
||||
mut symbols := []&ast.TypeSymbol{cap: g.table.type_symbols.len} // structs that need to be sorted
|
||||
for sym in g.table.type_symbols {
|
||||
if sym.name !in c.builtins {
|
||||
symbols << sym
|
||||
}
|
||||
}
|
||||
// sort structs
|
||||
sorted_symbols := g.sort_structs(symbols)
|
||||
// Generate C code
|
||||
g.type_definitions.writeln('// builtin types:')
|
||||
g.type_definitions.writeln('//------------------ #endbuiltin')
|
||||
g.write_types(sorted_symbols)
|
||||
}
|
||||
|
||||
|
@ -4706,7 +4706,7 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) {
|
|||
}
|
||||
|
||||
// sort structs by dependant fields
|
||||
fn (g &Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol {
|
||||
fn (mut g Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol {
|
||||
util.timing_start(@METHOD)
|
||||
defer {
|
||||
util.timing_measure(@METHOD)
|
||||
|
@ -4742,12 +4742,23 @@ fn (g &Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol {
|
|||
field_deps << dep
|
||||
}
|
||||
for field in sym.info.fields {
|
||||
dep := g.table.sym(field.typ).name
|
||||
if field.typ.is_ptr() {
|
||||
continue
|
||||
}
|
||||
fsym := g.table.sym(field.typ)
|
||||
dep := fsym.name
|
||||
// skip if not in types list or already in deps
|
||||
if dep !in type_names || dep in field_deps || field.typ.is_ptr() {
|
||||
if dep !in type_names || dep in field_deps {
|
||||
continue
|
||||
}
|
||||
field_deps << dep
|
||||
if fsym.info is ast.Alias {
|
||||
xdep := g.table.sym(fsym.info.parent_type).name
|
||||
if xdep !in type_names || xdep in field_deps {
|
||||
continue
|
||||
}
|
||||
field_deps << xdep
|
||||
}
|
||||
}
|
||||
}
|
||||
// ast.Interface {}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
module alias_to_another_module
|
||||
|
||||
import another_module
|
||||
|
||||
pub type MyAlias = another_module.SomeStruct
|
||||
|
||||
pub fn (m MyAlias) alias_method() int {
|
||||
return 42
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
module another_module
|
||||
|
||||
pub struct SomeStruct {
|
||||
pub mut:
|
||||
x int
|
||||
y int
|
||||
z int
|
||||
}
|
||||
|
||||
pub fn (s SomeStruct) some_method() int {
|
||||
return 999 + s.x + s.y + s.z
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import alias_to_another_module
|
||||
|
||||
struct MyStruct {
|
||||
myfield alias_to_another_module.MyAlias
|
||||
}
|
||||
|
||||
fn test_using_struct_with_alias() {
|
||||
m := MyStruct{
|
||||
myfield: alias_to_another_module.MyAlias{1, 2, 3}
|
||||
}
|
||||
dump(m)
|
||||
assert m.myfield.alias_method() == 42
|
||||
assert m.myfield.some_method() == 1005
|
||||
}
|
Loading…
Reference in New Issue