Skip to content

Commit

Permalink
fix inTypeofContext leaking after compiles raises exception [back…
Browse files Browse the repository at this point in the history
…port:2.0] (#24152)

fixes #24150, refs #22022

An exception is raised in the `semExprWithType` call, which means `dec
c.inTypeofContext` is never called, but `compiles` allows compilation to
continue. This means `c.inTypeofContext` is left perpetually nonzero,
which prevents `compileTime` evaluation for the rest of the program.

To fix this, `defer:` is used for the `dec c.inTypeofContext` call, as
is done for
[`instCounter`](https://github.com/nim-lang/Nim/blob/d51d88700b2fb3bd228d5e8f7385e2e4a2e2880c/compiler/seminst.nim#L374)
in other parts of the compiler.

(cherry picked from commit a177720)
  • Loading branch information
metagn authored and narimiran committed Sep 28, 2024
1 parent 9d65507 commit 3a180df
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 3 deletions.
2 changes: 1 addition & 1 deletion compiler/semmagic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ proc semTypeOf(c: PContext; n: PNode): PNode =
m = mode.intVal
result = newNodeI(nkTypeOfExpr, n.info)
inc c.inTypeofContext
defer: dec c.inTypeofContext # compiles can raise an exception
let typExpr = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
dec c.inTypeofContext
result.add typExpr
result.typ = makeTypeDesc(c, typExpr.typ)

Expand Down
4 changes: 2 additions & 2 deletions compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1808,8 +1808,8 @@ proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType =
proc semTypeOf(c: PContext; n: PNode; prev: PType): PType =
openScope(c)
inc c.inTypeofContext
defer: dec c.inTypeofContext # compiles can raise an exception
let t = semExprWithType(c, n, {efInTypeof})
dec c.inTypeofContext
closeScope(c)
fixupTypeOf(c, prev, t)
result = t.typ
Expand All @@ -1824,8 +1824,8 @@ proc semTypeOf2(c: PContext; n: PNode; prev: PType): PType =
else:
m = mode.intVal
inc c.inTypeofContext
defer: dec c.inTypeofContext # compiles can raise an exception
let t = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
dec c.inTypeofContext
closeScope(c)
fixupTypeOf(c, prev, t)
result = t.typ
Expand Down
7 changes: 7 additions & 0 deletions tests/vm/tgenericcompiletimeproc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@ block:
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()

0 comments on commit 3a180df

Please sign in to comment.