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