The D language specification does not forbid downcasting in @safe code, but the compiler rejects it. Downcasting is actually safe because such casts are checked run-time. The minimal testcase is: ------- CODE ------- class A { } class B : A { } @safe void main() { A a = new A(); B b = cast(B) a; } ----- END CODE ----- The above code is rejected by the compiler with the following message: safe_downcast.d(7): Error: cast from safe_downcast.A to safe_downcast.B not allowed in safe code Possible enhancement: make DMD issue a warning if the result of a downcast is not checked for null.
You should use std.conv.to, and then in Phobos the toImpl specialization T toImpl(T, S)(S value) if (!isImplicitlyConvertible!(S, T) && is(S : Object) && !is(typeof(value.opCast!T()) : T) && is(T : Object) && !is(typeof(new T(value)))) should be made @trusted.
https://github.com/D-Programming-Language/dmd/pull/252
https://github.com/D-Programming-Language/dmd/commit/48b8cee356ef3b3681df26129d7b3f4d9dd9d34c