summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2016-05-27 19:17:51 +0200
committerAndreas Rumpf <rumpf_a@web.de>2016-05-27 19:18:08 +0200
commit6d76df84546dd90d33a413c0bbd8df75f797767a (patch)
tree1deca5384e48fc7c7c642761843b83a1ee9cf228
parent6ff66bfd519f076b5453b1bdcf94086b4ee658f4 (diff)
downloadNim-6d76df84546dd90d33a413c0bbd8df75f797767a.tar.gz
fixes #4227
-rw-r--r--compiler/evaltempl.nim9
-rw-r--r--compiler/hlo.nim2
-rw-r--r--compiler/semdata.nim2
-rw-r--r--compiler/semexprs.nim2
-rw-r--r--tests/trmacros/tstatic_t_bug.nim24
5 files changed, 32 insertions, 7 deletions
diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim
index a5a132005..794e35d74 100644
--- a/compiler/evaltempl.nim
+++ b/compiler/evaltempl.nim
@@ -59,7 +59,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
       evalTemplateAux(templ.sons[i], actual, c, res)
     result.add res
 
-proc evalTemplateArgs(n: PNode, s: PSym): PNode =
+proc evalTemplateArgs(n: PNode, s: PSym; fromHlo: bool): PNode =
   # if the template has zero arguments, it can be called without ``()``
   # `n` is then a nkSym or something similar
   var totalParams = case n.kind
@@ -75,7 +75,7 @@ proc evalTemplateArgs(n: PNode, s: PSym): PNode =
     # their bodies. We could try to fix this, but it may be
     # wiser to just deprecate immediate templates and macros
     # now that we have working untyped parameters.
-    genericParams = if sfImmediate in s.flags: 0
+    genericParams = if sfImmediate in s.flags or fromHlo: 0
                     else: s.ast[genericParamsPos].len
     expectedRegularParams = <s.typ.len
     givenRegularParams = totalParams - genericParams
@@ -92,6 +92,7 @@ proc evalTemplateArgs(n: PNode, s: PSym): PNode =
   for i in givenRegularParams+1 .. expectedRegularParams:
     let default = s.typ.n.sons[i].sym.ast
     if default.isNil or default.kind == nkEmpty:
+      echo "fuck you ", genericParams
       localError(n.info, errWrongNumberOfArguments)
       addSon(result, ast.emptyNode)
     else:
@@ -104,14 +105,14 @@ proc evalTemplateArgs(n: PNode, s: PSym): PNode =
 var evalTemplateCounter* = 0
   # to prevent endless recursion in templates instantiation
 
-proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym): PNode =
+proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym; fromHlo=false): PNode =
   inc(evalTemplateCounter)
   if evalTemplateCounter > 100:
     globalError(n.info, errTemplateInstantiationTooNested)
     result = n
 
   # replace each param by the corresponding node:
-  var args = evalTemplateArgs(n, tmpl)
+  var args = evalTemplateArgs(n, tmpl, fromHlo)
   var ctx: TemplCtx
   ctx.owner = tmpl
   ctx.genSymOwner = genSymOwner
diff --git a/compiler/hlo.nim b/compiler/hlo.nim
index 6cc9567af..de0fa6216 100644
--- a/compiler/hlo.nim
+++ b/compiler/hlo.nim
@@ -24,7 +24,7 @@ proc evalPattern(c: PContext, n, orig: PNode): PNode =
   of skMacro:
     result = semMacroExpr(c, n, orig, s)
   of skTemplate:
-    result = semTemplateExpr(c, n, s)
+    result = semTemplateExpr(c, n, s, {efFromHlo})
   else:
     result = semDirectOp(c, n, {})
   if optHints in gOptions and hintPattern in gNotes:
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index a13f2c232..b25f72f2d 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -47,7 +47,7 @@ type
     efLValue, efWantIterator, efInTypeof,
     efWantStmt, efAllowStmt, efDetermineType,
     efAllowDestructor, efWantValue, efOperand, efNoSemCheck,
-    efNoProcvarCheck
+    efNoProcvarCheck, efFromHlo
   TExprFlags* = set[TExprFlag]
 
   TTypeAttachedOp* = enum
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 5aac1c2ac..ae0f42dd6 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -15,7 +15,7 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
   markUsed(n.info, s)
   styleCheckUse(n.info, s)
   pushInfoContext(n.info)
-  result = evalTemplate(n, s, getCurrOwner())
+  result = evalTemplate(n, s, getCurrOwner(), efFromHlo in flags)
   if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, s, flags)
   popInfoContext()
 
diff --git a/tests/trmacros/tstatic_t_bug.nim b/tests/trmacros/tstatic_t_bug.nim
new file mode 100644
index 000000000..cdfa53514
--- /dev/null
+++ b/tests/trmacros/tstatic_t_bug.nim
@@ -0,0 +1,24 @@
+discard """
+  output: "optimized"
+"""
+# bug #4227
+type Vector64[N: static[int]] = array[N, int]
+
+proc `*`*[N: static[int]](a: Vector64[N]; b: float64): Vector64[N] =
+  result = a
+
+proc `+=`*[N: static[int]](a: var Vector64[N]; b: Vector64[N]) =
+  echo "regular"
+
+proc linearCombinationMut[N: static[int]](a: float64, v: var Vector64[N], w: Vector64[N])  {. inline .} =
+  echo "optimized"
+
+template rewriteLinearCombinationMut*{v += `*`(w, a)}(a: float64, v: var Vector64, w: Vector64): auto =
+  linearCombinationMut(a, v, w)
+
+proc main() =
+  const scaleVal = 9.0
+  var a, b: Vector64[7]
+  a += b * scaleval
+
+main()