Tell us your DIP1000 woes

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Wed Aug 28 14:57:15 UTC 2024


On 29/08/2024 2:48 AM, Paul Backus wrote:
> On Sunday, 25 August 2024 at 13:10:22 UTC, Mike Parker wrote:
>> Second, we'd like to get a number of examples of problems people have 
>> had with using DIP1000 that haven't shown up in Bugzilla. Walter wants 
>> to be as certain as he can whether such issues are fixable or if the 
>> design is fundamentally flawed.
> 
> Here's an issue that stems from a fundamental shortcoming of DIP1000's 
> design: you can't write a `@safe` `swap` function.
> 
> Consider the following example:
> 
>      @safe void swap(ref /* ??? */ int* a, ref return scope int* b);
> 
>      @safe unittest
>      {
>          int local;
>          static int global;
> 
>          // Ensure both pointers have identical lexical scopes
>          static struct Pair { int* a, b; }
> 
>          auto p1 = Pair(&local, &local);
>          auto p2 = Pair(&global, &global);
>          auto p3 = Pair(&local, &global);
>          auto p4 = Pair(&global, &local);
> 
>          swap(p1.a, p1.b);
>          swap(p2.a, p2.b);
> 
>          static assert(!__traits(compiles, swap(p3.a, p3.b)));
>          static assert(!__traits(compiles, swap(p4.a, p4.b)));
>      }
> 
> A correct, `@safe` function signature for `swap` should be able to pass 
> this unit test. However, under the DIP1000 system, there is no possible 
> combination of attributes for the parameter `a` that will not cause one 
> of the test cases to fail.
> 
> - `ref int* a` causes `swap(p1.a, p1.b)` to fail.
> - Both `ref scope int* a` and `ref return scope int* a` cause 
> `swap(p3.a, p3.b)` to compile when it shouldn't.

This is a good example of what I mean by multiple outputs are not supported.

Both parameters are outputs, not just the first one.

```
onlineapp.d(9): Error: scope variable `temp` assigned to `ref` variable 
`a` with longer lifetime
onlineapp.d(25): Error: scope variable `p1` assigned to non-scope 
parameter `a` calling `swap`
onlineapp.d(8):        which is not `scope` because of `b = a`
```

```d
@safe void swap(ref /* ??? */ int* a, ref return scope int* b) {
     int* temp = b;
     b = a;
     a = temp;
}

  @safe unittest
  {
      int local;
      static int global;

      // Ensure both pointers have identical lexical scopes
      static struct Pair { int* a, b; }

      auto p1 = Pair(&local, &local);
      auto p2 = Pair(&global, &global);
      auto p3 = Pair(&local, &global);
      auto p4 = Pair(&global, &local);

      swap(p1.a, p1.b);
      swap(p2.a, p2.b);

      static assert(!__traits(compiles, swap(p3.a, p3.b)));
      static assert(!__traits(compiles, swap(p4.a, p4.b)));
  }
```

The line ``b = a;`` should also be erroring, but because ``b`` isn't 
seen as an error, its accepted.


More information about the Digitalmars-d mailing list