fixes #25400; Naked raised causes wrong exception effect (#25422)

fixes #25400

infers `Exception` for Naked raised
This commit is contained in:
ringabout
2026-01-16 22:25:14 +08:00
committed by GitHub
parent efc3a7429b
commit 9a23ff36bd
3 changed files with 45 additions and 2 deletions

View File

@@ -84,6 +84,7 @@ type
gcUnsafe, isRecursive, isTopLevel, hasSideEffect, inEnforcedGcSafe: bool
isInnerProc: bool
inEnforcedNoSideEffects: bool
currentExceptType: PType
unknownRaises: seq[(PSym, TLineInfo)]
currOptions: TOptions
optionsStack: seq[(TOptions, TNoteKinds)]
@@ -577,11 +578,25 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
let b = n[i]
if b.kind == nkExceptBranch:
setLen(tracked.init, oldState)
# If this except branch catches exactly one type, record it so an
# empty `raise` inside the branch can be inferred as re-raising that
# specific exception type instead of the generic `Exception`.
var savedExcept: PType = tracked.currentExceptType
var inferredExcept: PType = nil
if b.len == 2:
if b[0].isInfixAs():
assert(b[0][1].kind == nkType)
inferredExcept = b[0][1].typ
else:
assert(b[0].kind == nkType)
inferredExcept = b[0].typ
tracked.currentExceptType = inferredExcept
for j in 0..<b.len - 1:
if b[j].isInfixAs(): # skips initialization checks
assert(b[j][2].kind == nkSym)
tracked.init.add b[j][2].sym.id
track(tracked, b[^1])
tracked.currentExceptType = savedExcept
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i], bsNone)
else:
@@ -1264,7 +1279,14 @@ proc track(tracked: PEffects, n: PNode) =
# A `raise` with no arguments means we're going to re-raise the exception
# being handled or, if outside of an `except` block, a `ReraiseDefect`.
# Here we add a `Exception` tag in order to cover both the cases.
addRaiseEffect(tracked, createRaise(tracked.graph, n), nil)
if tracked.currentExceptType != nil:
var en = newNode(nkType)
en.typ = tracked.currentExceptType
en.info = n.info
addRaiseEffect(tracked, en, nil)
createTypeBoundOps(tracked, tracked.currentExceptType, n.info)
else:
addRaiseEffect(tracked, createRaise(tracked.graph, n), nil)
of nkCallKinds:
trackCall(tracked, n)
of nkDotExpr:

View File

@@ -1,5 +1,5 @@
discard """
errormsg: "can raise an unlisted exception: Exception"
errormsg: "ValueError can raise an unlisted exception: ValueError"
line: 10
"""
{.push warningAsError[Effect]: on.}

View File

@@ -37,3 +37,24 @@ block:
let newAdder = makeAdder(0)
newAdder(5)
block:
proc g() = discard
proc f() {.raises: [IOError].} =
try:
g()
except IOError:
raise
f()
block:
proc g() = discard
proc f() {.raises: [IOError].} =
try:
g()
except IOError as e:
raise
f()