summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-04-01 08:17:23 +0200
committerAraq <rumpf_a@web.de>2014-04-01 08:17:23 +0200
commit6a94ca318782de9a3bd0a20f69b5c2ecde3a0dba (patch)
treed6ec40dc1854a2268ecdc8111f28c14f568b22d3
parent3afb42496b1dd9ca1c8a0c31bbf53f82e4a2b39d (diff)
downloadNim-6a94ca318782de9a3bd0a20f69b5c2ecde3a0dba.tar.gz
fixes #880
-rw-r--r--compiler/semtempl.nim34
-rw-r--r--tests/template/ttempl5.nim11
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
+