www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.traits functions causing the compiler to crash

reply "Eric" <eric makechip.com> writes:
mport std.traits;

interface Xidentity(V, K) {
     static if (hasMember!(V, "k")) static assert(0);
     public int getInstanceCount();
}

class X(K) : Xidentity!(X!(K), K) {
     private K k;

     X newInstance(K k) { return(new X(k)); }

     private this(K k) { this.k = k; }
     public int getInstanceCount() { return(5); }
}

void main() {
     auto x = new X!(double)(6.0);
}

If I compile the above code, the static if statement in the 
interface
declaration causes the compiler to segfault without any other 
information.
gdb give the following stacktrace:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xf75106c0 (LWP 30889)]
0x08170d26 in TraitsExp::semantic ()
Current language:  auto; currently asm
(gdb) backtrace
#0  0x08170d26 in TraitsExp::semantic ()
#1  0x0809a51a in Expression::ctfeSemantic ()
#2  0x081446da in TemplateInstance::semanticTiargs ()
#3  0x08145035 in TemplateInstance::semanticTiargs ()
#4  0x08148f04 in TemplateInstance::semantic ()
#5  0x08149470 in TemplateInstance::semantic ()
#6  0x0809feae in ScopeExp::semantic ()
#7  0x0809fcfd in BinExp::semantic ()
#8  0x080ac66e in BinExp::semanticp ()
#9  0x080ac7bc in EqualExp::semantic ()
#10 0x080aa75e in OrOrExp::semantic ()
#11 0x0809a51a in Expression::ctfeSemantic ()
#12 0x08077bee in VarDeclaration::semantic ()
#13 0x0804ccc5 in StaticIfDeclaration::semantic ()
#14 0x0813fc49 in TemplateInstance::expandMembers ()
#15 0x0813fc8c in TemplateInstance::tryExpandMembers ()
#16 0x08148ce0 in TemplateInstance::semantic ()
#17 0x08149470 in TemplateInstance::semantic ()
#18 0x0809feae in ScopeExp::semantic ()
#19 0x0809a51a in Expression::ctfeSemantic ()
#20 0x080713c4 in StaticIfCondition::include ()
#21 0x0804b443 in ConditionalDeclaration::include ()
#22 0x0804cd40 in StaticIfDeclaration::include ()
#23 0x0804cc95 in StaticIfDeclaration::semantic ()
#24 0x0806a0f0 in InterfaceDeclaration::semantic ()
#25 0x0813fc49 in TemplateInstance::expandMembers ()
#26 0x0813fc8c in TemplateInstance::tryExpandMembers ()
#27 0x08148ce0 in TemplateInstance::semantic ()
#28 0x08149470 in TemplateInstance::semantic ()
#29 0x080fcd13 in TypeInstance::resolve ()
#30 0x080f9a4d in TypeInstance::semantic ()
#31 0x080685b0 in ClassDeclaration::semantic ()
#32 0x0813fc49 in TemplateInstance::expandMembers ()
#33 0x0813fc8c in TemplateInstance::tryExpandMembers ()
#34 0x08148ce0 in TemplateInstance::semantic ()
#35 0x08149470 in TemplateInstance::semantic ()
#36 0x080fcd13 in TypeInstance::resolve ()
#37 0x080f9a4d in TypeInstance::semantic ()
#38 0x080af314 in NewExp::semantic ()
#39 0x080deaf4 in ExpInitializer::inferType ()
#40 0x08077560 in VarDeclaration::semantic ()
#41 0x080a3ea1 in DeclarationExp::semantic ()
#42 0x0812cc41 in ExpStatement::semantic ()
#43 0x08138c91 in CompoundStatement::semantic ()
#44 0x080c0cf5 in FuncDeclaration::semantic3 ()
#45 0x080f16bb in Module::semantic3 ()
#46 0x080edf5c in tryMain ()
#47 0x080efab2 in main ()

I'm using compiler version v2.063-devel-53aa503.
Is this a known problem, or is there a work-around?

Thanks,

Eric
Jun 07 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Eric:

 Is this a known problem, or is there a work-around?
This is your code reduced a little: import std.traits: hasMember; interface Xidentity(V, K) if (!hasMember!(V, "x")) { } class Foo(K): Xidentity!(Foo!K, K) { K x; } void main() { new Foo!double; } I think it contains a loop at the level of types. In theory the compiler should catch them and give a nice error message. You probably want to use the template constraint syntax, as I have used. In D return is not a function, so don't use the ( ). Bye, bearophile
Jun 07 2013
parent reply "Eric" <eric makechip.com> writes:
O
 import std.traits: hasMember;
 interface Xidentity(V, K) if (!hasMember!(V, "x")) {
 }
 class Foo(K): Xidentity!(Foo!K, K) {
     K x;
 }
 void main() {
     new Foo!double;
 }


 I think it contains a loop at the level of types. In theory the 
 compiler should catch them and give a nice error message.

 You probably want to use the template constraint syntax, as I 
 have used.
Yes, the template constraint is much better. However, the compiler still crashes, even with the new code: import std.traits: hasMember; interface Identity(V, K) if (!hasMember!(V, "k")) { } class Foo(K): Identity!(Foo!K, K) { K k; } void main() { new Foo!double; } (dmd7) mrbig:~/tp/d_test2/dlib>dmd Test.d Segmentation fault (core dumped)
 In D return is not a function, so don't use the ( ).
Yeah, I know. return returns an expression, and parenthesis are legal expression syntax:) -Eric
Jun 07 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Eric:

 Yes, the template constraint is much better.  However, the 
 compiler still crashes, even with the new code:
Because there's a type definition loop, regardless. Using a constraint doesn't change that situation. Bye, bearophile
Jun 07 2013
parent reply "Eric" <eric makechip.com> writes:
On Saturday, 8 June 2013 at 02:32:57 UTC, bearophile wrote:
 Eric:

 Yes, the template constraint is much better.  However, the 
 compiler still crashes, even with the new code:
Because there's a type definition loop, regardless. Using a constraint doesn't change that situation. Bye, bearophile
How is there a type definition loop? I'm just trying to constrain the interface. At a minimum this should be a compiler bug, but I would hope that dimple constraints would work. -Eric
Jun 07 2013
parent "Regan Heath" <regan netmail.co.nz> writes:
On Sat, 08 Jun 2013 05:52:49 +0100, Eric <eric makechip.com> wrote:

 On Saturday, 8 June 2013 at 02:32:57 UTC, bearophile wrote:
 Eric:

 Yes, the template constraint is much better.  However, the compiler  
 still crashes, even with the new code:
Because there's a type definition loop, regardless. Using a constraint doesn't change that situation. Bye, bearophile
How is there a type definition loop? I'm just trying to constrain the interface. At a minimum this should be a compiler bug, but I would hope that dimple constraints would work.
There is a type loop but I agree the compiler should really be able to catch it. Using bearophile's short example.. import std.traits: hasMember; interface Xidentity(V, K) if (!hasMember!(V, "x")) { } class Foo(K): Xidentity!(Foo!K, K) { K x; } void main() { new Foo!double; } The compiler starts by generating the template for Foo(double), requiring Xidentity(Foo!double,.. requiring Foo(double), requiring Xidentity(Foo!double,.., and so on.. It should really be able to detect that it is re-generating the original Foo(double) and simply re-use/terminate the loop there, I think. (I am no compiler expert however) R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Jun 11 2013