Dlist and dip1000 challenge

Stanislav Blinov stanislav.blinov at gmail.com
Tue Oct 23 21:38:32 UTC 2018


On Tuesday, 23 October 2018 at 20:46:26 UTC, Steven Schveighoffer 
wrote:

>>> This is where I think there is going to be a problem. scope 
>>> shouldn't be transitive, you can easily have a pointer 
>>> allocated on the stack point to heap data.
>> 
>> Yeah, but OTOH, so can you have an array of pointers to the 
>> stack :\
>
> This is where dip1000 actually makes sense -- the lifetime of 
> that array should not outlive the stack. So, with dip1000 you 
> *shouldn't* be able to have a heap array of pointers to the 
> stack.

Indeed, but that's for heap arrays. This will (and should) work:

void sink(scope immutable(char)*[] arr) @safe {}
void test() @safe { // even though putting @nogc here will still 
result in 'may cause GC allocation'...
     immutable char c;
     sink([&c]); // ...this is actually fine
}

Now for the meat. It looks like it just won't let you @safe-ly 
store away `scope` strings in that List:

string[] hatch;

void escape(string s) @safe { hatch ~= s; }

// templated to force attribute inference
void testInferred()(scope string[] stuff) {
     static string[] hatch;

     while (!stuff.empty) {

         // this blatantly and silently strips @safe from 
`testInferred`
         // without compile errors
         escape(stuff.front);

         // however, this will result in compilation error:
         //hatch ~= stuff.front;

         stuff.popFront;
     }
}

// fails to compile outright
void testSafe(scope string[] stuff) @safe {

     while (!stuff.empty) {

         // in @safe scope can't escape like this at all
         escape(stuff.front);

         stuff.popFront;
     }
}

void main() {
     testInferred(["hello"]); // compiles

     // fails to compile, testInferred is @system!
     () @safe {
         testInferred(["hello"]);
     } ();
}

...so transitivity strikes yet again, albeit from the shadows 
this time.


More information about the Digitalmars-d mailing list