]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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)] | |
e9174d1e | 12 | #![unstable(feature = "raw", issue = "27751")] |
1a4d82fc JJ |
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 | ||
c34b1796 | 21 | use clone::Clone; |
1a4d82fc JJ |
22 | use marker::Copy; |
23 | use mem; | |
24 | ||
85aaf69f SL |
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 | /// ``` | |
c1a9b12d SL |
52 | /// #![feature(raw)] |
53 | /// | |
85aaf69f SL |
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 | /// ``` | |
1a4d82fc | 61 | #[repr(C)] |
54a0048b SL |
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")] | |
1a4d82fc JJ |
66 | pub struct Slice<T> { |
67 | pub data: *const T, | |
85aaf69f | 68 | pub len: usize, |
1a4d82fc JJ |
69 | } |
70 | ||
54a0048b | 71 | #[allow(deprecated)] |
1a4d82fc | 72 | impl<T> Copy for Slice<T> {} |
54a0048b | 73 | #[allow(deprecated)] |
c34b1796 AL |
74 | impl<T> Clone for Slice<T> { |
75 | fn clone(&self) -> Slice<T> { *self } | |
1a4d82fc JJ |
76 | } |
77 | ||
85aaf69f SL |
78 | /// The representation of a trait object like `&SomeTrait`. |
79 | /// | |
80 | /// This struct has the same layout as types like `&SomeTrait` and | |
9346a6ac | 81 | /// `Box<AnotherTrait>`. The [Trait Objects chapter of the |
85aaf69f SL |
82 | /// Book][moreinfo] contains more details about the precise nature of |
83 | /// these internals. | |
84 | /// | |
9346a6ac | 85 | /// [moreinfo]: ../../book/trait-objects.html#representation |
85aaf69f SL |
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 | |
d9579d0f | 90 | /// definition will not change the layout of a `&SomeTrait`). It is |
85aaf69f SL |
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 | |
b039eaaf | 103 | /// behavior. |
85aaf69f SL |
104 | /// |
105 | /// # Examples | |
106 | /// | |
107 | /// ``` | |
c1a9b12d SL |
108 | /// #![feature(raw)] |
109 | /// | |
85aaf69f SL |
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 | /// }; | |
1a4d82fc | 145 | /// |
85aaf69f SL |
146 | /// // it should work just like we constructed a trait object out of |
147 | /// // `other_value` directly | |
148 | /// assert_eq!(synthesized.bar(), 457); | |
149 | /// ``` | |
1a4d82fc | 150 | #[repr(C)] |
c34b1796 | 151 | #[derive(Copy, Clone)] |
54a0048b | 152 | #[allow(missing_debug_implementations)] |
1a4d82fc JJ |
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. | |
54a0048b SL |
160 | #[rustc_deprecated(reason = "use raw accessors/constructors in `slice` module", |
161 | since = "1.9.0")] | |
162 | #[unstable(feature = "raw", issue = "27751")] | |
85aaf69f | 163 | pub unsafe trait Repr<T> { |
1a4d82fc JJ |
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 | ||
54a0048b | 172 | #[allow(deprecated)] |
85aaf69f | 173 | unsafe impl<T> Repr<Slice<T>> for [T] {} |
54a0048b | 174 | #[allow(deprecated)] |
85aaf69f | 175 | unsafe impl Repr<Slice<u8>> for str {} |