On 2/8/16 4:48 PM, Jonathan M Davis wrote:

One of the most useful things that the compiler can do if a function is
pure is that if it can guarantee that the return value did not get
passed in as an argument or was otherwise obtained via an argument, then
it knows that the argument was created within the function and that
therefore the return value is the only reference to that data, and so
it's safe to alter its mutability - e.g. change a mutable array to an
immutable one. Exactly which conditions under which that can be
determined to be safe are not exactly straightforward. The simplest is
when all of the arguments were immutable, but there are others, some of
which are much more complicated (and under some circumstances, const can
help with that, whereas in others, it can't - it really depends on the
types involved). I don't know how sophisticated the compiler is in
determining that right now, but clearly, what it currently has is buggy,
because it failed to take the invisible this pointer/reference into
account in your example and thus incorrectly determined that it was not
possible for another reference to the same data to exist after the
function returned.

I'm not so sure. I think there is something we never considered, and the compiler might be more clever than it should be.

I tested this out:

int[] f(ref void[] m) pure
{
    auto result = new int[5];
    m = result;
    return result;
}

void main()
{
    void[] v;
    immutable x = f(v);
}

Compiles.

I think the rules at the moment are that the compiler allows implicit conversion if the return value could not have come from any of the parameters. But what it may not consider is if the parameters could be return values themselves via a reference!

What I think is happening is that the compiler is saying "Well, there is no way that int[] could come from m (without a cast), so I'm going to assume it's unique". However, we can see it's not. m actually is generated from it!

I'll amend the bug.

-Steve

Reply via email to