diff options
author | Araq <rumpf_a@web.de> | 2015-02-08 15:43:50 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-02-08 15:43:50 +0100 |
commit | 34b4e9fc9624042d9fb94a73535baa76b3033376 (patch) | |
tree | 2745c6f2f14100c20a9a6cfef3a5d52981848ee7 | |
parent | ada0f14711d3eff140f05f8a845cff5d489a71fd (diff) | |
download | Nim-34b4e9fc9624042d9fb94a73535baa76b3033376.tar.gz |
fixes #2004
-rw-r--r-- | compiler/semexprs.nim | 37 | ||||
-rw-r--r-- | compiler/seminst.nim | 13 | ||||
-rw-r--r-- | tests/generics/t1056.nim | 3 | ||||
-rw-r--r-- | tests/template/tparams_gensymed.nim | 19 |
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) + + |