why is ifThrown un at safe?

Bastiaan Veelo Bastiaan at Veelo.net
Fri Mar 15 19:24:17 UTC 2019


On Friday, 15 March 2019 at 19:19:41 UTC, H. S. Teoh wrote:
> On Fri, Mar 15, 2019 at 06:46:25PM +0000, bauss via 
> Digitalmars-d-learn wrote:
>> On Friday, 15 March 2019 at 18:04:05 UTC, Bastiaan Veelo wrote:
>> > In the code below (https://run.dlang.io/is/d0oTNi), ifThrown 
>> > is inferred as un at safe. If instead I write the 
>> > implementation of ifThrown out (after res2) then it is 
>> > @safe. As far as I can see, there is no real difference. So 
>> > why doesn't ifThrown work in this case, and can it be made 
>> > to work?
> [...]
>> Because the handlers may be unsafe.
>> 
>> There is no safe overload of ifThrown.
>> 
>> However you can work around this using @trusted.
>
> I wasn't satisfied with this answer, because in theory the 
> @safe-ness of ifThrown ought to be inferred from the @safe-ness 
> of its arguments, and ifThrown itself shouldn't do anything 
> un- at safe. So I investigated a little further, and found that 
> the problem lies in how ifThrown is declared:
>
> 	CommonType!(T1, T2) ifThrown(T1, T2)(lazy scope T1 expression, 
> scope T2 delegate(Exception) errorHandler) { ... }
>
> The problem is that the second parameter is declared to be a 
> delegate with no further qualifications, which means it 
> defaults to @system. Therefore, even if `expression` and 
> `errorHandler` are both @safe, the compiler will still infer 
> the call to `errorHandler` as @system, and therefore ifThrown 
> will also be inferred as @system.
>
> The obvious fix of adding @safe to the second parameter won't 
> work, because that would preclude ifThrown from being used with 
> @system error handlers.
>
> So it appears to me that in order to make this work as it 
> should, we need to templatize not only on the return type of 
> the delegate, but on the delegate type itself.  Perhaps 
> something along the lines of:
>
> 	CommonType!(T1, ErrorHandler) ifThrown(T1, T2)(lazy scope T1 
> expression, scope ErrorHandler errorHandler)
> 		if (... && is(ErrorHandler == delegate) &&
> 			is(ReturnType!ErrorHandler : T1))
> 	{
> 		...
> 	}
>
> This should probably be filed as an enhancement request in 
> bugzilla.
>
>
> T

Excellent, thank you. Will do the filing and maybe experiment a 
bit.

Bastiaan.


More information about the Digitalmars-d-learn mailing list