Comment #0 by verylonglogin.reg — 2014-01-02T05:00:51Z
This code should compile:
---
void f(int) { }
void f(out int) { }
void t(T)(T) { }
void t(T)(out T) if(false) { } // line 4
void main()
{
const int n = 1;
f(n); // line 9
t(n); // also causes ICE
}
---
main.d(9): Error: constant 1 is not an lvalue
main.d(4): Error: cannot have const out parameter of type const(int)
<access violation>
---
Previously dmd just shown error. Now it also ICE-s with access violation in template case.
Comment #2 by verylonglogin.reg — 2014-01-02T23:07:39Z
(In reply to comment #1)
> https://github.com/D-Programming-Language/dmd/pull/3034
>
> *** This issue has been marked as a duplicate of issue 11822 ***
If it really is change issue 11822 title appropriately as this issue has nothing to do with `-de` switch.
Comment #3 by verylonglogin.reg — 2014-01-11T13:53:22Z
So do I understand correctly ICE part of the issue is considered a duplicate of issue 11822 and "This code should compile" part is considered WONTFIX? If so, where is the documentation claiming such code incorrect?
Comment #4 by k.hara.pg — 2014-01-13T01:09:04Z
(In reply to comment #3)
> So do I understand correctly ICE part of the issue is considered a duplicate of
> issue 11822 and "This code should compile" part is considered WONTFIX? If so,
> where is the documentation claiming such code incorrect?
In short, yes.
Even `const int n = 1` is interpreted in compile time, `n` is a local variable that has runtime storage on stack. Therefore, expression `n` makes lvalue, then preferentially matches to `out` parameter.
This behavior is intended to reduce confusion at the situation that mixing constant-folding and compile-time/runtime evaluation. Example:
void f( immutable int n);
void f(ref immutable int n); // accepts only lvalue
void foo(int x)
{
immutable int n = x;
// n is evaluated in runtime (when foo is called)
f(n); // n matches to ref version
}
void bar(int x)
{
immutable int n = 1;
// n can be interpreted at compile time,
// but still allocated on stack and initialized in runtime.
f(n); // n still matches to ref version
}
D is designed to provide consistent overload resolution result for f(n) in both foo and bar.
In other words, variable evaluation and its ref-ness is strictly separated from the CTFE/constant-folding. Conflating them would make hard to understand overload resolution result.
Comment #5 by verylonglogin.reg — 2014-01-13T06:28:07Z
(In reply to comment #4)
Thanks, but this doesn't answer the question. Probably I should be more precise:
1. Why `ref` works and `out` doesn't work (in `ref` case the only matching non-ref overload is selected)?
2. Why disabled by `if(false)` constraint overload breaks overload resolution?
Comment #6 by verylonglogin.reg — 2014-01-13T06:57:38Z
I segregated Issue 11915 and Issue 11916 for discussion.