You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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;
});
}
The text was updated successfully, but these errors were encountered:
Bolpat reported this on 2019-01-19T21:01:11Z
Transferred from https://issues.dlang.org/show_bug.cgi?id=19597
Description
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; }); }The text was updated successfully, but these errors were encountered: