]> git.proxmox.com Git - rustc.git/blob - src/libcore/raw.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / libcore / raw.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(missing_docs)]
12 #![unstable(feature = "raw", issue = "27751")]
13
14 //! Contains struct definitions for the layout of compiler built-in types.
15 //!
16 //! They can be used as targets of transmutes in unsafe code for manipulating
17 //! the raw representations directly.
18 //!
19 //! Their definition should always match the ABI defined in `rustc::back::abi`.
20
21 use clone::Clone;
22 use marker::Copy;
23 use mem;
24
25 /// The representation of a slice like `&[T]`.
26 ///
27 /// This struct is guaranteed to have the layout of types like `&[T]`,
28 /// `&str`, and `Box<[T]>`, but is not the type of such slices
29 /// (e.g. the fields are not directly accessible on a `&[T]`) nor does
30 /// it control that layout (changing the definition will not change
31 /// the layout of a `&[T]`). It is only designed to be used by unsafe
32 /// code that needs to manipulate the low-level details.
33 ///
34 /// However, it is not recommended to use this type for such code,
35 /// since there are alternatives which may be safer:
36 ///
37 /// - Creating a slice from a data pointer and length can be done with
38 /// `std::slice::from_raw_parts` or `std::slice::from_raw_parts_mut`
39 /// instead of `std::mem::transmute`ing a value of type `Slice`.
40 /// - Extracting the data pointer and length from a slice can be
41 /// performed with the `as_ptr` (or `as_mut_ptr`) and `len`
42 /// methods.
43 ///
44 /// If one does decide to convert a slice value to a `Slice`, the
45 /// `Repr` trait in this module provides a method for a safe
46 /// conversion from `&[T]` (and `&str`) to a `Slice`, more type-safe
47 /// than a call to `transmute`.
48 ///
49 /// # Examples
50 ///
51 /// ```
52 /// #![feature(raw)]
53 ///
54 /// use std::raw::{self, Repr};
55 ///
56 /// let slice: &[u16] = &[1, 2, 3, 4];
57 ///
58 /// let repr: raw::Slice<u16> = slice.repr();
59 /// println!("data pointer = {:?}, length = {}", repr.data, repr.len);
60 /// ```
61 #[repr(C)]
62 #[allow(missing_debug_implementations)]
63 #[rustc_deprecated(reason = "use raw accessors/constructors in `slice` module",
64 since = "1.9.0")]
65 #[unstable(feature = "raw", issue = "27751")]
66 pub struct Slice<T> {
67 pub data: *const T,
68 pub len: usize,
69 }
70
71 #[allow(deprecated)]
72 impl<T> Copy for Slice<T> {}
73 #[allow(deprecated)]
74 impl<T> Clone for Slice<T> {
75 fn clone(&self) -> Slice<T> { *self }
76 }
77
78 /// The representation of a trait object like `&SomeTrait`.
79 ///
80 /// This struct has the same layout as types like `&SomeTrait` and
81 /// `Box<AnotherTrait>`. The [Trait Objects chapter of the
82 /// Book][moreinfo] contains more details about the precise nature of
83 /// these internals.
84 ///
85 /// [moreinfo]: ../../book/trait-objects.html#representation
86 ///
87 /// `TraitObject` is guaranteed to match layouts, but it is not the
88 /// type of trait objects (e.g. the fields are not directly accessible
89 /// on a `&SomeTrait`) nor does it control that layout (changing the
90 /// definition will not change the layout of a `&SomeTrait`). It is
91 /// only designed to be used by unsafe code that needs to manipulate
92 /// the low-level details.
93 ///
94 /// There is no `Repr` implementation for `TraitObject` because there
95 /// is no way to refer to all trait objects generically, so the only
96 /// way to create values of this type is with functions like
97 /// `std::mem::transmute`. Similarly, the only way to create a true
98 /// trait object from a `TraitObject` value is with `transmute`.
99 ///
100 /// Synthesizing a trait object with mismatched types—one where the
101 /// vtable does not correspond to the type of the value to which the
102 /// data pointer points—is highly likely to lead to undefined
103 /// behavior.
104 ///
105 /// # Examples
106 ///
107 /// ```
108 /// #![feature(raw)]
109 ///
110 /// use std::mem;
111 /// use std::raw;
112 ///
113 /// // an example trait
114 /// trait Foo {
115 /// fn bar(&self) -> i32;
116 /// }
117 /// impl Foo for i32 {
118 /// fn bar(&self) -> i32 {
119 /// *self + 1
120 /// }
121 /// }
122 ///
123 /// let value: i32 = 123;
124 ///
125 /// // let the compiler make a trait object
126 /// let object: &Foo = &value;
127 ///
128 /// // look at the raw representation
129 /// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) };
130 ///
131 /// // the data pointer is the address of `value`
132 /// assert_eq!(raw_object.data as *const i32, &value as *const _);
133 ///
134 ///
135 /// let other_value: i32 = 456;
136 ///
137 /// // construct a new object, pointing to a different `i32`, being
138 /// // careful to use the `i32` vtable from `object`
139 /// let synthesized: &Foo = unsafe {
140 /// mem::transmute(raw::TraitObject {
141 /// data: &other_value as *const _ as *mut (),
142 /// vtable: raw_object.vtable
143 /// })
144 /// };
145 ///
146 /// // it should work just like we constructed a trait object out of
147 /// // `other_value` directly
148 /// assert_eq!(synthesized.bar(), 457);
149 /// ```
150 #[repr(C)]
151 #[derive(Copy, Clone)]
152 #[allow(missing_debug_implementations)]
153 pub struct TraitObject {
154 pub data: *mut (),
155 pub vtable: *mut (),
156 }
157
158 /// This trait is meant to map equivalences between raw structs and their
159 /// corresponding rust values.
160 #[rustc_deprecated(reason = "use raw accessors/constructors in `slice` module",
161 since = "1.9.0")]
162 #[unstable(feature = "raw", issue = "27751")]
163 pub unsafe trait Repr<T> {
164 /// This function "unwraps" a rust value (without consuming it) into its raw
165 /// struct representation. This can be used to read/write different values
166 /// for the struct. This is a safe method because by default it does not
167 /// enable write-access to the fields of the return value in safe code.
168 #[inline]
169 fn repr(&self) -> T { unsafe { mem::transmute_copy(&self) } }
170 }
171
172 #[allow(deprecated)]
173 unsafe impl<T> Repr<Slice<T>> for [T] {}
174 #[allow(deprecated)]
175 unsafe impl Repr<Slice<u8>> for str {}