diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-01-06 15:34:10 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-01-06 15:34:10 -0800 |
| commit | 771fe9026a38cb673d0928fea1f6ebd4ba796e43 (patch) | |
| tree | eec8f16ffcd231cbdb822662a4aaca76eb10bcf0 /src/libcore | |
| parent | 3892dd1eaa9e1c52aba0179b9d6e27a5ced0afc7 (diff) | |
| parent | 9f07d055f7823ac0e17e014f3effa2a0be0947e9 (diff) | |
| download | rust-771fe9026a38cb673d0928fea1f6ebd4ba796e43.tar.gz rust-771fe9026a38cb673d0928fea1f6ebd4ba796e43.zip | |
rollup merge of #20607: nrc/kinds
Conflicts: src/libcore/array.rs src/libcore/cell.rs src/libcore/prelude.rs src/libstd/path/posix.rs src/libstd/prelude/v1.rs src/test/compile-fail/dst-sized-trait-param.rs
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/array.rs | 2 | ||||
| -rw-r--r-- | src/libcore/atomic.rs | 2 | ||||
| -rw-r--r-- | src/libcore/borrow.rs | 2 | ||||
| -rw-r--r-- | src/libcore/cell.rs | 4 | ||||
| -rw-r--r-- | src/libcore/clone.rs | 2 | ||||
| -rw-r--r-- | src/libcore/cmp.rs | 4 | ||||
| -rw-r--r-- | src/libcore/fmt/mod.rs | 2 | ||||
| -rw-r--r-- | src/libcore/iter.rs | 2 | ||||
| -rw-r--r-- | src/libcore/kinds.rs | 298 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 6 | ||||
| -rw-r--r-- | src/libcore/marker.rs | 314 | ||||
| -rw-r--r-- | src/libcore/mem.rs | 2 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/ops.rs | 2 | ||||
| -rw-r--r-- | src/libcore/prelude.rs | 2 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 2 | ||||
| -rw-r--r-- | src/libcore/raw.rs | 2 | ||||
| -rw-r--r-- | src/libcore/slice.rs | 4 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 2 | ||||
| -rw-r--r-- | src/libcore/ty.rs | 2 |
20 files changed, 339 insertions, 321 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs index a4b32f2b6a2..05db9e11760 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -17,7 +17,7 @@ use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use fmt; -use kinds::Copy; +use marker::Copy; use ops::{Deref, FullRange, Index}; use option::Option; diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index 15c20253c8b..aee1d825bc2 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -72,7 +72,7 @@ use self::Ordering::*; -use kinds::Sync; +use marker::Sync; use intrinsics; use cell::UnsafeCell; diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 8cde33c9408..31631355422 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -47,7 +47,7 @@ use clone::Clone; use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; use fmt; -use kinds::Sized; +use marker::Sized; use ops::Deref; use option::Option; use self::Cow::*; diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 3cc197c323c..674364269f1 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -160,7 +160,7 @@ use clone::Clone; use cmp::PartialEq; use default::Default; -use kinds::{Copy, Send}; +use marker::{Copy, Send}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{None, Some}; @@ -509,7 +509,7 @@ impl<'b, T> DerefMut for RefMut<'b, T> { /// /// ```rust /// use std::cell::UnsafeCell; -/// use std::kinds::marker; +/// use std::marker; /// /// struct NotThreadSafe<T> { /// value: UnsafeCell<T>, diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 17991659f97..3149247a83a 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -21,7 +21,7 @@ #![stable] -use kinds::Sized; +use marker::Sized; /// A common trait for cloning an object. #[stable] diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index af5e98ed303..c3dfd5f5159 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -43,7 +43,7 @@ use self::Ordering::*; -use kinds::Sized; +use marker::Sized; use option::Option::{self, Some, None}; /// Trait for equality comparisons which are [partial equivalence relations]( @@ -316,7 +316,7 @@ pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> { mod impls { use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering}; use cmp::Ordering::{Less, Greater, Equal}; - use kinds::Sized; + use marker::Sized; use option::Option; use option::Option::{Some, None}; diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index fdd758cedac..e44c001cc40 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -16,7 +16,7 @@ use any; use cell::{Cell, RefCell, Ref, RefMut}; use char::CharExt; use iter::{Iterator, IteratorExt, range}; -use kinds::{Copy, Sized}; +use marker::{Copy, Sized}; use mem; use option::Option; use option::Option::{Some, None}; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index e5753f6cc2e..97d26b5333a 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -67,7 +67,7 @@ use num::{ToPrimitive, Int}; use ops::{Add, Deref, FnMut}; use option::Option; use option::Option::{Some, None}; -use std::kinds::Sized; +use std::marker::Sized; use uint; /// An interface for dealing with "external iterators". These types of iterators diff --git a/src/libcore/kinds.rs b/src/libcore/kinds.rs deleted file mode 100644 index 5d69938fccf..00000000000 --- a/src/libcore/kinds.rs +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright 2012 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 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. - -/// Types able to be transferred across task boundaries. -#[lang="send"] -pub unsafe trait Send : 'static { - // empty. -} - -/// Types with a constant size known at compile-time. -#[lang="sized"] -pub trait Sized { - // Empty. -} - -/// Types that can be copied by simply copying bits (i.e. `memcpy`). -#[lang="copy"] -pub trait Copy { - // Empty. -} - -/// Types that can be safely shared between tasks 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 tasks. -/// -/// 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`. -/// -/// Users writing their own types with interior mutability (or anything -/// else that is not thread-safe) should use the `NoSync` marker type -/// (from `std::kinds::marker`) to ensure that the compiler doesn't -/// consider the user-defined type to be `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). -#[lang="sync"] -pub unsafe trait Sync { - // Empty -} - -/// 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. -pub mod marker { - use super::{Copy,Sized}; - use clone::Clone; - - /// A marker type whose type parameter `T` is considered to be - /// covariant with respect to the type itself. This is (typically) - /// used to indicate that an instance of the type `T` is being stored - /// into memory and read from, even though that may not be apparent. - /// - /// For more information about variance, refer to this Wikipedia - /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. - /// - /// *Note:* It is very unusual to have to add a covariant constraint. - /// If you are not sure, you probably want to use `InvariantType`. - /// - /// # Example - /// - /// Given a struct `S` that includes a type parameter `T` - /// but does not actually *reference* that type parameter: - /// - /// ```ignore - /// use std::mem; - /// - /// struct S<T> { x: *() } - /// fn get<T>(s: &S<T>) -> T { - /// unsafe { - /// let x: *T = mem::transmute(s.x); - /// *x - /// } - /// } - /// ``` - /// - /// The type system would currently infer that the value of - /// the type parameter `T` is irrelevant, and hence a `S<int>` is - /// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for - /// any `U`). But this is incorrect because `get()` converts the - /// `*()` into a `*T` and reads from it. Therefore, we should include the - /// a marker field `CovariantType<T>` to inform the type checker that - /// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U` - /// (for example, `S<&'static int>` is a subtype of `S<&'a int>` - /// for some lifetime `'a`, but not the other way around). - #[lang="covariant_type"] - #[derive(PartialEq, Eq, PartialOrd, Ord)] - pub struct CovariantType<T: ?Sized>; - - impl<T: ?Sized> Copy for CovariantType<T> {} - impl<T: ?Sized> Clone for CovariantType<T> { - fn clone(&self) -> CovariantType<T> { *self } - } - - /// A marker type whose type parameter `T` is considered to be - /// contravariant with respect to the type itself. This is (typically) - /// used to indicate that an instance of the type `T` will be consumed - /// (but not read from), even though that may not be apparent. - /// - /// For more information about variance, refer to this Wikipedia - /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. - /// - /// *Note:* It is very unusual to have to add a contravariant constraint. - /// If you are not sure, you probably want to use `InvariantType`. - /// - /// # Example - /// - /// Given a struct `S` that includes a type parameter `T` - /// but does not actually *reference* that type parameter: - /// - /// ``` - /// use std::mem; - /// - /// struct S<T> { x: *const () } - /// fn get<T>(s: &S<T>, v: T) { - /// unsafe { - /// let x: fn(T) = mem::transmute(s.x); - /// x(v) - /// } - /// } - /// ``` - /// - /// The type system would currently infer that the value of - /// the type parameter `T` is irrelevant, and hence a `S<int>` is - /// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for - /// any `U`). But this is incorrect because `get()` converts the - /// `*()` into a `fn(T)` and then passes a value of type `T` to it. - /// - /// Supplying a `ContravariantType` marker would correct the - /// problem, because it would mark `S` so that `S<T>` is only a - /// subtype of `S<U>` if `U` is a subtype of `T`; given that the - /// function requires arguments of type `T`, it must also accept - /// arguments of type `U`, hence such a conversion is safe. - #[lang="contravariant_type"] - #[derive(PartialEq, Eq, PartialOrd, Ord)] - pub struct ContravariantType<T: ?Sized>; - - impl<T: ?Sized> Copy for ContravariantType<T> {} - impl<T: ?Sized> Clone for ContravariantType<T> { - fn clone(&self) -> ContravariantType<T> { *self } - } - - /// A marker type whose type parameter `T` is considered to be - /// invariant with respect to the type itself. This is (typically) - /// used to indicate that instances of the type `T` may be read or - /// written, even though that may not be apparent. - /// - /// For more information about variance, refer to this Wikipedia - /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. - /// - /// # Example - /// - /// The Cell type is an example which uses unsafe code to achieve - /// "interior" mutability: - /// - /// ``` - /// pub struct Cell<T> { value: T } - /// # fn main() {} - /// ``` - /// - /// The type system would infer that `value` is only read here and - /// never written, but in fact `Cell` uses unsafe code to achieve - /// interior mutability. - #[lang="invariant_type"] - #[derive(PartialEq, Eq, PartialOrd, Ord)] - pub struct InvariantType<T: ?Sized>; - - impl<T: ?Sized> Copy for InvariantType<T> {} - impl<T: ?Sized> Clone for InvariantType<T> { - fn clone(&self) -> InvariantType<T> { *self } - } - - /// As `CovariantType`, but for lifetime parameters. Using - /// `CovariantLifetime<'a>` indicates that it is ok to substitute - /// a *longer* lifetime for `'a` than the one you originally - /// started with (e.g., you could convert any lifetime `'foo` to - /// `'static`). You almost certainly want `ContravariantLifetime` - /// instead, or possibly `InvariantLifetime`. The only case where - /// it would be appropriate is that you have a (type-casted, and - /// hence hidden from the type system) function pointer with a - /// signature like `fn(&'a T)` (and no other uses of `'a`). In - /// this case, it is ok to substitute a larger lifetime for `'a` - /// (e.g., `fn(&'static T)`), because the function is only - /// becoming more selective in terms of what it accepts as - /// argument. - /// - /// For more information about variance, refer to this Wikipedia - /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. - #[lang="covariant_lifetime"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct CovariantLifetime<'a>; - - /// As `ContravariantType`, but for lifetime parameters. Using - /// `ContravariantLifetime<'a>` indicates that it is ok to - /// substitute a *shorter* lifetime for `'a` than the one you - /// originally started with (e.g., you could convert `'static` to - /// any lifetime `'foo`). This is appropriate for cases where you - /// have an unsafe pointer that is actually a pointer into some - /// memory with lifetime `'a`, and thus you want to limit the - /// lifetime of your data structure to `'a`. An example of where - /// this is used is the iterator for vectors. - /// - /// For more information about variance, refer to this Wikipedia - /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. - #[lang="contravariant_lifetime"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct ContravariantLifetime<'a>; - - /// As `InvariantType`, but for lifetime parameters. Using - /// `InvariantLifetime<'a>` indicates that it is not ok to - /// substitute any other lifetime for `'a` besides its original - /// value. This is appropriate for cases where you have an unsafe - /// pointer that is actually a pointer into memory with lifetime `'a`, - /// and this pointer is itself stored in an inherently mutable - /// location (such as a `Cell`). - #[lang="invariant_lifetime"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct InvariantLifetime<'a>; - - /// A type which is considered "not sendable", meaning that it cannot - /// be safely sent between tasks, even if it is owned. This is - /// typically embedded in other types, such as `Gc`, to ensure that - /// their instances remain thread-local. - #[lang="no_send_bound"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct NoSend; - - /// 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. - #[lang="no_copy_bound"] - #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] - #[allow(missing_copy_implementations)] - pub struct NoCopy; - - /// A type which is considered "not sync", meaning that - /// its contents are not threadsafe, hence they cannot be - /// shared between tasks. - #[lang="no_sync_bound"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct NoSync; - - /// A type which is considered managed by the GC. This is typically - /// embedded in other types. - #[lang="managed_bound"] - #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] - #[allow(missing_copy_implementations)] - pub struct Managed; -} - diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 4b598fd5033..a7e3b61b0d4 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -107,7 +107,7 @@ pub mod ptr; /* Core language traits */ -pub mod kinds; +pub mod marker; pub mod ops; pub mod cmp; pub mod clone; @@ -146,7 +146,9 @@ mod core { mod std { pub use clone; pub use cmp; - pub use kinds; + #[cfg(stage0)] + pub use marker as kinds; + pub use marker; pub use option; pub use fmt; pub use hash; diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs new file mode 100644 index 00000000000..d400cb47cbf --- /dev/null +++ b/src/libcore/marker.rs @@ -0,0 +1,314 @@ +// 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] + +use clone::Clone; + +/// Types able to be transferred across task boundaries. +#[unstable = "will be overhauled with new lifetime rules; see RFC 458"] +#[lang="send"] +pub unsafe trait Send: 'static { + // empty. +} + +/// Types with a constant size known at compile-time. +#[stable] +#[lang="sized"] +pub trait Sized { + // Empty. +} + +/// Types that can be copied by simply copying bits (i.e. `memcpy`). +#[stable] +#[lang="copy"] +pub trait Copy { + // Empty. +} + +/// Types that can be safely shared between tasks 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 tasks. +/// +/// 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`. +/// +/// Users writing their own types with interior mutability (or anything +/// else that is not thread-safe) should use the `NoSync` marker type +/// (from `std::marker`) to ensure that the compiler doesn't +/// consider the user-defined type to be `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). +#[unstable = "will be overhauled with new lifetime rules; see RFC 458"] +#[lang="sync"] +pub unsafe trait Sync { + // Empty +} + + +/// A marker type whose type parameter `T` is considered to be +/// covariant with respect to the type itself. This is (typically) +/// used to indicate that an instance of the type `T` is being stored +/// into memory and read from, even though that may not be apparent. +/// +/// For more information about variance, refer to this Wikipedia +/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. +/// +/// *Note:* It is very unusual to have to add a covariant constraint. +/// If you are not sure, you probably want to use `InvariantType`. +/// +/// # Example +/// +/// Given a struct `S` that includes a type parameter `T` +/// but does not actually *reference* that type parameter: +/// +/// ```ignore +/// use std::mem; +/// +/// struct S<T> { x: *() } +/// fn get<T>(s: &S<T>) -> T { +/// unsafe { +/// let x: *T = mem::transmute(s.x); +/// *x +/// } +/// } +/// ``` +/// +/// The type system would currently infer that the value of +/// the type parameter `T` is irrelevant, and hence a `S<int>` is +/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for +/// any `U`). But this is incorrect because `get()` converts the +/// `*()` into a `*T` and reads from it. Therefore, we should include the +/// a marker field `CovariantType<T>` to inform the type checker that +/// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U` +/// (for example, `S<&'static int>` is a subtype of `S<&'a int>` +/// for some lifetime `'a`, but not the other way around). +#[unstable = "likely to change with new variance strategy"] +#[lang="covariant_type"] +#[derive(PartialEq, Eq, PartialOrd, Ord)] +pub struct CovariantType<T: ?Sized>; + +impl<T: ?Sized> Copy for CovariantType<T> {} +impl<T: ?Sized> Clone for CovariantType<T> { + fn clone(&self) -> CovariantType<T> { *self } +} + +/// A marker type whose type parameter `T` is considered to be +/// contravariant with respect to the type itself. This is (typically) +/// used to indicate that an instance of the type `T` will be consumed +/// (but not read from), even though that may not be apparent. +/// +/// For more information about variance, refer to this Wikipedia +/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. +/// +/// *Note:* It is very unusual to have to add a contravariant constraint. +/// If you are not sure, you probably want to use `InvariantType`. +/// +/// # Example +/// +/// Given a struct `S` that includes a type parameter `T` +/// but does not actually *reference* that type parameter: +/// +/// ``` +/// use std::mem; +/// +/// struct S<T> { x: *const () } +/// fn get<T>(s: &S<T>, v: T) { +/// unsafe { +/// let x: fn(T) = mem::transmute(s.x); +/// x(v) +/// } +/// } +/// ``` +/// +/// The type system would currently infer that the value of +/// the type parameter `T` is irrelevant, and hence a `S<int>` is +/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for +/// any `U`). But this is incorrect because `get()` converts the +/// `*()` into a `fn(T)` and then passes a value of type `T` to it. +/// +/// Supplying a `ContravariantType` marker would correct the +/// problem, because it would mark `S` so that `S<T>` is only a +/// subtype of `S<U>` if `U` is a subtype of `T`; given that the +/// function requires arguments of type `T`, it must also accept +/// arguments of type `U`, hence such a conversion is safe. +#[unstable = "likely to change with new variance strategy"] +#[lang="contravariant_type"] +#[derive(PartialEq, Eq, PartialOrd, Ord)] +pub struct ContravariantType<T: ?Sized>; + +impl<T: ?Sized> Copy for ContravariantType<T> {} +impl<T: ?Sized> Clone for ContravariantType<T> { + fn clone(&self) -> ContravariantType<T> { *self } +} + +/// A marker type whose type parameter `T` is considered to be +/// invariant with respect to the type itself. This is (typically) +/// used to indicate that instances of the type `T` may be read or +/// written, even though that may not be apparent. +/// +/// For more information about variance, refer to this Wikipedia +/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. +/// +/// # Example +/// +/// The Cell type is an example which uses unsafe code to achieve +/// "interior" mutability: +/// +/// ``` +/// pub struct Cell<T> { value: T } +/// # fn main() {} +/// ``` +/// +/// The type system would infer that `value` is only read here and +/// never written, but in fact `Cell` uses unsafe code to achieve +/// interior mutability. +#[unstable = "likely to change with new variance strategy"] +#[lang="invariant_type"] +#[derive(PartialEq, Eq, PartialOrd, Ord)] +pub struct InvariantType<T: ?Sized>; + +#[unstable = "likely to change with new variance strategy"] +impl<T: ?Sized> Copy for InvariantType<T> {} +#[unstable = "likely to change with new variance strategy"] +impl<T: ?Sized> Clone for InvariantType<T> { + fn clone(&self) -> InvariantType<T> { *self } +} + +/// As `CovariantType`, but for lifetime parameters. Using +/// `CovariantLifetime<'a>` indicates that it is ok to substitute +/// a *longer* lifetime for `'a` than the one you originally +/// started with (e.g., you could convert any lifetime `'foo` to +/// `'static`). You almost certainly want `ContravariantLifetime` +/// instead, or possibly `InvariantLifetime`. The only case where +/// it would be appropriate is that you have a (type-casted, and +/// hence hidden from the type system) function pointer with a +/// signature like `fn(&'a T)` (and no other uses of `'a`). In +/// this case, it is ok to substitute a larger lifetime for `'a` +/// (e.g., `fn(&'static T)`), because the function is only +/// becoming more selective in terms of what it accepts as +/// argument. +/// +/// For more information about variance, refer to this Wikipedia +/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. +#[unstable = "likely to change with new variance strategy"] +#[lang="covariant_lifetime"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct CovariantLifetime<'a>; + +/// As `ContravariantType`, but for lifetime parameters. Using +/// `ContravariantLifetime<'a>` indicates that it is ok to +/// substitute a *shorter* lifetime for `'a` than the one you +/// originally started with (e.g., you could convert `'static` to +/// any lifetime `'foo`). This is appropriate for cases where you +/// have an unsafe pointer that is actually a pointer into some +/// memory with lifetime `'a`, and thus you want to limit the +/// lifetime of your data structure to `'a`. An example of where +/// this is used is the iterator for vectors. +/// +/// For more information about variance, refer to this Wikipedia +/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. +#[unstable = "likely to change with new variance strategy"] +#[lang="contravariant_lifetime"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct ContravariantLifetime<'a>; + +/// As `InvariantType`, but for lifetime parameters. Using +/// `InvariantLifetime<'a>` indicates that it is not ok to +/// substitute any other lifetime for `'a` besides its original +/// value. This is appropriate for cases where you have an unsafe +/// pointer that is actually a pointer into memory with lifetime `'a`, +/// and this pointer is itself stored in an inherently mutable +/// location (such as a `Cell`). +#[unstable = "likely to change with new variance strategy"] +#[lang="invariant_lifetime"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct InvariantLifetime<'a>; + +/// A type which is considered "not sendable", meaning that it cannot +/// be safely sent between tasks, even if it is owned. This is +/// typically embedded in other types, such as `Gc`, to ensure that +/// their instances remain thread-local. +#[unstable = "likely to change with new variance strategy"] +#[lang="no_send_bound"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct NoSend; + +/// 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 = "likely to change with new variance strategy"] +#[lang="no_copy_bound"] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +#[allow(missing_copy_implementations)] +pub struct NoCopy; + +/// A type which is considered "not sync", meaning that +/// its contents are not threadsafe, hence they cannot be +/// shared between tasks. +#[unstable = "likely to change with new variance strategy"] +#[lang="no_sync_bound"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct NoSync; + +/// A type which is considered managed by the GC. This is typically +/// embedded in other types. +#[unstable = "likely to change with new variance strategy"] +#[lang="managed_bound"] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +#[allow(missing_copy_implementations)] +pub struct Managed; diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index c6056916121..8438c9b206e 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -15,7 +15,7 @@ #![stable] -use kinds::Sized; +use marker::Sized; use intrinsics; use ptr; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 3bcdd54463f..490d8111f46 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -21,7 +21,7 @@ use cmp::{PartialEq, Eq}; use cmp::{PartialOrd, Ord}; use intrinsics; use iter::IteratorExt; -use kinds::Copy; +use marker::Copy; use mem::size_of; use ops::{Add, Sub, Mul, Div, Rem, Neg}; use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr, Index}; @@ -992,7 +992,7 @@ impl_to_primitive_float! { f64 } /// A generic trait for converting a number to a value. #[experimental = "trait is likely to be removed"] -pub trait FromPrimitive : ::kinds::Sized { +pub trait FromPrimitive : ::marker::Sized { /// Convert an `int` to return an optional value of this type. If the /// value cannot be represented by this value, the `None` is returned. #[inline] diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 2a7e6eb4795..47c931e3198 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -63,7 +63,7 @@ use clone::Clone; use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator}; -use kinds::Sized; +use marker::Sized; use option::Option::{self, Some, None}; /// The `Drop` trait is used to run some code when a value goes out of scope. This diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index a560b68db01..c3bb9c91557 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -29,7 +29,7 @@ //! ``` // Reexported core operators -pub use kinds::{Copy, Send, Sized, Sync}; +pub use marker::{Copy, Send, Sized, Sync}; pub use ops::{Drop, Fn, FnMut, FnOnce, FullRange}; // Reexported functions diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 0b77f3456b2..c35d948165a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -92,7 +92,7 @@ use mem; use clone::Clone; use intrinsics; use option::Option::{self, Some, None}; -use kinds::{Send, Sized, Sync}; +use marker::{Send, Sized, Sync}; use cmp::{PartialEq, Eq, Ord, PartialOrd}; use cmp::Ordering::{self, Less, Equal, Greater}; diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index 5ef6f6b2623..1ad6d43f76f 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -18,7 +18,7 @@ //! //! Their definition should always match the ABI defined in `rustc::back::abi`. -use kinds::Copy; +use marker::Copy; use mem; /// The representation of a Rust slice diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 8ab927f701a..d197cb58a58 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -41,7 +41,7 @@ use cmp::Ordering::{Less, Equal, Greater}; use cmp; use default::Default; use iter::*; -use kinds::Copy; +use marker::Copy; use num::Int; use ops::{FnMut, self, Index}; use option::Option; @@ -52,7 +52,7 @@ use ptr; use ptr::PtrExt; use mem; use mem::size_of; -use kinds::{Sized, marker}; +use marker::{Sized, self}; use raw::Repr; // Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module. use raw::Slice as RawSlice; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 4d160c35577..d633f822ff7 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -23,7 +23,7 @@ use default::Default; use iter::range; use iter::ExactSizeIterator; use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator}; -use kinds::Sized; +use marker::Sized; use mem; use num::Int; use ops::{Fn, FnMut, Index}; diff --git a/src/libcore/ty.rs b/src/libcore/ty.rs index f8e03662b00..35c1cb09281 100644 --- a/src/libcore/ty.rs +++ b/src/libcore/ty.rs @@ -10,4 +10,4 @@ //! Types dealing with unsafe actions. -use kinds::marker; +use marker; |
