aboutsummaryrefslogtreecommitdiff
path: root/libcore/raw.rs
diff options
context:
space:
mode:
authorpravic <[email protected]>2016-04-12 17:47:49 +0300
committerpravic <[email protected]>2016-04-12 17:47:49 +0300
commit91d227b219446d3a8b13f5bf7eb87bfc78a8b339 (patch)
tree0e438aefd2b3cf07354a68595d5aa4ed73f81f15 /libcore/raw.rs
parentadd native import libraries (diff)
downloadarchived-kmd-env-rs-91d227b219446d3a8b13f5bf7eb87bfc78a8b339.tar.xz
archived-kmd-env-rs-91d227b219446d3a8b13f5bf7eb87bfc78a8b339.zip
add libcore from 2016-04-11 nightly
Diffstat (limited to 'libcore/raw.rs')
-rw-r--r--libcore/raw.rs165
1 files changed, 165 insertions, 0 deletions
diff --git a/libcore/raw.rs b/libcore/raw.rs
new file mode 100644
index 0000000..20c85b5
--- /dev/null
+++ b/libcore/raw.rs
@@ -0,0 +1,165 @@
+// 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 = "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::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(raw)]
+///
+/// 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)]
+#[allow(missing_debug_implementations)]
+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
+/// behavior.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(raw)]
+///
+/// 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)]
+#[allow(missing_debug_implementations)]
+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 {}