diff options
author | metagn <metagngn@gmail.com> | 2024-09-22 14:51:19 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-22 13:51:19 +0200 |
commit | a1777200c1a52b5a71d641309349618df2550b33 (patch) | |
tree | ef3b674e42820e87bef5ef4405a780f5ded775f1 | |
parent | d51d88700b2fb3bd228d5e8f7385e2e4a2e2880c (diff) | |
download | Nim-a1777200c1a52b5a71d641309349618df2550b33.tar.gz |
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`](https://github.com/nim-lang/Nim/blob/d51d88700b2fb3bd228d5e8f7385e2e4a2e2880c/compiler/seminst.nim#L374) in other parts of the compiler.
-rw-r--r-- | compiler/semmagic.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 4 | ||||
-rw-r--r-- | tests/vm/tgenericcompiletimeproc.nim | 7 |
3 files changed, 10 insertions, 3 deletions
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 360d23477..a12e933e7 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -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 diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 6302a4590..450b81dbf 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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 diff --git a/tests/vm/tgenericcompiletimeproc.nim b/tests/vm/tgenericcompiletimeproc.nim index cb4dbb2d8..08099ebbe 100644 --- a/tests/vm/tgenericcompiletimeproc.nim +++ b/tests/vm/tgenericcompiletimeproc.nim @@ -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() |