digitalmars.D.bugs - [Issue 19597] New: distinguish opApply overload on ref
- d-bugmail puremagic.com (78/78) Jan 19 2019 https://issues.dlang.org/show_bug.cgi?id=19597
https://issues.dlang.org/show_bug.cgi?id=19597 Issue ID: 19597 Summary: distinguish opApply overload on ref Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: qs.il.paperinik gmail.com When opApply overloads are considered for foreach resolution, that have different ref-ness, the better match should be taken. Currently, the compiler issues an ambiguity error. There are two cases: When inferring the iteration variable type, and with explicit types on the iteration variable. The case for inference: struct Test { const(int*) ptr; int opApply(scope int delegate(const(int)*) callback) { return callback(ptr); } int opApply(scope int delegate(ref const(int*)) callback) { return callback(ptr); } } void main() { Test t = Test(new const int(1)); foreach (p; t) { pragma(msg, typeof(p)); // should be const(int)* pragma(msg, __traits(isRef, p)); // should be false } foreach (ref p; t) { pragma(msg, typeof(p)); // should be const(int*) pragma(msg, __traits(isRef, p)); // should be true } } Making the types explicit solves this because the types aren't exactly the same. For explicit types on the iteration variable, change the first opApply overload to take const(int*). The compiler issues an ambiguity error while there is clearly a better overload for each of them. Calling opApply directly works: struct Test { const(int*) ptr; int opApply(scope int delegate(const(int*)) callback) { return callback(ptr); } int opApply(scope int delegate(ref const(int*)) callback) { return callback(ptr); } } void main() { t.opApply((const(int*) p) { pragma(msg, typeof(p)); // should be const(int*) pragma(msg, __traits(isRef, p)); // should be false return 0; }); t.opApply((ref const(int*) p) { pragma(msg, typeof(p)); // should be const(int*) pragma(msg, __traits(isRef, p)); // should be true return 0; }); } --
Jan 19 2019