On Thursday, 2 March 2023 at 15:56:35 UTC, ryuukk_ wrote:
> @safe ref int wrongIdentity(ref int x) {
return x; // ERROR! Cannot return a ref, please use "return ref"
}
@safe ref int identity(return ref int x) {
return x; // fine
}
a keyword to return a value
return 5;
and a keyword to tell that a reference is returnable
return ref int x
that's dumb, why?
Late answer, but it happens because DIP25 is now the default. ref
without return
means that the return value cannot refer to the parameter in question. You can alternatively fix this by turning function attribute inference on, by omitting int
from the function header.
Why DIP25 is needed? Consider this:
int* pointer1;
int* pointer2;
@safe ref int incrementAndCopy(ref int x)
{ return *new int(x++);
}
@safe unittest
{ int local = 0;
pointer1 = &local.identity;
pointer2 = &incrementAndCopy(local);
}
The compiler must prevent the first assignment to pointer
, because otherwise it would end up pointing to an expired stack variable. On the other hand, we don't want to disallow harmless usage of ref
like that of the incrementAndCopy
call in the second assignment. To achieve that, the compiler needs to distinguish between ref
variables that may be referenced to by the return value, and those that cannot. Plain ref
means it can not, return ref
means it can.