From 1f64f4707e14636a160bc695dc0c4add154bb4e2 Mon Sep 17 00:00:00 2001 From: dimgigov Date: Fri, 5 Jun 2026 22:47:37 +0300 Subject: [PATCH] fix: algebraic enum C backend and sema field type resolution - Fix sema.nim: use objType.name instead of obj.name for algebraic enum tag/data field types (was generating _Tag instead of EnumName_Tag) - Fix c_backend.nim: emit enum definitions before struct definitions to allow structs to reference algebraic enum types --- compiler/bootstrap/c_backend.nim | 16 ++++++++++++---- compiler/bootstrap/sema.nim | 6 +++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/compiler/bootstrap/c_backend.nim b/compiler/bootstrap/c_backend.nim index 1344b99..430016c 100644 --- a/compiler/bootstrap/c_backend.nim +++ b/compiler/bootstrap/c_backend.nim @@ -616,14 +616,22 @@ proc emitModule*(be: var CBackend, module: HirModule): string = be.emitLine(&"/* const {c.name} (complex expression) */") be.emitLine("") + # Forward declarations for all structs + for s in module.structs: + be.emitLine(&"typedef struct {s.name} {s.name};") + if module.structs.len > 0: + be.emitLine("") + + # Enum definitions (must come before structs that reference them) + for e in module.enums: + be.emitEnum(e.name, e.variants) + if module.enums.len > 0: + be.emitLine("") + # Struct definitions for s in module.structs: be.emitStruct(s.name, s.fields) - # Enum definitions - for e in module.enums: - be.emitEnum(e.name, e.variants) - # Slice fat-pointer typedefs if sliceTypes.len > 0: be.emitLine("/* Slice types */") diff --git a/compiler/bootstrap/sema.nim b/compiler/bootstrap/sema.nim index 7d78f98..f608698 100644 --- a/compiler/bootstrap/sema.nim +++ b/compiler/bootstrap/sema.nim @@ -1086,11 +1086,11 @@ proc checkExpr(sema: var Sema, expr: Expr, scope: Scope): Type = elif sym.decl.kind == dkEnum: # Algebraic enum fields if expr.exprFieldName == "tag": - return makeNamed(obj.name & "_Tag") + return makeNamed(objType.name & "_Tag") elif expr.exprFieldName == "data": - return makeNamed(obj.name & "_Data") + return makeNamed(objType.name & "_Data") else: - sema.emitError(expr.loc, &"enum '{obj.name}' has no field '{expr.exprFieldName}'") + sema.emitError(expr.loc, &"enum '{objType.name}' has no field '{expr.exprFieldName}'") elif sym.decl.kind == dkUnion: # Union fields for f in sym.decl.declUnionFields: