Compiler version
kairo-0.1.1+dev.20260618
Compiler stage
Stage 1 (self-hosted)
Host platform
Linux (x86_64)
Minimal reproduction
class Point {
var x: i32
var y: i32
fn dist() -> f64 { 0.0 }
}
Command line
kairo Tests/Bugs/bug07_dc_decls.k --print-ast=tree
Actual behavior
The AST prints correctly via the hybrid walk in the printer:
TranslationUnit '/mnt/linux-dev/projects/kairo-lang/Tests/Bugs/bug07_dc_decls.k'(fid=0)
`-ClassDecl Point
|-FieldDecl var x: i32
|-FieldDecl var y: i32
`-FunctionDecl dist() -> f64
`-CompoundStmt (1)
`-ExpressionStmt
`-FloatingLiteralExpr 0.0
-- 0 error(s), 0 warning(s) --
However, `DeclContext.dc_decls` does not contain these members. For a type body (class/struct/union/interface/extension), `dc_decls` contains only nested type decls and `VisibilityGroupDecl` wrappers. Fields and methods are stored in the separate `fields` and `methods` projection lists and are absent from `dc_decls`. For enums, `dc_decls` is entirely empty — `_parse_enum` never calls `add_decl`. Only modules and the TU populate `dc_decls` completely.
The `DeclContext.k` doc comment claims `dc_decls` is "the COMPLETE source-ordered member list." That is false for every type body.
Expected behavior
Either:
(a) The doc comment is corrected to say dc_decls contains only nested type decls and visibility-group wrappers for type bodies, with flat members in fields/methods and enum members in variants; or
(b) The parser is fixed to push every member (fields, methods, variants, nested types) into dc_decls in source order, making the comment true and collapsing every AST consumer to a single dc_decls walk with no hybrid merge or source-sort.
Option (b) is the correct long-term fix. It eliminates the per-consumer hybrid walk, removes the SourceLocation-sort assumption, and avoids burning every future sema/codegen/LSP pass on the same trap.
Additional context
Root cause: _parse_member_body / _parse_member_vis_group in DeclParse.k push flat members to fields_out/methods_out buffers and only push nested types + the group wrapper via owner->add_decl. _parse_enum never calls add_decl. The AST printer already works around this with a hybrid walk (fields + methods + nested-types-from-dc_decls, skipping VisibilityGroupDecl, sorted by SourceLocation). Sema will hit this trap next and pay the same cost.
Compiler version
kairo-0.1.1+dev.20260618
Compiler stage
Stage 1 (self-hosted)
Host platform
Linux (x86_64)
Minimal reproduction
Command line
Actual behavior
Expected behavior
Either:
(a) The doc comment is corrected to say
dc_declscontains only nested type decls and visibility-group wrappers for type bodies, with flat members infields/methodsand enum members invariants; or(b) The parser is fixed to push every member (fields, methods, variants, nested types) into
dc_declsin source order, making the comment true and collapsing every AST consumer to a singledc_declswalk with no hybrid merge or source-sort.Option (b) is the correct long-term fix. It eliminates the per-consumer hybrid walk, removes the
SourceLocation-sort assumption, and avoids burning every future sema/codegen/LSP pass on the same trap.Additional context
Root cause:
_parse_member_body/_parse_member_vis_groupinDeclParse.kpush flat members tofields_out/methods_outbuffers and only push nested types + the group wrapper viaowner->add_decl._parse_enumnever callsadd_decl. The AST printer already works around this with a hybrid walk (fields + methods + nested-types-from-dc_decls, skippingVisibilityGroupDecl, sorted bySourceLocation). Sema will hit this trap next and pay the same cost.