Bug 6419 – [CTFE] Cannot create a non-static nested struct
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
All
Creation time
2011-07-31T15:54:00Z
Last change time
2013-02-08T15:17:48Z
Keywords
CTFE, rejects-valid
Assigned to
nobody
Creator
kennytm
Comments
Comment #0 by kennytm — 2011-07-31T15:54:28Z
Test case 1:
----------------------
static assert({
struct Result {
this(int x) {}
}
auto x = Result(1); // <-- line 5
return true;
}());
----------------------
x.d(5): Error: CTFE internal error assigning struct
x.d(7): Error: cannot evaluate delegate @system bool()
{
struct Result
{
this(int x)
{
return this;
}
void* this;
}
Result x = x = 0 , x.this(1);
return true;
}
() at compile time
...
----------------------
Test case 2 (causes ICE):
----------------------
static assert(({
struct Result {
this(int x) {}
}
return Result(1);
}(), true));
----------------------
x.d(6): Error: CTFE internal error assigning struct
Bus error: 10
----------------------
This bug affects using std.algorithm.map in CTFE, although I don't see any point keeping that constructor any more.
Comment #1 by clugdbug — 2011-08-11T23:39:26Z
*** Issue 6460 has been marked as a duplicate of this issue. ***
Comment #2 by clugdbug — 2011-08-11T23:43:40Z
This is because if the struct is nested, TypeStruct::defaultInitLiteral() doesn't return a literal!
Comment #3 by clugdbug — 2011-08-23T13:31:26Z
The bug which caused an ICE was independent to this one, and has been fixed.
Comment #4 by clugdbug — 2011-09-29T01:21:18Z
*** Issue 6653 has been marked as a duplicate of this issue. ***
Comment #5 by clugdbug — 2011-12-29T02:50:58Z
Actually, it doesn't need a constructor. The presence of _any_ member function triggers the bug:
static assert({
struct Result {
void foo(){}
}
Result x;
return true;
}());
If it doesn't have any member functions, then it is actually a static nested struct. So true nested structs are never supported in CTFE.
It's because the hidden member of the struct needs a pointer to the enclosing function, and this is not implemented.
Comment #6 by aliloko — 2012-07-02T12:32:26Z
This is sad because you can't do compile-time FizzBuzz :)
-------------------
import std.stdio, std.conv, std.range, std.algorithm;
void main()
{
enum fizzbuzz = iota(1, 100)
.map!(x =>
(0 == x % 15) ? "FizzBuzz" :
(0 == x % 5) ? "Buzz" :
(0 == x % 3) ? "Fizz" : to!string(x))
.joiner("\n");
writeln(fizzbuzz);
}
-------------------
Comment #7 by andrej.mitrovich — 2013-02-08T15:17:48Z