Phobos is now compiled with -preview=dip1000
Meta
jared771 at gmail.com
Fri May 17 17:03:51 UTC 2019
On Friday, 17 May 2019 at 05:32:42 UTC, Mike Franklin wrote:
> On Friday, 17 May 2019 at 05:22:30 UTC, Mike Franklin wrote:
>
>> My assessment (which could be wrong):
>> `scope` and `return` only apply to pointers and `ref`s. If
>> you remove all `scope` and `return` attributes from the
>> function `push`, it works fine.
>>
>> I consider it a bug that the compiler doesn't emit an error
>> when using attributes on types for which they are not intended.
>>
>> Mike
>
> Working example: https://run.dlang.io/is/TCP0td
That does compile, but I don't think that it's working the way I
want it to. I believe it only works because a GC-managed string
is used for the backing storage. If you change that to a static
array on the stack:
@safe
void main()
{
immutable(char)[16] rawData = "2 6 4 1 0 2 9 4 5";
auto dataRange = makeDataRange(rawData);
auto result = dataRange.copyToQueue();
import std.stdio;
writeln("The result of data processing is: ", result);
}
It will refuse to compile with this message:
Error: reference to local variable rawData assigned to non-scope
parameter input calling makeDataRange
`makeDataRange` is defined like this:
@safe
DataRange makeDataRange(string input)
{
auto range = DataRange(input);
return range;
}
So that static array is getting implicitly sliced, i.e., its
address is being taken. It's pretty obvious why `input` is not
being inferred as scope - it's being returned from
`makeDataRange`. However, when I try to manually annotate it with
return or return scope, I run into further errors:
DataRange makeDataRange(return scope string input)
{ ...etc. }
Error: scope variable input assigned to non-scope parameter
rawData calling DataRange.this
Error: scope variable dataRange assigned to non-scope parameter
data calling copyToQueue
So I continue annotating things with scope or return or return
scope whenever the compiler complains about it, going up through
the call chain until I arrive back at my original problem
mentioned in the post I linked.
(My original example with changes made going through this
exercise: https://run.dlang.io/is/uQDXG6)
This is why I say that I'm not sure that I quite understand
dip1000. I *thought* I did, but an example that seems like it
should clearly work (at least to me), does not.
If you look at `main` above, `rawData` has the same lifetime as
the `dataRange` struct returned from `makeDataRange` and the
queue returned from `copyToQueue`. True, there is some
traditionally unsafe stuff happening in between; however, I
thought that the point of adding all these annotations is to tell
the compiler how the lifetimes of these objects propagate up and
down the call stack, so that it can check that there will be no
memory corruption. I'm not doing anything here that will result
in a pointer to an expired stack frame, or otherwise cause memory
corruption or use after free, or anything like that (*unless* I
allow either `dataRange` or `result` to escape from the main
function - which dip1000 correctly disallows).
More information about the Digitalmars-d-announce
mailing list