* Fixes 5034 * address comments
This commit is contained in:
parent
369a7d1246
commit
06d50bfd4c
2 changed files with 52 additions and 4 deletions
|
|
@ -1439,16 +1439,33 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) =
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errNoSymbolToBorrowFromFound)
|
localError(c.config, n.info, errNoSymbolToBorrowFromFound)
|
||||||
|
|
||||||
|
proc swapResult(n: PNode, sRes: PSym, dNode: PNode) =
|
||||||
|
## Swap nodes that are (skResult) symbols to d(estination)Node.
|
||||||
|
for i in 0..<n.safeLen:
|
||||||
|
if n[i].kind == nkSym and n[i].sym == sRes:
|
||||||
|
n[i] = dNode
|
||||||
|
swapResult(n[i], sRes, dNode)
|
||||||
|
|
||||||
proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) =
|
proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) =
|
||||||
|
template genResSym(s) =
|
||||||
|
var s = newSym(skResult, getIdent(c.cache, "result"), nextSymId c.idgen,
|
||||||
|
getCurrOwner(c), n.info)
|
||||||
|
s.typ = t
|
||||||
|
incl(s.flags, sfUsed)
|
||||||
|
|
||||||
if owner == skMacro or t != nil:
|
if owner == skMacro or t != nil:
|
||||||
if n.len > resultPos and n[resultPos] != nil:
|
if n.len > resultPos and n[resultPos] != nil:
|
||||||
if n[resultPos].sym.kind != skResult or n[resultPos].sym.owner != getCurrOwner(c):
|
if n[resultPos].sym.kind != skResult:
|
||||||
localError(c.config, n.info, "incorrect result proc symbol")
|
localError(c.config, n.info, "incorrect result proc symbol")
|
||||||
|
if n[resultPos].sym.owner != getCurrOwner(c):
|
||||||
|
# re-write result with new ownership, and re-write the proc accordingly
|
||||||
|
let sResSym = n[resultPos].sym
|
||||||
|
genResSym(s)
|
||||||
|
n[resultPos] = newSymNode(s)
|
||||||
|
swapResult(n, sResSym, n[resultPos])
|
||||||
c.p.resultSym = n[resultPos].sym
|
c.p.resultSym = n[resultPos].sym
|
||||||
else:
|
else:
|
||||||
var s = newSym(skResult, getIdent(c.cache, "result"), nextSymId c.idgen, getCurrOwner(c), n.info)
|
genResSym(s)
|
||||||
s.typ = t
|
|
||||||
incl(s.flags, sfUsed)
|
|
||||||
c.p.resultSym = s
|
c.p.resultSym = s
|
||||||
n.add newSymNode(c.p.resultSym)
|
n.add newSymNode(c.p.resultSym)
|
||||||
addParamOrResult(c, c.p.resultSym, owner)
|
addParamOrResult(c, c.p.resultSym, owner)
|
||||||
|
|
|
||||||
31
tests/macros/tmacrogetimpl.nim
Normal file
31
tests/macros/tmacrogetimpl.nim
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import macros
|
||||||
|
|
||||||
|
# bug #5034
|
||||||
|
|
||||||
|
macro copyImpl(srsProc: typed, toSym: untyped) =
|
||||||
|
result = copyNimTree(getImplTransformed(srsProc))
|
||||||
|
result[0] = ident $toSym.toStrLit()
|
||||||
|
|
||||||
|
proc foo1(x: float, one: bool = true): float =
|
||||||
|
if one:
|
||||||
|
return 1'f
|
||||||
|
result = x
|
||||||
|
|
||||||
|
proc bar1(what: string): string =
|
||||||
|
## be a little more adversarial with `skResult`
|
||||||
|
proc buzz: string =
|
||||||
|
result = "lightyear"
|
||||||
|
if what == "buzz":
|
||||||
|
result = "buzz " & buzz()
|
||||||
|
else:
|
||||||
|
result = what
|
||||||
|
return result
|
||||||
|
|
||||||
|
copyImpl(foo1, foo2)
|
||||||
|
doAssert foo1(1'f) == 1.0
|
||||||
|
doAssert foo2(10.0, false) == 10.0
|
||||||
|
doAssert foo2(10.0) == 1.0
|
||||||
|
|
||||||
|
copyImpl(bar1, bar2)
|
||||||
|
doAssert bar1("buzz") == "buzz lightyear"
|
||||||
|
doAssert bar1("macros") == "macros"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue