Casting to interface not allowed in @safe code?

Marco de Wild mdwild at sogyo.nl
Tue May 21 07:19:38 UTC 2019


On Tuesday, 21 May 2019 at 05:51:30 UTC, Jim wrote:
> Hi,
>
> consider this:
>
> interface Base
> {
>   void setup();
> }
>
> interface FeatureX
> {
>   void x();
> }
>
> class Foo: Base, FeatureX
> {
>   void setup(){};
>   void x(){};
> }
>
> void main()
> {
>   Base foo = new Foo(); // This would be the result of a 
> factory class
>
>   (cast(FeatureX)foo).x(); // 1
> }
>
> 1) error: casting to interface FeatureX is not allowed in @safe 
> code.
>
> Question: How to call foo.x in @safe code ?

I got it compiling using `(cast(FeatureX)(cast(Foo)foo)).x();`, 
but I don't really recommend it. As far as the compiler is 
concerned, `Base` and `FeatureX` are not related in any way (I'd 
still expect it to work though). I don't know the circumstances 
of your problem (so some assumptions here), but usually casting 
is not the best option. You are basically overriding the type 
system manually. Some suggestions you can evaluate:
- Extend the base interface:
interface FeatureX : Base { /+...+/}
or
interface Combined : FeatureX, Base {}

- Change the factory class to return either Foo, FeatureX or a 
templated type (if it's a more general factory class). This way 
we can leverage the type system.

- You can also make the cast @trusted, but that seems like it 
kinda defeats the purpose of the function being @safe...

---
Returning to the original point (the cast is disallowed in safe 
code), I don't think it is listed in the spec: 
https://dlang.org/spec/function.html#safe-functions Unless I am 
missing some implementation details about interfaces, I would 
expect it to work just like class casts (i.e. return null on a 
failed cast, thereby having defined behaviour, thereby being 
@safe).



More information about the Digitalmars-d-learn mailing list