Consider these two functions:
auto ref foo(ref int x) {
if (condition) return x;
return 3;
}
auto ref bar(ref int x) {
return condition ? x : 3;
}
At a first glance, they appear to be equivalent, however foo is a
compile-time error "constant 3 is not an lvalue" while bar
compiles fine and returns an rvalue int.
The rule in the spec is "The lexically first ReturnStatement
determines the ref-ness of [an auto ref] function"
Why is this? I think it would be more consistent and convenient
to be: "An auto ref function returns by ref if all return paths
return an lvalue, else it returns by value".
Am I missing something? I don't see why foo should be rejected at
compile time when it can happily return by value.
It is especially problematic in generic code where you
opportunistically want to return by ref when possible, e.g.:
auto ref f(alias g, alias h)()
{
if (condition)
return g();
return h();
}
If g returns by ref while h returns by value then this fails to
instantiate. It would be nice if it just returned by value (as
return condition ? g() : h() would)