From 4ab6dd51b03bfb5d180927fac34d76ed855ed4b7 Mon Sep 17 00:00:00 2001 From: Vindaar Date: Sun, 10 Jun 2018 14:13:55 +0200 Subject: fix #7997 Fixes issue #7997, which was caused by an export of a `release` proc in `locks`. Thus the `release` in `defined(release)` of the `ifDebug` template, was of kind `nkSym` instead of `nkIdent`. We fix this by getting the `PIdent` of the argument to `defined` using `considerQuotedIdent`. This has the nice property of also checking for a valid identifier for us. E.g. `defined(123)` would fail with ``` Error: in expression 'defined(123)': identifier expected, but found '123' ``` The `localError` is removed, due to a clear distinction between `declared` and `defined` now. --- compiler/semexprs.nim | 6 ++---- 1 file changed, 2 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 -- cgit 1.4.1-2-gfad0 From 9c5f38850d5ebc3fba8ea2e6b0a561c75d70675b Mon Sep 17 00:00:00 2001 From: Vindaar Date: Sun, 10 Jun 2018 17:09:26 +0200 Subject: add test case for fix to #7997 --- tests/template/tdefined_overload.nim | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/template/tdefined_overload.nim 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" -- cgit 1.4.1-2-gfad0