diff options
author | Clyybber <darkmine956@gmail.com> | 2021-06-16 16:40:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-16 16:40:22 +0200 |
commit | 13b94c0297806911cf317ff6169dba8595a0333d (patch) | |
tree | 9b46d161503b511120ce225c74e9fedf594ee2d6 | |
parent | c51680e7012bff32156623fad0996d62f7918222 (diff) | |
download | Nim-13b94c0297806911cf317ff6169dba8595a0333d.tar.gz |
Fix doubly typed forward declarations (#18279)
* Add testcase * Fix testcase * Fix doubly typed forward decls * Better fix
-rw-r--r-- | compiler/semstmts.nim | 7 | ||||
-rw-r--r-- | tests/macros/tmacros_issues.nim | 22 |
2 files changed, 27 insertions, 2 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index d6ad7ab54..f29dc24ef 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1890,11 +1890,16 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, var (proto, comesFromShadowScope) = if isAnon: (nil, false) else: searchForProc(c, declarationScope, s) - if proto == nil and sfForward in s.flags: + if proto == nil and sfForward in s.flags and n[bodyPos].kind != nkEmpty: ## In cases such as a macro generating a proc with a gensymmed name we ## know `searchForProc` will not find it and sfForward will be set. In ## such scenarios the sym is shared between forward declaration and we ## can treat the `s` as the proto. + ## To differentiate between that happening and a macro just returning a + ## forward declaration that has been typed before we check if the body + ## is not empty. This has the sideeffect of allowing multiple forward + ## declarations if they share the same sym. + ## See the "doubly-typed forward decls" case in tmacros_issues.nim proto = s let hasProto = proto != nil diff --git a/tests/macros/tmacros_issues.nim b/tests/macros/tmacros_issues.nim index a964f46ba..a81c51658 100644 --- a/tests/macros/tmacros_issues.nim +++ b/tests/macros/tmacros_issues.nim @@ -484,6 +484,26 @@ func expMin: float {.aadMin.} = 1 echo expMin() +# doubly-typed forward decls +macro noop(x: typed) = x +noop: + proc cally() = discard + +cally() + +noop: + proc barry() + +proc barry() = discard + +# some more: +proc barry2() {.noop.} +proc barry2() = discard + +proc barry3() {.noop.} +proc barry3() {.noop.} = discard + + # issue #15389 block double_sem_for_procs: @@ -498,4 +518,4 @@ block double_sem_for_procs: return x1 + 1.0 result = 10.0 - discard exp(5.0) \ No newline at end of file + discard exp(5.0) |