diff options
author | Araq <rumpf_a@web.de> | 2014-04-01 08:17:23 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-04-01 08:17:23 +0200 |
commit | 6a94ca318782de9a3bd0a20f69b5c2ecde3a0dba (patch) | |
tree | d6ec40dc1854a2268ecdc8111f28c14f568b22d3 | |
parent | 3afb42496b1dd9ca1c8a0c31bbf53f82e4a2b39d (diff) | |
download | Nim-6a94ca318782de9a3bd0a20f69b5c2ecde3a0dba.tar.gz |
fixes #880
-rw-r--r-- | compiler/semtempl.nim | 34 | ||||
-rw-r--r-- | tests/template/ttempl5.nim | 11 |
2 files changed, 31 insertions, 14 deletions
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index b71198119..1432b76f0 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -138,6 +138,18 @@ proc semTemplBodyScope(c: var TemplCtx, n: PNode): PNode = result = semTemplBody(c, n) 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 = result = newSym(kind, considerAcc(n), c.owner, n.info) incl(result.flags, sfGenSym) @@ -154,7 +166,13 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = of nkPostfix: x = x[1] of nkPragmaExpr: x = x[0] 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) if not isTemplParam(c, ident): 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): 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 semTemplBody(c: var TemplCtx, n: PNode): PNode = result = n @@ -380,7 +386,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = of nkPragma: result = onlyReplaceParams(c, n) 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 if n.kind == nkDotExpr or n.kind == nkAccQuoted: let s = qualifiedLookUp(c.c, n, {}) diff --git a/tests/template/ttempl5.nim b/tests/template/ttempl5.nim index 1f2378780..a020a8e2c 100644 --- a/tests/template/ttempl5.nim +++ b/tests/template/ttempl5.nim @@ -16,3 +16,14 @@ get_next_ident() #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 + |