@trusted attribute should be replaced with @trusted blocks
H. S. Teoh
hsteoh at quickfur.ath.cx
Thu Jan 16 18:42:35 UTC 2020
On Thu, Jan 16, 2020 at 06:10:16PM +0000, Joseph Rushton Wakeling via Digitalmars-d wrote:
> On Thursday, 16 January 2020 at 18:05:25 UTC, H. S. Teoh wrote:
> > This is why I proposed that @trusted functions should *still* be
> > subject to @safe checks, only with the exception that they're
> > allowed to have embedded @system blocks where such checks are
> > relaxed (and these @system blocks are only allowed inside @trusted
> > functions). So the @trusted is a visual marker that it needs to be
> > manually verified, but you still have the benefit of the compiler
> > automatically verifying most of its body except for the (hopefully
> > small) @system block where such checks are temporarily suspended.
> Hang on, have 3 of us all made the same proposal? (OK, I just
> reiterated what I understood to be Steven's proposal, but ...:-)
> I'll leave it to others to decide if we're great minds or fools or
> anything in between ;-)
Fools or not, the important thing is whether we can convince Walter to
agree with this...
This is far from the first time such an idea came up. I remember back
when Mihail Strashuns was actively contributing to Phobos, we had this
discussion on Github where we agreed that we'd like to reduce the scope
of @trusted as much as possible, meaning, the unsafe parts of @trusted
should be as small as possible in order to minimize the surface area of
potential problems. This was before people came up with the idea of a
nested @trusted lambda. We both felt very uncomfortable that there were
some functions Phobos that were marked @trusted, but were so large that
it was impractical to review the entire function body for correctness.
Furthermore, since Phobos at the time was undergoing a rapid rate of
change, we were uncomfortable with the idea that any random PR might
touch some seemingly-innocuous part of a @trusted function and break its
safety, yet there would be no warning whatsoever from the autotester
because the compiler simply turned off all checks inside a @trusted
IIRC it was that discussion, which later led to other, further
discussions, that eventually resulted in the idea of using nested
@trusted lambdas inside functions. Of course, in the interim, we also
learned from Walter what his stance was: @trusted functions should sport
a safe API, i.e., even though by necessity it has to do uncheckable
things inside, its outward-facing API should be such that it's
impossible to break its safety without also breaking your own @safety.
I.e., taking `int` is OK because, presumably, @safe code will not
allow you to construct an `int` that has an illegal pointer or wrong
length; but taking `int*, size_t` is not OK, because the caller can just
pass the wrong length and you're screwed. Eventually, this restriction
was relaxed for nested @trusted lambdas, due to the API restriction
being too onerous and impractical in some cases.
Regardless of what the story was, the basic idea is the same: to shrink
the scope of unchecked code as much as possible, and to leverage the
compiler's @safe-ty checks as much as possible. Ideally, most of a
@trusted function's body should actually be @safe, and only a small part
@system -- where the compiler is unable to mechanically verify its
correctness. That way, if you make a mistake while editing a @trusted
function, most of the time the compiler will catch it. Only inside the
@system block (or whatever we decide to call the unchecked block), the
checks are suspended and you have to be extra careful when changing it.
Basically, we want all the help we can get from the compiler to minimize
human error, and we want to reduce the scope of human error to as narrow
a scope as possible (while acknowledging that we can never fully
eliminate it -- which is why we need @trusted in the first place).
Once bitten, twice cry...
More information about the Digitalmars-d