From 5afcd09cb3d75d4f01427082563966e3f435c9a2 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 23 Aug 2018 15:17:38 +0200 Subject: [PATCH] Pervasive replacement of nkRecWhen in generic types Long story short, even if the type contains no reference at all to its generic parameters we still have to walk its AST and evaluate any nkRecWhen nodes that semRecordNodeAux skipped due to the type being a generic one. We also must be careful to modify the type `n` node in place since it may be referenced by the caller as seen in the tillegaltyperecursion test. Moreover we also can't have the nkSym drift away from their original values in order not to break the JS nkObjConstr codegen. --- compiler/semtypinst.nim | 40 +++++++++++++++++++++++++++++++ tests/objects/twhen1.nim | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 tests/objects/twhen1.nim diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index c315cbebb6..1a9fa5589b 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -166,6 +166,36 @@ proc reResolveCallsWithTypedescParams(cl: var TReplTypeVars, n: PNode): PNode = return n +proc replaceObjBranches(cl: TReplTypeVars, n: PNode): PNode = + result = n + case n.kind + of nkNone..nkNilLit: + discard + of nkRecWhen: + var branch: PNode = nil # the branch to take + for i in countup(0, sonsLen(n) - 1): + var it = n.sons[i] + if it == nil: illFormedAst(n, cl.c.config) + case it.kind + of nkElifBranch: + checkSonsLen(it, 2, cl.c.config) + var cond = it.sons[0] + var e = cl.c.semConstExpr(cl.c, cond) + if e.kind != nkIntLit: + internalError(cl.c.config, e.info, "ReplaceTypeVarsN: when condition not a bool") + if e.intVal != 0 and branch == nil: branch = it.sons[1] + of nkElse: + checkSonsLen(it, 1, cl.c.config) + if branch == nil: branch = it.sons[0] + else: illFormedAst(n, cl.c.config) + if branch != nil: + result = replaceObjBranches(cl, branch) + else: + result = newNodeI(nkRecList, n.info) + else: + for i in 0..