diff options
author | metagn <metagngn@gmail.com> | 2024-08-29 17:11:37 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-29 16:11:37 +0200 |
commit | d7e77b330f3f84a9cebcca057c0697687ebe8ec3 (patch) | |
tree | 33d3df9299980c8985c527305974c8641aa84c79 | |
parent | da7670c8e0aff740a66783e83134d212383f9dd1 (diff) | |
download | Nim-d7e77b330f3f84a9cebcca057c0697687ebe8ec3.tar.gz |
fix `include` in templates, with prefix operators (#24029)
fixes #12539, refs #21636 `evalInclude` now uses `getPIdent` to check if a symbol isn't `/` anymore instead of assuming it's an ident, which it's not when used in templates. Also it just checks if the symbol is `as` now, because there are other infix operators that could be used like `/../`. It also works with prefix operators now by copying what was done in #21636.
-rw-r--r-- | compiler/semstmts.nim | 27 | ||||
-rw-r--r-- | tests/modules/mincludeprefix.nim | 1 | ||||
-rw-r--r-- | tests/modules/mincludetemplate.nim | 1 | ||||
-rw-r--r-- | tests/modules/tincludeprefix.nim | 3 | ||||
-rw-r--r-- | tests/modules/tincludetemplate.nim | 5 |
5 files changed, 25 insertions, 12 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index be60b093d..ce928eef9 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -2735,20 +2735,23 @@ proc incMod(c: PContext, n: PNode, it: PNode, includeStmtResult: PNode) = proc evalInclude(c: PContext, n: PNode): PNode = result = newNodeI(nkStmtList, n.info) result.add n + template checkAs(it: PNode) = + if it.kind == nkInfix and it.len == 3: + let op = it[0].getPIdent + if op != nil and op.id == ord(wAs): + localError(c.config, it.info, "Cannot use '" & it[0].renderTree & "' in 'include'.") for i in 0..<n.len: - var imp: PNode let it = n[i] - if it.kind == nkInfix and it.len == 3 and it[0].ident.s != "/": - localError(c.config, it.info, "Cannot use '" & it[0].ident.s & "' in 'include'.") - if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket: - let sep = it[0] - let dir = it[1] - imp = newNodeI(nkInfix, it.info) - imp.add sep - imp.add dir - imp.add sep # dummy entry, replaced in the loop - for x in it[2]: - imp[2] = x + checkAs(it) + if it.kind in {nkInfix, nkPrefix} and it[^1].kind == nkBracket: + let lastPos = it.len - 1 + var imp = copyNode(it) + newSons(imp, it.len) + for i in 0 ..< lastPos: imp[i] = it[i] + imp[lastPos] = imp[0] # dummy entry, replaced in the loop + for x in it[lastPos]: + checkAs(x) + imp[lastPos] = x incMod(c, n, imp, result) else: incMod(c, n, it, result) diff --git a/tests/modules/mincludeprefix.nim b/tests/modules/mincludeprefix.nim new file mode 100644 index 000000000..6d557a430 --- /dev/null +++ b/tests/modules/mincludeprefix.nim @@ -0,0 +1 @@ +const bar = 456 diff --git a/tests/modules/mincludetemplate.nim b/tests/modules/mincludetemplate.nim new file mode 100644 index 000000000..febe9bfcf --- /dev/null +++ b/tests/modules/mincludetemplate.nim @@ -0,0 +1 @@ +const foo = 123 diff --git a/tests/modules/tincludeprefix.nim b/tests/modules/tincludeprefix.nim new file mode 100644 index 000000000..d45a6eff3 --- /dev/null +++ b/tests/modules/tincludeprefix.nim @@ -0,0 +1,3 @@ +include ./[mincludeprefix, mincludetemplate] +doAssert foo == 123 +doAssert bar == 456 diff --git a/tests/modules/tincludetemplate.nim b/tests/modules/tincludetemplate.nim new file mode 100644 index 000000000..77e409ee5 --- /dev/null +++ b/tests/modules/tincludetemplate.nim @@ -0,0 +1,5 @@ +# issue #12539 + +template includePath(n: untyped) = include ../modules/n # But `include n` works +includePath(mincludetemplate) +doAssert foo == 123 |