Forbid casts of raw pointers to trait objects with the same trait, but different args
This commit is contained in:
parent
36b1f4411d
commit
d06cf5b399
@ -44,7 +44,7 @@
|
|||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitableExt, VariantDef};
|
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitableExt, VariantDef};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::def_id::{DefId, LOCAL_CRATE};
|
use rustc_span::def_id::LOCAL_CRATE;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
@ -73,7 +73,7 @@ enum PointerKind<'tcx> {
|
|||||||
/// No metadata attached, ie pointer to sized type or foreign type
|
/// No metadata attached, ie pointer to sized type or foreign type
|
||||||
Thin,
|
Thin,
|
||||||
/// A trait object
|
/// A trait object
|
||||||
VTable(Option<DefId>),
|
VTable(Option<ty::Binder<'tcx, ty::ExistentialTraitRef<'tcx>>>),
|
||||||
/// Slice
|
/// Slice
|
||||||
Length,
|
Length,
|
||||||
/// The unsize info of this projection or opaque type
|
/// The unsize info of this projection or opaque type
|
||||||
@ -101,7 +101,7 @@ fn pointer_kind(
|
|||||||
|
|
||||||
Ok(match *t.kind() {
|
Ok(match *t.kind() {
|
||||||
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
|
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
|
||||||
ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())),
|
ty::Dynamic(tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal())),
|
||||||
ty::Adt(def, args) if def.is_struct() => match def.non_enum_variant().tail_opt() {
|
ty::Adt(def, args) if def.is_struct() => match def.non_enum_variant().tail_opt() {
|
||||||
None => Some(PointerKind::Thin),
|
None => Some(PointerKind::Thin),
|
||||||
Some(f) => {
|
Some(f) => {
|
||||||
|
@ -16,13 +16,6 @@ impl<T> Foo<T> for () {}
|
|||||||
impl Foo<u32> for u32 { fn foo(&self, _: u32) -> u32 { self+43 } }
|
impl Foo<u32> for u32 { fn foo(&self, _: u32) -> u32 { self+43 } }
|
||||||
impl Bar for () {}
|
impl Bar for () {}
|
||||||
|
|
||||||
unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo<u32>+'a)) -> u32 {
|
|
||||||
let foo_e : *const dyn Foo<u32> = t as *const _;
|
|
||||||
let r_1 = foo_e as *mut dyn Foo<u32>;
|
|
||||||
|
|
||||||
(&*r_1).foo(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct FooS<T:?Sized>(T);
|
struct FooS<T:?Sized>(T);
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -38,11 +31,6 @@ fn tuple_i32_to_u32<T:?Sized>(u: *const (i32, T)) -> *const (u32, T) {
|
|||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = 4u32;
|
|
||||||
let y : &dyn Foo<u32> = &x;
|
|
||||||
let fl = unsafe { round_trip_and_call(y as *const dyn Foo<u32>) };
|
|
||||||
assert_eq!(fl, (43+4));
|
|
||||||
|
|
||||||
let s = FooS([0,1,2]);
|
let s = FooS([0,1,2]);
|
||||||
let u: &FooS<[u32]> = &s;
|
let u: &FooS<[u32]> = &s;
|
||||||
let u: *const FooS<[u32]> = u;
|
let u: *const FooS<[u32]> = u;
|
||||||
|
@ -19,12 +19,12 @@ fn main() {
|
|||||||
let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid
|
let b: *const dyn B = a as _; //~ error: casting `*const dyn A` as `*const dyn B` is invalid
|
||||||
|
|
||||||
let x: *const dyn Trait<X> = &();
|
let x: *const dyn Trait<X> = &();
|
||||||
let y: *const dyn Trait<Y> = x as _;
|
let y: *const dyn Trait<Y> = x as _; //~ error: casting `*const dyn Trait<X>` as `*const dyn Trait<Y>` is invalid
|
||||||
|
|
||||||
_ = (b, y);
|
_ = (b, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generic<T>(x: *const dyn Trait<X>, t: *const dyn Trait<T>) {
|
fn generic<T>(x: *const dyn Trait<X>, t: *const dyn Trait<T>) {
|
||||||
let _: *const dyn Trait<T> = x as _;
|
let _: *const dyn Trait<T> = x as _; //~ error: casting `*const (dyn Trait<X> + 'static)` as `*const dyn Trait<T>` is invalid
|
||||||
let _: *const dyn Trait<X> = t as _;
|
let _: *const dyn Trait<X> = t as _; //~ error: casting `*const (dyn Trait<T> + 'static)` as `*const dyn Trait<X>` is invalid
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,30 @@ LL | let b: *const dyn B = a as _;
|
|||||||
|
|
|
|
||||||
= note: vtable kinds may not match
|
= note: vtable kinds may not match
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error[E0606]: casting `*const dyn Trait<X>` as `*const dyn Trait<Y>` is invalid
|
||||||
|
--> $DIR/ptr-to-trait-obj-different-args.rs:22:34
|
||||||
|
|
|
||||||
|
LL | let y: *const dyn Trait<Y> = x as _;
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: vtable kinds may not match
|
||||||
|
|
||||||
|
error[E0606]: casting `*const (dyn Trait<X> + 'static)` as `*const dyn Trait<T>` is invalid
|
||||||
|
--> $DIR/ptr-to-trait-obj-different-args.rs:28:34
|
||||||
|
|
|
||||||
|
LL | let _: *const dyn Trait<T> = x as _;
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: vtable kinds may not match
|
||||||
|
|
||||||
|
error[E0606]: casting `*const (dyn Trait<T> + 'static)` as `*const dyn Trait<X>` is invalid
|
||||||
|
--> $DIR/ptr-to-trait-obj-different-args.rs:29:34
|
||||||
|
|
|
||||||
|
LL | let _: *const dyn Trait<X> = t as _;
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: vtable kinds may not match
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0606`.
|
For more information about this error, try `rustc --explain E0606`.
|
||||||
|
Loading…
Reference in New Issue
Block a user