On Friday, 10 February 2023 at 14:37:35 UTC, ag0aep6g wrote:
>On Friday, 10 February 2023 at 14:00:20 UTC, Steven Schveighoffer wrote:
>It can be weakly pure. The docs are wrong.
i.e. this works:
pure int *foo(const int *p)
{
return new int(5);
}
void main()
{
int x;
immutable int * bar = foo(&x);
}
That function "has no parameters with mutable indirections". So it's strongly pure, not weakly pure.
Uniqueness analysis depends on the return type as much as on parameter types.
In Steve’s example, foo
does have parameters with mutable indirections (as I interpret that phrase – it’s honestly not precise wording) because const
allows binding mutable values. The reason Steve’s example compiles is that by thorough investigation of parameter and return types, the compiler comes to the conclusion that there is no way p
, which is a const(int)*
makes it into the return value, and therefore the result must be uniquely created and thus may be cast to immutable
. If you change the return type of foo
to const(int)*
(cf. goo
in the example below), the parameter’s value could make it into the result and because p
may be bound to mutable, the result cannot be cast to immutable
implicitly:
pure @safe int * foo(const(int)* p) { return new int(1); }
pure @safe const(int)* goo(const(int)* p) { return new int(1); }
void main() @safe
{
auto p = new int;
immutable a = foo(p); // ok
immutable b = goo(p); // error
}