// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // FIXME: remove the next line when https://github.com/rust-lang/rust/issues/43358 is resolved // compile-flags: -Zmir-opt-level=0 // Check that you can cast between different pointers to trait objects // whose vtable have the same kind (both lengths, or both trait pointers). trait Foo { fn foo(&self, _: T) -> u32 { 42 } } trait Bar { fn bar(&self) { println!("Bar!"); } } impl Foo for () {} impl Foo for u32 { fn foo(&self, _: u32) -> u32 { self+43 } } impl Bar for () {} unsafe fn round_trip_and_call<'a>(t: *const (Foo+'a)) -> u32 { let foo_e : *const Foo = t as *const _; let r_1 = foo_e as *mut Foo; (&*r_1).foo(0) } #[repr(C)] struct FooS(T); #[repr(C)] struct BarS(T); fn foo_to_bar(u: *const FooS) -> *const BarS { u as *const BarS } fn main() { let x = 4u32; let y : &Foo = &x; let fl = unsafe { round_trip_and_call(y as *const Foo) }; assert_eq!(fl, (43+4)); let s = FooS([0,1,2]); let u: &FooS<[u32]> = &s; let u: *const FooS<[u32]> = u; let bar_ref : *const BarS<[u32]> = foo_to_bar(u); let z : &BarS<[u32]> = unsafe{&*bar_ref}; assert_eq!(&z.0, &[0,1,2]); }