Thread overview
Is the `in` operator @safe?
Feb 11, 2019
Luís Marques
Feb 12, 2019
Simen Kjærås
Feb 12, 2019
Kagamin
Feb 12, 2019
Dukc
February 11, 2019
After a quick look it seems like the `in` operator may return a pointer that becomes invalid when an AA is resized:

https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L601
https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L114
https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L193

Yet you can use `in` in @safe functions and keep the pointer around. Is my assessment correct, or did I overlook anything? If so, I'll open a bug report (I didn't find one already open for that, but maybe I searched the wrong keywords).
February 12, 2019
On Monday, 11 February 2019 at 21:47:05 UTC, Luís Marques wrote:
> After a quick look it seems like the `in` operator may return a pointer that becomes invalid when an AA is resized:
>
> https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L601
> https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L114
> https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L193
>
> Yet you can use `in` in @safe functions and keep the pointer around. Is my assessment correct, or did I overlook anything? If so, I'll open a bug report (I didn't find one already open for that, but maybe I searched the wrong keywords).

This quick test indicates that the pointer doesn't get invalidated:

@safe unittest {
    import std.stdio : writeln;
    int[int] arr;
    arr[0] = 0;
    int* p = 0 in arr;
    int n = 1;
    while (p == (0 in arr)) {
        if (n % 1000 == 0) n.writeln;
        arr[n++] = 0;
    }
    n.writeln;
}

It crashes with an OutOfMemoryError after allocating ~27M elements on my machine.

It seems the AA is actually holding a list of Buckets, with each bucket containing a pointer to the actual element. When it's resize only the bucket list is affected, and the element pointers are still valid.

--
  Simen
February 12, 2019
On Monday, 11 February 2019 at 21:47:05 UTC, Luís Marques wrote:
> After a quick look it seems like the `in` operator may return a pointer that becomes invalid when an AA is resized

Memory allocated from GC is valid, that's how GC is part of the safety system.
February 12, 2019
On Monday, 11 February 2019 at 21:47:05 UTC, Luís Marques wrote:
> Yet you can use `in` in @safe functions and keep the pointer around. Is my assessment correct, or did I overlook anything? If so, I'll open a bug report (I didn't find one already open for that, but maybe I searched the wrong keywords).

I believe the memory referenced to by AA is garbage collected, not memory managed by ownership. As long as the memory you keep the pointer at is scanned by the collector, the AA content should not get freed.