1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
#![allow(missing_docs)] #![unstable(feature = "raw", issue = "27751")] //! Contains struct definitions for the layout of compiler built-in types. //! //! They can be used as targets of transmutes in unsafe code for manipulating //! the raw representations directly. //! //! Their definition should always match the ABI defined in `rustc::back::abi`. /// The representation of a trait object like `&SomeTrait`. /// /// This struct has the same layout as types like `&SomeTrait` and /// `Box<dyn AnotherTrait>`. /// /// `TraitObject` is guaranteed to match layouts, but it is not the /// type of trait objects (e.g., the fields are not directly accessible /// on a `&SomeTrait`) nor does it control that layout (changing the /// definition will not change the layout of a `&SomeTrait`). It is /// only designed to be used by unsafe code that needs to manipulate /// the low-level details. /// /// There is no way to refer to all trait objects generically, so the only /// way to create values of this type is with functions like /// [`std::mem::transmute`][transmute]. Similarly, the only way to create a true /// trait object from a `TraitObject` value is with `transmute`. /// /// [transmute]: ../intrinsics/fn.transmute.html /// /// Synthesizing a trait object with mismatched types—one where the /// vtable does not correspond to the type of the value to which the /// data pointer points—is highly likely to lead to undefined /// behavior. /// /// # Examples /// /// ``` /// #![feature(raw)] /// /// use std::{mem, raw}; /// /// // an example trait /// trait Foo { /// fn bar(&self) -> i32; /// } /// /// impl Foo for i32 { /// fn bar(&self) -> i32 { /// *self + 1 /// } /// } /// /// let value: i32 = 123; /// /// // let the compiler make a trait object /// let object: &Foo = &value; /// /// // look at the raw representation /// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) }; /// /// // the data pointer is the address of `value` /// assert_eq!(raw_object.data as *const i32, &value as *const _); /// /// let other_value: i32 = 456; /// /// // construct a new object, pointing to a different `i32`, being /// // careful to use the `i32` vtable from `object` /// let synthesized: &Foo = unsafe { /// mem::transmute(raw::TraitObject { /// data: &other_value as *const _ as *mut (), /// vtable: raw_object.vtable, /// }) /// }; /// /// // it should work just as if we had constructed a trait object out of /// // `other_value` directly /// assert_eq!(synthesized.bar(), 457); /// ``` #[repr(C)] #[derive(Copy, Clone)] #[allow(missing_debug_implementations)] pub struct TraitObject { pub data: *mut (), pub vtable: *mut (), }