aboutsummaryrefslogtreecommitdiff
path: root/libcore/marker.rs
diff options
context:
space:
mode:
authorpravic <[email protected]>2016-04-12 17:47:49 +0300
committerpravic <[email protected]>2016-04-12 17:47:49 +0300
commit91d227b219446d3a8b13f5bf7eb87bfc78a8b339 (patch)
tree0e438aefd2b3cf07354a68595d5aa4ed73f81f15 /libcore/marker.rs
parentadd native import libraries (diff)
downloadarchived-kmd-env-rs-91d227b219446d3a8b13f5bf7eb87bfc78a8b339.tar.xz
archived-kmd-env-rs-91d227b219446d3a8b13f5bf7eb87bfc78a8b339.zip
add libcore from 2016-04-11 nightly
Diffstat (limited to 'libcore/marker.rs')
-rw-r--r--libcore/marker.rs463
1 files changed, 463 insertions, 0 deletions
diff --git a/libcore/marker.rs b/libcore/marker.rs
new file mode 100644
index 0000000..1ed2a21
--- /dev/null
+++ b/libcore/marker.rs
@@ -0,0 +1,463 @@
+// 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.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use clone::Clone;
+use cmp;
+use default::Default;
+use option::Option;
+use hash::Hash;
+use hash::Hasher;
+
+/// Types that can be transferred across thread boundaries.
+///
+/// This trait is automatically derived when the compiler determines it's appropriate.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[lang = "send"]
+#[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+pub unsafe trait Send {
+ // empty.
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl Send for .. { }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> !Send for *const T { }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> !Send for *mut T { }
+
+/// Types with a constant size known at compile-time.
+///
+/// All type parameters which can be bounded have an implicit bound of `Sized`. The special syntax
+/// `?Sized` can be used to remove this bound if it is not appropriate.
+///
+/// ```
+/// # #![allow(dead_code)]
+/// struct Foo<T>(T);
+/// struct Bar<T: ?Sized>(T);
+///
+/// // struct FooUse(Foo<[i32]>); // error: Sized is not implemented for [i32]
+/// struct BarUse(Bar<[i32]>); // OK
+/// ```
+#[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.
+}
+
+/// Types that can be "unsized" to a dynamically sized type.
+#[unstable(feature = "unsize", issue = "27732")]
+#[lang="unsize"]
+pub trait Unsize<T: ?Sized> {
+ // 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`:
+///
+/// ```
+/// # #[allow(dead_code)]
+/// struct Point {
+/// x: i32,
+/// y: i32,
+/// }
+/// ```
+///
+/// A `struct` can be `Copy`, and `i32` is `Copy`, so therefore, `Point` is eligible to be `Copy`.
+///
+/// ```
+/// # #![allow(dead_code)]
+/// # 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`.
+///
+/// # Derivable
+///
+/// This trait can be used with `#[derive]`.
+#[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 unsynchronized 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 behavior (for example,
+/// `transmute`-ing from `&T` to `&mut T` is invalid).
+///
+/// This trait is automatically derived when the compiler determines it's appropriate.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[lang = "sync"]
+#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
+pub unsafe trait Sync {
+ // Empty
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl Sync for .. { }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> !Sync for *const T { }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> !Sync for *mut T { }
+
+macro_rules! impls{
+ ($t: ident) => (
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<T:?Sized> Hash for $t<T> {
+ #[inline]
+ fn hash<H: Hasher>(&self, _: &mut H) {
+ }
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<T:?Sized> cmp::PartialEq for $t<T> {
+ fn eq(&self, _other: &$t<T>) -> bool {
+ true
+ }
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<T:?Sized> cmp::Eq for $t<T> {
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<T:?Sized> cmp::PartialOrd for $t<T> {
+ fn partial_cmp(&self, _other: &$t<T>) -> Option<cmp::Ordering> {
+ Option::Some(cmp::Ordering::Equal)
+ }
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<T:?Sized> cmp::Ord for $t<T> {
+ fn cmp(&self, _other: &$t<T>) -> cmp::Ordering {
+ cmp::Ordering::Equal
+ }
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<T:?Sized> Copy for $t<T> { }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<T:?Sized> Clone for $t<T> {
+ fn clone(&self) -> $t<T> {
+ $t
+ }
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl<T:?Sized> Default for $t<T> {
+ fn default() -> $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.
+///
+/// For a more in-depth explanation of how to use `PhantomData<T>`, please see [the Nomicon].
+///
+/// [the Nomicon]: ../../nomicon/phantom-data.html
+///
+/// # A ghastly note 👻👻👻
+///
+/// Though they both have scary names, `PhantomData<T>` and 'phantom types' are related, but not
+/// identical. Phantom types are a more general concept that don't require `PhantomData<T>` to
+/// implement, but `PhantomData<T>` is the most common way to implement them in a correct manner.
+///
+/// # 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;
+///
+/// # #[allow(dead_code)]
+/// 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:
+///
+/// ```
+/// # #![allow(dead_code)]
+/// # 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};
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {}
+ #[stable(feature = "rust1", since = "1.0.0")]
+ unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
+}
+
+/// Types 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;
+///
+/// # #[allow(dead_code)]
+/// 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 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",
+ issue = "27749")]
+#[rustc_on_unimplemented = "`{Self}` does not implement `Any`; \
+ ensure all type parameters are bounded by `Any`"]
+pub trait Reflect {}
+
+#[unstable(feature = "reflect_marker",
+ reason = "requires RFC and more experience",
+ issue = "27749")]
+impl Reflect for .. { }