Bug 4953 – Regression(2.031): templates don't do implicit conversion properly
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-09-28T14:13:00Z
Last change time
2012-07-10T08:38:27Z
Keywords
pull, rejects-valid
Assigned to
bugzilla
Creator
schveiguy
Comments
Comment #0 by schveiguy — 2010-09-28T14:13:57Z
Given this struct:
struct S
{
short _x;
bool opBinaryRight(string op)(short x) if (op == "in")
{
return x == _x;
}
}
void main()
{
S s;
5 in s;
}
This produces the error:
testopin.d(13): Error: rvalue of in expression must be an associative array, not S
But change the type of x to int, and it works. However, the type of the argument should play no role in whether the template can be instantiated. It seems this is the error message that is given when a type does not support opIn, so the error message is very bad too.
Slightly related, but not the same issue: bug 3905
Comment #1 by schveiguy — 2010-09-29T06:06:21Z
Further evidence, this compiles:
void main()
{
S s;
s.opBinaryRight!"in"(5);
}
Comment #2 by clugdbug — 2010-09-30T01:48:40Z
(In reply to comment #1)
> Further evidence, this compiles:
>
> void main()
> {
> S s;
> s.opBinaryRight!"in"(5);
> }
This is not specific to "in". The code below fails to compile, but it works if you change "short" to "int".
struct S
{
void opBinary(string op)(short x)
{}
}
void main()
{
S s;
s + 5;
}
Original title for this bug was:
opBinaryRight for "in" doesn't work right
Comment #3 by clugdbug — 2010-09-30T09:47:34Z
Wow. This is a lot more general than I thought. Consider this code:
void foo(T = void)(short x) {}
void main()
{
foo(5);
}
This compiled in 2.030, failed in 2.031 and later.
However, if you change 'short' to 'long', it works.
It's because of mtype.c, TypeBasic::implicitConvTo(), line 3010.
Implicit conversion to a smaller size is disallowed. That's fine in general, but shouldn't be true of template deduction.
Comment #4 by bearophile_hugs — 2010-09-30T10:19:37Z
*** Issue 6567 has been marked as a duplicate of this issue. ***
Comment #9 by ebaklund — 2011-09-25T01:38:23Z
Yet another example:
module main;
struct MyStruct
{
void funOpAssign(float[1u] data) { }
void opOpAssign(string op)(float[1u] data) if(op=="<<") { }
}
int main(string[] argv)
{
// dmd v2.054, v2.055
MyStruct s;
float[1u] a = [1.0f]; // OK: Implicit cast from float[] compiles
s.funOpAssign([1.0f]); // OK: Implicit cast from float[] compiles
s <<= [1.0f]; // Issue: Implicit cast from float[] does not compile
s <<= cast(float[1u])[1.0f]; // OK: Explicit cast from float[] compiles
return 0;
}
Comment #10 by yebblies — 2012-02-19T05:17:01Z
The pull is still valid (if in need of a rebase) but the solution needs a decision from Walter on how the match level problem is going to be solved in the future.
See issue 2367 for another example.
Comment #11 by hsteoh — 2012-03-19T08:04:35Z
Another data point:
void f(dstring d) { dstring e = d; }
f("abc"); // OK
void f()(dstring d) { dstring e = d; }
f("abc"); // OK
void f(byte[] b) { byte[] c = b; }
f([1,2,3]); // OK
void f()(byte[] b) { byte[] c = b; }
f([1,2,3]);
// Error: template test2.f() does not match any function template declaration
// Error: template test2.f() cannot deduce template function from argument types !()(int[])
Looking at this history of this bug and the pulls in github, it looks like there isn't a valid pull request that fixes this bug right now. Removing the keyword.
Comment #14 by k.hara.pg — 2012-05-12T10:19:09Z
(In reply to comment #13)
> Looking at this history of this bug and the pulls in github, it looks like
> there isn't a valid pull request that fixes this bug right now. Removing the
> keyword.
My dmd/pull/45 fixes both bug 5896 and this. I think the two bugs need the changes of each other.
Please keep 'pull' keyword.
Comment #15 by braddr — 2012-05-12T10:29:31Z
I'll add it back, but it looked like Walter was rejecting the pull request. It is still open, so might as well leave them linked.
Walter, would you put regression pull requests such as this one near the top of your todo list? Either reject with reasons or pull. Limbo sucks.
Comment #16 by github-bugzilla — 2012-05-12T11:35:46Z