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