I'm trying to fold an array at compile time, and store the result in an enum. It works just fine when the enum (and call to fold) is at module-level, but compilation fails when its both contained within a struct and called using a lambda.
Here's a simple example of some failing code:
import std.algorithm.iteration;
import std.stdio;
struct Foo
{
// Version 1 (works)
//enum x = [ 1, 2, 3 ].fold!"a * b";
// Version 2 (works)
//enum x = [ 1, 2, 3 ].fold!mult;
// Version 3 (broken)
enum x = [ 1, 2, 3 ].fold!((a, b) => a * b);
pragma(msg, "x = ", x);
}
// Outside of the struct, it works
enum y = [ 1, 2, 3 ].fold!((a, b) => a * b);
pragma(msg, "y = ", y);
int mult(int a, int b)
{
return a * b;
}
void main(){}
(Versions 1 and 2, which are commented out, compile just fine. It's just Version 3 that has problems.)
Upon compiling, the following error is thrown:
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(3690): Error: `this.__lambda2` has no value
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(3690): while evaluating: `static assert(((int)).length == fun.length)`
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(3697): Error: `this.__lambda2` has no value
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(3718): Error: `this.__lambda2` has no value
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(3636): Error: template instance `broken.Foo.reduce!((a, b) => a * b).reduceImpl!(false, int[], int)` error instantiating
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\iteration.d(4086): instantiated from here: `reduce!(int[])`
.\broken.d(13): instantiated from here: `fold!(int[])`
x = .\broken.d(13): Error: CTFE failed because of previous errors in `fold`
.\broken.d(16): while evaluating `pragma(msg, x)`
y = 6
Failed: ["C:\\D\\dmd2\\windows\\bin\\dmd.exe", "-v", "-o-", ".\\broken.d", "-I."]
I've tried looking at the source code mentioned in the error, but the concepts it uses are beyond my current level of knowledge of D.
I initially assumed that lambdas might not work properly at compile-time, but enum y evaluates correctly, so I'm guessing it's not that...
I'm using DMD v2.086.1, but had the same problem using LDC 1.16.0 and 1.14.0.