summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-06-11 01:33:14 +0200
committerGitHub <noreply@github.com>2018-06-11 01:33:14 +0200
commitdf1784dabf48971792f130c4b77a41c8d011430c (patch)
treeb60da72446ceddb6567d074681711ca10e4eb3ee
parent5f2cdcd4fa0f3d5dd0156026c0685aa59d9f7f92 (diff)
parent9c5f38850d5ebc3fba8ea2e6b0a561c75d70675b (diff)
downloadNim-df1784dabf48971792f130c4b77a41c8d011430c.tar.gz
Merge pull request #8005 from Vindaar/fixes-7997
fix #7997
-rw-r--r--compiler/semexprs.nim6
-rw-r--r--tests/template/tdefined_overload.nim46
2 files changed, 48 insertions, 4 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 92b9c365a..1296bddaa 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1613,10 +1613,8 @@ proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode =
   # we replace this node by a 'true' or 'false' node:
   result = newIntNode(nkIntLit, 0)
   if not onlyCurrentScope and considerQuotedIdent(c.config, n[0], n).s == "defined":
-    if n.sons[1].kind != nkIdent:
-      localError(c.config, n.info, "obsolete usage of 'defined', use 'declared' instead")
-    elif isDefined(c.config, n.sons[1].ident.s):
-      result.intVal = 1
+    let d = considerQuotedIdent(c.config, n[1], n)
+    result.intVal = ord isDefined(c.config, d.s)
   elif lookUpForDefined(c, n.sons[1], onlyCurrentScope) != nil:
     result.intVal = 1
   result.info = n.info
diff --git a/tests/template/tdefined_overload.nim b/tests/template/tdefined_overload.nim
new file mode 100644
index 000000000..bcc83e414
--- /dev/null
+++ b/tests/template/tdefined_overload.nim
@@ -0,0 +1,46 @@
+discard """
+  output: "Valid and not defined"
+"""
+# test for issue #7997
+# checking for `when not defined` in a template for some compile time symbol
+# results in a compilation error of:
+# Error: obsolete usage of 'defined', use 'declared' instead
+# if the symbol is 'overloaded' by some variable or procedure, because in
+# that case the argument of `defined` is of kind `nkSym` instead of `nkIdent`
+# (for which was checked in `semexprs.semDefined`).
+
+block:
+  # check whether a proc with the same name as the argument to `defined`
+  # compiles
+  proc overloaded() =
+    discard
+
+  template definedCheck(): untyped =
+    when not defined(overloaded): true
+    else: false
+  doAssert definedCheck == true
+
+block:
+  # check whether a variable with the same name as the argument to `defined`
+  # compiles
+  var overloaded: int
+
+  template definedCheck(): untyped =
+    when not defined(overloaded): true
+    else: false
+  doAssert definedCheck == true
+
+block:
+  # check whether a non overloaded when check still works properly
+  when not defined(validIdentifier):
+    echo "Valid and not defined"
+
+block:
+  # now check that invalid identifiers cause a compilation error
+  # by using reject template.
+  template reject(b) =
+    static: doAssert(not compiles(b))
+
+  reject:
+    when defined(123):
+      echo "Invalid identifier! Will not be echoed"