fixes #2215
This commit is contained in:
parent
335c19c869
commit
f2cdbc92eb
3 changed files with 41 additions and 11 deletions
|
|
@ -80,13 +80,9 @@ proc freshGenSyms(n: PNode, owner: PSym, symMap: var TIdTable) =
|
||||||
let s = n.sym
|
let s = n.sym
|
||||||
var x = PSym(idTableGet(symMap, s))
|
var x = PSym(idTableGet(symMap, s))
|
||||||
if x == nil:
|
if x == nil:
|
||||||
if s.kind == skParam:
|
x = copySym(s, false)
|
||||||
x = owner.typ.n[s.position+1].sym
|
x.owner = owner
|
||||||
internalAssert x.kind == skParam
|
idTablePut(symMap, s, x)
|
||||||
else:
|
|
||||||
x = copySym(s, false)
|
|
||||||
x.owner = owner
|
|
||||||
idTablePut(symMap, s, x)
|
|
||||||
n.sym = x
|
n.sym = x
|
||||||
else:
|
else:
|
||||||
for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, symMap)
|
for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, symMap)
|
||||||
|
|
@ -104,13 +100,18 @@ proc addProcDecls(c: PContext, fn: PSym) =
|
||||||
|
|
||||||
maybeAddResult(c, fn, fn.ast)
|
maybeAddResult(c, fn, fn.ast)
|
||||||
|
|
||||||
proc instantiateBody(c: PContext, n: PNode, result: PSym) =
|
proc instantiateBody(c: PContext, n, params: PNode, result: PSym) =
|
||||||
if n.sons[bodyPos].kind != nkEmpty:
|
if n.sons[bodyPos].kind != nkEmpty:
|
||||||
inc c.inGenericInst
|
inc c.inGenericInst
|
||||||
# add it here, so that recursive generic procs are possible:
|
# add it here, so that recursive generic procs are possible:
|
||||||
var b = n.sons[bodyPos]
|
var b = n.sons[bodyPos]
|
||||||
var symMap: TIdTable
|
var symMap: TIdTable
|
||||||
initIdTable symMap
|
initIdTable symMap
|
||||||
|
if params != nil:
|
||||||
|
for i in 1 .. <params.len:
|
||||||
|
let param = params[i].sym
|
||||||
|
if sfGenSym in param.flags:
|
||||||
|
idTablePut(symMap, params[i].sym, result.typ.n[param.position+1].sym)
|
||||||
freshGenSyms(b, result, symMap)
|
freshGenSyms(b, result, symMap)
|
||||||
b = semProcBody(c, b)
|
b = semProcBody(c, b)
|
||||||
b = hloBody(c, b)
|
b = hloBody(c, b)
|
||||||
|
|
@ -127,7 +128,7 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
|
||||||
openScope(c)
|
openScope(c)
|
||||||
var n = oldPrc.ast
|
var n = oldPrc.ast
|
||||||
n.sons[bodyPos] = copyTree(s.getBody)
|
n.sons[bodyPos] = copyTree(s.getBody)
|
||||||
instantiateBody(c, n, oldPrc)
|
instantiateBody(c, n, nil, oldPrc)
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
popInfoContext()
|
popInfoContext()
|
||||||
|
|
||||||
|
|
@ -249,7 +250,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
pragma(c, result, n.sons[pragmasPos], allRoutinePragmas)
|
pragma(c, result, n.sons[pragmasPos], allRoutinePragmas)
|
||||||
if isNil(n.sons[bodyPos]):
|
if isNil(n.sons[bodyPos]):
|
||||||
n.sons[bodyPos] = copyTree(fn.getBody)
|
n.sons[bodyPos] = copyTree(fn.getBody)
|
||||||
instantiateBody(c, n, result)
|
instantiateBody(c, n, fn.typ.n, result)
|
||||||
sideEffectsCheck(c, result)
|
sideEffectsCheck(c, result)
|
||||||
paramsTypeCheck(c, result.typ)
|
paramsTypeCheck(c, result.typ)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -494,7 +494,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
|
||||||
semParamList(c, n.sons[paramsPos], gp, s)
|
semParamList(c, n.sons[paramsPos], gp, s)
|
||||||
# a template's parameters are not gensym'ed even if that was originally the
|
# a template's parameters are not gensym'ed even if that was originally the
|
||||||
# case as we determine whether it's a template parameter in the template
|
# case as we determine whether it's a template parameter in the template
|
||||||
# body by the absence of the skGenSym flag:
|
# body by the absence of the sfGenSym flag:
|
||||||
for i in 1 .. s.typ.n.len-1:
|
for i in 1 .. s.typ.n.len-1:
|
||||||
s.typ.n.sons[i].sym.flags.excl sfGenSym
|
s.typ.n.sons[i].sym.flags.excl sfGenSym
|
||||||
if sonsLen(gp) > 0:
|
if sonsLen(gp) > 0:
|
||||||
|
|
|
||||||
|
|
@ -31,3 +31,32 @@ var x: Something
|
||||||
testB(x)
|
testB(x)
|
||||||
|
|
||||||
|
|
||||||
|
# bug #2215
|
||||||
|
# Test that templates in generics still work (regression to fix the
|
||||||
|
# regression...)
|
||||||
|
|
||||||
|
template forStatic(index: expr, slice: Slice[int], predicate: stmt):
|
||||||
|
stmt {.immediate.} =
|
||||||
|
const a = slice.a
|
||||||
|
const b = slice.b
|
||||||
|
when a <= b:
|
||||||
|
template iteration(i: int) =
|
||||||
|
block:
|
||||||
|
const index = i
|
||||||
|
predicate
|
||||||
|
template iterateStartingFrom(i: int): stmt =
|
||||||
|
when i <= b:
|
||||||
|
iteration i
|
||||||
|
iterateStartingFrom i + 1
|
||||||
|
iterateStartingFrom a
|
||||||
|
|
||||||
|
proc concreteProc(x: int) =
|
||||||
|
forStatic i, 0..3:
|
||||||
|
echo i
|
||||||
|
|
||||||
|
proc genericProc(x: any) =
|
||||||
|
forStatic i, 0..3:
|
||||||
|
echo i
|
||||||
|
|
||||||
|
concreteProc(7) # This works
|
||||||
|
genericProc(7) # This doesn't compile
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue