From 49228e1acdad90495d8351f2b14dd227cb4be4d8 Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Thu, 21 Jul 2022 16:16:24 +1000 Subject: [PATCH] cgen: fix dep cycle for `struct Node { children [4]&Node }` closes #15136 --- vlib/v/gen/c/cgen.v | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 807c4aa4a4..13dc1dbbb4 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5074,9 +5074,25 @@ fn (mut g Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol { mut field_deps := []string{} match sym.info { ast.ArrayFixed { - dep := g.table.final_sym(sym.info.elem_type).name - if dep in type_names { - field_deps << dep + mut skip := false + // allow: `struct Node{ children [4]&Node }` + // skip adding the struct as a dependency to the fixed array: [4]&Node -> Node + // the struct must depend on the fixed array for definition order: Node -> [4]&Node + // NOTE: Is there is a simpler way to do this? + elem_sym := g.table.final_sym(sym.info.elem_type) + if elem_sym.info is ast.Struct && sym.info.elem_type.is_ptr() { + for field in elem_sym.info.fields { + if sym.idx == field.typ.idx() { + skip = true + break + } + } + } + if !skip { + dep := g.table.final_sym(sym.info.elem_type).name + if dep in type_names { + field_deps << dep + } } } ast.Struct {