Implicit cast to immutable

Steven Schveighoffer schveiguy at yahoo.com
Mon Oct 24 08:29:57 PDT 2011


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.

> 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


More information about the Digitalmars-d-learn mailing list