Skip to content

Commit d9eb6d8

Browse files
author
Lukas Markeffsky
committed
elaborate why dropping principal in *dyn casts is non-trivial
1 parent b89751b commit d9eb6d8

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

Diff for: compiler/rustc_hir_typeck/src/cast.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -959,8 +959,15 @@ impl<'a, 'tcx> CastCheck<'tcx> {
959959
// dyn Auto -> dyn Auto'? ok.
960960
(None, None) => Ok(CastKind::PtrPtrCast),
961961

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+
// As a validity invariant of pointers to trait objects, we
965+
// currently require the layout of the vtable in the metadata
966+
// to exactly match the pointee's expected vtable layout.
967+
//
968+
// Since ptr-to-ptr casts, unlike unsizing coercions, cannot change
969+
// the pointer metadata, dropping a the principal in a (non-coercion)
970+
// cast is currently not allowed.
964971
(Some(_), None) => Err(CastError::DifferingKinds { src_kind, dst_kind }),
965972

966973
// dyn Auto -> dyn Trait? not ok.

Diff for: tests/ui/cast/ptr-to-trait-obj-drop-principal.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//! Test that non-coercion casts aren't allowed to drop the principal,
2+
//! because they cannot modify the pointer metadata.
3+
//!
4+
//! We test this in a const context to guard against UB if this is allowed
5+
//! in the future.
6+
7+
trait Trait {}
8+
impl Trait for () {}
9+
10+
struct Wrapper<T: ?Sized>(T);
11+
12+
const OBJECT: *const (dyn Trait + Send) = &();
13+
14+
// coercions are allowed
15+
const _: *const dyn Send = OBJECT as _;
16+
17+
// casts are **not** allowed
18+
const _: *const Wrapper<dyn Send> = OBJECT as _;
19+
//~^ ERROR casting `*const (dyn Trait + Send + 'static)` as `*const Wrapper<dyn Send>` is invalid
20+
21+
fn main() {}

Diff for: tests/ui/cast/ptr-to-trait-obj-drop-principal.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0606]: casting `*const (dyn Trait + Send + 'static)` as `*const Wrapper<dyn Send>` is invalid
2+
--> $DIR/ptr-to-trait-obj-drop-principal.rs:18:37
3+
|
4+
LL | const _: *const Wrapper<dyn Send> = OBJECT as _;
5+
| ^^^^^^^^^^^
6+
|
7+
= note: the trait objects may have different vtables
8+
9+
error: aborting due to 1 previous error
10+
11+
For more information about this error, try `rustc --explain E0606`.

0 commit comments

Comments
 (0)