Files
Nim/tests/vm/tgenericcompiletimeproc.nim
metagn ea9811a4d2 reset inTypeofContext in generic instantiations (#24229)
fixes #24228, refs #22022

As described in
https://github.com/nim-lang/Nim/issues/24228#issuecomment-2392462221,
instantiating generic routines inside `typeof` causes all code inside to
be treated as being in a typeof context, and thus preventing compile
time proc folding, causing issues when code is generated for the
instantiated routine. Now, instantiated generic procs are treated as
never being inside a `typeof` context.

This is probably an arbitrary special case and more issues with the
`typeof` behavior from #22022 are likely. Ideally this behavior would be
removed but it's necessary to accomodate the current [proc `declval` in
the package `stew`](https://github.com/status-im/nim-stew/pull/190), at
least without changes to `compileTime` that would either break other
code (making it not eagerly fold by default) or still require a change
in stew (adding an option to disable the eager folding).

Alternatively we could also make the eager folding opt-in only for
generic compileTime procs so that #22022 breaks nothing whatsoever, but
a universal solution would be better. Edit: Done in #24230 via
experimental switch
2024-10-06 19:36:46 +02:00

58 lines
1.3 KiB
Nim

block: # issue #10753
proc foo(x: int): int {.compileTime.} = x
const a = foo(123)
doAssert foo(123) == a
proc bar[T](x: T): T {.compileTime.} = x
const b = bar(123)
doAssert bar(123) == b
const c = bar("abc")
doAssert bar("abc") == c
block: # issue #22021
proc foo(x: static int): int {.compileTime.} = x + 1
doAssert foo(123) == 124
block: # issue #19365
proc f[T](x: static T): T {.compileTime.} = x + x
doAssert f(123) == 246
doAssert f(1.0) == 2.0
block:
# don't fold compile time procs in typeof
proc fail[T](x: T): T {.compileTime.} =
doAssert false
x
doAssert typeof(fail(123)) is typeof(123)
proc p(x: int): int = x
type Foo = typeof(p(fail(123)))
block: # issue #24150, related regression
proc w(T: type): T {.compileTime.} = default(ptr T)[]
template y(v: auto): auto = typeof(v) is int
discard compiles(y(w int))
proc s(): int {.compileTime.} = discard
discard s()
block: # issue #24228, also related regression
proc d(_: static[string]) = discard $0
proc m(_: static[string]) = d("")
iterator v(): int {.closure.} =
template a(n: untyped) =
when typeof(n) is void:
n
else:
n
a(m(""))
let _ = v
block: # issue #24228 simplified
proc d[T]() =
let x = $0
proc v() =
when typeof(d[string]()) is void:
d[string]()
v()