In this bug report I have asked for better error messages:
http://d.puremagic.com/issues/show_bug.cgi?id=6696
But beside the error message, do you know why an immutable ref can't be given
to a function with a const ref argument? foo() can't change the contents of the
array a any way, so what's wrong in this code?
void foo(const ref int[5] a) {}
void main() {
immutable int[5] arr;
foo(arr); // Error?
}
Bye,
bearophile

In this bug report I have asked for better error messages:
http://d.puremagic.com/issues/show_bug.cgi?id=6696
But beside the error message, do you know why an immutable ref can't be given
to a function with a const ref argument? foo() can't change the contents of the
array a any way, so what's wrong in this code?
void foo(const ref int[5] a) {}
void main() {
immutable int[5] arr;
foo(arr); // Error?
}

Looks like a bug. Seems like the compiler treats casted argument as an rvalue
and you can't pass rvalue byref, can you?

In this bug report I have asked for better error messages:
http://d.puremagic.com/issues/show_bug.cgi?id=6696
But beside the error message, do you know why an immutable ref can't be
given to a function with a const ref argument? foo() can't change the
contents of the array a any way, so what's wrong in this code?
void foo(const ref int[5] a) {}
void main() {
immutable int[5] arr;
foo(arr); // Error?
}

The complaint from the compiler is that cast(const(int[5u])) arr is not an
lvalue.
So apparently, the compiler wants to *copy* arr (via cast), then ref that.
This smells like a bug, but could potentially be intended behavior.
There is a workaround, but it's UGLY and dangerous:
foo(*(cast(const(int[5])*)&arr));
I think the rules for implicit casting need to take into account whether
it can use this kind of rewrite.
I'd file a bug, but note that it could possibly be an enhancement.
BTW, there are some funky things that happen with an immutable storage
class. For example:
void foo(ref const(int) a) {}
void bar(immutable int a) { foo(a); }
void main()
{
immutable int a = 5;
foo(a); // error, see below
bar(a); // ok
}
The error for the foo(a) line is:
Error: constant 5 is not an lvalue
So the compiler is apparently replacing a with an enum. But if it's a
parameter, it gets storage on the stack. That doesn't seem right. I
thought immutable data was supposed to live where you declare it, and
that's why you use enum to force it to be a compile-time constant.
The same trick does not work with a fixed-size array, so I think
definitely the original issue is a bug (behavior should be consistent with
int).
-Steve

The complaint from the compiler is that cast(const(int[5u])) arr is not an
lvalue.

It's a bug, the compiler shouldn't be inserting a cast when the value
implicitly converts. It's also a bug when the compiler tries to optimise
away the variable to a literal when passing by reference, I've got a patch
for this I haven't written up yet.

In this bug report I have asked for better error messages:
http://d.puremagic.com/issues/show_bug.cgi?id=6696
But beside the error message, do you know why an immutable ref can't be
given to a function with a const ref argument? foo() can't change the
contents of the array a any way, so what's wrong in this code?
void foo(const ref int[5] a) {}
void main() {
immutable int[5] arr;
foo(arr); // Error?
}

BTW, when posting questions like this, it is *immensely* helpful to give
exact error messages, so I don't have to try it out to see what you are
talking about. I spent a while writing a response until I saw the error
message (which changed completely how I viewed the issue), and erased it
before writing my eventual reply.
-Steve