]> git.lizzy.rs Git - rust.git/blob - src/libstd/kinds.rs
Ignore tests broken by failing on ICE
[rust.git] / src / libstd / kinds.rs
1 // Copyright 2012 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 /*!
12 Primitive traits representing basic 'kinds' of types
13
14 Rust types can be classified in various useful ways according to
15 intrinsic properties of the type. These classifications, often called
16 'kinds', are represented as traits.
17
18 They cannot be implemented by user code, but are instead implemented
19 by the compiler automatically for the types to which they apply.
20
21 */
22
23 /// Types able to be transferred across task boundaries.
24 #[lang="send"]
25 pub trait Send {
26     // empty.
27 }
28
29 /// Types with a constant size known at compile-time.
30 #[lang="sized"]
31 pub trait Sized {
32     // Empty.
33 }
34
35 /// Types that can be copied by simply copying bits (i.e. `memcpy`).
36 #[lang="copy"]
37 pub trait Copy {
38     // Empty.
39 }
40
41 /// Types that can be safely shared between tasks when aliased.
42 ///
43 /// The precise definition is: a type `T` is `Share` if `&T` is
44 /// thread-safe. In other words, there is no possibility of data races
45 /// when passing `&T` references between tasks.
46 ///
47 /// As one would expect, primitive types like `u8` and `f64` are all
48 /// `Share`, and so are simple aggregate types containing them (like
49 /// tuples, structs and enums). More instances of basic `Share` types
50 /// include "immutable" types like `&T` and those with simple
51 /// inherited mutability, such as `~T`, `Vec<T>` and most other
52 /// collection types. (Generic parameters need to be `Share` for their
53 /// container to be `Share`.)
54 ///
55 /// A somewhat surprising consequence of the definition is `&mut T` is
56 /// `Share` (if `T` is `Share`) even though it seems that it might
57 /// provide unsynchronised mutation. The trick is a mutable reference
58 /// stored in an aliasable reference (that is, `& &mut T`) becomes
59 /// read-only, as if it were a `& &T`, hence there is no risk of a data
60 /// race.
61 ///
62 /// Types that are not `Share` are those that have "interior
63 /// mutability" in a non-thread-safe way, such as `Cell` and `RefCell`
64 /// in `std::cell`. These types allow for mutation of their contents
65 /// even when in an immutable, aliasable slot, e.g. the contents of
66 /// `&Cell<T>` can be `.set`, and do not ensure data races are
67 /// impossible, hence they cannot be `Share`. A higher level example
68 /// of a non-`Share` type is the reference counted pointer
69 /// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new
70 /// reference, which modifies the reference counts in a non-atomic
71 /// way.
72 ///
73 /// For cases when one does need thread-safe interior mutability,
74 /// types like the atomics in `std::sync` and `Mutex` & `RWLock` in
75 /// the `sync` crate do ensure that any mutation cannot cause data
76 /// races.  Hence these types are `Share`.
77 ///
78 /// Users writing their own types with interior mutability (or anything
79 /// else that is not thread-safe) should use the `NoShare` marker type
80 /// (from `std::kinds::marker`) to ensure that the compiler doesn't
81 /// consider the user-defined type to be `Share`.  Any types with
82 /// interior mutability must also use the `std::ty::Unsafe` wrapper
83 /// around the value(s) which can be mutated when behind a `&`
84 /// reference; not doing this is undefined behaviour (for example,
85 /// `transmute`-ing from `&T` to `&mut T` is illegal).
86 #[lang="share"]
87 pub trait Share {
88     // Empty
89 }
90
91 /// Marker types are special types that are used with unsafe code to
92 /// inform the compiler of special constraints. Marker types should
93 /// only be needed when you are creating an abstraction that is
94 /// implemented using unsafe code. In that case, you may want to embed
95 /// some of the marker types below into your type.
96 pub mod marker {
97
98     /// A marker type whose type parameter `T` is considered to be
99     /// covariant with respect to the type itself. This is (typically)
100     /// used to indicate that an instance of the type `T` is being stored
101     /// into memory and read from, even though that may not be apparent.
102     ///
103     /// For more information about variance, refer to this Wikipedia
104     /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
105     ///
106     /// *Note:* It is very unusual to have to add a covariant constraint.
107     /// If you are not sure, you probably want to use `InvariantType`.
108     ///
109     /// # Example
110     ///
111     /// Given a struct `S` that includes a type parameter `T`
112     /// but does not actually *reference* that type parameter:
113     ///
114     /// ```ignore
115     /// use std::cast;
116     ///
117     /// struct S<T> { x: *() }
118     /// fn get<T>(s: &S<T>) -> T {
119     ///    unsafe {
120     ///        let x: *T = cast::transmute(s.x);
121     ///        *x
122     ///    }
123     /// }
124     /// ```
125     ///
126     /// The type system would currently infer that the value of
127     /// the type parameter `T` is irrelevant, and hence a `S<int>` is
128     /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
129     /// any `U`). But this is incorrect because `get()` converts the
130     /// `*()` into a `*T` and reads from it. Therefore, we should include the
131     /// a marker field `CovariantType<T>` to inform the type checker that
132     /// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
133     /// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
134     /// for some lifetime `'a`, but not the other way around).
135     #[lang="covariant_type"]
136     #[deriving(Eq,Clone)]
137     pub struct CovariantType<T>;
138
139     /// A marker type whose type parameter `T` is considered to be
140     /// contravariant with respect to the type itself. This is (typically)
141     /// used to indicate that an instance of the type `T` will be consumed
142     /// (but not read from), even though that may not be apparent.
143     ///
144     /// For more information about variance, refer to this Wikipedia
145     /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
146     ///
147     /// *Note:* It is very unusual to have to add a contravariant constraint.
148     /// If you are not sure, you probably want to use `InvariantType`.
149     ///
150     /// # Example
151     ///
152     /// Given a struct `S` that includes a type parameter `T`
153     /// but does not actually *reference* that type parameter:
154     ///
155     /// ```
156     /// use std::cast;
157     ///
158     /// struct S<T> { x: *() }
159     /// fn get<T>(s: &S<T>, v: T) {
160     ///    unsafe {
161     ///        let x: fn(T) = cast::transmute(s.x);
162     ///        x(v)
163     ///    }
164     /// }
165     /// ```
166     ///
167     /// The type system would currently infer that the value of
168     /// the type parameter `T` is irrelevant, and hence a `S<int>` is
169     /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
170     /// any `U`). But this is incorrect because `get()` converts the
171     /// `*()` into a `fn(T)` and then passes a value of type `T` to it.
172     ///
173     /// Supplying a `ContravariantType` marker would correct the
174     /// problem, because it would mark `S` so that `S<T>` is only a
175     /// subtype of `S<U>` if `U` is a subtype of `T`; given that the
176     /// function requires arguments of type `T`, it must also accept
177     /// arguments of type `U`, hence such a conversion is safe.
178     #[lang="contravariant_type"]
179     #[deriving(Eq,Clone)]
180     pub struct ContravariantType<T>;
181
182     /// A marker type whose type parameter `T` is considered to be
183     /// invariant with respect to the type itself. This is (typically)
184     /// used to indicate that instances of the type `T` may be read or
185     /// written, even though that may not be apparent.
186     ///
187     /// For more information about variance, refer to this Wikipedia
188     /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
189     ///
190     /// # Example
191     ///
192     /// The Cell type is an example which uses unsafe code to achieve
193     /// "interior" mutability:
194     ///
195     /// ```
196     /// pub struct Cell<T> { value: T }
197     /// # fn main() {}
198     /// ```
199     ///
200     /// The type system would infer that `value` is only read here and
201     /// never written, but in fact `Cell` uses unsafe code to achieve
202     /// interior mutability.
203     #[lang="invariant_type"]
204     #[deriving(Eq,Clone)]
205     pub struct InvariantType<T>;
206
207     /// As `CovariantType`, but for lifetime parameters. Using
208     /// `CovariantLifetime<'a>` indicates that it is ok to substitute
209     /// a *longer* lifetime for `'a` than the one you originally
210     /// started with (e.g., you could convert any lifetime `'foo` to
211     /// `'static`). You almost certainly want `ContravariantLifetime`
212     /// instead, or possibly `InvariantLifetime`. The only case where
213     /// it would be appropriate is that you have a (type-casted, and
214     /// hence hidden from the type system) function pointer with a
215     /// signature like `fn(&'a T)` (and no other uses of `'a`). In
216     /// this case, it is ok to substitute a larger lifetime for `'a`
217     /// (e.g., `fn(&'static T)`), because the function is only
218     /// becoming more selective in terms of what it accepts as
219     /// argument.
220     ///
221     /// For more information about variance, refer to this Wikipedia
222     /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
223     #[lang="covariant_lifetime"]
224     #[deriving(Eq,Clone)]
225     pub struct CovariantLifetime<'a>;
226
227     /// As `ContravariantType`, but for lifetime parameters. Using
228     /// `ContravariantLifetime<'a>` indicates that it is ok to
229     /// substitute a *shorter* lifetime for `'a` than the one you
230     /// originally started with (e.g., you could convert `'static` to
231     /// any lifetime `'foo`). This is appropriate for cases where you
232     /// have an unsafe pointer that is actually a pointer into some
233     /// memory with lifetime `'a`, and thus you want to limit the
234     /// lifetime of your data structure to `'a`. An example of where
235     /// this is used is the iterator for vectors.
236     ///
237     /// For more information about variance, refer to this Wikipedia
238     /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
239     #[lang="contravariant_lifetime"]
240     #[deriving(Eq,Clone)]
241     pub struct ContravariantLifetime<'a>;
242
243     /// As `InvariantType`, but for lifetime parameters. Using
244     /// `InvariantLifetime<'a>` indicates that it is not ok to
245     /// substitute any other lifetime for `'a` besides its original
246     /// value. This is appropriate for cases where you have an unsafe
247     /// pointer that is actually a pointer into memory with lifetime `'a`,
248     /// and this pointer is itself stored in an inherently mutable
249     /// location (such as a `Cell`).
250     #[lang="invariant_lifetime"]
251     #[deriving(Eq,Clone)]
252     pub struct InvariantLifetime<'a>;
253
254     /// A type which is considered "not sendable", meaning that it cannot
255     /// be safely sent between tasks, even if it is owned. This is
256     /// typically embedded in other types, such as `Gc`, to ensure that
257     /// their instances remain thread-local.
258     #[lang="no_send_bound"]
259     #[deriving(Eq,Clone)]
260     pub struct NoSend;
261
262     /// A type which is considered "not POD", meaning that it is not
263     /// implicitly copyable. This is typically embedded in other types to
264     /// ensure that they are never copied, even if they lack a destructor.
265     #[lang="no_copy_bound"]
266     #[deriving(Eq,Clone)]
267     pub struct NoCopy;
268
269     /// A type which is considered "not sharable", meaning that
270     /// its contents are not threadsafe, hence they cannot be
271     /// shared between tasks.
272     #[lang="no_share_bound"]
273     #[deriving(Eq,Clone)]
274     pub struct NoShare;
275
276     /// A type which is considered managed by the GC. This is typically
277     /// embedded in other types.
278     #[lang="managed_bound"]
279     #[deriving(Eq,Clone)]
280     pub struct Managed;
281 }