Skip to content

Commit 3141b78

Browse files
committed
Forbid casts of raw pointers to trait objects with the same trait, but different args
1 parent 622ca1d commit 3141b78

File tree

4 files changed

+31
-19
lines changed

4 files changed

+31
-19
lines changed

compiler/rustc_hir_typeck/src/cast.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use rustc_middle::ty::cast::{CastKind, CastTy};
4242
use rustc_middle::ty::error::TypeError;
4343
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitableExt, VariantDef};
4444
use rustc_session::lint;
45-
use rustc_span::def_id::{DefId, LOCAL_CRATE};
45+
use rustc_span::def_id::LOCAL_CRATE;
4646
use rustc_span::symbol::sym;
4747
use rustc_span::Span;
4848
use rustc_trait_selection::infer::InferCtxtExt;
@@ -72,7 +72,7 @@ enum PointerKind<'tcx> {
7272
/// No metadata attached, ie pointer to sized type or foreign type
7373
Thin,
7474
/// A trait object
75-
VTable(Option<DefId>),
75+
VTable(Option<ty::Binder<'tcx, ty::ExistentialTraitRef<'tcx>>>),
7676
/// Slice
7777
Length,
7878
/// The unsize info of this projection or opaque type
@@ -100,7 +100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
100100

101101
Ok(match *t.kind() {
102102
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
103-
ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())),
103+
ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal())),
104104
ty::Adt(def, args) if def.is_struct() => match def.non_enum_variant().tail_opt() {
105105
None => Some(PointerKind::Thin),
106106
Some(f) => {

tests/ui/cast/cast-rfc0401-vtable-kinds.rs

-12
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,6 @@ impl<T> Foo<T> for () {}
1616
impl Foo<u32> for u32 { fn foo(&self, _: u32) -> u32 { self+43 } }
1717
impl Bar for () {}
1818

19-
unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo<u32>+'a)) -> u32 {
20-
let foo_e : *const dyn Foo<u16> = t as *const _;
21-
let r_1 = foo_e as *mut dyn Foo<u32>;
22-
23-
(&*r_1).foo(0)
24-
}
25-
2619
#[repr(C)]
2720
struct FooS<T:?Sized>(T);
2821
#[repr(C)]
@@ -38,11 +31,6 @@ fn tuple_i32_to_u32<T:?Sized>(u: *const (i32, T)) -> *const (u32, T) {
3831

3932

4033
fn main() {
41-
let x = 4u32;
42-
let y : &dyn Foo<u32> = &x;
43-
let fl = unsafe { round_trip_and_call(y as *const dyn Foo<u32>) };
44-
assert_eq!(fl, (43+4));
45-
4634
let s = FooS([0,1,2]);
4735
let u: &FooS<[u32]> = &s;
4836
let u: *const FooS<[u32]> = u;

tests/ui/cast/ptr-to-trait-obj-different-args.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ fn main() {
1919
let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid
2020

2121
let x: *const dyn Trait<X> = &();
22-
let y: *const dyn Trait<Y> = x as _;
22+
let y: *const dyn Trait<Y> = x as _; //~ error: casting `*const dyn Trait<X>` as `*const dyn Trait<Y>` is invalid
2323

2424
_ = (b, y);
2525
}
2626

2727
fn generic<T>(x: *const dyn Trait<X>, t: *const dyn Trait<T>) {
28-
let _: *const dyn Trait<T> = x as _;
29-
let _: *const dyn Trait<X> = t as _;
28+
let _: *const dyn Trait<T> = x as _; //~ error: casting `*const (dyn Trait<X> + 'static)` as `*const dyn Trait<T>` is invalid
29+
let _: *const dyn Trait<X> = t as _; //~ error: casting `*const (dyn Trait<T> + 'static)` as `*const dyn Trait<X>` is invalid
3030
}

tests/ui/cast/ptr-to-trait-obj-different-args.stderr

+25-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,30 @@ LL | let b: *const dyn B = a as _;
66
|
77
= note: vtable kinds may not match
88

9-
error: aborting due to 1 previous error
9+
error[E0606]: casting `*const dyn Trait<X>` as `*const dyn Trait<Y>` is invalid
10+
--> $DIR/ptr-to-trait-obj-different-args.rs:22:34
11+
|
12+
LL | let y: *const dyn Trait<Y> = x as _;
13+
| ^^^^^^
14+
|
15+
= note: vtable kinds may not match
16+
17+
error[E0606]: casting `*const (dyn Trait<X> + 'static)` as `*const dyn Trait<T>` is invalid
18+
--> $DIR/ptr-to-trait-obj-different-args.rs:28:34
19+
|
20+
LL | let _: *const dyn Trait<T> = x as _;
21+
| ^^^^^^
22+
|
23+
= note: vtable kinds may not match
24+
25+
error[E0606]: casting `*const (dyn Trait<T> + 'static)` as `*const dyn Trait<X>` is invalid
26+
--> $DIR/ptr-to-trait-obj-different-args.rs:29:34
27+
|
28+
LL | let _: *const dyn Trait<X> = t as _;
29+
| ^^^^^^
30+
|
31+
= note: vtable kinds may not match
32+
33+
error: aborting due to 4 previous errors
1034

1135
For more information about this error, try `rustc --explain E0606`.

0 commit comments

Comments
 (0)