Bug 8520 – Simple "in"-constrained opBinaryRight in interface doesn't work

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-08-07T16:54:18Z
Last change time
2024-12-13T18:00:54Z
Assigned to
No Owner
Creator
Alex Rønne Petersen
Moved to GitHub: dmd#18458 →

Comments

Comment #0 by alex — 2012-08-07T16:54:18Z
┌─[alexrp@zor] - [~/Projects/tests] - [2012-08-08 01:52:24] └─[$] <> cat test.d import std.stdio; interface I { int* opBinaryRight(string op : "in")(int i); } class C : I { int* opBinaryRight(string op : "in")(int i) { return null; } } void main() { I i = new C; int* p = 42 in i; writeln(p); } ┌─[alexrp@zor] - [~/Projects/tests] - [2012-08-08 01:52:26] └─[$] <> dmd test.d test.o:test.d:function _Dmain: error: undefined reference to '_D4test1I30__T13opBinaryRightVAyaa2_696eZ13opBinaryRightMFiZPi' collect2: ld returned 1 exit status --- errorlevel 1 It's my understanding that this is supposed to work since the opBinaryRight template is constrained specifically to "in". This bug makes operators in interfaces pretty unusable.
Comment #1 by simen.kjaras — 2012-08-07T18:26:30Z
Your understanding is wrong - templates never go in the vtable. The solution is to use NVI and forwarding: interface I { int* opBinaryRight_in(int i); int* opBinaryRight(string op : "in")(int i) { return opBinaryRight_in(i); } } class C : I { int* opBinaryRight_in(int i) { return null; } }
Comment #2 by alex — 2012-08-08T03:15:19Z
(In reply to comment #1) > Your understanding is wrong - templates never go in the vtable. > > The solution is to use NVI and forwarding: > > interface I > { > int* opBinaryRight_in(int i); > > int* opBinaryRight(string op : "in")(int i) > { > return opBinaryRight_in(i); > } > } > > class C : I > { > int* opBinaryRight_in(int i) > { > return null; > } > } I could understand if the opBinaryRight template wasn't constrained to "in", but it is, so I see no reason why it cannot be in the vtable since it can only ever have one instance in a class. The NVI solution works, but it's very ugly.
Comment #3 by alex — 2012-08-08T03:15:50Z
Changing to enhancement.
Comment #4 by issues.dlang — 2012-08-08T10:11:34Z
> I could understand if the opBinaryRight template wasn't constrained to "in", but it is, so I see no reason why it cannot be in the vtable since it can only ever have one instance in a class. Because templated functions _never_ end up in the vtable. Mixed in templates may if they're fully instantiated when mixed in (I don't remember), but a templated function written directly in the class is _never_ virtual. That doesn't necessarily mean that there are no situations where the language could be enhanced to make a templated function virtual if it's actually restricted enough (and this may be such a case), but as it stands, being a template is enough to make it non-virtual regardless of what it does or how constrained it is or isn't. I don't believe that even int func()() { return 2; } would be virtual, and that's pretty much as constrained as it gets. Of course, if such a function _did_ get changed to virtual, then it would always defined, whereas right now it's only defined if used, which could be a definite negative, depending on the programmer's intent. So, there's defintely a tradeoff here even if it's possible to make some templated functions virtual.
Comment #5 by robert.schadek — 2024-12-13T18:00:54Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18458 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB