A finally body should not be allowed to return
A finally block should not be allowed to eat exceptions. That means that it shouldn't be allowed to return, break, or continue.
Note that we do exploit this in the kernel in https://github.com/toitware/toit
I just did a quick survey to see how extensively this feature is used, and it is a lot less than I recall. In https://github.com/toitlang/toit we exploit this to implement catch:
https://github.com/toitlang/toit/blob/d8749a7156684522d4167db74c2b6c94767d0f9f/lib/core/exceptions.toit#L131
and we use it in a couple of other places:
https://github.com/toitlang/toit/blob/d8749a7156684522d4167db74c2b6c94767d0f9f/lib/expect.toit#L97
https://github.com/toitlang/toit/blob/d8749a7156684522d4167db74c2b6c94767d0f9f/lib/rpc/broker.toit#L105
In https://github.com/toitware/toit we only use it in a test: https://github.com/toitware/toit/blob/b4402bc0336f6a7e4e7c0764698b209a4e21ff9f/tools/wilson/tests/pubsub_test.toit#L65
I can not access the linked repositories to see how the VM (and especially the kernel!) is actually implemented.
Any insights?
@dumblob for the VM and its implementation have a look here: https://github.com/toitlang/toit
The toitware reference just links to a test that changes an exception in a finally to a return.
That code is now deprecated. All the interesting code has been moved to the toitlang repository.
Here is the code:
test_pubsub_close_listen_ sub/pubsub.TemporarySubscription started/monitor.Latch closed/monitor.Latch -> int:
received := 0
started.set null
try:
sub.listen: | msg/pubsub.Message |
received++
finally: | is_exception exception |
expect is_exception
expect_equals pubsub.ERR_SUBSCRIPTION_CLOSED exception.value
closed.set null
return received