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