Skip to content

Commit cfa769f

Browse files
authored
fixes #22950; Poor error message on cast effect violation (#25839)
fixes #22950 This pull request improves the tracking and reporting of effect annotations (such as `raises`, `tags`, and `forbids`) in pragma blocks, particularly when using the `cast` pragma. It ensures that the source of these effect annotations is correctly preserved and referenced, which improves error reporting and effect analysis. Additionally, a new test was added to check for violations when using `cast` with effect annotations. Effect annotation source tracking and propagation: * Added new fields (`excSource`, `tagsSource`, `forbidsSource`) to the `PragmaBlockContext` type to store the original source node for each effect annotation. * Updated `castBlock` to set these new source fields when processing `raises`, `tags`, and `forbids` pragmas, ensuring the source node is preserved for later error reporting. * Modified `unapplyBlockContext` to use the stored source node (if available) when calling `addRaiseEffect`, `addTag`, and `addNotTag`, improving the accuracy of effect tracking and diagnostics. Pragma handling improvements: * Changed the call to `castBlock` in the main pragma processing loop to pass the entire pragma node, enabling access to the original source for effect annotations. Testing: * Added a new test (`tests/effects/tcast_effect_violation.nim`) to verify that using `cast(raises: ValueError)` inside a procedure with `.raises: [].` correctly triggers an error message about an unlisted exception.
1 parent 8771451 commit cfa769f

2 files changed

Lines changed: 18 additions & 5 deletions

File tree

compiler/sempass2.nim

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,7 @@ type
12081208
enforcedGcSafety, enforceNoSideEffects: bool
12091209
oldExc, oldTags, oldForbids: int
12101210
exc, tags, forbids: PNode
1211+
excSource, tagsSource, forbidsSource: PNode
12111212

12121213
proc createBlockContext(tracked: PEffects): PragmaBlockContext =
12131214
var oldForbidsLen = 0
@@ -1230,17 +1231,18 @@ proc unapplyBlockContext(tracked: PEffects; bc: PragmaBlockContext) =
12301231
# anything about 'raises' in the 'cast' at all. Same applies for 'tags'.
12311232
setLen(tracked.exc.sons, bc.oldExc)
12321233
for e in bc.exc:
1233-
addRaiseEffect(tracked, e, e)
1234+
addRaiseEffect(tracked, e, if bc.excSource != nil: bc.excSource else: e)
12341235
if bc.tags != nil:
12351236
setLen(tracked.tags.sons, bc.oldTags)
12361237
for t in bc.tags:
1237-
addTag(tracked, t, t)
1238+
addTag(tracked, t, if bc.tagsSource != nil: bc.tagsSource else: t)
12381239
if bc.forbids != nil:
12391240
setLen(tracked.forbids.sons, bc.oldForbids)
12401241
for t in bc.forbids:
1241-
addNotTag(tracked, t, t)
1242+
addNotTag(tracked, t, if bc.forbidsSource != nil: bc.forbidsSource else: t)
12421243

1243-
proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) =
1244+
proc castBlock(tracked: PEffects, castPragma: PNode, bc: var PragmaBlockContext) =
1245+
let pragma = castPragma[1]
12441246
case whichPragma(pragma)
12451247
of wGcSafe:
12461248
bc.enforcedGcSafety = true
@@ -1253,20 +1255,23 @@ proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) =
12531255
else:
12541256
bc.tags = newNodeI(nkArgList, pragma.info)
12551257
bc.tags.add n
1258+
bc.tagsSource = castPragma
12561259
of wForbids:
12571260
let n = pragma[1]
12581261
if n.kind in {nkCurly, nkBracket}:
12591262
bc.forbids = n
12601263
else:
12611264
bc.forbids = newNodeI(nkArgList, pragma.info)
12621265
bc.forbids.add n
1266+
bc.forbidsSource = castPragma
12631267
of wRaises:
12641268
let n = pragma[1]
12651269
if n.kind in {nkCurly, nkBracket}:
12661270
bc.exc = n
12671271
else:
12681272
bc.exc = newNodeI(nkArgList, pragma.info)
12691273
bc.exc.add n
1274+
bc.excSource = castPragma
12701275
of wUncheckedAssign:
12711276
discard "handled in sempass1"
12721277
else:
@@ -1520,7 +1525,7 @@ proc track(tracked: PEffects, n: PNode) =
15201525
of wNoSideEffect:
15211526
bc.enforceNoSideEffects = true
15221527
of wCast:
1523-
castBlock(tracked, pragmaList[i][1], bc)
1528+
castBlock(tracked, pragmaList[i], bc)
15241529
else:
15251530
discard
15261531
applyBlockContext(tracked, bc)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
discard """
2+
errormsg: "cast(raises: ValueError) can raise an unlisted exception: ValueError"
3+
line: 7
4+
"""
5+
6+
proc fff() {.raises: [].} =
7+
{.cast(raises: ValueError).}:
8+
discard

0 commit comments

Comments
 (0)