why is ifThrown un at safe?

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Mar 15 19:19:41 UTC 2019


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

-- 
I am not young enough to know everything. -- Oscar Wilde


More information about the Digitalmars-d-learn mailing list