Fix doubly typed forward declarations (#18279)

* Add testcase

* Fix testcase

* Fix doubly typed forward decls

* Better fix
This commit is contained in:
Clyybber 2021-06-16 16:40:22 +02:00 • committed by GitHub
commit 13b94c0297
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 2 deletions

View file

@ -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

View file

@ -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)
discard exp(5.0)