diff --git a/compiler/ast2nif.nim b/compiler/ast2nif.nim index a8098f82745c5..67a265c28f41c 100644 --- a/compiler/ast2nif.nim +++ b/compiler/ast2nif.nim @@ -700,7 +700,10 @@ proc writeOp(w: var Writer; content: var TokenBuf; op: LogEntry) = of MethodEntry: discard "to implement" of EnumToStrEntry: - discard "to implement" + content.addParLe repEnumToStrTag, NoLineInfo + content.add strToken(pool.strings.getOrIncl(op.key), NoLineInfo) + content.add symToken(pool.syms.getOrIncl(w.toNifSymName(op.sym)), NoLineInfo) + content.addParRi() of GenericInstEntry: discard "will only be written later to ensure it is materialized" diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index 55f751cda74d1..a50d40b5e6c90 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -66,6 +66,7 @@ type memberProcsPerType*: Table[ItemId, seq[PSym]] # Type ID, attached member procs (only c++, virtual,member and ctor so far). initializersPerType*: Table[ItemId, PNode] # Type ID, AST call to the default ctor (c++ only) enumToStringProcs*: Table[ItemId, PSym] + loadedEnumToStringProcs: Table[string, PSym] emittedTypeInfo*: Table[string, FileIndex] packageSyms*: TStrTable @@ -147,6 +148,7 @@ proc resetForBackend*(g: ModuleGraph) = a.clear() g.methodsPerGenericType.clear() g.enumToStringProcs.clear() + g.loadedEnumToStringProcs.clear() g.dispatchers.setLen(0) g.methodsPerType.clear() for a in mitems(g.loadedOps): @@ -332,7 +334,10 @@ iterator getMethodsPerType*(g: ModuleGraph; t: PType): PSym = yield it proc getToStringProc*(g: ModuleGraph; t: PType): PSym = - result = g.enumToStringProcs[t.itemId] + result = g.enumToStringProcs.getOrDefault(t.itemId) + if result == nil and g.config.cmd in {cmdNifC, cmdM}: + let key = typeKey(t, g.config, loadTypeCallback, loadSymCallback) + result = g.loadedEnumToStringProcs.getOrDefault(key) assert result != nil proc setToStringProc*(g: ModuleGraph; t: PType; value: PSym) = @@ -692,7 +697,7 @@ when not defined(nimKochBootstrap): of MethodEntry: discard "todo" of EnumToStrEntry: - discard "todo" + g.loadedEnumToStringProcs[x.key] = x.sym of GenericInstEntry: raiseAssert "GenericInstEntry should not be in the NIF index" # Register methods per type from NIF index diff --git a/tests/ic/tenum.nim b/tests/ic/tenum.nim new file mode 100644 index 0000000000000..30fd3cbd1fafa --- /dev/null +++ b/tests/ic/tenum.nim @@ -0,0 +1,22 @@ +discard """ + disabled: "linux" + output: "42" +""" + +# Object variant / case object +type + NodeKind = enum + nkInt, nkStr, nkAdd + + Node = object + case kind: NodeKind + of nkInt: intVal: int + of nkStr: strVal: string + of nkAdd: left, right: ref Node + +proc newInt(v: int): ref Node = + new(result) + result[] = Node(kind: nkInt, intVal: v) + +let n = newInt(42) +echo n.intVal