Bug 10586 – DMD unable to interpret cascaded template calls at compile time
Status
RESOLVED
Resolution
DUPLICATE
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-07-09T11:31:00Z
Last change time
2013-08-25T17:44:43Z
Keywords
ice
Assigned to
nobody
Creator
puneet
Comments
Comment #0 by puneet — 2013-07-09T11:31:58Z
I am using latest github dmd -- 712c3e256b1198523bb8a5c49e5e08d3f8409855
Here is the minimized code for the regression.
$ dmd -c bvec.d
foo.d(12): Error: Cannot interpret FooSize!N at compile time
foo.d(13): while evaluating SIZE.init
foo.d(13): while looking for match for FooParams!(1LU)
foo.d(9): Error: template instance foo.foo!1 error instantiating
I think the regression got introduced while fixing 10579.
// Regression Code starts here
private template FooParams(size_t SIZE) {
private alias ubyte StoreT;
}
template FooSize(size_t N=1) {
enum size_t FooSize = N;
}
enum foo!1 BIT_0 = foo!1.init;
struct foo(size_t N) {
enum size_t SIZE = FooSize!N;
private alias FooParams!(SIZE).StoreT store_t;
}
Comment #1 by clugdbug — 2013-07-10T01:40:50Z
(In reply to comment #0)
> I think the regression got introduced while fixing 10579.
No, that's unrelated. This isn't a CTFE bug, it's a bug in enums. Semantic has not yet been run on the enum initializer. My guess is that this is a forward reference issue.
If you change it:
struct foo(size_t N) {
- enum size_t SIZE = FooSize!N;
+ enum size_t SIZE = 0 + FooSize!N;
then you get a segfault, because the type is still NULL.
My guess is that this was exposed by my "do const-folding in CTFE" patch. Previously these kinds of errors went undetected.
Comment #2 by clugdbug — 2013-07-10T02:54:12Z
Further reduced shows I'm wrong about it being enums:
------------
template FooParams(size_t K) {
alias int X;
}
struct foo {
static const int SIZE = int.sizeof;
alias FooParams!(SIZE).X Y;
}
-----------
bug.d(6): Error: Cannot interpret int at compile time
bug.d(7): while evaluating SIZE.init
bug.d(7): while looking for match for FooParams!(4)
---
A very difficult related case is this one:
const int Z = baz(3);
const int W = baz(2);
int baz(int k) {
if (k == 3) return W;
return 6;
}
static assert(Z == 6);
because it means that baz cannot be JIT-compiled. Arguably this is a circular reference. It would be much simpler and would give better performance if we disallowed pseudo-circular refs.
Comment #3 by k.hara.pg — 2013-08-25T17:44:43Z
The same regression was reported in 10669, and it was already fixed by Rainer Schuetze in git-head.
*** This issue has been marked as a duplicate of issue 10669 ***