Discussion Thread: DIP 1035-- at system Variables--Community Review Round 1

Dennis dkorpel at gmail.com
Wed Jun 17 15:58:01 UTC 2020


On Wednesday, 17 June 2020 at 14:27:17 UTC, Andrei Alexandrescu 
wrote:
> The crux of the matter is that forgetting to add @system to 
> that variable makes @safe code do unsafe things with no 
> diagnostic for the compiler. That's a problem with the safety 
> system, regardless of the adoption of this DIP. We can't say 
> "@safe D code is safe, except of course if you forget to insert 
> @system on key variables, in which case it won't be with no 
> warning.

Forgetting a @system annotation does not allow you to break @safe 
with DIP 1035. Let's take this example:
```
int* x = cast(int*) 0x0F48;
void main() @safe {
     *x = 3;
}
```
This compiles today. With DIP 1035, x would be _inferred_ 
@system. Marking it @safe would be an error, marking it @system 
would be redundant. If the initializer for x were `null`, it 
would be inferred @safe, but that's okay. Variable `x` won't 
break a @safe main without bad @trusted or exploiting @safe bugs.

> Coming from the other side: assume all bugs in @safe mentioned 
> in the DIP are fixed (as they should anyway) - the question is 
> what would be the usefulness of it then.

This DIP *is* a fix for those bugs, for which there is no obvious 
solution. The idea is to have a consistent design, instead of 
having a list of small enhancements and hole plugs that are 
half-baked. Notice the trend here:
- https://issues.dlang.org/show_bug.cgi?id=18554 (does not solve 
union/array casts, undone by 15371, spawns your issue)
- https://issues.dlang.org/show_bug.cgi?id=19646 (incomplete 
solution, spawns 20347)
- https://issues.dlang.org/show_bug.cgi?id=19968 (incomplete 
solution, spawns 20148)

So let's say we fix those second round bugs like you suggest, 
which I will call 'bug fix':

```
import std.bigint;
BigInt x = BigInt(10);

void main() @safe {
     x *= 2;
     // now: compiles, no problem
     // DIP 1035: compiles iff BigInt constructor is @safe, which 
it is
     // 'bug fix': error: x cannot be assumed to have a safe value
}
```

```
import std.experimental.checkedint;
void foo(int[] x) @safe {
     auto data = cast(Checked!int[]) x;
     // now: compiles, no problem
     // DIP 1035: compiles, no problem
     // 'bug fix': error: Checked!int has private members that are 
implicitly set
}
```

Ideally, programmers now:
- add @trusted blocks, albeit redundant
- review their entire modules

Pessimistically, programmers:
- just leave things @system
- add @trusted on too large scopes
- make members needlessly public
- make their JSON serializer work on private fields with a custom 
UDA that signals trusted access, of which some people think it's 
bad @trusted and other's won't, furthering the discussion


More information about the Digitalmars-d mailing list