diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 8bc68728cb80..3d89771f845a 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -535,13 +535,20 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = of nkConverterDef: result = semRoutineInTemplBody(c, n, skConverter) of nkPragmaExpr: - result[0] = semTemplBody(c, n[0]) + result = semTemplBodySons(c, n) of nkPostfix: result[1] = semTemplBody(c, n[1]) of nkPragma: - for x in n: - if x.kind == nkExprColonExpr: - x[1] = semTemplBody(c, x[1]) + for i in 0 ..< n.len: + let x = n[i] + let prag = whichPragma(x) + if prag == wInvalid: + # only sem if not a language-level pragma + result[i] = semTemplBody(c, x) + elif x.kind in nkPragmaCallKinds: + # is pragma, but value still needs to be checked + for j in 1 ..< x.len: + x[j] = semTemplBody(c, x[j]) of nkBracketExpr: if n.typ == nil: # if a[b] is nested inside a typed expression, don't convert it diff --git a/compiler/trees.nim b/compiler/trees.nim index 41b54eb09676..da58878f82f4 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -147,6 +147,13 @@ proc whichPragma*(n: PNode): TSpecialWord = of nkCast: return wCast of nkClosedSymChoice, nkOpenSymChoice: return whichPragma(key[0]) + of nkBracketExpr: + if n.kind notin nkPragmaCallKinds: return wInvalid + result = whichPragma(key[0]) + if result notin {wHint, wHintAsError, wWarning, wWarningAsError}: + # note bracket pragmas, see processNote + result = wInvalid + return else: return wInvalid if result in nonPragmaWordsLow..nonPragmaWordsHigh: result = wInvalid diff --git a/tests/template/tpragma.nim b/tests/template/tpragma.nim new file mode 100644 index 000000000000..bc8c7b74167b --- /dev/null +++ b/tests/template/tpragma.nim @@ -0,0 +1,28 @@ +# issue #24186 + +macro mymacro(typ: typedesc; def) = + def + +macro mymacro2(typ: typedesc; typ2: typedesc; def) = + def + +template mytemplate(typ: typedesc) = # works + proc myproc() {.mymacro: typ .} = + discard + +template mytemplate2(typ: typedesc) = # Error: undeclared identifier: 'typ' + proc myproc2() {.mymacro(typ) .} = + discard + +template mytemplate3(typ: typedesc, typ2: typedesc) = # Error: undeclared identifier: 'typ' + proc myproc3() {.mymacro2(typ, typ2) .} = + discard + +template mytemplate4() = # works + proc myproc4() {.mymacro2(string, int) .} = + discard + +mytemplate(string) +mytemplate2(string) +mytemplate3(string, int) +mytemplate4()