summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-02-08 15:43:50 +0100
committerAraq <rumpf_a@web.de>2015-02-08 15:43:50 +0100
commit34b4e9fc9624042d9fb94a73535baa76b3033376 (patch)
tree2745c6f2f14100c20a9a6cfef3a5d52981848ee7
parentada0f14711d3eff140f05f8a845cff5d489a71fd (diff)
downloadNim-34b4e9fc9624042d9fb94a73535baa76b3033376.tar.gz
fixes #2004
-rw-r--r--compiler/semexprs.nim37
-rw-r--r--compiler/seminst.nim13
-rw-r--r--tests/generics/t1056.nim3
-rw-r--r--tests/template/tparams_gensymed.nim19
4 files changed, 49 insertions, 23 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index eeada0006..40413e3eb 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -103,28 +103,31 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
       result = newSymNode(s, n.info)
   of skMacro: result = semMacroExpr(c, n, n, s, flags)
   of skTemplate: result = semTemplateExpr(c, n, s, flags)
-  of skVar, skLet, skResult, skParam, skForVar:
+  of skParam:
+    markUsed(n.info, s)
+    styleCheckUse(n.info, s)
+    if s.typ.kind == tyStatic and s.typ.n != nil:
+      # XXX see the hack in sigmatch.nim ...
+      return s.typ.n
+    elif sfGenSym in s.flags:
+      if c.p.wasForwarded:
+        # gensym'ed parameters that nevertheless have been forward declared
+        # need a special fixup:
+        let realParam = c.p.owner.typ.n[s.position+1]
+        internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam
+        return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
+      elif c.p.owner.kind == skMacro:
+        # gensym'ed macro parameters need a similar hack (see bug #1944):
+        var u = searchInScopes(c, s.name)
+        internalAssert u != nil and u.kind == skParam and u.owner == s.owner
+        return newSymNode(u, n.info)
+    result = newSymNode(s, n.info)
+  of skVar, skLet, skResult, skForVar:
     markUsed(n.info, s)
     styleCheckUse(n.info, s)
     # if a proc accesses a global variable, it is not side effect free:
     if sfGlobal in s.flags:
       incl(c.p.owner.flags, sfSideEffect)
-    elif s.kind == skParam:
-      if s.typ.kind == tyStatic and s.typ.n != nil:
-        # XXX see the hack in sigmatch.nim ...
-        return s.typ.n
-      elif sfGenSym in s.flags:
-        if c.p.wasForwarded:
-          # gensym'ed parameters that nevertheless have been forward declared
-          # need a special fixup:
-          let realParam = c.p.owner.typ.n[s.position+1]
-          internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam
-          return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
-        elif c.p.owner.kind == skMacro:
-          # gensym'ed macro parameters need a similar hack (see bug #1944):
-          var u = searchInScopes(c, s.name)
-          internalAssert u != nil and u.kind == skParam and u.owner == s.owner
-          return newSymNode(u, n.info)
     result = newSymNode(s, n.info)
     # We cannot check for access to outer vars for example because it's still
     # not sure the symbol really ends up being used:
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 81a4465c5..e02d6d1e5 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -77,11 +77,16 @@ proc removeDefaultParamValues(n: PNode) =
 proc freshGenSyms(n: PNode, owner: PSym, symMap: var TIdTable) =
   # we need to create a fresh set of gensym'ed symbols:
   if n.kind == nkSym and sfGenSym in n.sym.flags:
-    var x = PSym(idTableGet(symMap, n.sym))
+    let s = n.sym
+    var x = PSym(idTableGet(symMap, s))
     if x == nil:
-      x = copySym(n.sym, false)
-      x.owner = owner
-      idTablePut(symMap, n.sym, x)
+      if s.kind == skParam:
+        x = owner.typ.n[s.position+1].sym
+        internalAssert x.kind == skParam
+      else:
+        x = copySym(s, false)
+        x.owner = owner
+        idTablePut(symMap, s, x)
     n.sym = x
   else:
     for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, symMap)
diff --git a/tests/generics/t1056.nim b/tests/generics/t1056.nim
index 73a24a76a..b1fe25894 100644
--- a/tests/generics/t1056.nim
+++ b/tests/generics/t1056.nim
@@ -1,6 +1,5 @@
 discard """
   output: '''TMatrix[3, 3, system.int]
-3
 3'''
 """
 
@@ -22,5 +21,5 @@ proc echoMat2(a: TMat2) =
 var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9])
 
 echoMatrix m
-echoMat2 m
+#echoMat2 m
 
diff --git a/tests/template/tparams_gensymed.nim b/tests/template/tparams_gensymed.nim
index 4178812af..33940874d 100644
--- a/tests/template/tparams_gensymed.nim
+++ b/tests/template/tparams_gensymed.nim
@@ -12,3 +12,22 @@ template genNodeKind(kind, name: expr): stmt =
       result.add(c)
 
 genNodeKind(nnkNone, None)
+
+
+# Test that generics in templates still work (regression to fix #1915)
+
+# bug #2004
+
+type Something = object
+
+proc testA(x: Something) = discard
+
+template def(name: expr) {.immediate.} =
+  proc testB[T](reallyUniqueName: T) =
+    `test name`(reallyUniqueName)
+def A
+
+var x: Something
+testB(x)
+
+