DIP1000: The return of 'Extend Return Scope Semantics'
ZachAttack!
reachzach at gmail.com
Sun Jun 13 16:48:04 UTC 2021
On Sunday, 13 June 2021 at 11:59:49 UTC, ZachAttack! wrote:
> Challenge: Provide a code example illustrating how the existing
> variant of `move` compiles when it shouldn't—or errors when it
> shouldn't—while the alternative form works correctly.
>
> I actually couldn't do it... it may be harder than we suspect.
Ok I found out how to do it. It requires the arguments being
passed to `move` to be qualified with `scope`:
```d
void move1(ref int* source, scope ref int* target) @safe {
target = source;
}
void move2(scope ref int* target, return ref int* source) @safe {
target = source;
}
void main() @safe {
scope int* src;
scope int* tgt;
move2(tgt, src); // pass
move1(src, tgt); // Error: scope variable `src` assigned to
non-scope parameter
() @trusted{ move1(src, tgt); }(); // passes correctly
}
```
The `source` parameter in `move1` above cannot be marked `scope`
without an error. Thus, the error when `move1` is called is
unavoidable.
Apparently, only those `move`s involving `scope` variables—a very
small percentage—will be *falsely* flagged by the compiler as
unsafe.
If this is the only price that is being paid for the language
limitation, it would seem impossible to justify a language change.
Therefore, I suspect Walter's "simple" solution, involving no
language change, is the best one.
However, marking `move` (or functions like it) as `@system` is
overkill.
Since only a very small percentage of calls to `move` and similar
functions will be flagged wrongly, I believe the right solution
is to *document* functions of this form, saying that otherwise
`@safe` calls to them may occasionally need to be wrapped in
`@trusted` blocks, to avoid the compiler falsely identifying them
as having escaping pointers.
More information about the Digitalmars-d
mailing list