]> git.lizzy.rs Git - rust.git/blob - src/libcore/raw.rs
Rollup merge of #61862 - vorner:weak-into-raw-methods, r=sfackler
[rust.git] / src / libcore / raw.rs
1 #![allow(missing_docs)]
2 #![unstable(feature = "raw", issue = "27751")]
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
11 /// The representation of a trait object like `&SomeTrait`.
12 ///
13 /// This struct has the same layout as types like `&SomeTrait` and
14 /// `Box<dyn AnotherTrait>`.
15 ///
16 /// `TraitObject` is guaranteed to match layouts, but it is not the
17 /// type of trait objects (e.g., the fields are not directly accessible
18 /// on a `&SomeTrait`) nor does it control that layout (changing the
19 /// definition will not change the layout of a `&SomeTrait`). It is
20 /// only designed to be used by unsafe code that needs to manipulate
21 /// the low-level details.
22 ///
23 /// There is no way to refer to all trait objects generically, so the only
24 /// way to create values of this type is with functions like
25 /// [`std::mem::transmute`][transmute]. Similarly, the only way to create a true
26 /// trait object from a `TraitObject` value is with `transmute`.
27 ///
28 /// [transmute]: ../intrinsics/fn.transmute.html
29 ///
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
33 /// behavior.
34 ///
35 /// # Examples
36 ///
37 /// ```
38 /// #![feature(raw)]
39 ///
40 /// use std::{mem, raw};
41 ///
42 /// // an example trait
43 /// trait Foo {
44 ///     fn bar(&self) -> i32;
45 /// }
46 ///
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
56 /// let object: &dyn Foo = &value;
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 ///
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`
68 /// let synthesized: &dyn Foo = unsafe {
69 ///      mem::transmute(raw::TraitObject {
70 ///          data: &other_value as *const _ as *mut (),
71 ///          vtable: raw_object.vtable,
72 ///      })
73 /// };
74 ///
75 /// // it should work just as if we had constructed a trait object out of
76 /// // `other_value` directly
77 /// assert_eq!(synthesized.bar(), 457);
78 /// ```
79 #[repr(C)]
80 #[derive(Copy, Clone)]
81 #[allow(missing_debug_implementations)]
82 pub struct TraitObject {
83     pub data: *mut (),
84     pub vtable: *mut (),
85 }