Thread overview
Cannot cast X to Y at compile time...?
Mar 19, 2014
dnspies
Mar 19, 2014
Frustrated
Mar 20, 2014
dnspies
Mar 21, 2014
Kapps
Mar 21, 2014
Timon Gehr
March 19, 2014
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?

March 19, 2014
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.
March 20, 2014
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.
March 21, 2014
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.

March 21, 2014
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.