On Fri, 21 Oct 2011 11:20:01 -0400, Christophe
<trav...@phare.normalesup.org> wrote:
"Daniel Murphy" , dans le message (digitalmars.D.learn:30139), a écrit :
"bearophile" <bearophileh...@lycos.com> wrote in message
news:j7jepi$prp$1...@digitalmars.com...
Daniel Murphy:
2)
immutable(int[]) fun() { return new int[]; } // conversion happens
here
immutable x = fun();
Bearophile's example is of the second, where it definately matters
what
the
purity of the function is.
This is the enhancement request I have written days ago:
http://d.puremagic.com/issues/show_bug.cgi?id=6783
Bye,
bearophile
Yes, and the problem in that report is that the function is const-pure,
not
strong-pure.
Without checking if the return type can contain a non-immutable
reference
from the arguments, it is not safe to implicitly convert the result to
immutable.
eg.
immutable(int[]) foo(in int[] x) { return x; }
auto g = [1, 2, 3];
auto a = foo(g.idup); //safe
auto b = foo(g); // unsafe
Checking at the call site is possible, but not from inside the function.
int[] foo(in int[] x) { return new int[](3); }
auto g = [1, 2, 3];
immutable a = foo(g.idup); // safe
immutable b = foo(g); // unsafe, and easily rejected
In your example, it is safe as the argument is not returned. Allowing
this
in the general case requires checking (recursively) that the return type
does not contain any types that any of the arguments can implicitly
convert
to that are non-immutable.
What is the rule ?
The theoretical rule should be, if it can be proven (except for the case
where a cast is used) the result is not a subset of the input, then the
result can be implicitly cast to immutable.
The actual rule may be more conservative, since it may be difficult to
prove it.
The result of
pure int[] foo(in int[] x);
is castable to immutable, since elements of x are not supposed to escape
the function.
The result of
pure int[] foo(const int[] x);
is not, because the value return by foo may be elements of x.
Only via cast. How does foo legally change const int[] data to int[] data
without a cast?
Note that the two functions you wrote are equivalent, since in translates
to "const scope" and scope does nothing to array parameters.
-Steve