diff options
author | metagn <metagngn@gmail.com> | 2024-08-20 22:27:55 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-20 21:27:55 +0200 |
commit | 6320b0cd5b79fb0a11601c2a4cd675a0fc3b13f7 (patch) | |
tree | 47ddcf9f168b6b1aa93b296407703d29024d0713 | |
parent | eed9cb0d3f8e1357956adcacd54e6d9baf25f899 (diff) | |
download | Nim-6320b0cd5b79fb0a11601c2a4cd675a0fc3b13f7.tar.gz |
allow qualifying macro pragmas (#23985)
fixes #12696
-rw-r--r-- | compiler/semstmts.nim | 10 | ||||
-rw-r--r-- | compiler/semtypes.nim | 11 | ||||
-rw-r--r-- | tests/pragmas/mqualifiedmacro.nim | 10 | ||||
-rw-r--r-- | tests/pragmas/tqualifiedmacro.nim | 14 |
4 files changed, 36 insertions, 9 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 5e7aabe01..7e55a7046 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -622,15 +622,15 @@ proc setVarType(c: PContext; v: PSym, typ: PType) = proc isPossibleMacroPragma(c: PContext, it: PNode, key: PNode): bool = # make sure it's not a normal pragma, and calls an identifier # considerQuotedIdent below will fail on non-identifiers - result = whichPragma(it) == wInvalid and key.kind in nkIdentKinds + result = whichPragma(it) == wInvalid and key.kind in nkIdentKinds+{nkDotExpr} if result: # make sure it's not a user pragma - let ident = considerQuotedIdent(c, key) - result = strTableGet(c.userPragmas, ident) == nil + if key.kind != nkDotExpr: + let ident = considerQuotedIdent(c, key) + result = strTableGet(c.userPragmas, ident) == nil if result: # make sure it's not a custom pragma - var amb = false - let sym = searchInScopes(c, ident, amb) + let sym = qualifiedLookUp(c, key, {}) result = sym == nil or sfCustomPragma notin sym.flags proc copyExcept(n: PNode, i: int): PNode = diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index a5cd5b5b0..4f2d397a6 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1770,12 +1770,15 @@ proc applyTypeSectionPragmas(c: PContext; pragmas, operand: PNode): PNode = discard "builtin pragma" else: trySuggestPragmas(c, key) - let ident = considerQuotedIdent(c, key) - if strTableGet(c.userPragmas, ident) != nil: + let ident = + if key.kind in nkIdentKinds: + considerQuotedIdent(c, key) + else: + nil + if ident != nil and strTableGet(c.userPragmas, ident) != nil: discard "User-defined pragma" else: - var amb = false - let sym = searchInScopes(c, ident, amb) + let sym = qualifiedLookUp(c, key, {}) # XXX: What to do here if amb is true? if sym != nil and sfCustomPragma in sym.flags: discard "Custom user pragma" diff --git a/tests/pragmas/mqualifiedmacro.nim b/tests/pragmas/mqualifiedmacro.nim new file mode 100644 index 000000000..908973206 --- /dev/null +++ b/tests/pragmas/mqualifiedmacro.nim @@ -0,0 +1,10 @@ +template t*(x:untyped): untyped = + echo "template t" + +import macros +macro m*(name: static string, x: untyped): untyped = + let newName = ident(name) + result = quote do: + type `newName` = object + if result.kind == nnkStmtList: + result = result[^1] diff --git a/tests/pragmas/tqualifiedmacro.nim b/tests/pragmas/tqualifiedmacro.nim new file mode 100644 index 000000000..bc95ec1ea --- /dev/null +++ b/tests/pragmas/tqualifiedmacro.nim @@ -0,0 +1,14 @@ +discard """ + output: ''' +template t +''' +""" + +# issue #12696 + +import mqualifiedmacro +proc p() {. mqualifiedmacro.t .} = # errors with identifier expected but a.t found + echo "proc p" + +type Foo {. mqualifiedmacro.m("Bar") .} = object +doAssert Bar is object |