From 7935c4aa5adad20ced26ed67860179f88189987e Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 2 Oct 2018 19:35:24 +0200 Subject: [PATCH] C++ codegen: emit correctly typed code for closures in 'const'; refs #7870 --- compiler/ccgexprs.nim | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 1789ce4f16..cf5eac56cc 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2571,15 +2571,21 @@ proc genConstExpr(p: BProc, n: PNode): Rope = var t = skipTypes(n.typ, abstractInst) if t.kind == tySequence: result = genConstSeq(p, n, n.typ) - elif t.kind == tyProc and t.callConv == ccClosure and n.len > 0 and - n.sons[0].kind == nkNilLit and n.sons[1].kind == nkNilLit: + elif t.kind == tyProc and t.callConv == ccClosure and n.len > 1 and + n.sons[1].kind == nkNilLit: + # Conversion: nimcall -> closure. # this hack fixes issue that nkNilLit is expanded to {NIM_NIL,NIM_NIL} # this behaviour is needed since closure_var = nil must be # expanded to {NIM_NIL,NIM_NIL} # in VM closures are initialized with nkPar(nkNilLit, nkNilLit) # leading to duplicate code like this: # "{NIM_NIL,NIM_NIL}, {NIM_NIL,NIM_NIL}" - result = ~"{NIM_NIL,NIM_NIL}" + if n[0].kind == nkNilLit: + result = ~"{NIM_NIL,NIM_NIL}" + else: + var d: TLoc + initLocExpr(p, n[0], d) + result = "{(($1) $2),NIM_NIL}" % [getClosureType(p.module, t, clHalfWithEnv), rdLoc(d)] else: result = genConstSimpleList(p, n) of nkObjConstr: