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