Bug 4880 – [patch] std.range.put does not handle output ranges implement via opDispatch; breaks on RefAppender
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2010-09-17T10:14:54Z
Last change time
2019-12-12T14:01:25Z
Keywords
pull
Assigned to
Andrei Alexandrescu
Creator
Rob Jacques
Comments
Comment #0 by sandford — 2010-09-17T10:14:54Z
std.range.put does not correctly introspect types which implement put via opDispatch. This is fairly simple to fix by swapping hasMember out for a __traits compiles test.
void put(R, E)(ref R r, E e)
{
+ static if (__traits(compiles, {return R.init.put(E.init);}) )
- static if (hasMember!(R, "put") ||
- (isPointer!R && is(pointerTarget!R == struct) &&
- hasMember!(pointerTarget!R, "put")))
{
Comment #1 by dsimcha — 2010-09-17T10:38:01Z
This is a rather problematic bug. If we use your patch, it will break when uniform function call syntax is fully implemented. I guess what we need is for hasMember to be less restrictive. It should include opDispatch, and while we're at it, pointers to structs.
Comment #2 by sandford — 2010-09-17T12:33:14Z
Well half of puts' functionality is to emulate uniform function call syntax for structs and classes: i.e. re-write put(r,e) into r.put(e). So I'd expect UFC to break put with or without this patch.
I had thought of improving hasMembers (either the __traits or templated version) to support opDispatch, however, I do not think that it is possible. The problem is template constraints. Consider the highly synthetic example:
void opDispatch(string name, T...)
if( name.length == T.length ) {}
Because the template constraint could be non-trivially dependent on something more than name there's no way to check if r.opDispatch!"put" is valid without actually evaluating r.put(e) (i.e. __traits(compiles,...))
I close this, because the bug is very old, the code (for ranges) has had lots of changes since then and no example is provided. I also was not able to provide an example myself, but I cannot say, if this was due to my missing skills or the bug being fixed meanwhile. If anyone can provide an example, please feel free to reopen!