Attribute transference from callbacks?

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Sun Dec 15 09:15:07 UTC 2024


On 15/12/2024 10:08 PM, Zach Tollen wrote:
> On Sunday, 15 December 2024 at 07:04:54 UTC, Richard (Rikki) Andrew 
> Cattermole wrote:
>> ``nothrow`` is a very bad example to give here.
>>
>> In fact, it needs an entirely separate mechanism from the others.
>>
>> It isn't boolean, and has codegen changes associated with it.
> 
> That's fair. I don't know if delegates work with exception handlers in a 
> way that would permit this mechanism. Like, if a function is otherwise 
> `nothrow`, but is called with a delegate parameter which throws, can the 
> function be compiled to allow the throwing delegate to bypass the 
> function it is called within and have the delegate throw straight to the 
> calling function instead? Probably not, but I don't know enough about 
> how modern exception handlers are programmed to know for sure.

Its not just how exception handlers work, but I also have to consider 
how a sum type exception handling mechanism would work. There is plenty 
of desire for it, and I've got a proposal in ideas for one.

Either way, it has codegen implications.

>> Also in your example, the delegate could be marked as throwing and it 
>> would work today.
>>
>> ``nothrow`` is already scope aware.
> 
> Under the current system, the following is an error:
> ```d
> // Error: function `g` may throw but is marked as `nothrow`
> void g(void delegate() sink) nothrow {
>      sink();
> }
> ```
> Under the new system (apart from the mechanism and codegen issues you 
> raised), the above would be permitted... only if you called it with a 
> throwing delegate would it be classified as throwing, and at the call 
> site, but not in the function itself. This is much cleaner. I believe 
> that it is primarily within this context that the new attribute 
> `@noimply` would be occasionally useful, as a way to say that even if 
> you call the `nothrow` function with a *throwable* delegate, the call 
> can *still* be treated as `nothrow`, because `@noimply(throw)` 
> statically guarantees that any incoming throw will be neutralized.
> 
> I'm pretty sure the purpose of `@noimply` would only become apparent if 
> the new default were already adopted.

In your previous example you had the sink call wrapped in a try catch 
statement. That'll work.

```d
void f(void delegate() del) nothrow {
	try {
		del();
	} catch (Exception) {
	}
}
```



More information about the Digitalmars-d mailing list