]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2012-2015 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 | ||
9e0c209e | 11 | //! Primitive traits and types representing basic properties of types. |
1a4d82fc JJ |
12 | //! |
13 | //! Rust types can be classified in various useful ways according to | |
9e0c209e SL |
14 | //! their intrinsic properties. These classifications are represented |
15 | //! as traits. | |
1a4d82fc | 16 | |
85aaf69f | 17 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 18 | |
85aaf69f | 19 | use cmp; |
85aaf69f SL |
20 | use hash::Hash; |
21 | use hash::Hasher; | |
1a4d82fc | 22 | |
92a42be0 | 23 | /// Types that can be transferred across thread boundaries. |
9cc50fc6 | 24 | /// |
9e0c209e SL |
25 | /// This trait is automatically implemented when the compiler determines it's |
26 | /// appropriate. | |
27 | /// | |
28 | /// An example of a non-`Send` type is the reference-counting pointer | |
476ff2be | 29 | /// [`rc::Rc`][`Rc`]. If two threads attempt to clone [`Rc`]s that point to the same |
9e0c209e | 30 | /// reference-counted value, they might try to update the reference count at the |
476ff2be | 31 | /// same time, which is [undefined behavior][ub] because [`Rc`] doesn't use atomic |
9e0c209e SL |
32 | /// operations. Its cousin [`sync::Arc`][arc] does use atomic operations (incurring |
33 | /// some overhead) and thus is `Send`. | |
34 | /// | |
35 | /// See [the Nomicon](../../nomicon/send-and-sync.html) for more details. | |
36 | /// | |
476ff2be | 37 | /// [`Rc`]: ../../std/rc/struct.Rc.html |
9e0c209e SL |
38 | /// [arc]: ../../std/sync/struct.Arc.html |
39 | /// [ub]: ../../reference.html#behavior-considered-undefined | |
85aaf69f | 40 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 41 | #[lang = "send"] |
85aaf69f | 42 | #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] |
9346a6ac AL |
43 | pub unsafe trait Send { |
44 | // empty. | |
45 | } | |
46 | ||
92a42be0 | 47 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
48 | unsafe impl Send for .. { } |
49 | ||
92a42be0 SL |
50 | #[stable(feature = "rust1", since = "1.0.0")] |
51 | impl<T: ?Sized> !Send for *const T { } | |
52 | #[stable(feature = "rust1", since = "1.0.0")] | |
53 | impl<T: ?Sized> !Send for *mut T { } | |
c34b1796 | 54 | |
9e0c209e | 55 | /// Types with a constant size known at compile time. |
b039eaaf | 56 | /// |
9e0c209e SL |
57 | /// All type parameters have an implicit bound of `Sized`. The special syntax |
58 | /// `?Sized` can be used to remove this bound if it's not appropriate. | |
b039eaaf SL |
59 | /// |
60 | /// ``` | |
92a42be0 | 61 | /// # #![allow(dead_code)] |
b039eaaf SL |
62 | /// struct Foo<T>(T); |
63 | /// struct Bar<T: ?Sized>(T); | |
64 | /// | |
65 | /// // struct FooUse(Foo<[i32]>); // error: Sized is not implemented for [i32] | |
66 | /// struct BarUse(Bar<[i32]>); // OK | |
67 | /// ``` | |
9e0c209e SL |
68 | /// |
69 | /// The one exception is the implicit `Self` type of a trait, which does not | |
70 | /// get an implicit `Sized` bound. This is because a `Sized` bound prevents | |
71 | /// the trait from being used to form a [trait object]: | |
72 | /// | |
73 | /// ``` | |
74 | /// # #![allow(unused_variables)] | |
75 | /// trait Foo { } | |
76 | /// trait Bar: Sized { } | |
77 | /// | |
78 | /// struct Impl; | |
79 | /// impl Foo for Impl { } | |
80 | /// impl Bar for Impl { } | |
81 | /// | |
82 | /// let x: &Foo = &Impl; // OK | |
83 | /// // let y: &Bar = &Impl; // error: the trait `Bar` cannot | |
84 | /// // be made into an object | |
85 | /// ``` | |
86 | /// | |
87 | /// [trait object]: ../../book/trait-objects.html | |
85aaf69f | 88 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 89 | #[lang = "sized"] |
85aaf69f | 90 | #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] |
c34b1796 | 91 | #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable |
9346a6ac AL |
92 | pub trait Sized { |
93 | // Empty. | |
94 | } | |
95 | ||
9e0c209e SL |
96 | /// Types that can be "unsized" to a dynamically-sized type. |
97 | /// | |
98 | /// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and | |
99 | /// `Unsize<fmt::Debug>`. | |
100 | /// | |
101 | /// All implementations of `Unsize` are provided automatically by the compiler. | |
102 | /// | |
103 | /// `Unsize` is used along with [`ops::CoerceUnsized`][coerceunsized] to allow | |
104 | /// "user-defined" containers such as [`rc::Rc`][rc] to contain dynamically-sized | |
105 | /// types. See the [DST coercion RFC][RFC982] for more details. | |
106 | /// | |
107 | /// [coerceunsized]: ../ops/trait.CoerceUnsized.html | |
108 | /// [rc]: ../../std/rc/struct.Rc.html | |
109 | /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md | |
e9174d1e | 110 | #[unstable(feature = "unsize", issue = "27732")] |
d9579d0f | 111 | #[lang="unsize"] |
e9174d1e | 112 | pub trait Unsize<T: ?Sized> { |
1a4d82fc JJ |
113 | // Empty. |
114 | } | |
115 | ||
9e0c209e | 116 | /// Types whose values can be duplicated simply by copying bits. |
85aaf69f SL |
117 | /// |
118 | /// By default, variable bindings have 'move semantics.' In other | |
119 | /// words: | |
120 | /// | |
121 | /// ``` | |
122 | /// #[derive(Debug)] | |
123 | /// struct Foo; | |
124 | /// | |
125 | /// let x = Foo; | |
126 | /// | |
127 | /// let y = x; | |
128 | /// | |
129 | /// // `x` has moved into `y`, and so cannot be used | |
130 | /// | |
131 | /// // println!("{:?}", x); // error: use of moved value | |
132 | /// ``` | |
133 | /// | |
134 | /// However, if a type implements `Copy`, it instead has 'copy semantics': | |
135 | /// | |
136 | /// ``` | |
9e0c209e SL |
137 | /// // We can derive a `Copy` implementation. `Clone` is also required, as it's |
138 | /// // a supertrait of `Copy`. | |
c34b1796 | 139 | /// #[derive(Debug, Copy, Clone)] |
85aaf69f SL |
140 | /// struct Foo; |
141 | /// | |
142 | /// let x = Foo; | |
143 | /// | |
144 | /// let y = x; | |
145 | /// | |
146 | /// // `y` is a copy of `x` | |
147 | /// | |
148 | /// println!("{:?}", x); // A-OK! | |
149 | /// ``` | |
150 | /// | |
9e0c209e SL |
151 | /// It's important to note that in these two examples, the only difference is whether you |
152 | /// are allowed to access `x` after the assignment. Under the hood, both a copy and a move | |
153 | /// can result in bits being copied in memory, although this is sometimes optimized away. | |
154 | /// | |
155 | /// ## How can I implement `Copy`? | |
156 | /// | |
157 | /// There are two ways to implement `Copy` on your type. The simplest is to use `derive`: | |
158 | /// | |
159 | /// ``` | |
160 | /// #[derive(Copy, Clone)] | |
161 | /// struct MyStruct; | |
162 | /// ``` | |
163 | /// | |
164 | /// You can also implement `Copy` and `Clone` manually: | |
165 | /// | |
166 | /// ``` | |
167 | /// struct MyStruct; | |
168 | /// | |
169 | /// impl Copy for MyStruct { } | |
170 | /// | |
171 | /// impl Clone for MyStruct { | |
172 | /// fn clone(&self) -> MyStruct { | |
173 | /// *self | |
174 | /// } | |
175 | /// } | |
176 | /// ``` | |
177 | /// | |
178 | /// There is a small difference between the two: the `derive` strategy will also place a `Copy` | |
179 | /// bound on type parameters, which isn't always desired. | |
180 | /// | |
181 | /// ## What's the difference between `Copy` and `Clone`? | |
182 | /// | |
183 | /// Copies happen implicitly, for example as part of an assignment `y = x`. The behavior of | |
184 | /// `Copy` is not overloadable; it is always a simple bit-wise copy. | |
185 | /// | |
476ff2be | 186 | /// Cloning is an explicit action, `x.clone()`. The implementation of [`Clone`] can |
9e0c209e | 187 | /// provide any type-specific behavior necessary to duplicate values safely. For example, |
476ff2be SL |
188 | /// the implementation of [`Clone`] for [`String`] needs to copy the pointed-to string |
189 | /// buffer in the heap. A simple bitwise copy of [`String`] values would merely copy the | |
190 | /// pointer, leading to a double free down the line. For this reason, [`String`] is [`Clone`] | |
9e0c209e SL |
191 | /// but not `Copy`. |
192 | /// | |
476ff2be SL |
193 | /// [`Clone`] is a supertrait of `Copy`, so everything which is `Copy` must also implement |
194 | /// [`Clone`]. If a type is `Copy` then its [`Clone`] implementation need only return `*self` | |
9e0c209e SL |
195 | /// (see the example above). |
196 | /// | |
85aaf69f SL |
197 | /// ## When can my type be `Copy`? |
198 | /// | |
199 | /// A type can implement `Copy` if all of its components implement `Copy`. For example, this | |
9e0c209e | 200 | /// struct can be `Copy`: |
85aaf69f SL |
201 | /// |
202 | /// ``` | |
92a42be0 | 203 | /// # #[allow(dead_code)] |
85aaf69f SL |
204 | /// struct Point { |
205 | /// x: i32, | |
206 | /// y: i32, | |
207 | /// } | |
208 | /// ``` | |
209 | /// | |
476ff2be | 210 | /// A struct can be `Copy`, and [`i32`] is `Copy`, therefore `Point` is eligible to be `Copy`. |
9e0c209e | 211 | /// By contrast, consider |
85aaf69f SL |
212 | /// |
213 | /// ``` | |
92a42be0 | 214 | /// # #![allow(dead_code)] |
85aaf69f SL |
215 | /// # struct Point; |
216 | /// struct PointList { | |
217 | /// points: Vec<Point>, | |
218 | /// } | |
219 | /// ``` | |
220 | /// | |
9e0c209e | 221 | /// The struct `PointList` cannot implement `Copy`, because [`Vec<T>`] is not `Copy`. If we |
62682a34 | 222 | /// attempt to derive a `Copy` implementation, we'll get an error: |
85aaf69f SL |
223 | /// |
224 | /// ```text | |
62682a34 | 225 | /// the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy` |
85aaf69f SL |
226 | /// ``` |
227 | /// | |
9e0c209e | 228 | /// ## When *can't* my type be `Copy`? |
3157f602 XL |
229 | /// |
230 | /// Some types can't be copied safely. For example, copying `&mut T` would create an aliased | |
476ff2be SL |
231 | /// mutable reference. Copying [`String`] would duplicate responsibility for managing the |
232 | /// [`String`]'s buffer, leading to a double free. | |
3157f602 | 233 | /// |
9e0c209e SL |
234 | /// Generalizing the latter case, any type implementing [`Drop`] can't be `Copy`, because it's |
235 | /// managing some resource besides its own [`size_of::<T>()`] bytes. | |
3157f602 | 236 | /// |
9e0c209e SL |
237 | /// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get a |
238 | /// compile-time error. Specifically, with structs you'll get [E0204] and with enums you'll get | |
239 | /// [E0205]. | |
85aaf69f | 240 | /// |
c30ab7b3 SL |
241 | /// [E0204]: ../../error-index.html#E0204 |
242 | /// [E0205]: ../../error-index.html#E0205 | |
85aaf69f | 243 | /// |
9e0c209e | 244 | /// ## When *should* my type be `Copy`? |
85aaf69f | 245 | /// |
9e0c209e SL |
246 | /// Generally speaking, if your type _can_ implement `Copy`, it should. Keep in mind, though, |
247 | /// that implementing `Copy` is part of the public API of your type. If the type might become | |
248 | /// non-`Copy` in the future, it could be prudent to omit the `Copy` implementation now, to | |
249 | /// avoid a breaking API change. | |
85aaf69f | 250 | /// |
9e0c209e SL |
251 | /// [`Vec<T>`]: ../../std/vec/struct.Vec.html |
252 | /// [`String`]: ../../std/string/struct.String.html | |
253 | /// [`Drop`]: ../../std/ops/trait.Drop.html | |
254 | /// [`size_of::<T>()`]: ../../std/mem/fn.size_of.html | |
476ff2be SL |
255 | /// [`Clone`]: ../clone/trait.Clone.html |
256 | /// [`String`]: ../../std/string/struct.String.html | |
257 | /// [`i32`]: ../../std/primitive.i32.html | |
85aaf69f | 258 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 259 | #[lang = "copy"] |
c34b1796 | 260 | pub trait Copy : Clone { |
1a4d82fc JJ |
261 | // Empty. |
262 | } | |
263 | ||
9e0c209e SL |
264 | /// Types for which it is safe to share references between threads. |
265 | /// | |
266 | /// This trait is automatically implemented when the compiler determines | |
267 | /// it's appropriate. | |
1a4d82fc JJ |
268 | /// |
269 | /// The precise definition is: a type `T` is `Sync` if `&T` is | |
9e0c209e SL |
270 | /// [`Send`][send]. In other words, if there is no possibility of |
271 | /// [undefined behavior][ub] (including data races) when passing | |
272 | /// `&T` references between threads. | |
273 | /// | |
274 | /// As one would expect, primitive types like [`u8`][u8] and [`f64`][f64] | |
275 | /// are all `Sync`, and so are simple aggregate types containing them, | |
276 | /// like tuples, structs and enums. More examples of basic `Sync` | |
277 | /// types include "immutable" types like `&T`, and those with simple | |
278 | /// inherited mutability, such as [`Box<T>`][box], [`Vec<T>`][vec] and | |
279 | /// most other collection types. (Generic parameters need to be `Sync` | |
280 | /// for their container to be `Sync`.) | |
281 | /// | |
282 | /// A somewhat surprising consequence of the definition is that `&mut T` | |
283 | /// is `Sync` (if `T` is `Sync`) even though it seems like that might | |
284 | /// provide unsynchronized mutation. The trick is that a mutable | |
285 | /// reference behind a shared reference (that is, `& &mut T`) | |
286 | /// becomes read-only, as if it were a `& &T`. Hence there is no risk | |
287 | /// of a data race. | |
1a4d82fc JJ |
288 | /// |
289 | /// Types that are not `Sync` are those that have "interior | |
9e0c209e SL |
290 | /// mutability" in a non-thread-safe form, such as [`cell::Cell`][cell] |
291 | /// and [`cell::RefCell`][refcell]. These types allow for mutation of | |
292 | /// their contents even through an immutable, shared reference. For | |
476ff2be SL |
293 | /// example the `set` method on [`Cell<T>`][cell] takes `&self`, so it requires |
294 | /// only a shared reference [`&Cell<T>`][cell]. The method performs no | |
295 | /// synchronization, thus [`Cell`][cell] cannot be `Sync`. | |
1a4d82fc | 296 | /// |
9e0c209e | 297 | /// Another example of a non-`Sync` type is the reference-counting |
476ff2be SL |
298 | /// pointer [`rc::Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone |
299 | /// a new [`Rc<T>`][rc], modifying the reference counts in a non-atomic way. | |
9cc50fc6 | 300 | /// |
9e0c209e SL |
301 | /// For cases when one does need thread-safe interior mutability, |
302 | /// Rust provides [atomic data types], as well as explicit locking via | |
303 | /// [`sync::Mutex`][mutex] and [`sync::RWLock`][rwlock]. These types | |
304 | /// ensure that any mutation cannot cause data races, hence the types | |
305 | /// are `Sync`. Likewise, [`sync::Arc`][arc] provides a thread-safe | |
476ff2be | 306 | /// analogue of [`Rc`][rc]. |
9e0c209e SL |
307 | /// |
308 | /// Any types with interior mutability must also use the | |
309 | /// [`cell::UnsafeCell`][unsafecell] wrapper around the value(s) which | |
310 | /// can be mutated through a shared reference. Failing to doing this is | |
311 | /// [undefined behavior][ub]. For example, [`transmute`][transmute]-ing | |
312 | /// from `&T` to `&mut T` is invalid. | |
313 | /// | |
314 | /// See [the Nomicon](../../nomicon/send-and-sync.html) for more | |
315 | /// details about `Sync`. | |
316 | /// | |
317 | /// [send]: trait.Send.html | |
318 | /// [u8]: ../../std/primitive.u8.html | |
319 | /// [f64]: ../../std/primitive.f64.html | |
320 | /// [box]: ../../std/boxed/struct.Box.html | |
321 | /// [vec]: ../../std/vec/struct.Vec.html | |
322 | /// [cell]: ../cell/struct.Cell.html | |
323 | /// [refcell]: ../cell/struct.RefCell.html | |
324 | /// [rc]: ../../std/rc/struct.Rc.html | |
325 | /// [arc]: ../../std/sync/struct.Arc.html | |
326 | /// [atomic data types]: ../sync/atomic/index.html | |
327 | /// [mutex]: ../../std/sync/struct.Mutex.html | |
328 | /// [rwlock]: ../../std/sync/struct.RwLock.html | |
329 | /// [unsafecell]: ../cell/struct.UnsafeCell.html | |
330 | /// [ub]: ../../reference.html#behavior-considered-undefined | |
331 | /// [transmute]: ../../std/mem/fn.transmute.html | |
9346a6ac | 332 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 333 | #[lang = "sync"] |
9346a6ac AL |
334 | #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] |
335 | pub unsafe trait Sync { | |
336 | // Empty | |
337 | } | |
338 | ||
92a42be0 | 339 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
340 | unsafe impl Sync for .. { } |
341 | ||
92a42be0 SL |
342 | #[stable(feature = "rust1", since = "1.0.0")] |
343 | impl<T: ?Sized> !Sync for *const T { } | |
344 | #[stable(feature = "rust1", since = "1.0.0")] | |
345 | impl<T: ?Sized> !Sync for *mut T { } | |
c34b1796 | 346 | |
85aaf69f SL |
347 | macro_rules! impls{ |
348 | ($t: ident) => ( | |
92a42be0 | 349 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
350 | impl<T:?Sized> Hash for $t<T> { |
351 | #[inline] | |
352 | fn hash<H: Hasher>(&self, _: &mut H) { | |
353 | } | |
354 | } | |
355 | ||
92a42be0 | 356 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
357 | impl<T:?Sized> cmp::PartialEq for $t<T> { |
358 | fn eq(&self, _other: &$t<T>) -> bool { | |
359 | true | |
360 | } | |
361 | } | |
362 | ||
92a42be0 | 363 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
364 | impl<T:?Sized> cmp::Eq for $t<T> { |
365 | } | |
366 | ||
92a42be0 | 367 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
368 | impl<T:?Sized> cmp::PartialOrd for $t<T> { |
369 | fn partial_cmp(&self, _other: &$t<T>) -> Option<cmp::Ordering> { | |
370 | Option::Some(cmp::Ordering::Equal) | |
371 | } | |
372 | } | |
373 | ||
92a42be0 | 374 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
375 | impl<T:?Sized> cmp::Ord for $t<T> { |
376 | fn cmp(&self, _other: &$t<T>) -> cmp::Ordering { | |
377 | cmp::Ordering::Equal | |
378 | } | |
379 | } | |
380 | ||
92a42be0 | 381 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
382 | impl<T:?Sized> Copy for $t<T> { } |
383 | ||
92a42be0 | 384 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
385 | impl<T:?Sized> Clone for $t<T> { |
386 | fn clone(&self) -> $t<T> { | |
387 | $t | |
388 | } | |
389 | } | |
92a42be0 SL |
390 | |
391 | #[stable(feature = "rust1", since = "1.0.0")] | |
392 | impl<T:?Sized> Default for $t<T> { | |
393 | fn default() -> $t<T> { | |
394 | $t | |
395 | } | |
396 | } | |
85aaf69f SL |
397 | ) |
398 | } | |
399 | ||
9e0c209e | 400 | /// Zero-sized type used to mark things that "act like" they own a `T`. |
9346a6ac | 401 | /// |
9e0c209e SL |
402 | /// Adding a `PhantomData<T>` field to your type tells the compiler that your |
403 | /// type acts as though it stores a value of type `T`, even though it doesn't | |
404 | /// really. This information is used when computing certain safety properties. | |
9cc50fc6 | 405 | /// |
9e0c209e SL |
406 | /// For a more in-depth explanation of how to use `PhantomData<T>`, please see |
407 | /// [the Nomicon](../../nomicon/phantom-data.html). | |
9cc50fc6 | 408 | /// |
e9174d1e SL |
409 | /// # A ghastly note 👻👻👻 |
410 | /// | |
9e0c209e SL |
411 | /// Though they both have scary names, `PhantomData` and 'phantom types' are |
412 | /// related, but not identical. A phantom type parameter is simply a type | |
413 | /// parameter which is never used. In Rust, this often causes the compiler to | |
414 | /// complain, and the solution is to add a "dummy" use by way of `PhantomData`. | |
1a4d82fc | 415 | /// |
c34b1796 | 416 | /// # Examples |
1a4d82fc | 417 | /// |
9e0c209e | 418 | /// ## Unused lifetime parameters |
1a4d82fc | 419 | /// |
9e0c209e SL |
420 | /// Perhaps the most common use case for `PhantomData` is a struct that has an |
421 | /// unused lifetime parameter, typically as part of some unsafe code. For | |
422 | /// example, here is a struct `Slice` that has two pointers of type `*const T`, | |
423 | /// presumably pointing into an array somewhere: | |
85aaf69f | 424 | /// |
9346a6ac AL |
425 | /// ```ignore |
426 | /// struct Slice<'a, T> { | |
427 | /// start: *const T, | |
428 | /// end: *const T, | |
1a4d82fc JJ |
429 | /// } |
430 | /// ``` | |
431 | /// | |
9346a6ac AL |
432 | /// The intention is that the underlying data is only valid for the |
433 | /// lifetime `'a`, so `Slice` should not outlive `'a`. However, this | |
434 | /// intent is not expressed in the code, since there are no uses of | |
435 | /// the lifetime `'a` and hence it is not clear what data it applies | |
436 | /// to. We can correct this by telling the compiler to act *as if* the | |
9e0c209e | 437 | /// `Slice` struct contained a reference `&'a T`: |
1a4d82fc | 438 | /// |
c34b1796 | 439 | /// ``` |
9346a6ac | 440 | /// use std::marker::PhantomData; |
1a4d82fc | 441 | /// |
92a42be0 | 442 | /// # #[allow(dead_code)] |
9cc50fc6 | 443 | /// struct Slice<'a, T: 'a> { |
9346a6ac AL |
444 | /// start: *const T, |
445 | /// end: *const T, | |
9e0c209e | 446 | /// phantom: PhantomData<&'a T>, |
9346a6ac | 447 | /// } |
c34b1796 | 448 | /// ``` |
1a4d82fc | 449 | /// |
9e0c209e SL |
450 | /// This also in turn requires the annotation `T: 'a`, indicating |
451 | /// that any references in `T` are valid over the lifetime `'a`. | |
452 | /// | |
453 | /// When initializing a `Slice` you simply provide the value | |
454 | /// `PhantomData` for the field `phantom`: | |
455 | /// | |
456 | /// ``` | |
457 | /// # #![allow(dead_code)] | |
458 | /// # use std::marker::PhantomData; | |
459 | /// # struct Slice<'a, T: 'a> { | |
460 | /// # start: *const T, | |
461 | /// # end: *const T, | |
462 | /// # phantom: PhantomData<&'a T>, | |
463 | /// # } | |
464 | /// fn borrow_vec<'a, T>(vec: &'a Vec<T>) -> Slice<'a, T> { | |
465 | /// let ptr = vec.as_ptr(); | |
466 | /// Slice { | |
467 | /// start: ptr, | |
468 | /// end: unsafe { ptr.offset(vec.len() as isize) }, | |
469 | /// phantom: PhantomData, | |
470 | /// } | |
471 | /// } | |
472 | /// ``` | |
1a4d82fc | 473 | /// |
9346a6ac | 474 | /// ## Unused type parameters |
1a4d82fc | 475 | /// |
9e0c209e | 476 | /// It sometimes happens that you have unused type parameters which |
9346a6ac AL |
477 | /// indicate what type of data a struct is "tied" to, even though that |
478 | /// data is not actually found in the struct itself. Here is an | |
9e0c209e SL |
479 | /// example where this arises with [FFI]. The foreign interface uses |
480 | /// handles of type `*mut ()` to refer to Rust values of different | |
481 | /// types. We track the Rust type using a phantom type parameter on | |
482 | /// the struct `ExternalResource` which wraps a handle. | |
483 | /// | |
484 | /// [FFI]: ../../book/ffi.html | |
c34b1796 AL |
485 | /// |
486 | /// ``` | |
92a42be0 | 487 | /// # #![allow(dead_code)] |
9e0c209e | 488 | /// # trait ResType { } |
c34b1796 AL |
489 | /// # struct ParamType; |
490 | /// # mod foreign_lib { | |
9e0c209e SL |
491 | /// # pub fn new(_: usize) -> *mut () { 42 as *mut () } |
492 | /// # pub fn do_stuff(_: *mut (), _: usize) {} | |
c34b1796 AL |
493 | /// # } |
494 | /// # fn convert_params(_: ParamType) -> usize { 42 } | |
495 | /// use std::marker::PhantomData; | |
496 | /// use std::mem; | |
497 | /// | |
498 | /// struct ExternalResource<R> { | |
499 | /// resource_handle: *mut (), | |
500 | /// resource_type: PhantomData<R>, | |
501 | /// } | |
502 | /// | |
503 | /// impl<R: ResType> ExternalResource<R> { | |
504 | /// fn new() -> ExternalResource<R> { | |
505 | /// let size_of_res = mem::size_of::<R>(); | |
506 | /// ExternalResource { | |
507 | /// resource_handle: foreign_lib::new(size_of_res), | |
508 | /// resource_type: PhantomData, | |
509 | /// } | |
510 | /// } | |
511 | /// | |
512 | /// fn do_stuff(&self, param: ParamType) { | |
513 | /// let foreign_params = convert_params(param); | |
514 | /// foreign_lib::do_stuff(self.resource_handle, foreign_params); | |
515 | /// } | |
516 | /// } | |
517 | /// ``` | |
518 | /// | |
9e0c209e | 519 | /// ## Ownership and the drop check |
9346a6ac | 520 | /// |
9e0c209e SL |
521 | /// Adding a field of type `PhantomData<T>` indicates that your |
522 | /// type owns data of type `T`. This in turn implies that when your | |
523 | /// type is dropped, it may drop one or more instances of the type | |
524 | /// `T`. This has bearing on the Rust compiler's [drop check] | |
525 | /// analysis. | |
9346a6ac AL |
526 | /// |
527 | /// If your struct does not in fact *own* the data of type `T`, it is | |
528 | /// better to use a reference type, like `PhantomData<&'a T>` | |
529 | /// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so | |
530 | /// as not to indicate ownership. | |
9e0c209e SL |
531 | /// |
532 | /// [drop check]: ../../nomicon/dropck.html | |
d9579d0f | 533 | #[lang = "phantom_data"] |
85aaf69f SL |
534 | #[stable(feature = "rust1", since = "1.0.0")] |
535 | pub struct PhantomData<T:?Sized>; | |
1a4d82fc | 536 | |
85aaf69f | 537 | impls! { PhantomData } |
1a4d82fc | 538 | |
85aaf69f | 539 | mod impls { |
92a42be0 | 540 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f | 541 | unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {} |
92a42be0 | 542 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
543 | unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {} |
544 | } | |
1a4d82fc | 545 | |
92a42be0 SL |
546 | /// Types that can be reflected over. |
547 | /// | |
9e0c209e SL |
548 | /// By "reflection" we mean use of the [`Any`][any] trait, or related |
549 | /// machinery such as [`TypeId`][typeid]. | |
550 | /// | |
551 | /// `Reflect` is implemented for all types. Its purpose is to ensure | |
552 | /// that when you write a generic function that will employ reflection, | |
553 | /// that must be reflected (no pun intended) in the generic bounds of | |
554 | /// that function. | |
c34b1796 AL |
555 | /// |
556 | /// ``` | |
62682a34 | 557 | /// #![feature(reflect_marker)] |
c34b1796 AL |
558 | /// use std::marker::Reflect; |
559 | /// use std::any::Any; | |
92a42be0 SL |
560 | /// |
561 | /// # #[allow(dead_code)] | |
9cc50fc6 | 562 | /// fn foo<T: Reflect + 'static>(x: &T) { |
c34b1796 AL |
563 | /// let any: &Any = x; |
564 | /// if any.is::<u32>() { println!("u32"); } | |
565 | /// } | |
566 | /// ``` | |
567 | /// | |
9e0c209e SL |
568 | /// Without the bound `T: Reflect`, `foo` would not typecheck. (As |
569 | /// a matter of style, it would be preferable to write `T: Any`, | |
570 | /// because `T: Any` implies `T: Reflect` and `T: 'static`, but we | |
571 | /// use `Reflect` here for illustrative purposes.) | |
572 | /// | |
573 | /// The `Reflect` bound serves to alert `foo`'s caller to the | |
574 | /// fact that `foo` may behave differently depending on whether | |
575 | /// `T` is `u32` or not. The ability for a caller to reason about what | |
576 | /// a function may do based solely on what generic bounds are declared | |
577 | /// is often called the "[parametricity property][param]". Despite the | |
578 | /// use of `Reflect`, Rust lacks true parametricity because a generic | |
579 | /// function can, at the very least, call [`mem::size_of`][size_of] | |
580 | /// without employing any trait bounds whatsoever. | |
581 | /// | |
582 | /// [any]: ../any/trait.Any.html | |
583 | /// [typeid]: ../any/struct.TypeId.html | |
584 | /// [param]: http://en.wikipedia.org/wiki/Parametricity | |
585 | /// [size_of]: ../mem/fn.size_of.html | |
c34b1796 | 586 | #[rustc_reflect_like] |
62682a34 | 587 | #[unstable(feature = "reflect_marker", |
e9174d1e SL |
588 | reason = "requires RFC and more experience", |
589 | issue = "27749")] | |
9e0c209e | 590 | #[rustc_deprecated(since = "1.14.0", reason = "Specialization makes parametricity impossible")] |
bd371182 AL |
591 | #[rustc_on_unimplemented = "`{Self}` does not implement `Any`; \ |
592 | ensure all type parameters are bounded by `Any`"] | |
9346a6ac AL |
593 | pub trait Reflect {} |
594 | ||
92a42be0 SL |
595 | #[unstable(feature = "reflect_marker", |
596 | reason = "requires RFC and more experience", | |
597 | issue = "27749")] | |
9e0c209e SL |
598 | #[rustc_deprecated(since = "1.14.0", reason = "Specialization makes parametricity impossible")] |
599 | #[allow(deprecated)] | |
c34b1796 | 600 | impl Reflect for .. { } |