D needs first-class lifetimes before it can get ownership and borrowing

Olivier FAURE couteaubleu at gmail.com
Sat Aug 10 13:30:17 UTC 2019


I've been trying to nail down the semantics of my in-progress DIP 
for a `unique` qualifier, and I couldn't come up with coherent 
rules for double-indirection.

To give you an shortened example of the problem, contemplate this:

     int* gptr;

     struct SmartPtr {
         int* ptr;

     @safe:
         ~this() { reset(); }
     @trusted:
         void init() { ptr = cast(int*)malloc(int.sizeof); *ptr = 
0; }
         void reset() { free(ptr); ptr = null; }

     @safe:
         ref int get() return { assert(ptr); return *ptr; }

         void borrow() { gptr = this.ptr; }
     }

     @safe
     void main() {
         SmartPtr s;
         s.init();
         s.borrow();
         s.reset();
         *gptr = 1; 		// Memory corruption
     }

The problem above is that, under DIP-1000, the compiler assumes 
`borrow()` doesn't escape any data, because it takes `this` by 
ref; and yet it escapes this.ptr, because there's no way to mark 
this.ptr as scope. As long as borrow() is @safe, there's no way 
reset() can be @trusted.

To my knowledge, the proposed @live semantics don't solve this 
problem (because they would also assume that `borrow()` doesn't 
escape data); so I think it's necessary to have lifetime 
annotations inside structs before any ownership-borrowing scheme 
can be achieved.


More information about the Digitalmars-d mailing list