Bug 9272 – opDispatch conflicts with UFCS on template functions

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-01-05T04:57:00Z
Last change time
2013-01-06T04:49:57Z
Assigned to
nobody
Creator
dransic

Comments

Comment #0 by dransic — 2013-01-05T04:57:36Z
struct Foo { void opDispatch(string s)() {} } void bar(T)(Foo f) {} unittest { Foo foo; bar!int(foo); // OK foo.bar!int(); // Error: foo.opDispatch isn't a template }
Comment #1 by nilsbossung — 2013-01-05T06:33:55Z
No bug here, I think. opDispatch takes precedence and just fails to compile. The same thing happens with --- struct Foo { void bar() {} } --- The error message could be improved though. foo.opDispatch is a template. It's foo.opDispatch!"bar" that is not.
Comment #2 by dransic — 2013-01-05T09:05:00Z
(In reply to comment #1) > opDispatch takes precedence and just fails to compile. Obviously. But is it really by design? This works, where opDispatch does not take precedence: --- struct Foo { void opDispatch(string s)() {} } void baz(Foo f) {} unittest { Foo foo; foo.baz(); // OK } ---
Comment #3 by k.hara.pg — 2013-01-05T09:12:16Z
(In reply to comment #2) > (In reply to comment #1) > > opDispatch takes precedence and just fails to compile. > > Obviously. But is it really by design? > > This works, where opDispatch does not take precedence: > --- > struct Foo { > void opDispatch(string s)() {} > } > > void baz(Foo f) {} > > unittest { > Foo foo; > foo.baz(); // OK > } > --- Just *template* opDispach is required for operator overloading. Therefore non-template function is simply ignored.
Comment #4 by dransic — 2013-01-05T09:17:39Z
(In reply to comment #3) > (In reply to comment #2) > > (In reply to comment #1) > > > opDispatch takes precedence and just fails to compile. > > > > Obviously. But is it really by design? > > > > This works, where opDispatch does not take precedence: > > --- > > struct Foo { > > void opDispatch(string s)() {} > > } > > > > void baz(Foo f) {} > > > > unittest { > > Foo foo; > > foo.baz(); // OK > > } > > --- > > Just *template* opDispach is required for operator overloading. Therefore > non-template function is simply ignored. Yes. I understand why it doen't work at the moment. I just found it inconsistent. Maybe this should be an enhancement request then...
Comment #5 by simen.kjaras — 2013-01-05T12:19:17Z
(In reply to comment #2) > This works, where opDispatch does not take precedence: > --- > struct Foo { > void opDispatch(string s)() {} > } > > void baz(Foo f) {} > > unittest { > Foo foo; > foo.baz(); // OK > } Except, of course, opDispatch *does* take precedence here. Try this instead: import std.stdio : writeln; struct Foo { void opDispatch(string s)() { writeln("opDispatch: ", s); } } void baz(Foo f) { writeln("function: baz"); } void main( ) { Foo foo; foo.baz(); // OK } I can assure you it prints opDispatch: baz.
Comment #6 by dransic — 2013-01-06T04:49:57Z
(In reply to comment #5) > (In reply to comment #2) > > This works, where opDispatch does not take precedence: > > --- > > struct Foo { > > void opDispatch(string s)() {} > > } > > > > void baz(Foo f) {} > > > > unittest { > > Foo foo; > > foo.baz(); // OK > > } > > Except, of course, opDispatch *does* take precedence here. Try this instead: > > import std.stdio : writeln; > > struct Foo { > void opDispatch(string s)() { writeln("opDispatch: ", s); } > } > > void baz(Foo f) { writeln("function: baz"); } > > void main( ) { > Foo foo; > foo.baz(); // OK > } > > I can assure you it prints opDispatch: baz. Ah! I was trapped by the minimalism of my example. OK thanks.