From ecc7e3d41dc9acbeca61cd36719490b9eb4350a0 Mon Sep 17 00:00:00 2001 From: Alexander Kernozhitsky Date: Sat, 6 Jul 2024 22:50:46 +0200 Subject: [PATCH] fixes #23790; roll back instCounter properly in case of exceptions (#23802) fixes #23790 (cherry picked from commit 841d30a213720813130c410a15bee79dd00d5ccf) --- compiler/pragmas.nim | 2 +- compiler/seminst.nim | 4 ++-- tests/generics/t23790.nim | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 tests/generics/t23790.nim diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 449b6720fe..d64e6200fd 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -862,6 +862,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) @@ -871,7 +872,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 f779d38006..6b85986411 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -339,7 +339,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, # 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 @@ -416,7 +417,6 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, 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 0000000000..9ac0df6a10 --- /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)