@trusted considered harmful
Jonathan M Davis
jmdavisProg at gmx.com
Sat Jul 28 13:22:13 PDT 2012
On Saturday, July 28, 2012 21:53:25 Jesse Phillips wrote:
> For your example of the proposal, when does the compiler mark
> save() as @system over @trusted?
>
> @property auto save()
> {
> import std.conv;
> alias typeof((*_range).save) S;
> static assert(isForwardRange!S, S.stringof ~ " is not a
> forward range.");
>
> @trusted
> {
> auto mem = new void[S.sizeof];`
> emplace!S(mem, cast(S)(*_range).save);`
> return RefRange!S(cast(S*)mem.ptr);
> }
> }
>
> You make a call to _range.save in the @trusted block. So why
> isn't the function marked @trusted?
I screwed up my changes there. I made them in a bit of a hurry. And actually,
in this particular case, using an @trusted block is still a bit entertaining,
since the save call is in middle of an expression which is doing @system stuff.
But the principle is the same regardless. If you need to do @system stuff in a
function where you know that the @system stuff that you're doing is @safe but
the function is also calling templated stuff which may or may not be @safe, you
can't mark the whole function as @trusted, or you'll be marking code which is
potentially truly unsafe as @trusted. With an @trusted block, you can mark
sections of the code @trusted and let the rest be properly inferred based on
what the the template was instantiated with.
In this particular case, it could still drastically reduce save, because only
the line with @save would need to be duplicated. So, it could become something
more like
@property auto save()
{
import std.conv;
alias typeof((*_range).save) S;
static assert(isForwardRange!S, S.stringof ~ " is not a forward range.");
@trusted {auto mem = new void[S.sizeof];}
static if(isSafelyCallable!((){(*_range).save;}))
{
@trusted { emplace!S(mem, cast(S)(*_range).save); }
}
else
{
emplace!S(mem, cast(S)(*_range).save);
}
@trusted {return RefRange!S(cast(S*)mem.ptr);}
}
It's still a bit ugly, but it's far better than what we can currently do. As
it stands, you can't even put the emplace call in a separate function and mark
it @trusted or @system depending on save, because the only way to mark the
rest of the function as @trusted is to mark the whole thing as @trusted. You'd
have to specifically put _everything else_ in its own function _and_ emplace in
its own function (one @trusted, one @system) and have the outer function call
both. It's a mess. Being able to mark statements as @trusted rather than just
entire functons would be _huge_.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list