fix inTypeofContext leaking after compiles raises exception [backport: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`](d51d88700b/compiler/seminst.nim (L374))
in other parts of the compiler.
This commit is contained in:
metagn
2024-09-22 14:51:19 +03:00
committed by GitHub
parent d51d88700b
commit a1777200c1
3 changed files with 10 additions and 3 deletions

View File

@@ -50,8 +50,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
if typExpr.typ.kind == tyFromExpr:
typExpr.typ.flags.incl tfNonConstExpr

View File

@@ -1866,8 +1866,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
@@ -1884,8 +1884,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

View File

@@ -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()