digitalmars.D.bugs - [Issue 10574] New: "auto ref" fails to match when IFTI succeeds (strip to level const)
- d-bugmail puremagic.com (47/47) Jul 08 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
- d-bugmail puremagic.com (17/17) Jul 08 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
- d-bugmail puremagic.com (11/11) Jul 08 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
- d-bugmail puremagic.com (9/11) Jul 08 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
- d-bugmail puremagic.com (45/52) Jul 09 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
- d-bugmail puremagic.com (15/18) Jul 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
- d-bugmail puremagic.com (11/24) Jul 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
- d-bugmail puremagic.com (21/27) Jul 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
- d-bugmail puremagic.com (16/35) Jul 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
- d-bugmail puremagic.com (11/17) Jul 11 2013 http://d.puremagic.com/issues/show_bug.cgi?id=10574
http://d.puremagic.com/issues/show_bug.cgi?id=10574 Summary: "auto ref" fails to match when IFTI succeeds (strip to level const) Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Keywords: rejects-valid Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: monarchdodra gmail.com Basically, an "immutable(int[])" will not match "auto ref T[]", when it does match "T[]". Example: //-------- import std.stdio; version(all) { void foo(T)(auto ref T[] i) { writeln(typeof(i).stringof); } } else { void foo(T)(T[] i) { writeln(typeof(i).stringof); } void foo(T)(ref T[] i) { writeln(typeof(i).stringof); } } void main() { immutable(int[]) i; foo(i); } //-------- -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 08 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10574 Steven Schveighoffer <schveiguy yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy yahoo.com 12:10:26 PDT --- For clarification, the error displayed for the given code is: Error: template testautoref.foo(T)(auto ref T[] i) cannot deduce template function from argument types !()(immutable(int[])) And it does match immutable(int)[]. As implied, if you change to version(none), it does indeed work. const(int[]) also fails. A workaround that seems to work, but I don't really like it, is to add overloads for immutable(T[]) and const(T[]) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 08 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10574 Martin Nowak <code dawg.eu> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |code dawg.eu Just an educated guess. The problem seems to be that the value is a L-value so the signature becomes (ref T[]) which cannot match immutable(int[]). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 08 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10574Just an educated guess. The problem seems to be that the value is a L-value so the signature becomes (ref T[]) which cannot match immutable(int[]).That's exactly the current compiler's behavior. "auto ref" always behave as "ref" parameter against lvalue argument `i`, then T[] cannot deduce type T from immutable(int[]). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 08 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10574More generally, it seems auto ref will never operate a cast on an lvalue *even if* the parameter is not templatized. This is strange because auto ref *will* do it for RValues. Here is another (reduced) example that shows it. //---- void foo()(auto ref long a); void main() { int get(); int a; foo(get()); //Fine, rvalue int is cast to long foo(a); //Nope! } //---- main.d(7): Error: template main.foo does not match any function template declaration. Candidates are: main.d(1): main.foo()(auto ref long a) main.d(7): Error: template main.foo()(auto ref long a) cannot deduce template function from argument types !()(int) //---- I also spotted this (which, IMO, is even more problematic): //---- struct S { property long get(); alias get this; } void foo()(auto ref long a); void main() { S s; foo(S()); //Fine. foo(s); //Nope! } //---- This time, it gives the "cryptic" error: main.d(14): Error: s.get() is not an lvalue => But that's strange: foo takes by auto ref... what do I care about lvalue? Because s is an Lvalue, it would appear the auto ref is "primed" to take by ref. It then fails when an actual Rvalue is given. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------Just an educated guess. The problem seems to be that the value is a L-value so the signature becomes (ref T[]) which cannot match immutable(int[]).That's exactly the current compiler's behavior. "auto ref" always behave as "ref" parameter against lvalue argument `i`, then T[] cannot deduce type T from immutable(int[]).
Jul 09 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10574 07:17:57 PDT ---That's exactly the current compiler's behavior. "auto ref" always behave as "ref" parameter against lvalue argument `i`, then T[] cannot deduce type T from immutable(int[]).To the user, auto ref should really mean "use ref if possible, otherwise do not" In other words, I think auto ref should be the equivalent of having two identical templates, one with ref, and one without. Because IFTI can do some implicit casting, and implicit casting changes lvalues to rvalues, I think the rule is incorrect. The algorithm should be: If lvalue, then try ref. If that does not work, try non-ref version. If that does not work, error. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10574For the record (without putting any words in Kenji's mouth), I think he was just stating what the compiler was *doing*, and why the code was rejected. I don't think he meant to say that the current behavior was correct. Kenji, could you confirm that this is what you meant? That this is a correct "rejects-valid" ? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------That's exactly the current compiler's behavior. "auto ref" always behave as "ref" parameter against lvalue argument `i`, then T[] cannot deduce type T from immutable(int[]).To the user, auto ref should really mean "use ref if possible, otherwise do not" In other words, I think auto ref should be the equivalent of having two identical templates, one with ref, and one without. Because IFTI can do some implicit casting, and implicit casting changes lvalues to rvalues, I think the rule is incorrect.
Jul 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10574For the record (without putting any words in Kenji's mouth), I think he was just stating what the compiler was *doing*, and why the code was rejected. I don't think he meant to say that the current behavior was correct. Kenji, could you confirm that this is what you meant? That this is a correct "rejects-valid" ?No, indeed I just talked about the current compiler's work, but I'm sure that current behavior is correct. The main point is what "auto ref" is doing - it's ref-ness deduction. If given argument is an lvalue, auto ref parameter would become ref. If it's an rvalue, would become non-ref. Nothing else is done. Type deduction and ref-ness deduction are completely orthogonal. It means that the combination of each deduction results might finally reject given argument. It's exactly what happened in the OP code. So I can say it's expected behavior. I believe that one language feature (in here "auto ref") should do just one thing correctly. Orthogonality between each features could reduce language's "special case", and combining them would bring abundant usage. For example, when you use "auto ref", the ref-ness deduction reliably avoids copy-construction of given argument. A brief conclusion is: "auto ref" is not a magic parameter. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10574I strongly disagree. The argument of "ref-ness deduction" should be applied *after* type deduction. though. Applying it *before* makes no sense. Having a function that accepts an RValue of type U, yet reject an LValue of type U, is unheard of. It is strongly anti-expected. Finally, regardless of "how" auto ref works, this definitely goes against "what" auto ref is trying to solve: Writing functions that can take either by value or by ref, without having to write overloads. As is, the only solution here is to *not* use auto ref, but instead, write ref/value overloads: auto ref => Failed to provide solution it was designed for => design is flawed. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------For the record (without putting any words in Kenji's mouth), I think he was just stating what the compiler was *doing*, and why the code was rejected. I don't think he meant to say that the current behavior was correct. Kenji, could you confirm that this is what you meant? That this is a correct "rejects-valid" ?No, indeed I just talked about the current compiler's work, but I'm sure that current behavior is correct. The main point is what "auto ref" is doing - it's ref-ness deduction. If given argument is an lvalue, auto ref parameter would become ref. If it's an rvalue, would become non-ref. Nothing else is done. Type deduction and ref-ness deduction are completely orthogonal. It means that the combination of each deduction results might finally reject given argument. It's exactly what happened in the OP code. So I can say it's expected behavior.
Jul 11 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10574 11:32:46 PDT ---The main point is what "auto ref" is doing - it's ref-ness deduction. If given argument is an lvalue, auto ref parameter would become ref. If it's an rvalue, would become non-ref. Nothing else is done. Type deduction and ref-ness deduction are completely orthogonal. It means that the combination of each deduction results might finally reject given argument. It's exactly what happened in the OP code.I agree that was what auto-ref is supposed to do, but in this case, it's hurting more than helping. I can't think of a valid reason to forbid this, can you? This bug report should be changed to an enhancement, though (and the description appropriately modified). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 11 2013