www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Cannot cast X to Y at compile time...?

reply "dnspies" <dspies ualberta.ca> writes:
I have a function called at CTFE which includes the lines:

97	if(conjunction exp = cast(conjunction)this_exp) {
98		inner_substitutions!(first,conjunction)(exp, map);
99	} else if(disjunction exp = cast(disjunction)this_exp) {
100		inner_substitutions!(first,disjunction)(exp, map);
101	}

Here, this_exp is a reference of type "expression" to an object 
whose CTFE-runtime-type is of type "disjunction".  conjunction 
and disjunction are both descendent classes of expression.
This code produces the following compilation error:

source/cfgparse.d(97): Error: cannot cast [...] to 
cfgparse.conjunction at compile time.

([...] stands in for a very long string which I think is some 
sort of representation of this_exp)

Just for the hell of it, I tried moving the assignment out of the 
conditional, and something very strange happens.

97	if(cast(conjunction)this_exp) {
98		conjunction exp = cast(conjunction)this_exp;
99		inner_substitutions!(first,conjunction)(exp, map);
100	} else if(cast(disjunction)this_exp) {
101		disjunction exp = cast(disjunction)this_exp;
102		inner_substitutions!(first,disjunction)(exp, map);
103	}

source/cfgparse.d(101): Error: cannot cast [...] to 
cfgparse.disjunction at compile time

Both the conditions compile properly, and now only the assignment 
fails.  Why  is this happening and how can I avoid it?
Mar 19 2014
next sibling parent reply "Frustrated" <Frustrated nowhere.com> writes:
On Wednesday, 19 March 2014 at 16:57:38 UTC, dnspies wrote:
 I have a function called at CTFE which includes the lines:

 97	if(conjunction exp = cast(conjunction)this_exp) {
 98		inner_substitutions!(first,conjunction)(exp, map);
 99	} else if(disjunction exp = cast(disjunction)this_exp) {
 100		inner_substitutions!(first,disjunction)(exp, map);
 101	}

 Here, this_exp is a reference of type "expression" to an object 
 whose CTFE-runtime-type is of type "disjunction".  conjunction 
 and disjunction are both descendent classes of expression.
 This code produces the following compilation error:

 source/cfgparse.d(97): Error: cannot cast [...] to 
 cfgparse.conjunction at compile time.

 ([...] stands in for a very long string which I think is some 
 sort of representation of this_exp)

 Just for the hell of it, I tried moving the assignment out of 
 the conditional, and something very strange happens.

 97	if(cast(conjunction)this_exp) {
 98		conjunction exp = cast(conjunction)this_exp;
 99		inner_substitutions!(first,conjunction)(exp, map);
 100	} else if(cast(disjunction)this_exp) {
 101		disjunction exp = cast(disjunction)this_exp;
 102		inner_substitutions!(first,disjunction)(exp, map);
 103	}

 source/cfgparse.d(101): Error: cannot cast [...] to 
 cfgparse.disjunction at compile time

 Both the conditions compile properly, and now only the 
 assignment fails.  Why  is this happening and how can I avoid 
 it?

I ran up to a similar situation when the thing trying to be cast was not what I thought it was. I.e., the error is exactly what it means. Try to create a this_exp that is a conjunction explicitly to see if that is the problem.
Mar 19 2014
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 03/21/2014 06:12 AM, Kapps wrote:
 On Thursday, 20 March 2014 at 21:32:08 UTC, dnspies wrote:
 Sorry, I don't understand.  When I cast something to the wrong
 type, I should just get a null reference, shouldn't I?  It
 shouldn't throw an error.

If the compiler can statically determine that the cast is invalid you get an error instead.

No. class C{} class D{} void main(){ C c=new C; D d=cast(D)c; // no error assert(c !is null); assert(d is null); } (In any case, his problem is that the cast fails in CTFE.)
 You can use something like 'static if(is(T :
 Foo))' to test at compile-time if T is implicitly convertible to Foo
 (I'm not certain the exact semantics) or 'static
 if(is(typeof(cast(Foo)T.init)))'.

 There's probably better ways to do it, and I recommend asking on D.learn
 to figure out how to do what you're looking for.

I guess it might be a compiler bug, but it is hard to tell lacking a complete example.
Mar 21 2014
prev sibling next sibling parent "dnspies" <dspies ualberta.ca> writes:
On Wednesday, 19 March 2014 at 20:43:59 UTC, Frustrated wrote:
 On Wednesday, 19 March 2014 at 16:57:38 UTC, dnspies wrote:
 I have a function called at CTFE which includes the lines:

 97	if(conjunction exp = cast(conjunction)this_exp) {
 98		inner_substitutions!(first,conjunction)(exp, map);
 99	} else if(disjunction exp = cast(disjunction)this_exp) {
 100		inner_substitutions!(first,disjunction)(exp, map);
 101	}

 Here, this_exp is a reference of type "expression" to an 
 object whose CTFE-runtime-type is of type "disjunction".  
 conjunction and disjunction are both descendent classes of 
 expression.
 This code produces the following compilation error:

 source/cfgparse.d(97): Error: cannot cast [...] to 
 cfgparse.conjunction at compile time.

 ([...] stands in for a very long string which I think is some 
 sort of representation of this_exp)

 Just for the hell of it, I tried moving the assignment out of 
 the conditional, and something very strange happens.

 97	if(cast(conjunction)this_exp) {
 98		conjunction exp = cast(conjunction)this_exp;
 99		inner_substitutions!(first,conjunction)(exp, map);
 100	} else if(cast(disjunction)this_exp) {
 101		disjunction exp = cast(disjunction)this_exp;
 102		inner_substitutions!(first,disjunction)(exp, map);
 103	}

 source/cfgparse.d(101): Error: cannot cast [...] to 
 cfgparse.disjunction at compile time

 Both the conditions compile properly, and now only the 
 assignment fails.  Why  is this happening and how can I avoid 
 it?

I ran up to a similar situation when the thing trying to be cast was not what I thought it was. I.e., the error is exactly what it means. Try to create a this_exp that is a conjunction explicitly to see if that is the problem.

Sorry, I don't understand. When I cast something to the wrong type, I should just get a null reference, shouldn't I? It shouldn't throw an error.
Mar 20 2014
prev sibling parent "Kapps" <opantm2+spam gmail.com> writes:
On Thursday, 20 March 2014 at 21:32:08 UTC, dnspies wrote:
 Sorry, I don't understand.  When I cast something to the wrong
 type, I should just get a null reference, shouldn't I?  It
 shouldn't throw an error.

If the compiler can statically determine that the cast is invalid you get an error instead. You can use something like 'static if(is(T : Foo))' to test at compile-time if T is implicitly convertible to Foo (I'm not certain the exact semantics) or 'static if(is(typeof(cast(Foo)T.init)))'. There's probably better ways to do it, and I recommend asking on D.learn to figure out how to do what you're looking for.
Mar 20 2014