162 lines
5.4 KiB
Rust
162 lines
5.4 KiB
Rust
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
|
// file at the top-level directory of this distribution and at
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
#![allow(missing_docs)]
|
|
#![unstable(feature = "core")]
|
|
|
|
//! 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::back::abi`.
|
|
|
|
use clone::Clone;
|
|
use marker::Copy;
|
|
use mem;
|
|
|
|
/// The representation of a slice like `&[T]`.
|
|
///
|
|
/// This struct is guaranteed to have the layout of types like `&[T]`,
|
|
/// `&str`, and `Box<[T]>`, but is not the type of such slices
|
|
/// (e.g. the fields are not directly accessible on a `&[T]`) nor does
|
|
/// it control that layout (changing the definition will not change
|
|
/// the layout of a `&[T]`). It is only designed to be used by unsafe
|
|
/// code that needs to manipulate the low-level details.
|
|
///
|
|
/// However, it is not recommended to use this type for such code,
|
|
/// since there are alternatives which may be safer:
|
|
///
|
|
/// - Creating a slice from a data pointer and length can be done with
|
|
/// `std::slice::from_raw_parts` or `std::slice::from_raw_parts_mut`
|
|
/// instead of `std::mem::transmute`ing a value of type `Slice`.
|
|
/// - Extracting the data pointer and length from a slice can be
|
|
/// performed with the `as_ptr` (or `as_mut_ptr`) and `len`
|
|
/// methods.
|
|
///
|
|
/// If one does decide to convert a slice value to a `Slice`, the
|
|
/// `Repr` trait in this module provides a method for a safe
|
|
/// conversion from `&[T]` (and `&str`) to a `Slice`, more type-safe
|
|
/// than a call to `transmute`.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # #![feature(core)]
|
|
/// use std::raw::{self, Repr};
|
|
///
|
|
/// let slice: &[u16] = &[1, 2, 3, 4];
|
|
///
|
|
/// let repr: raw::Slice<u16> = slice.repr();
|
|
/// println!("data pointer = {:?}, length = {}", repr.data, repr.len);
|
|
/// ```
|
|
#[repr(C)]
|
|
pub struct Slice<T> {
|
|
pub data: *const T,
|
|
pub len: usize,
|
|
}
|
|
|
|
impl<T> Copy for Slice<T> {}
|
|
impl<T> Clone for Slice<T> {
|
|
fn clone(&self) -> Slice<T> { *self }
|
|
}
|
|
|
|
/// The representation of a trait object like `&SomeTrait`.
|
|
///
|
|
/// This struct has the same layout as types like `&SomeTrait` and
|
|
/// `Box<AnotherTrait>`. The [Trait Objects chapter of the
|
|
/// Book][moreinfo] contains more details about the precise nature of
|
|
/// these internals.
|
|
///
|
|
/// [moreinfo]: ../../book/trait-objects.html#representation
|
|
///
|
|
/// `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 `&SomeTrait`) nor does it control that layout (changing the
|
|
/// definition will not change the layout of a `&SomeTrait`). It is
|
|
/// only designed to be used by unsafe code that needs to manipulate
|
|
/// the low-level details.
|
|
///
|
|
/// There is no `Repr` implementation for `TraitObject` because 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`. Similarly, the only way to create a true
|
|
/// trait object from a `TraitObject` value is with `transmute`.
|
|
///
|
|
/// 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
|
|
/// behaviour.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # #![feature(core)]
|
|
/// use std::mem;
|
|
/// use std::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: &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: &Foo = unsafe {
|
|
/// mem::transmute(raw::TraitObject {
|
|
/// data: &other_value as *const _ as *mut (),
|
|
/// vtable: raw_object.vtable
|
|
/// })
|
|
/// };
|
|
///
|
|
/// // it should work just like we constructed a trait object out of
|
|
/// // `other_value` directly
|
|
/// assert_eq!(synthesized.bar(), 457);
|
|
/// ```
|
|
#[repr(C)]
|
|
#[derive(Copy, Clone)]
|
|
pub struct TraitObject {
|
|
pub data: *mut (),
|
|
pub vtable: *mut (),
|
|
}
|
|
|
|
/// This trait is meant to map equivalences between raw structs and their
|
|
/// corresponding rust values.
|
|
pub unsafe trait Repr<T> {
|
|
/// This function "unwraps" a rust value (without consuming it) into its raw
|
|
/// struct representation. This can be used to read/write different values
|
|
/// for the struct. This is a safe method because by default it does not
|
|
/// enable write-access to the fields of the return value in safe code.
|
|
#[inline]
|
|
fn repr(&self) -> T { unsafe { mem::transmute_copy(&self) } }
|
|
}
|
|
|
|
unsafe impl<T> Repr<Slice<T>> for [T] {}
|
|
unsafe impl Repr<Slice<u8>> for str {}
|