mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
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
(cherry picked from commit ea9811a4d2)
This commit is contained in:
@@ -342,7 +342,11 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||
if c.instCounter > 50:
|
||||
globalError(c.config, info, "generic instantiation too nested")
|
||||
inc c.instCounter
|
||||
defer: dec c.instCounter
|
||||
let currentTypeofContext = c.inTypeofContext
|
||||
c.inTypeofContext = 0
|
||||
defer:
|
||||
dec c.instCounter
|
||||
c.inTypeofContext = currentTypeofContext
|
||||
# careful! we copy the whole AST including the possibly nil body!
|
||||
var n = copyTree(fn.ast)
|
||||
# NOTE: for access of private fields within generics from a different module
|
||||
|
||||
@@ -34,3 +34,24 @@ block: # issue #24150, related regression
|
||||
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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user