| |
 | Posted by Steven Schveighoffer in reply to Paul Backus | Permalink Reply |
|
Steven Schveighoffer 
Posted in reply to Paul Backus
| On 6/17/21 12:21 PM, Paul Backus wrote:
> On Thursday, 17 June 2021 at 14:30:58 UTC, Steven Schveighoffer wrote:
>> On 6/16/21 9:07 PM, Paul Backus wrote:
>>>
>>> It's impossible to guarantee, at the language level, that @safe code can never require manual review. The programmer is allowed to use any and all knowledge at their disposal to verify the memory safety of @trusted (or in your proposal, @system-block) code, including knowledge about @safe code.
>>
>> The goal is to guarantee that *as long as* your @trusted functions and blocks have a @safe interface, then @safe code does not need to be checked. When I say "not require review" I mean "I have checked all the @trusted code, and it has a sound @safe interface, so all @safe code that may call it have no need for review." We will never have a marking that is language-guaranteed to not require review.
>>
>> To put it another way, as long as you aren't using @trusted escapes that leak implementation details, your @safe code shouldn't need a review. The problem is that trusted lambdas are not only the norm, it's actually required, due to template inference.
>>
>> Right now, a @safe function can only be "assumed safe" as long as there are no @trusted blocks in it. Once there is one trusted block, then you have to review the whole function. The same thing goes for data invariants (though that spreads to the whole module instead).
>>
>> Not having to review code for memory safety is supposed to be the major point of @safe.
>
> Consider the following example:
>
> ```d
> size_t favoriteNumber() @safe { return 42; }
>
> int favoriteElement(ref int[50] array) @trusted
> {
> // This is memory safe because we know favoriteNumber returns 42
> return array.ptr[favoriteNumber()];
> }
> ```
>
> `favoriteElement` has a safe interface. There is no argument you can pass to it from `@safe` code that can possibly result in memory corruption.
>
> However, if you change `favoriteNumber` to return something different (for example, 69), this may no longer be the case. So changes to `favoriteNumber`--a `@safe` function with no `@trusted` escapes--must still be manually reviewed to ensure that memory safety is maintained.
But that's a different kind of problem. If favoriteNumber is allowed to return anything above 49, then favoriteElement is invalid.
If favoriteNumber is *required* by spec to return 42, then it needs to be reviewed to ensure that it does that. And then the @safe function does not need to be reviewed for *memory* problems, just that it's written to spec.
>
> There is no language change you can make (short of removing `@trusted` entirely) that will prevent this situation from arising.
Sure, code reviews on @safe code still need to happen to ensure they are correct. But code reviews for *memory safety errors* which are *really hard* to do right, should not be required.
It's similar to unit-tests. Instead of testing the whole project at once, you test one thing, and if all the little things are correct, the combination of things is valid.
-Steve
|