[Issue 19183] DIP1000 defeated if auto used instead of scope in variable declaration with template this member function

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Aug 21 21:03:21 UTC 2018


https://issues.dlang.org/show_bug.cgi?id=19183

--- Comment #7 from ag0aep6g <ag0aep6g at gmail.com> ---
(In reply to Atila Neves from comment #6)
> What's @trusted is that I'm calling `free` on the same pointer I allocated
> in the constructor, and the other thing needing checking is the postblit.

If you want to keep the @trusted promise, you can't rely on the pointer being
the same. @safe code can mess with it. There's no way around that. Maybe there
should be.

So what you do is this: You mark the `free` call as @trusted anyway, because
there's no other way. And then you have to check manually that your @safe code
doesn't mess with the pointer. Ideally, manual checks wouldn't be needed for
@safe code, but that's the price you pay for breaking the @trusted promise.


> This all is besides the point, given the code below has no @trusted
> anywhere, compiles, and shouldn't:
> 
> -------------------------------
> @safe:
> 
> const(int)* gInts;
> 
> void main() {
>     auto s = MyStruct();
>     gInts = s.ptr;
> }
> 
> struct MyStruct {
>     int* _ints;
>     auto ptr(this This)() { return _ints; }
> }
> -------------------------------

Why shouldn't this compile? There's no `scope` anywhere now (except maybe an
inferred one). You're just copying an `int*` around. That's not against any
rules.


> As in the original report:
> 
> 
> * Adding a no-op destructor does nothing (i.e. the code still compiles):
> 
> ~this() {} // ok but shouldn't be

Why shouldn't it compile with the destructor? The destructor is marked as @safe
and does nothing. So it's the same as not having a destructor at all, no?


> * Adding a no-op destructor annotate with scope causes a compile-time error:
> 
> ~this() scope { }
> 
> baz.d(7): Error: scope variable s assigned to gInts with longer lifetime

Interesting. Looks like a `scope` destructor also makes any instances
implicitly `scope`. I don't think I understand DIP 1000 or its implementation
well enough to this. DIP 1000 doesn't seem to mention it, as far as I see.


> * With no destructor at all but replacing `auto` with `scope` also fails to
> compile:
> 
> scope s = MyStruct();
> 
> baz.d(7): Error: scope variable s assigned to gInts with longer lifetime

This makes sense to me. With `s` being `scope`, the compiler now checks it and
its contents don't leave `main`.

If `s` is not `scope`, there's no indication that its contents shouldn't be
allowed to leave `main`.


> Weirdly enough, changing `gInts` to a static array and returning &_ints[0]
> in ptr also fails to compile;

Do you mean making `_ints` a static array (e.g., `int[1] _ints;`)? If so, the
code effectively becomes:

----
const(int)* gInts;
void main() @safe
{
    int _ints;
    gInts = &_ints;
}
----

Leaking a reference to a local variable is not allowed, of course. It's very
different from copying a pointer.

If you really mean making `gInts` a static array, could you post the full code?
I don't understand what you mean in that case.

--


More information about the Digitalmars-d-bugs mailing list