Skip to content

Commit

Permalink
reset inTypeofContext in generic instantiations (nim-lang#24229)
Browse files Browse the repository at this point in the history
fixes nim-lang#24228, refs nim-lang#22022

As described in
nim-lang#24228 (comment),
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 nim-lang#22022 are likely. Ideally this behavior would be
removed but it's necessary to accomodate the current [proc `declval` in
the package `stew`](status-im/nim-stew#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 nim-lang#22022 breaks nothing whatsoever, but
a universal solution would be better. Edit: Done in nim-lang#24230 via
experimental switch
  • Loading branch information
metagn authored Oct 6, 2024
1 parent 7f2e6a1 commit ea9811a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
6 changes: 5 additions & 1 deletion compiler/seminst.nim
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,11 @@ proc generateInstance(c: PContext, fn: PSym, pt: LayeredIdTable,
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
Expand Down
21 changes: 21 additions & 0 deletions tests/vm/tgenericcompiletimeproc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit ea9811a

Please sign in to comment.