Escape Analysis & Owner Escape Analysis
Dennis
dkorpel at gmail.com
Wed Sep 4 10:24:51 UTC 2024
On Wednesday, 4 September 2024 at 03:02:10 UTC, Richard (Rikki)
Andrew Cattermole wrote:
> It would be an easy enough swap to change ``@safe`` to
> ``@tsafe``. But that isn't a decision we need to make here. We
> can make that prior to launch.
`@safe` `@trusted` and `@system` are already misunderstood as
they are, we really don't want to throw a fourth attribute into
the mix.
> But I do want to make a point here, owner escape analysis only
> kicks in and forces effectively const on the owner if:
That's not consistent with this example from the DIP, where
there's no `scope` or `&field`:
```D
struct Top {
int* field;
}
void func(ref Top owner) @safe {
int* field = owner.field;
// owner is now effectively const, it cannot be mutated
owner = Top.init; // Error: The variable `owner` has a borrow
and cannot be mutated
```
> This is the same meaning it has today with DIP1000.
Today, `scope` doesn't imply 'strong relationship with input
variable', only `return ref` does.
> It needs to mean something, so got an alternative?
No, because I don't like this escape set definition syntax in the
first place.
> Giving ``scope`` a default escape set is to allow it to match
> existing understanding, which does help with communicability.
That's sending mixed messages. On the one hand, this DIP
completely redefines lifetime semantics and syntax, trying to
forget DIP1000 ever existed. On the other hand, it adds a special
meaning to `scope` feigning some sort of backward compatibility,
but adding a new double meaning to the keyword, which is the very
thing the new syntax is supposed to fix!
> Yes you are correct.
>
> If you were allowed to take a pointer to a by-ref variable and
> then store it some place you are most likely escaping a pointer.
The address of the variable and the pointer value it holds are
two different things. So the following becomes impossible to
express with this DIP:
```D
int* global;
int** f(return ref int* v) @safe
{
global = v;
return &v;
}
```
> I'm going to need an example of what you think is not addressed
> here.
To clarify, the headings in my post are common DIP1000 woes that
alternative DIPs should have an answer to. Timon has brought up
the composability problem before:
```D
import std.typecons;
int* y;
int* foo(){
int x;
auto t=tuple(&x,y); // type has to be Tuple!(scope(int*),int*)
return t[1];
}
```
https://forum.dlang.org/post/qqgjop$kan$1@digitalmars.com
The example could compile, but it doesn't because the entire
tuple shares one lifetime.
Another example is item 1 of my post:
https://forum.dlang.org/post/icoavlbaxqpcnkhijcpy@forum.dlang.org
> From my perspective the field gets conflated with its
> containing instance variable and that covers composability.
So this DIP's answer is: tough luck, we're still conflating.
> ``scope`` is not transitive, at least as far as the language
> knows transitive to mean.
Same here, I meant to say that "lack of transitive scope" is a
DIP1000 woe that the DIP should address. The DIP doesn't have a
single example where a pointer gets dereferenced and then
escaped. What happens to the following examples?
```D
// Assuming -preview=dip1000
int* deref(scope int** x) @safe => *x; // currently allowed
// because x gets dereferenced and scope only applies to first
indirection
void main() @safe
{
int x, y;
scope int[] arr = [&x, &y]; // currently not allowed
// because it requires scope to apply to two levels of
pointer indirection
}
```
> I focus upon multiple outputs, because to make flattening to a
> function signature to work, you have to do this. If you don't
> you are not going to model enough code, and will be going
> against the literature on this subject making it harder to use.
Walter has stated that he's not looking for a complete lifetime
tracking solution for all possible situations, just something
simple and pragmatic to cover common cases. In the [DIP1000 woes
thread](https://forum.dlang.org/post/xvzzmgwibbjhuvmnhrgi@forum.dlang.org), the only multiple output-related issue is with `swap`. This DIP's syntax is overkill to solve just that problem. It would help if there were examples of actual code that really needs to use @escape(parametername).
More information about the dip.ideas
mailing list