From 3d7c57db8812e6cf7bf1e48d074d3c1a986ede4e Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 4 Jan 2016 03:10:09 +0100 Subject: [PATCH] fixes #2659 --- compiler/ccgcalls.nim | 4 ++-- compiler/lambdalifting.nim | 2 +- compiler/transf.nim | 3 +++ tests/ccgbugs/tgeneric_closure.nim | 28 ++++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 tests/ccgbugs/tgeneric_closure.nim diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 86ecc9db88..69cc304133 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -515,7 +515,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = line(p, cpsStmts, pl) proc genCall(p: BProc, e: PNode, d: var TLoc) = - if e.sons[0].typ.callConv == ccClosure: + if e.sons[0].typ.skipTypes({tyGenericInst}).callConv == ccClosure: genClosureCall(p, nil, e, d) elif e.sons[0].kind == nkSym and sfInfixCall in e.sons[0].sym.flags: genInfixCall(p, nil, e, d) @@ -528,7 +528,7 @@ proc genCall(p: BProc, e: PNode, d: var TLoc) = if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d) proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) = - if ri.sons[0].typ.callConv == ccClosure: + if ri.sons[0].typ.skipTypes({tyGenericInst}).callConv == ccClosure: genClosureCall(p, le, ri, d) elif ri.sons[0].kind == nkSym and sfInfixCall in ri.sons[0].sym.flags: genInfixCall(p, le, ri, d) diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 95a4432e33..ed022eeec7 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -207,7 +207,7 @@ proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode = result.sons[0] = le result.sons[1] = ri -proc makeClosure(prc: PSym; env: PNode; info: TLineInfo): PNode = +proc makeClosure*(prc: PSym; env: PNode; info: TLineInfo): PNode = result = newNodeIT(nkClosure, info, prc.typ) result.add(newSymNode(prc)) if env == nil: diff --git a/compiler/transf.nim b/compiler/transf.nim index 83311d95c2..1aba33c74c 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -114,6 +114,9 @@ proc transformSymAux(c: PTransf, n: PNode): PNode = if n.sym.kind == skIterator and n.sym.typ.callConv == ccClosure: if c.tooEarly: return n else: return liftIterSym(n, getCurrOwner(c)) + #elif n.sym.kind in {skVar, skLet} and n.sym.typ.callConv == ccClosure: + # echo n.info, " come heer for ", c.tooEarly + # if not c.tooEarly: return makeClosure(n.sym, nil, n.info) var b: PNode var tc = c.transCon if sfBorrow in n.sym.flags and n.sym.kind in routineKinds: diff --git a/tests/ccgbugs/tgeneric_closure.nim b/tests/ccgbugs/tgeneric_closure.nim new file mode 100644 index 0000000000..f9d5e7910c --- /dev/null +++ b/tests/ccgbugs/tgeneric_closure.nim @@ -0,0 +1,28 @@ + + +# bug 2659 + +type + GenProcType[T,U] = proc(x:T, y:var U) + IntProcType = proc(x:int, y:var int) + +proc mult(x:int, y:var int) = + y = 2 * x + +when isMainModule: + + var input = 1 + var output = 0 + + var someIntProc:IntProcType = mult + var someGenProc:GenProcType[int,int] = mult + + mult(input, output) + echo output + + someIntProc(input, output) + echo output + + # Uncommenting causes an error in the C compiler. + someGenProc(input, output) + echo output