RFC: Change what assert does on error

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Tue Jul 8 07:47:30 UTC 2025


On 08/07/2025 9:44 AM, Dukc wrote:
> On Sunday, 6 July 2025 at 23:53:54 UTC, Timon Gehr wrote:
>> The insane part is that we are in fact allowed to throw in `@safe 
>> nothrow` functions without any `@trusted` shenanigans. Such code 
>> should not be allowed to break any compiler assumptions.
> 
> Technically, memory safety is supposed to be guaranteed by not letting 
> you _catch_ unrecoverable throwables in `@safe`. When you do catch them, 
> you're supposed to verify that any code you have in the try block 
> (including called functions) doesn't rely on destructors or similar for 
> memory safety.
> 
> I understand this is problematic, because in practice pretty much all 
> code often is guarded by a top-level pokemon catcher, meaning 
> destructor-relying memory safety isn't going to fly anywhere. I guess we 
> should just learn to not do that, or else give up on all `nothrow` 
> optimisations. I tend to agree with Dennis that a switch is not the way 
> to go as that might cause incompatibilities when different libraries 
> expect different settings.

Currently threads in D do not have this guarantee.

More often than not, you'll find that people use threads in D without 
joining them or handling Error's. People don't think about this stuff, 
as the default behavior should be good enough.

> In idea: What if we retained the `nothrow` optimisations, but changed 
> the finally blocks so they are never executed for non-`Exception` 
> `Throwable`s unless there is a catch block for one? Still skipping 
> destructors, but at least the rules between `try x; finally y;`, 
> `scope(exit)` and destructors would stay consistent, and `nothrow` 
> wouldn't be silently changing behaviour since the assert failures would 
> be skipping the finalisers regardless. `scope(failure)` would also catch 
> only `Exception`s.

Long story short there is no nothrow specific optimizations taking place.

The compiler does a simplification rewrite from a finally statement over 
to sequence if it thinks that it isn't needed.

The unwinder has no knowledge of Error vs Exception, let alone a 
differentiation when running the cleanup handler. Nor does the cleanup 
handler know what the exception is. That would require converting 
finally statements to a catch all which will have implications.



More information about the Digitalmars-d mailing list