This commit is contained in:
Araq 2014-04-01 08:17:23 +02:00
commit 6a94ca3187
2 changed files with 31 additions and 14 deletions

View file

@ -138,6 +138,18 @@ proc semTemplBodyScope(c: var TemplCtx, n: PNode): PNode =
result = semTemplBody(c, n) result = semTemplBody(c, n)
closeScope(c) closeScope(c)
proc onlyReplaceParams(c: var TemplCtx, n: PNode): PNode =
result = n
if n.kind == nkIdent:
let s = qualifiedLookUp(c.c, n, {})
if s != nil:
if s.owner == c.owner and s.kind == skParam:
incl(s.flags, sfUsed)
result = newSymNode(s, n.info)
else:
for i in 0 .. <n.safeLen:
result.sons[i] = onlyReplaceParams(c, n.sons[i])
proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym = proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
result = newSym(kind, considerAcc(n), c.owner, n.info) result = newSym(kind, considerAcc(n), c.owner, n.info)
incl(result.flags, sfGenSym) incl(result.flags, sfGenSym)
@ -154,7 +166,13 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
of nkPostfix: x = x[1] of nkPostfix: x = x[1]
of nkPragmaExpr: x = x[0] of nkPragmaExpr: x = x[0]
of nkIdent: break of nkIdent: break
else: illFormedAst(x) of nkAccQuoted:
# consider: type `T TemplParam` {.inject.}
# it suffices to return to treat it like 'inject':
n = onlyReplaceParams(c, n)
return
else:
illFormedAst(x)
let ident = getIdentNode(c, x) let ident = getIdentNode(c, x)
if not isTemplParam(c, ident): if not isTemplParam(c, ident):
c.toInject.incl(x.ident.id) c.toInject.incl(x.ident.id)
@ -232,18 +250,6 @@ proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind) =
for j in countup(0, L-3): for j in countup(0, L-3):
addLocalDecl(c, a.sons[j], symKind) addLocalDecl(c, a.sons[j], symKind)
proc onlyReplaceParams(c: var TemplCtx, n: PNode): PNode =
result = n
if n.kind == nkIdent:
let s = qualifiedLookUp(c.c, n, {})
if s != nil:
if s.owner == c.owner and s.kind == skParam:
incl(s.flags, sfUsed)
result = newSymNode(s, n.info)
else:
for i in 0 .. <n.safeLen:
result.sons[i] = onlyReplaceParams(c, n.sons[i])
proc semPattern(c: PContext, n: PNode): PNode proc semPattern(c: PContext, n: PNode): PNode
proc semTemplBody(c: var TemplCtx, n: PNode): PNode = proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
result = n result = n
@ -380,7 +386,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
of nkPragma: of nkPragma:
result = onlyReplaceParams(c, n) result = onlyReplaceParams(c, n)
else: else:
# dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam', # dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam',
# so we use the generic code for nkDotExpr too # so we use the generic code for nkDotExpr too
if n.kind == nkDotExpr or n.kind == nkAccQuoted: if n.kind == nkDotExpr or n.kind == nkAccQuoted:
let s = qualifiedLookUp(c.c, n, {}) let s = qualifiedLookUp(c.c, n, {})

View file

@ -16,3 +16,14 @@ get_next_ident()
#identifier expected, but found '(open|open|open)' #identifier expected, but found '(open|open|open)'
#bug #880 (also example in the manual!)
template typedef(name: expr, typ: typedesc) {.immediate.} =
type
`T name`* {.inject.} = typ
`P name`* {.inject.} = ref `T name`
typedef(myint, int)
var x: PMyInt