mv std libs to library/
This commit is contained in:
86
library/core/src/raw.rs
Normal file
86
library/core/src/raw.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
#![allow(missing_docs)]
|
||||
#![unstable(feature = "raw", issue = "27751")]
|
||||
|
||||
//! Contains struct definitions for the layout of compiler built-in types.
|
||||
//!
|
||||
//! They can be used as targets of transmutes in unsafe code for manipulating
|
||||
//! the raw representations directly.
|
||||
//!
|
||||
//! Their definition should always match the ABI defined in
|
||||
//! `rustc_middle::ty::layout`.
|
||||
|
||||
/// The representation of a trait object like `&dyn SomeTrait`.
|
||||
///
|
||||
/// This struct has the same layout as types like `&dyn SomeTrait` and
|
||||
/// `Box<dyn AnotherTrait>`.
|
||||
///
|
||||
/// `TraitObject` is guaranteed to match layouts, but it is not the
|
||||
/// type of trait objects (e.g., the fields are not directly accessible
|
||||
/// on a `&dyn SomeTrait`) nor does it control that layout (changing the
|
||||
/// definition will not change the layout of a `&dyn SomeTrait`). It is
|
||||
/// only designed to be used by unsafe code that needs to manipulate
|
||||
/// the low-level details.
|
||||
///
|
||||
/// There is no way to refer to all trait objects generically, so the only
|
||||
/// way to create values of this type is with functions like
|
||||
/// [`std::mem::transmute`][transmute]. Similarly, the only way to create a true
|
||||
/// trait object from a `TraitObject` value is with `transmute`.
|
||||
///
|
||||
/// [transmute]: ../intrinsics/fn.transmute.html
|
||||
///
|
||||
/// Synthesizing a trait object with mismatched types—one where the
|
||||
/// vtable does not correspond to the type of the value to which the
|
||||
/// data pointer points—is highly likely to lead to undefined
|
||||
/// behavior.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(raw)]
|
||||
///
|
||||
/// use std::{mem, raw};
|
||||
///
|
||||
/// // an example trait
|
||||
/// trait Foo {
|
||||
/// fn bar(&self) -> i32;
|
||||
/// }
|
||||
///
|
||||
/// impl Foo for i32 {
|
||||
/// fn bar(&self) -> i32 {
|
||||
/// *self + 1
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let value: i32 = 123;
|
||||
///
|
||||
/// // let the compiler make a trait object
|
||||
/// let object: &dyn Foo = &value;
|
||||
///
|
||||
/// // look at the raw representation
|
||||
/// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) };
|
||||
///
|
||||
/// // the data pointer is the address of `value`
|
||||
/// assert_eq!(raw_object.data as *const i32, &value as *const _);
|
||||
///
|
||||
/// let other_value: i32 = 456;
|
||||
///
|
||||
/// // construct a new object, pointing to a different `i32`, being
|
||||
/// // careful to use the `i32` vtable from `object`
|
||||
/// let synthesized: &dyn Foo = unsafe {
|
||||
/// mem::transmute(raw::TraitObject {
|
||||
/// data: &other_value as *const _ as *mut (),
|
||||
/// vtable: raw_object.vtable,
|
||||
/// })
|
||||
/// };
|
||||
///
|
||||
/// // it should work just as if we had constructed a trait object out of
|
||||
/// // `other_value` directly
|
||||
/// assert_eq!(synthesized.bar(), 457);
|
||||
/// ```
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct TraitObject {
|
||||
pub data: *mut (),
|
||||
pub vtable: *mut (),
|
||||
}
|
||||
Reference in New Issue
Block a user