Implicit cast to immutable

Christophe travert at phare.normalesup.org
Thu Oct 27 07:48:15 PDT 2011


"Steven Schveighoffer" , dans le message (digitalmars.D.learn:30255), a
 écrit :
> On Fri, 21 Oct 2011 11:20:01 -0400, Christophe  
> <travert at phare.normalesup.org> wrote:
> 
>> "Daniel Murphy" , dans le message (digitalmars.D.learn:30139), a écrit :
>>> "bearophile" <bearophileHUGS at lycos.com> wrote in message
>>> news:j7jepi$prp$1 at 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.

OK, it must be proven from the signature of the function alone, and not 
from the function body.

>> 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.
> 

I meant:
pure const(int)[] foo(const/in int[] x);

But I thought scope was transitive like const, so it had effect on 
arrays. I find it pretty useless like that. A transitive scope could be 
very useful for purity checking and memory management optimisations. It 
would be useful for implicit casting to immutable too, even in no pure 
function. I may write about that later in another thread.


More information about the Digitalmars-d-learn mailing list