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