foreach on a tuple using aliases

Steven Schveighoffer schveiguy at gmail.com
Sun Aug 5 14:07:30 UTC 2018


I have found something that looks like a bug to me, but also looks like 
it could simply be a limitation of the foreach construct.

Consider this code:

struct Foo {}

enum isFoo(alias x) = is(typeof(x) == Foo);

void main()
{
     Foo foo;
     assert(isFoo!foo);
     static struct X { int i; Foo foo; }
     X x;
     foreach(i, ref item; x.tupleof)
         static if(is(typeof(item) == Foo))  // line A
             static assert(isFoo!item);      // line B
         else
             static assert(!isFoo!item);
}

Consider just the two lines A and B. If you saw those lines anywhere, 
given the isFoo definition, you would expect the assert to pass. But in 
this case, it fails.

What is happening is that the first time through the loop, we are 
considering x.i. This is an int, and not a Foo, so it assigns false to 
the template isFoo!item.

The second time through the loop on x.foo, the compiler decides that it 
ALREADY FIGURED OUT isFoo!item, and so it just substitutes false, even 
though the item in question is a different item.

So is this a bug? Is it expected? Is it too difficult to fix?

The workaround of course is to use x.tupleof[i] when instantiating 
isFoo. But it's a bit ugly. I can also see other issues cropping up if 
you use `item` for other meta things.

-Steve


More information about the Digitalmars-d-learn mailing list