diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index a5a132005c..794e35d748 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 = 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 6cc9567af7..de0fa6216f 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 a13f2c2329..b25f72f2d9 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 5aac1c2ace..ae0f42dd68 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 0000000000..cdfa535148 --- /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()