]> git.proxmox.com Git - rustc.git/blame - src/libcore/raw.rs
New upstream version 1.42.0+dfsg0+pve1
[rustc.git] / src / libcore / raw.rs
CommitLineData
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
82pub struct TraitObject {
83 pub data: *mut (),
84 pub vtable: *mut (),
85}