@@ -959,8 +959,35 @@ impl<'a, 'tcx> CastCheck<'tcx> {
959
959
// dyn Auto -> dyn Auto'? ok.
960
960
( None , None ) => Ok ( CastKind :: PtrPtrCast ) ,
961
961
962
- // dyn Trait -> dyn Auto? should be ok, but we used to not allow it.
963
- // FIXME: allow this
962
+ // dyn Trait -> dyn Auto? not ok (for now).
963
+ //
964
+ // Although dropping the principal is already allowed for unsizing coercions
965
+ // (e.g. `*const (dyn Trait + Auto)` to `*const dyn Auto`), dropping it is
966
+ // currently **NOT** allowed for (non-coercion) ptr-to-ptr casts (e.g
967
+ // `*const Foo` to `*const Bar` where `Foo` has a `dyn Trait + Auto` tail
968
+ // and `Bar` has a `dyn Auto` tail), because the underlying MIR operations
969
+ // currently work very differently:
970
+ //
971
+ // * A MIR unsizing coercion on raw pointers to trait objects (`*const dyn Src`
972
+ // to `*const dyn Dst`) is currently equivalent to downcasting the source to
973
+ // the concrete sized type that it was originally unsized from first (via a
974
+ // ptr-to-ptr cast from `*const Src` to `*const T` with `T: Sized`) and then
975
+ // unsizing this thin pointer to the target type (unsizing `*const T` to
976
+ // `*const Dst`). In particular, this means that the pointer's metadata
977
+ // (vtable) will semantically change, e.g. for const eval and miri, even
978
+ // though the vtables will always be merged for codegen.
979
+ //
980
+ // * A MIR ptr-to-ptr cast is currently equivalent to a transmute and does not
981
+ // change the pointer metadata (vtable) at all.
982
+ //
983
+ // In addition to this potentially surprising difference between coercion and
984
+ // non-coercion casts, casting away the principal with a MIR ptr-to-ptr cast
985
+ // is currently considered undefined behavior:
986
+ //
987
+ // As a validity invariant of pointers to trait objects, we currently require
988
+ // that the principal of the vtable in the pointer metadata exactly matches
989
+ // the principal of the pointee type, where "no principal" is also considered
990
+ // a kind of principal.
964
991
( Some ( _) , None ) => Err ( CastError :: DifferingKinds { src_kind, dst_kind } ) ,
965
992
966
993
// dyn Auto -> dyn Trait? not ok.
0 commit comments