]>
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 | ||
11 | //! Primitive traits and marker types representing basic 'kinds' of types. | |
12 | //! | |
13 | //! Rust types can be classified in various useful ways according to | |
14 | //! intrinsic properties of the type. These classifications, often called | |
15 | //! 'kinds', are represented as traits. | |
1a4d82fc | 16 | |
85aaf69f | 17 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc JJ |
18 | |
19 | use clone::Clone; | |
85aaf69f | 20 | use cmp; |
92a42be0 | 21 | use default::Default; |
85aaf69f SL |
22 | use option::Option; |
23 | use hash::Hash; | |
24 | use hash::Hasher; | |
1a4d82fc | 25 | |
92a42be0 | 26 | /// Types that can be transferred across thread boundaries. |
85aaf69f | 27 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 28 | #[lang = "send"] |
85aaf69f | 29 | #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] |
9346a6ac AL |
30 | pub unsafe trait Send { |
31 | // empty. | |
32 | } | |
33 | ||
92a42be0 | 34 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
35 | unsafe impl Send for .. { } |
36 | ||
92a42be0 SL |
37 | #[stable(feature = "rust1", since = "1.0.0")] |
38 | impl<T: ?Sized> !Send for *const T { } | |
39 | #[stable(feature = "rust1", since = "1.0.0")] | |
40 | impl<T: ?Sized> !Send for *mut T { } | |
c34b1796 | 41 | |
1a4d82fc | 42 | /// Types with a constant size known at compile-time. |
b039eaaf SL |
43 | /// |
44 | /// All type parameters which can be bounded have an implicit bound of `Sized`. The special syntax | |
45 | /// `?Sized` can be used to remove this bound if it is not appropriate. | |
46 | /// | |
47 | /// ``` | |
92a42be0 | 48 | /// # #![allow(dead_code)] |
b039eaaf SL |
49 | /// struct Foo<T>(T); |
50 | /// struct Bar<T: ?Sized>(T); | |
51 | /// | |
52 | /// // struct FooUse(Foo<[i32]>); // error: Sized is not implemented for [i32] | |
53 | /// struct BarUse(Bar<[i32]>); // OK | |
54 | /// ``` | |
85aaf69f | 55 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 56 | #[lang = "sized"] |
85aaf69f | 57 | #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] |
c34b1796 | 58 | #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable |
9346a6ac AL |
59 | pub trait Sized { |
60 | // Empty. | |
61 | } | |
62 | ||
d9579d0f | 63 | /// Types that can be "unsized" to a dynamically sized type. |
e9174d1e | 64 | #[unstable(feature = "unsize", issue = "27732")] |
d9579d0f | 65 | #[lang="unsize"] |
e9174d1e | 66 | pub trait Unsize<T: ?Sized> { |
1a4d82fc JJ |
67 | // Empty. |
68 | } | |
69 | ||
70 | /// Types that can be copied by simply copying bits (i.e. `memcpy`). | |
85aaf69f SL |
71 | /// |
72 | /// By default, variable bindings have 'move semantics.' In other | |
73 | /// words: | |
74 | /// | |
75 | /// ``` | |
76 | /// #[derive(Debug)] | |
77 | /// struct Foo; | |
78 | /// | |
79 | /// let x = Foo; | |
80 | /// | |
81 | /// let y = x; | |
82 | /// | |
83 | /// // `x` has moved into `y`, and so cannot be used | |
84 | /// | |
85 | /// // println!("{:?}", x); // error: use of moved value | |
86 | /// ``` | |
87 | /// | |
88 | /// However, if a type implements `Copy`, it instead has 'copy semantics': | |
89 | /// | |
90 | /// ``` | |
91 | /// // we can just derive a `Copy` implementation | |
c34b1796 | 92 | /// #[derive(Debug, Copy, Clone)] |
85aaf69f SL |
93 | /// struct Foo; |
94 | /// | |
95 | /// let x = Foo; | |
96 | /// | |
97 | /// let y = x; | |
98 | /// | |
99 | /// // `y` is a copy of `x` | |
100 | /// | |
101 | /// println!("{:?}", x); // A-OK! | |
102 | /// ``` | |
103 | /// | |
104 | /// It's important to note that in these two examples, the only difference is if you are allowed to | |
105 | /// access `x` after the assignment: a move is also a bitwise copy under the hood. | |
106 | /// | |
107 | /// ## When can my type be `Copy`? | |
108 | /// | |
109 | /// A type can implement `Copy` if all of its components implement `Copy`. For example, this | |
110 | /// `struct` can be `Copy`: | |
111 | /// | |
112 | /// ``` | |
92a42be0 | 113 | /// # #[allow(dead_code)] |
85aaf69f SL |
114 | /// struct Point { |
115 | /// x: i32, | |
116 | /// y: i32, | |
117 | /// } | |
118 | /// ``` | |
119 | /// | |
120 | /// A `struct` can be `Copy`, and `i32` is `Copy`, so therefore, `Point` is eligible to be `Copy`. | |
121 | /// | |
122 | /// ``` | |
92a42be0 | 123 | /// # #![allow(dead_code)] |
85aaf69f SL |
124 | /// # struct Point; |
125 | /// struct PointList { | |
126 | /// points: Vec<Point>, | |
127 | /// } | |
128 | /// ``` | |
129 | /// | |
130 | /// The `PointList` `struct` cannot implement `Copy`, because `Vec<T>` is not `Copy`. If we | |
62682a34 | 131 | /// attempt to derive a `Copy` implementation, we'll get an error: |
85aaf69f SL |
132 | /// |
133 | /// ```text | |
62682a34 | 134 | /// the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy` |
85aaf69f SL |
135 | /// ``` |
136 | /// | |
137 | /// ## How can I implement `Copy`? | |
138 | /// | |
139 | /// There are two ways to implement `Copy` on your type: | |
140 | /// | |
141 | /// ``` | |
c34b1796 | 142 | /// #[derive(Copy, Clone)] |
85aaf69f SL |
143 | /// struct MyStruct; |
144 | /// ``` | |
145 | /// | |
146 | /// and | |
147 | /// | |
148 | /// ``` | |
149 | /// struct MyStruct; | |
150 | /// impl Copy for MyStruct {} | |
c34b1796 | 151 | /// impl Clone for MyStruct { fn clone(&self) -> MyStruct { *self } } |
85aaf69f SL |
152 | /// ``` |
153 | /// | |
154 | /// There is a small difference between the two: the `derive` strategy will also place a `Copy` | |
155 | /// bound on type parameters, which isn't always desired. | |
156 | /// | |
157 | /// ## When can my type _not_ be `Copy`? | |
158 | /// | |
159 | /// Some types can't be copied safely. For example, copying `&mut T` would create an aliased | |
160 | /// mutable reference, and copying `String` would result in two attempts to free the same buffer. | |
161 | /// | |
162 | /// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's | |
163 | /// managing some resource besides its own `size_of::<T>()` bytes. | |
164 | /// | |
165 | /// ## When should my type be `Copy`? | |
166 | /// | |
167 | /// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing | |
168 | /// to consider though: if you think your type may _not_ be able to implement `Copy` in the future, | |
169 | /// then it might be prudent to not implement `Copy`. This is because removing `Copy` is a breaking | |
170 | /// change: that second example would fail to compile if we made `Foo` non-`Copy`. | |
92a42be0 SL |
171 | /// |
172 | /// # Derivable | |
173 | /// | |
174 | /// This trait can be used with `#[derive]`. | |
85aaf69f | 175 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 176 | #[lang = "copy"] |
c34b1796 | 177 | pub trait Copy : Clone { |
1a4d82fc JJ |
178 | // Empty. |
179 | } | |
180 | ||
85aaf69f | 181 | /// Types that can be safely shared between threads when aliased. |
1a4d82fc JJ |
182 | /// |
183 | /// The precise definition is: a type `T` is `Sync` if `&T` is | |
184 | /// thread-safe. In other words, there is no possibility of data races | |
85aaf69f | 185 | /// when passing `&T` references between threads. |
1a4d82fc JJ |
186 | /// |
187 | /// As one would expect, primitive types like `u8` and `f64` are all | |
188 | /// `Sync`, and so are simple aggregate types containing them (like | |
189 | /// tuples, structs and enums). More instances of basic `Sync` types | |
190 | /// include "immutable" types like `&T` and those with simple | |
191 | /// inherited mutability, such as `Box<T>`, `Vec<T>` and most other | |
192 | /// collection types. (Generic parameters need to be `Sync` for their | |
193 | /// container to be `Sync`.) | |
194 | /// | |
195 | /// A somewhat surprising consequence of the definition is `&mut T` is | |
196 | /// `Sync` (if `T` is `Sync`) even though it seems that it might | |
b039eaaf | 197 | /// provide unsynchronized mutation. The trick is a mutable reference |
1a4d82fc JJ |
198 | /// stored in an aliasable reference (that is, `& &mut T`) becomes |
199 | /// read-only, as if it were a `& &T`, hence there is no risk of a data | |
200 | /// race. | |
201 | /// | |
202 | /// Types that are not `Sync` are those that have "interior | |
203 | /// mutability" in a non-thread-safe way, such as `Cell` and `RefCell` | |
204 | /// in `std::cell`. These types allow for mutation of their contents | |
205 | /// even when in an immutable, aliasable slot, e.g. the contents of | |
206 | /// `&Cell<T>` can be `.set`, and do not ensure data races are | |
207 | /// impossible, hence they cannot be `Sync`. A higher level example | |
208 | /// of a non-`Sync` type is the reference counted pointer | |
209 | /// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new | |
210 | /// reference, which modifies the reference counts in a non-atomic | |
211 | /// way. | |
212 | /// | |
213 | /// For cases when one does need thread-safe interior mutability, | |
214 | /// types like the atomics in `std::sync` and `Mutex` & `RWLock` in | |
215 | /// the `sync` crate do ensure that any mutation cannot cause data | |
216 | /// races. Hence these types are `Sync`. | |
217 | /// | |
9346a6ac AL |
218 | /// Any types with interior mutability must also use the `std::cell::UnsafeCell` |
219 | /// wrapper around the value(s) which can be mutated when behind a `&` | |
b039eaaf | 220 | /// reference; not doing this is undefined behavior (for example, |
c1a9b12d | 221 | /// `transmute`-ing from `&T` to `&mut T` is invalid). |
9346a6ac | 222 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 223 | #[lang = "sync"] |
9346a6ac AL |
224 | #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] |
225 | pub unsafe trait Sync { | |
226 | // Empty | |
227 | } | |
228 | ||
92a42be0 | 229 | #[stable(feature = "rust1", since = "1.0.0")] |
c34b1796 AL |
230 | unsafe impl Sync for .. { } |
231 | ||
92a42be0 SL |
232 | #[stable(feature = "rust1", since = "1.0.0")] |
233 | impl<T: ?Sized> !Sync for *const T { } | |
234 | #[stable(feature = "rust1", since = "1.0.0")] | |
235 | impl<T: ?Sized> !Sync for *mut T { } | |
c34b1796 | 236 | |
85aaf69f SL |
237 | macro_rules! impls{ |
238 | ($t: ident) => ( | |
92a42be0 | 239 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
240 | impl<T:?Sized> Hash for $t<T> { |
241 | #[inline] | |
242 | fn hash<H: Hasher>(&self, _: &mut H) { | |
243 | } | |
244 | } | |
245 | ||
92a42be0 | 246 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
247 | impl<T:?Sized> cmp::PartialEq for $t<T> { |
248 | fn eq(&self, _other: &$t<T>) -> bool { | |
249 | true | |
250 | } | |
251 | } | |
252 | ||
92a42be0 | 253 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
254 | impl<T:?Sized> cmp::Eq for $t<T> { |
255 | } | |
256 | ||
92a42be0 | 257 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
258 | impl<T:?Sized> cmp::PartialOrd for $t<T> { |
259 | fn partial_cmp(&self, _other: &$t<T>) -> Option<cmp::Ordering> { | |
260 | Option::Some(cmp::Ordering::Equal) | |
261 | } | |
262 | } | |
263 | ||
92a42be0 | 264 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
265 | impl<T:?Sized> cmp::Ord for $t<T> { |
266 | fn cmp(&self, _other: &$t<T>) -> cmp::Ordering { | |
267 | cmp::Ordering::Equal | |
268 | } | |
269 | } | |
270 | ||
92a42be0 | 271 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
272 | impl<T:?Sized> Copy for $t<T> { } |
273 | ||
92a42be0 | 274 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
275 | impl<T:?Sized> Clone for $t<T> { |
276 | fn clone(&self) -> $t<T> { | |
277 | $t | |
278 | } | |
279 | } | |
92a42be0 SL |
280 | |
281 | #[stable(feature = "rust1", since = "1.0.0")] | |
282 | impl<T:?Sized> Default for $t<T> { | |
283 | fn default() -> $t<T> { | |
284 | $t | |
285 | } | |
286 | } | |
85aaf69f SL |
287 | ) |
288 | } | |
289 | ||
9346a6ac AL |
290 | /// `PhantomData<T>` allows you to describe that a type acts as if it stores a value of type `T`, |
291 | /// even though it does not. This allows you to inform the compiler about certain safety properties | |
292 | /// of your code. | |
293 | /// | |
e9174d1e SL |
294 | /// # A ghastly note 👻👻👻 |
295 | /// | |
296 | /// Though they both have scary names, `PhantomData<T>` and 'phantom types' are related, but not | |
297 | /// identical. Phantom types are a more general concept that don't require `PhantomData<T>` to | |
298 | /// implement, but `PhantomData<T>` is the most common way to implement them in a correct manner. | |
1a4d82fc | 299 | /// |
c34b1796 | 300 | /// # Examples |
1a4d82fc | 301 | /// |
9346a6ac | 302 | /// ## Unused lifetime parameter |
1a4d82fc | 303 | /// |
9346a6ac AL |
304 | /// Perhaps the most common time that `PhantomData` is required is |
305 | /// with a struct that has an unused lifetime parameter, typically as | |
306 | /// part of some unsafe code. For example, here is a struct `Slice` | |
307 | /// that has two pointers of type `*const T`, presumably pointing into | |
308 | /// an array somewhere: | |
85aaf69f | 309 | /// |
9346a6ac AL |
310 | /// ```ignore |
311 | /// struct Slice<'a, T> { | |
312 | /// start: *const T, | |
313 | /// end: *const T, | |
1a4d82fc JJ |
314 | /// } |
315 | /// ``` | |
316 | /// | |
9346a6ac AL |
317 | /// The intention is that the underlying data is only valid for the |
318 | /// lifetime `'a`, so `Slice` should not outlive `'a`. However, this | |
319 | /// intent is not expressed in the code, since there are no uses of | |
320 | /// the lifetime `'a` and hence it is not clear what data it applies | |
321 | /// to. We can correct this by telling the compiler to act *as if* the | |
322 | /// `Slice` struct contained a borrowed reference `&'a T`: | |
1a4d82fc | 323 | /// |
c34b1796 | 324 | /// ``` |
9346a6ac | 325 | /// use std::marker::PhantomData; |
1a4d82fc | 326 | /// |
92a42be0 | 327 | /// # #[allow(dead_code)] |
9346a6ac AL |
328 | /// struct Slice<'a, T:'a> { |
329 | /// start: *const T, | |
330 | /// end: *const T, | |
331 | /// phantom: PhantomData<&'a T> | |
332 | /// } | |
c34b1796 | 333 | /// ``` |
1a4d82fc | 334 | /// |
9346a6ac AL |
335 | /// This also in turn requires that we annotate `T:'a`, indicating |
336 | /// that `T` is a type that can be borrowed for the lifetime `'a`. | |
1a4d82fc | 337 | /// |
9346a6ac | 338 | /// ## Unused type parameters |
1a4d82fc | 339 | /// |
9346a6ac AL |
340 | /// It sometimes happens that there are unused type parameters that |
341 | /// indicate what type of data a struct is "tied" to, even though that | |
342 | /// data is not actually found in the struct itself. Here is an | |
343 | /// example where this arises when handling external resources over a | |
344 | /// foreign function interface. `PhantomData<T>` can prevent | |
345 | /// mismatches by enforcing types in the method implementations: | |
c34b1796 AL |
346 | /// |
347 | /// ``` | |
92a42be0 | 348 | /// # #![allow(dead_code)] |
d9579d0f | 349 | /// # trait ResType { fn foo(&self); } |
c34b1796 AL |
350 | /// # struct ParamType; |
351 | /// # mod foreign_lib { | |
352 | /// # pub fn new(_: usize) -> *mut () { 42 as *mut () } | |
353 | /// # pub fn do_stuff(_: *mut (), _: usize) {} | |
354 | /// # } | |
355 | /// # fn convert_params(_: ParamType) -> usize { 42 } | |
356 | /// use std::marker::PhantomData; | |
357 | /// use std::mem; | |
358 | /// | |
359 | /// struct ExternalResource<R> { | |
360 | /// resource_handle: *mut (), | |
361 | /// resource_type: PhantomData<R>, | |
362 | /// } | |
363 | /// | |
364 | /// impl<R: ResType> ExternalResource<R> { | |
365 | /// fn new() -> ExternalResource<R> { | |
366 | /// let size_of_res = mem::size_of::<R>(); | |
367 | /// ExternalResource { | |
368 | /// resource_handle: foreign_lib::new(size_of_res), | |
369 | /// resource_type: PhantomData, | |
370 | /// } | |
371 | /// } | |
372 | /// | |
373 | /// fn do_stuff(&self, param: ParamType) { | |
374 | /// let foreign_params = convert_params(param); | |
375 | /// foreign_lib::do_stuff(self.resource_handle, foreign_params); | |
376 | /// } | |
377 | /// } | |
378 | /// ``` | |
379 | /// | |
9346a6ac AL |
380 | /// ## Indicating ownership |
381 | /// | |
382 | /// Adding a field of type `PhantomData<T>` also indicates that your | |
383 | /// struct owns data of type `T`. This in turn implies that when your | |
384 | /// struct is dropped, it may in turn drop one or more instances of | |
385 | /// the type `T`, though that may not be apparent from the other | |
386 | /// structure of the type itself. This is commonly necessary if the | |
62682a34 | 387 | /// structure is using a raw pointer like `*mut T` whose referent |
9346a6ac AL |
388 | /// may be dropped when the type is dropped, as a `*mut T` is |
389 | /// otherwise not treated as owned. | |
390 | /// | |
391 | /// If your struct does not in fact *own* the data of type `T`, it is | |
392 | /// better to use a reference type, like `PhantomData<&'a T>` | |
393 | /// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so | |
394 | /// as not to indicate ownership. | |
d9579d0f | 395 | #[lang = "phantom_data"] |
85aaf69f SL |
396 | #[stable(feature = "rust1", since = "1.0.0")] |
397 | pub struct PhantomData<T:?Sized>; | |
1a4d82fc | 398 | |
85aaf69f | 399 | impls! { PhantomData } |
1a4d82fc | 400 | |
85aaf69f SL |
401 | mod impls { |
402 | use super::{Send, Sync, Sized}; | |
403 | ||
92a42be0 | 404 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f | 405 | unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {} |
92a42be0 | 406 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
407 | unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {} |
408 | } | |
1a4d82fc | 409 | |
92a42be0 SL |
410 | /// Types that can be reflected over. |
411 | /// | |
412 | /// This trait is implemented for all types. Its purpose is to ensure | |
413 | /// that when you write a generic function that will employ | |
414 | /// reflection, that must be reflected (no pun intended) in the | |
415 | /// generic bounds of that function. Here is an example: | |
c34b1796 AL |
416 | /// |
417 | /// ``` | |
62682a34 | 418 | /// #![feature(reflect_marker)] |
c34b1796 AL |
419 | /// use std::marker::Reflect; |
420 | /// use std::any::Any; | |
92a42be0 SL |
421 | /// |
422 | /// # #[allow(dead_code)] | |
c34b1796 AL |
423 | /// fn foo<T:Reflect+'static>(x: &T) { |
424 | /// let any: &Any = x; | |
425 | /// if any.is::<u32>() { println!("u32"); } | |
426 | /// } | |
427 | /// ``` | |
428 | /// | |
429 | /// Without the declaration `T:Reflect`, `foo` would not type check | |
b039eaaf | 430 | /// (note: as a matter of style, it would be preferable to write |
c34b1796 AL |
431 | /// `T:Any`, because `T:Any` implies `T:Reflect` and `T:'static`, but |
432 | /// we use `Reflect` here to show how it works). The `Reflect` bound | |
433 | /// thus serves to alert `foo`'s caller to the fact that `foo` may | |
434 | /// behave differently depending on whether `T=u32` or not. In | |
435 | /// particular, thanks to the `Reflect` bound, callers know that a | |
436 | /// function declared like `fn bar<T>(...)` will always act in | |
437 | /// precisely the same way no matter what type `T` is supplied, | |
438 | /// because there are no bounds declared on `T`. (The ability for a | |
439 | /// caller to reason about what a function may do based solely on what | |
440 | /// generic bounds are declared is often called the ["parametricity | |
441 | /// property"][1].) | |
442 | /// | |
443 | /// [1]: http://en.wikipedia.org/wiki/Parametricity | |
444 | #[rustc_reflect_like] | |
62682a34 | 445 | #[unstable(feature = "reflect_marker", |
e9174d1e SL |
446 | reason = "requires RFC and more experience", |
447 | issue = "27749")] | |
bd371182 AL |
448 | #[rustc_on_unimplemented = "`{Self}` does not implement `Any`; \ |
449 | ensure all type parameters are bounded by `Any`"] | |
9346a6ac AL |
450 | pub trait Reflect {} |
451 | ||
92a42be0 SL |
452 | #[unstable(feature = "reflect_marker", |
453 | reason = "requires RFC and more experience", | |
454 | issue = "27749")] | |
c34b1796 | 455 | impl Reflect for .. { } |