summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAlexander Kernozhitsky <sh200105@mail.ru>2024-07-06 22:50:46 +0200
committerGitHub <noreply@github.com>2024-07-06 22:50:46 +0200
commit841d30a213720813130c410a15bee79dd00d5ccf (patch)
tree3726a905ac6c7ff8e8c9b9e1163dd9c541516c0b
parent05df263b84de9008266b3d53e2c28b009890ca61 (diff)
downloadNim-841d30a213720813130c410a15bee79dd00d5ccf.tar.gz
fixes #23790; roll back instCounter properly in case of exceptions (#23802)
fixes #23790
-rw-r--r--compiler/pragmas.nim2
-rw-r--r--compiler/seminst.nim4
-rw-r--r--tests/generics/t23790.nim14
3 files changed, 17 insertions, 3 deletions
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index c724aa025..972f3def9 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -882,6 +882,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
 
     # number of pragmas increase/decrease with user pragma expansion
     inc c.instCounter
+    defer: dec c.instCounter
     if c.instCounter > 100:
       globalError(c.config, it.info, "recursive dependency: " & userPragma.name.s)
 
@@ -891,7 +892,6 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
     pragma(c, sym, userPragma.ast, validPragmas, isStatement)
     n.sons[i..i] = userPragma.ast.sons # expand user pragma with its content
     i.inc(userPragma.ast.len - 1) # inc by -1 is ok, user pragmas was empty
-    dec c.instCounter
   else:
     let k = whichKeyword(ident)
     if k in validPragmas:
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 37f081dbc..84ae9a26f 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -345,7 +345,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TypeMapping,
   # generates an instantiated proc
   if c.instCounter > 50:
     globalError(c.config, info, "generic instantiation too nested")
-  inc(c.instCounter)
+  inc c.instCounter
+  defer: dec c.instCounter
   # 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
@@ -439,7 +440,6 @@ proc generateInstance(c: PContext, fn: PSym, pt: TypeMapping,
   popOwner(c)
   c.currentScope = oldScope
   discard c.friendModules.pop()
-  dec(c.instCounter)
   c.matchedConcept = oldMatchedConcept
   if result.kind == skMethod: finishMethod(c, result)
 
diff --git a/tests/generics/t23790.nim b/tests/generics/t23790.nim
new file mode 100644
index 000000000..9ac0df6a1
--- /dev/null
+++ b/tests/generics/t23790.nim
@@ -0,0 +1,14 @@
+# bug #23790
+
+discard compiles($default(seq[seq[ref int]]))
+discard compiles($default(seq[seq[ref uint]]))
+discard compiles($default(seq[seq[ref int8]]))
+discard compiles($default(seq[seq[ref uint8]]))
+discard compiles($default(seq[seq[ref int16]]))
+discard compiles($default(seq[seq[ref uint16]]))
+discard compiles($default(seq[seq[ref int32]]))
+discard compiles($default(seq[seq[ref uint32]]))
+discard compiles($default(seq[seq[ref int64]]))
+discard compiles($default(seq[seq[ref uint64]]))
+proc s(_: int | string) = discard
+s(0)