     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
    86

    #![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_middle::ty::layout`.

    /// The representation of a trait object like `&dyn SomeTrait`.
    ///
    /// This struct has the same layout as types like `&dyn 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 `&dyn SomeTrait`) nor does it control that layout (changing the
    /// definition will not change the layout of a `&dyn 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: &dyn 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: &dyn 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 (),
    }