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