Bug 9410 – [Regression 2.061] Wrong selection for function overload

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-01-27T05:11:00Z
Last change time
2013-01-28T13:41:48Z
Keywords
diagnostic, pull, rejects-valid
Assigned to
nobody
Creator
rswhite4

Comments

Comment #0 by rswhite4 — 2013-01-27T05:11:22Z
This code: [code] import std.stdio; struct Vec2(T) { public: T x; T y; this(T x, T y) { } } alias Vec2f = Vec2!(float); class Foo { public: static Foo make(float i, ref const Vec2f a) { return new Foo(); } static Foo make(float i, const Vec2f a) { return Foo.make(i, a); } } void main() { Foo f = Foo.make(42, Vec2f(4, 2)); } [/code] prints: Error: (Vec2!(float) __ctmp1173 = _D4c42511__T4Vec2TfZ4Vec26__initZ; , __ctmp1173).this(4F, 2F) is not an lvalue But IMO it should compile. Also this code: [code] import std.stdio; struct Rect(T) { private: T x, y, w, h; public: this(T x, T y, T w, T h) { } } alias FloatRect = Rect!(float); class A { } class B : A { } class C { public: this(A a, ref const FloatRect sr) { } this(A a, const FloatRect sr) { this(a, sr); } } void main() { // new C(new A(), FloatRect(0, 1, 2, 3)); // works new C(new B(), FloatRect(0, 1, 2, 3)); } [/code] seems to have the same problem. It prints: Error: (Rect!(float) __ctmp1173 = _D4c84111__T4RectTfZ4Rect6__initZ; , __ctmp1173).this(0F, 1F, 2F, 3F) is not an lvalue
Comment #1 by maxim — 2013-01-27T05:35:11Z
Reduced (Error: S() is not an lvalue) import std.stdio; struct S {} void foo(float f, ref const S s) { writeln("const"); } void foo(float f, const S s) { writeln("ref const"); } void main() { foo(1, S()); // 1f fixes code and calls ref const version } If overloaded functions have several parameters, one of which is const-qualified used-defined type and functions differer only in refness of that parameter, supplying implicitly convertible arguments (like int to float) to other parameters breaks compiler. Passing 1f results in calling ref const version which contradicts to recent revertion of passing struct literals by ref (however that was without const). It is unclear what should happen in presence of const.
Comment #2 by rswhite4 — 2013-01-27T09:31:13Z
This also fails. Error: A() is not an lvalue [code] import std.stdio; struct A { } void foo(const A a, float r) { } void foo(ref A a, float r) { } void main() { foo(A(), 12); } [/code] _That_ is strange.
Comment #3 by rswhite4 — 2013-01-28T02:40:36Z
(In reply to comment #1) > Reduced (Error: S() is not an lvalue) > > import std.stdio; > > struct S {} > > void foo(float f, ref const S s) > { > writeln("const"); > } > > void foo(float f, const S s) > { > writeln("ref const"); > } > > void main() > { > foo(1, S()); // 1f fixes code and calls ref const version > } > > > If overloaded functions have several parameters, one of which is > const-qualified used-defined type and functions differer only in refness of > that parameter, supplying implicitly convertible arguments (like int to float) > to other parameters breaks compiler. > > Passing 1f results in calling ref const version which contradicts to recent > revertion of passing struct literals by ref (however that was without const). > It is unclear what should happen in presence of const. The problem isn't the presence of const. This code fails, also: [code] import std.stdio; struct S {} void foo(float f, ref S s) { writeln("ref"); } void foo(float f, S s) { writeln("without ref"); } void main() { S s; foo(1, s); // works fine. Print: ref //foo(1, S()); // Fails with: Error: S() is not an lvalue } [/code] IMO the problem is, that the compiler cannot convert 1 (int) to 1f (float). He found the correct match: foo(float f, S s). But the compiler could not convert int to float, so he tried another "match", which is wrong because S() is not an lvalue. That recognize the compiler and print an error. But IMO he should convert int to float by his first match, which was the only correct match. I believe the problem comes from the change that structs aren't handled as lvalues anymore. Something of the old behaviour interfere with the new behaviour.
Comment #4 by k.hara.pg — 2013-01-28T04:27:54Z
Comment #5 by github-bugzilla — 2013-01-28T13:27:17Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/ee8cf8344602a113185a7f489f2b3b1988510615 fix Issue 9410 - Wrong selection for function overload https://github.com/D-Programming-Language/dmd/commit/e7d4abc28f77ba7a2771003fe13f56efa94e0f3f Merge pull request #1571 from 9rnsr/fix9410 [Regression 2.061] Issue 9410 - Wrong selection for function overload