diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 9c84b721ad..f1e2e69cbe 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1208,6 +1208,7 @@ type enforcedGcSafety, enforceNoSideEffects: bool oldExc, oldTags, oldForbids: int exc, tags, forbids: PNode + excSource, tagsSource, forbidsSource: PNode proc createBlockContext(tracked: PEffects): PragmaBlockContext = var oldForbidsLen = 0 @@ -1230,17 +1231,18 @@ proc unapplyBlockContext(tracked: PEffects; bc: PragmaBlockContext) = # anything about 'raises' in the 'cast' at all. Same applies for 'tags'. setLen(tracked.exc.sons, bc.oldExc) for e in bc.exc: - addRaiseEffect(tracked, e, e) + addRaiseEffect(tracked, e, if bc.excSource != nil: bc.excSource else: e) if bc.tags != nil: setLen(tracked.tags.sons, bc.oldTags) for t in bc.tags: - addTag(tracked, t, t) + addTag(tracked, t, if bc.tagsSource != nil: bc.tagsSource else: t) if bc.forbids != nil: setLen(tracked.forbids.sons, bc.oldForbids) for t in bc.forbids: - addNotTag(tracked, t, t) + addNotTag(tracked, t, if bc.forbidsSource != nil: bc.forbidsSource else: t) -proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) = +proc castBlock(tracked: PEffects, castPragma: PNode, bc: var PragmaBlockContext) = + let pragma = castPragma[1] case whichPragma(pragma) of wGcSafe: bc.enforcedGcSafety = true @@ -1253,6 +1255,7 @@ proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) = else: bc.tags = newNodeI(nkArgList, pragma.info) bc.tags.add n + bc.tagsSource = castPragma of wForbids: let n = pragma[1] if n.kind in {nkCurly, nkBracket}: @@ -1260,6 +1263,7 @@ proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) = else: bc.forbids = newNodeI(nkArgList, pragma.info) bc.forbids.add n + bc.forbidsSource = castPragma of wRaises: let n = pragma[1] if n.kind in {nkCurly, nkBracket}: @@ -1267,6 +1271,7 @@ proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) = else: bc.exc = newNodeI(nkArgList, pragma.info) bc.exc.add n + bc.excSource = castPragma of wUncheckedAssign: discard "handled in sempass1" else: @@ -1520,7 +1525,7 @@ proc track(tracked: PEffects, n: PNode) = of wNoSideEffect: bc.enforceNoSideEffects = true of wCast: - castBlock(tracked, pragmaList[i][1], bc) + castBlock(tracked, pragmaList[i], bc) else: discard applyBlockContext(tracked, bc) diff --git a/tests/effects/tcast_effect_violation.nim b/tests/effects/tcast_effect_violation.nim new file mode 100644 index 0000000000..fe7f93cc4a --- /dev/null +++ b/tests/effects/tcast_effect_violation.nim @@ -0,0 +1,8 @@ +discard """ + errormsg: "cast(raises: ValueError) can raise an unlisted exception: ValueError" + line: 7 +""" + +proc fff() {.raises: [].} = + {.cast(raises: ValueError).}: + discard \ No newline at end of file