Bug 9563 – (2.062) typeof(T[0]) no longer works with array T's
Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-02-21T19:08:00Z
Last change time
2013-02-23T15:58:46Z
Keywords
rejects-valid
Assigned to
nobody
Creator
siegelords_abode
Comments
Comment #0 by siegelords_abode — 2013-02-21T19:08:04Z
Both invocations of ElemTypeOf used to work fine with DMD 2.061 but with DMD 2.062 only the class one works. Either none of them should work, or preferably both should work as they had since D1:
template ElemTypeOf( T )
{
alias typeof(T[0]) ElemTypeOf;
}
class A
{
int opIndex(size_t i)
{
return 0;
}
}
void main()
{
ElemTypeOf!(A) a;
ElemTypeOf!(int[]) b;
static assert(is(typeof(a) == int));
static assert(is(typeof(b) == int));
}
With dmd 2.062 the second invocation now gives the error:
test.d(3): Error: argument int[][0LU] to typeof is not an expression
test.d(3): Error: argument int[][0LU] to typeof is not an expression
test.d(17): Error: template instance test.ElemTypeOf!(int[]) error instantiating
test.d(20): Error: static assert (is(_error_ == int)) is false
Comment #1 by Marco.Leise — 2013-02-21T21:03:11Z
You made me smile. I recently needed ElementType! in my code for arrays. I had almost written a simple template, but remembered that Phobos had it already. And I thought "I better use the Phobos one, that's sure to still work in the future. Not that it's likely that typeof(T[0]) breaks anytime soon... but still." Sometimes you have these gut feelings you can't even explain to co-workers.
Sorry for the noise.
Comment #2 by monarchdodra — 2013-02-21T22:39:48Z
(In reply to comment #0)
> Both invocations of ElemTypeOf used to work fine with DMD 2.061 but with DMD
> 2.062 only the class one works. Either none of them should work, or preferably
> both should work as they had since D1:
What do you mean "only the class one works"? I'm getting a failure for both asserts.
Furthermore, I expect a failure. Your ElemTypeOf simply declares a static array of size 0 of your type, it is not actually calling opIndex. Then combining it with calling "typeof" on something that is already a type, makes this dobly wrong code.
This worked in 2.060, but was fixed starting in 2.061.
Try something like this:
template ElemTypeOf( T )
{
static private T t = T.init;
alias typeof(t[0]) ElemTypeOf;
}
Or better yet, std.range's ElementType or ElementEncodingType.
Comment #3 by siegelords_abode — 2013-02-22T07:35:52Z
> What do you mean "only the class one works"? I'm getting a failure for both
> asserts.
I am not with DMD 2.062. This code compiles without any error and prints "int":
template ElemTypeOf( T )
{
alias typeof(T[0]) ElemTypeOf;
}
class A
{
int opIndex(size_t i)
{
return 0;
}
}
void main()
{
ElemTypeOf!(A) a;
pragma(msg, typeof(a).stringof);
static assert(is(typeof(a) == int));
}
> This worked in 2.060, but was fixed starting in 2.061.
>
> Try something like this:
>
> template ElemTypeOf( T )
> {
> static private T t = T.init;
> alias typeof(t[0]) ElemTypeOf;
> }
I guess that works (with some simplification of course), although the existence of a workaround does not negate the existence of the regression.
> Or better yet, std.range's ElementType or ElementEncodingType.
Not using Phobos.
Comment #4 by monarchdodra — 2013-02-22T07:54:25Z
(In reply to comment #3)
> > What do you mean "only the class one works"? I'm getting a failure for both
> > asserts.
>
> I am not with DMD 2.062. This code compiles without any error and prints "int":
>
> > This worked in 2.060, but was fixed starting in 2.061.
My bad, I must have botched the test. That does indeed work in 2.061, so was broken in 2.062.
> > Try something like this:
> >
> > template ElemTypeOf( T )
> > {
> > static private T t = T.init;
> > alias typeof(t[0]) ElemTypeOf;
> > }
>
> I guess that works (with some simplification of course), although the existence
> of a workaround does not negate the existence of the regression.
Well, as I said, I think this is not a matter of regression and workaround, but rather wrong code finally getting rejected, and new and correct code being deployed to replace it.
In any case, I'll let one of the more compiler knowledgeable guys (Kenji? Walter) give you definitive answer.
Comment #5 by schveiguy — 2013-02-22T08:21:07Z
This is indeed a bug that was fixed.
T[0] is applying index to the type, not an instance of the type. I wouldn't expect typeof(T[0]) to work at all, it's like saying typeof(int) (which doesn't compile), typeof converts an expression into its type.
You should be able to do typeof(T.init[0]).