@system blocks and safer @trusted (ST) functions
julian.fondren at gmail.com
Sun Jul 25 06:13:41 UTC 2021
On Sunday, 25 July 2021 at 05:05:44 UTC, Bruce Carneal wrote:
> The presence of one or more @system blocks would enable @safe
> checking elsewhere in the enclosing @trusted function.
This has an unfortunate result: if in maintenance you edit a
@trusted function to remove its @system blocks, it'll quietly no
longer be checked as @safe.
Of the current behavior, Walter's said that he doesn't want
@trusted blocks because they should be discouraged in @safe code.
With this change, we'll have exactly what he doesn't want with
different names: s/@trusted/@system/, s/@safe/@trusted/, and the
exact same behavior: @system blocks are just what @trusted blocks
would've been, and @trusted code with @system blocks in it is
just @safe code with a different name.
Instead of people accepting that @safe "isn't really @safe" in
the presence of @trusted blocks, and that the whole body of the
function has to be audited, with this change we'll have
s/@safe/@trusted/ blocks that aren't really @safe in the presence
of @system blocks, and that the whole body of the function has to
be audited. The "you have to audit this" signifier is the same,
an internal lower-protection block, and all that's gained is that
the function attribute's spelled differently. Is this really
One way to avoid the "unfortunate result" above is to permit
@trusted blocks in @safe code. Which results in Rust equivalent
functionality: @safe code is checked as @safe, @safe code with
internal @trusted blocks is still checked as @safe but people
know to audit it, and @system code isn't checked as @safe.
People like Rust's unsafe system, the current @trusted-lambda
abuse is a simulation of unsafe, Phobos already uses @trusted
lambdas in exactly the same way as unsafe blocks are used in
Rust, and this proposed behavior is 99.9% identical to unsafe
except it has this bonus "you can silently, accidentally remove
@safe checks from your code now" feature.
I appreciate that there's a vision also to
@safe/@trusted/@system, but it doesn't seem to have stuck, with
Phobos having more than twice as many @trusted lambdas than
phobos$ grep -rP '\W\(\) @trusted' --include '*.d'|wc -l
phobos$ grep -rP '\w\(\) @trusted' --include '*.d'|wc -l
I don't think that Rust has everything right. And, I don't pay
attention to the Rust community at all; maybe they've a lot of
gripes about how they're using unsafe blocks and unsafe
functions. But, just look at all those @trusted lambadas. If you
run the first command without the "|wc -l" on the end you'll see
they're almost all single statements or expressions.
Adding a @trusted block to @safe code doesn't discard the
@safe/@trusted/@system vision, it just lets people follow the
unsafe vision that they're already following without so many
complaints about how ugly the workaround is, when D's good looks
are one of its advantages over Rust.
This proposal also doesn't immediately discard the
@safe/@trusted/@system vision, but it introduces a minor footgun
because of a subtle conflict with that vision, and as people
adopt it they'll also want another --preview switch to deal with
the footgun, and that switch will break all current @trusted code
that's currently assuming no @safe checks, and so there will a
long deprecation cycle...
@trusted blocks win this. Or rather--not to be rude--but if you
came out and said that this DIP was just some triangulation to
get people to accept @trusted blocks, I would say: "good job! It
got me thinking!" If not, I'm sorry.
More information about the Digitalmars-d