Fix forward declarations in shadow scope contexts (#15386)

* Fix forward declarations in shadow scope contexts

* Add testcase for #15385

* Less empty lines

* Fix tests

* Inline isShadowScope

* Add original testcase (with reduced amount of iterations)

* Add testcase without forward decl
This commit is contained in:
Clyybber
2020-09-22 18:24:13 +02:00
committed by GitHub
parent 11c377c114
commit 4b9eea2fcc
5 changed files with 101 additions and 13 deletions

View File

@@ -39,6 +39,7 @@ true
false
true
false
1.0
'''
"""
@@ -403,3 +404,79 @@ testEvenOdd5()
# it works, because the forward decl and definition share the symbol and the compiler is forgiving here
#testEvenOdd6() #Don't test it though, the compiler may become more strict in the future
# bug #15385
var captured_funcs {.compileTime.}: seq[NimNode] = @[]
macro aad*(fns: varargs[typed]): typed =
result = newStmtList()
for fn in fns:
captured_funcs.add fn[0]
result.add fn
func exp*(x: float): float ## get different error if you remove forward declaration
func exp*(x: float): float {.aad.} =
var x1 = min(max(x, -708.4), 709.8)
var result: float ## looks weird because it is taken from template expansion
result = x1 + 1.0
result
template check_accuracy(f: untyped, rng: Slice[float], n: int, verbose = false): auto =
proc check_accuracy: tuple[avg_ulp: float, max_ulp: int] {.gensym.} =
let k = (rng.b - rng.a) / (float) n
var
res, x: float
i, max_ulp = 0
avg_ulp = 0.0
x = rng.a
while (i < n):
res = f(x)
i.inc
x = x + 0.001
(avg_ulp, max_ulp)
check_accuracy()
discard check_accuracy(exp, -730.0..709.4, 4)
# And without forward decl
macro aad2*(fns: varargs[typed]): typed =
result = newStmtList()
for fn in fns:
captured_funcs.add fn[0]
result.add fn
func exp2*(x: float): float {.aad2.} =
var x1 = min(max(x, -708.4), 709.8)
var result: float ## looks weird because it is taken from template expansion
result = x1 + 1.0
result
template check_accuracy2(f: untyped, rng: Slice[float], n: int, verbose = false): auto =
proc check_accuracy2: tuple[avg_ulp: float, max_ulp: int] {.gensym.} =
let k = (rng.b - rng.a) / (float) n
var
res, x: float
i, max_ulp = 0
avg_ulp = 0.0
x = rng.a
while (i < n):
res = f(x)
i.inc
x = x + 0.001
(avg_ulp, max_ulp)
check_accuracy2()
discard check_accuracy2(exp2, -730.0..709.4, 4)
# And minimized:
macro aadMin(fn: typed): typed = fn
func expMin: float
func expMin: float {.aadMin.} = 1
echo expMin()