Bug 21683 – ref/non-ref opApply overloads used in foreach loops are ambiguous

Status
RESOLVED
Resolution
DUPLICATE
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-03-06T20:23:14Z
Last change time
2023-04-17T15:24:23Z
Assigned to
No Owner
Creator
Vladimir Panteleev

Comments

Comment #0 by dlang-bugzilla — 2021-03-06T20:23:14Z
/////////////////////////////// test.d ////////////////////////////// void main() { // D AAs auto-infer constness of the key, based on whether "ref" // iteration was requested or not: bool[int] aa; foreach (k, v; aa) pragma(msg, typeof(k)); // int foreach (ref k, v; aa) pragma(msg, typeof(k)); // const(int) // However, attempting to implement the same behavior in a custom // type does not appear to be possible. struct S { // One would think that the compiler would pick the // appropriate overload, based on whether ref is requested // or not: int opApply(int delegate( int, bool)); int opApply(int delegate(ref const int, bool)); } S s; // However, the following simply fails with an ambiguity error: foreach (k, v; s) {} } ///////////////////////////////////////////////////////////////////// Compiler output: int const(int) test.d(25): Error: `s.opApply` matches more than one declaration: `test.d(19)`: `int(int delegate(int, bool))` and: `test.d(20)`: `int(int delegate(ref const(int), bool))` test.d(25): Error: cannot uniquely infer `foreach` argument types This blocks wrapping native D AAs into custom types, or creating custom AA implementations.
Comment #1 by razvan.nitu1305 — 2023-04-17T15:24:23Z
This looks like a duplicate of 20912. It seems that functions/delegates are not properly checked during overload resolution when they are used as function parameters/arguments. *** This issue has been marked as a duplicate of issue 20912 ***