Skip to content

Commit

Permalink
fixes #21245; warn about destructors that can raise (#21726)
Browse files Browse the repository at this point in the history
* fixes #21245; warn about destructors that can raise

* doc update

* progress

* typo
  • Loading branch information
Araq authored Apr 26, 2023
1 parent 8f79a12 commit 220b450
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 7 deletions.
11 changes: 8 additions & 3 deletions changelogs/changelog_2_0_0.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
for 64-bit integer types (`int64` and `uint64`) by default. As this affects
JS code generation, code using these types to interface with the JS backend
may need to be updated. Note that `int` and `uint` are not affected.

For compatibility with [platforms that do not support BigInt](https://caniuse.com/bigint)
and in the case of potential bugs with the new implementation, the
old behavior is currently still supported with the command line option
Expand All @@ -195,7 +195,7 @@
iterator iter(): int =
yield 123
proc takesProc[T: proc](x: T) = discard
proc takesIter[T: iterator](x: T) = discard
Expand All @@ -221,10 +221,15 @@

- Signed integer literals in `set` literals now default to a range type of
`0..255` instead of `0..65535` (the maximum size of sets).

- Case statements with else branches put before elif/of branches in macros
are rejected with "invalid order of case branches".

- Destructors now default to `.raises: []` (i.e. destructors must not raise
unlisted exceptions) and explicitly raising destructors are implementation
defined behavior.


## Standard library additions and changes

[//]: # "Changes:"
Expand Down
3 changes: 2 additions & 1 deletion compiler/sempass2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1499,7 +1499,8 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
let p = s.ast[pragmasPos]
let raisesSpec = effectSpec(p, wRaises)
if not isNil(raisesSpec):
checkRaisesSpec(g, false, raisesSpec, t.exc, "can raise an unlisted exception: ",
let useWarning = s.name.s == "=destroy"
checkRaisesSpec(g, useWarning, raisesSpec, t.exc, "can raise an unlisted exception: ",
hints=on, subtypeRelation, hintsArg=s.ast[0])
# after the check, use the formal spec:
effects[exceptionEffects] = raisesSpec
Expand Down
5 changes: 5 additions & 0 deletions compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,11 @@ proc semOverride(c: PContext, s: PSym, n: PNode) =
case name
of "=destroy":
bindTypeHook(c, s, n, attachedDestructor)
if s.ast != nil:
if s.ast[pragmasPos].kind == nkEmpty:
s.ast[pragmasPos] = newNodeI(nkPragma, s.info)
s.ast[pragmasPos].add newTree(nkExprColonExpr,
newIdentNode(c.cache.getIdent("raises"), s.info), newNodeI(nkBracket, s.info))
of "deepcopy", "=deepcopy":
if s.typ.len == 2 and
s.typ[1].skipTypes(abstractInst).kind in {tyRef, tyPtr} and
Expand Down
14 changes: 11 additions & 3 deletions doc/destructors.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ Nim Destructors and Move Semantics
About this document
===================

This document describes the upcoming Nim runtime which does
This document describes the ARC/ORC Nim runtime which does
not use classical GC algorithms anymore but is based on destructors and
move semantics. The new runtime's advantages are that Nim programs become
move semantics. The advantages are that Nim programs become
oblivious to the involved heap sizes and programs are easier to write to make
effective use of multi-core machines. As a nice bonus, files and sockets and
the like will not require manual `close` calls anymore.
the like can be written not to require manual `close` calls anymore.

This document aims to be a precise specification about how
move semantics and destructors work in Nim.
Expand Down Expand Up @@ -132,6 +132,14 @@ The general pattern in `=destroy` looks like:
freeResource(x.field)
```

A `=destroy` is implicitly annotated with `.raises: []`; a destructor
should not raise exceptions. For backwards compatibility the compiler
produces a warning for a `=destroy` that does raise.

A `=destroy` can explicitly list the exceptions it can raise, if any,
but this of little utility as a raising destructor is implementation defined
behavior. Later versions of the language specification might cover this case precisely.


`=sink` hook
------------
Expand Down

0 comments on commit 220b450

Please sign in to comment.