Bug 11722 – Qualifier-only casts should not invoke opCast
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-12-10T17:17:00Z
Last change time
2013-12-12T23:49:57Z
Keywords
pull, wrong-code
Assigned to
nobody
Creator
k.hara.pg
Comments
Comment #0 by k.hara.pg — 2013-12-10T17:17:25Z
This is a spin-off issue from bug 5747.
D has a cast syntax for modifying just only the type qualifier of the operand.
http://dlang.org/expression#CastExpression
CastExpression:
cast ( Type ) UnaryExpression
cast ( CastQual ) UnaryExpression <--
cast ( ) UnaryExpression <--
However, if the operand is class or struct, and has opCast member function, the qualifier-cast cast(qual)exp is translated to cast(qual(typeof(exp))exp, then it will unintendedly invoke opCast. For example, following code wrongly asserts in C.opCast.
class C
{
T opCast(T)() { assert(0); }
}
void main()
{
C c = new C();
shared C sc = cast(shared)c;
}
I think this is not good behavior in generic code, and should be fixed.
I find the existing behavior reasonable enough, provided it is cast(qual(unqual(typeof(exp)))exp instead of cast(qual(typeof(exp))exp.
Comment #4 by samukha — 2013-12-11T12:20:07Z
I disagree. That was not necessary, unless you prove otherwise.
Comment #5 by monarchdodra — 2013-12-12T23:34:46Z
(In reply to comment #0)
> This is a spin-off issue from bug 5747.
>
> D has a cast syntax for modifying just only the type qualifier of the operand.
>
> http://dlang.org/expression#CastExpression
>
> CastExpression:
> cast ( Type ) UnaryExpression
> cast ( CastQual ) UnaryExpression <--
> cast ( ) UnaryExpression <--
Kenji: I'm wondering: Your original post seemed to imply the enhancement was *only* for qualifier cast. However, the final result seems to be for *any* kind of cast, whith matching types. I mean:
const(S) s;
auto a = cast() s;
auto b = cast(S) s;
In the case of "a": We have a "CastQual" type cast, and this bypasses the opCast operator entirelly.
In the case of "b": We have a *Type* cast, but that happens to result only in a qualifier change.
In the case of "b", *should* we call opCast? Please clarify.
Comment #6 by k.hara.pg — 2013-12-12T23:44:33Z
(In reply to comment #5)
> (In reply to comment #0)
> > This is a spin-off issue from bug 5747.
> >
> > D has a cast syntax for modifying just only the type qualifier of the operand.
> >
> > http://dlang.org/expression#CastExpression
> >
> > CastExpression:
> > cast ( Type ) UnaryExpression
> > cast ( CastQual ) UnaryExpression <--
> > cast ( ) UnaryExpression <--
>
> Kenji: I'm wondering: Your original post seemed to imply the enhancement was
> *only* for qualifier cast. However, the final result seems to be for *any* kind
> of cast, whith matching types. I mean:
>
> const(S) s;
> auto a = cast() s;
> auto b = cast(S) s;
>
> In the case of "a": We have a "CastQual" type cast, and this bypasses the
> opCast operator entirelly.
> In the case of "b": We have a *Type* cast, but that happens to result only in a
> qualifier change.
>
> In the case of "b", *should* we call opCast? Please clarify.
Yes.
And actually, with git-head, following code asserts only in the case of "b".
struct S {
T opCast(T)() const { assert(0); }
}
void main()
{
const(S) s;
auto a = cast() s; // bypass opCast
auto b = cast(S) s; // call opCast and assert
}
Comment #7 by monarchdodra — 2013-12-12T23:49:57Z
(In reply to comment #6)
> (In reply to comment #5)
> > (In reply to comment #0)
> > > This is a spin-off issue from bug 5747.
> > >
> > > D has a cast syntax for modifying just only the type qualifier of the operand.
> > >
> > > http://dlang.org/expression#CastExpression
> > >
> > > CastExpression:
> > > cast ( Type ) UnaryExpression
> > > cast ( CastQual ) UnaryExpression <--
> > > cast ( ) UnaryExpression <--
> >
> > Kenji: I'm wondering: Your original post seemed to imply the enhancement was
> > *only* for qualifier cast. However, the final result seems to be for *any* kind
> > of cast, whith matching types. I mean:
> >
> > const(S) s;
> > auto a = cast() s;
> > auto b = cast(S) s;
> >
> > In the case of "a": We have a "CastQual" type cast, and this bypasses the
> > opCast operator entirelly.
> > In the case of "b": We have a *Type* cast, but that happens to result only in a
> > qualifier change.
> >
> > In the case of "b", *should* we call opCast? Please clarify.
>
> Yes.
> And actually, with git-head, following code asserts only in the case of "b".
Ah. Oops. I was testing the wrong code. Thanks.