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 ***