(index<- ) ./libcore/kinds.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Fri May 9 13:02:28 2014
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 `Box<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 }
libcore/kinds.rs:260:4-260:4 -struct- definition:
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
references:- 5258: #[lang="no_send_bound"]
259: #[deriving(Eq,Clone)]
260: pub struct NoSend;
libcore/kinds.rs:137:4-137:4 -struct- definition:
pub struct CovariantType<T>;
/// A marker type whose type parameter `T` is considered to be
/// contravariant with respect to the type itself. This is (typically)
references:- 5135: #[lang="covariant_type"]
136: #[deriving(Eq,Clone)]
137: pub struct CovariantType<T>;
libcore/kinds.rs:205:4-205:4 -struct- definition:
pub struct InvariantType<T>;
/// As `CovariantType`, but for lifetime parameters. Using
/// `CovariantLifetime<'a>` indicates that it is ok to substitute
references:- 6203: #[lang="invariant_type"]
204: #[deriving(Eq,Clone)]
205: pub struct InvariantType<T>;
libcore/ty.rs:
53: /// Invariance marker
54: pub marker1: marker::InvariantType<T>
55: }
libcore/kinds.rs:267:4-267:4 -struct- definition:
pub struct NoCopy;
/// A type which is considered "not sharable", meaning that
/// its contents are not threadsafe, hence they cannot be
references:- 7265: #[lang="no_copy_bound"]
266: #[deriving(Eq,Clone)]
267: pub struct NoCopy;
libcore/cell.rs:
65: borrow: Cell<BorrowFlag>,
66: nocopy: marker::NoCopy,
67: noshare: marker::NoShare,
libcore/slice.rs:
1267: marker: marker::ContravariantLifetime<'a>,
1268: marker2: marker::NoCopy
1269: }
libcore/kinds.rs:280:4-280:4 -struct- definition:
pub struct Managed;
}
references:- 5278: #[lang="managed_bound"]
279: #[deriving(Eq,Clone)]
280: pub struct Managed;
libcore/kinds.rs:36:15-36:15 -trait- definition:
pub trait Copy {
// Empty.
}
references:- 4libcore/cell.rs:
56: impl<T:Eq + Copy> Eq for Cell<T> {
57: fn eq(&self, other: &Cell<T>) -> bool {
libcore/num/mod.rs:
260: /// may be useful for systems programming.
261: pub trait Primitive: Copy
262: + Clone
libcore/kinds.rs:241:4-241:4 -struct- definition:
pub struct ContravariantLifetime<'a>;
/// As `InvariantType`, but for lifetime parameters. Using
/// `InvariantLifetime<'a>` indicates that it is not ok to
references:- 7239: #[lang="contravariant_lifetime"]
240: #[deriving(Eq,Clone)]
241: pub struct ContravariantLifetime<'a>;
libcore/slice.rs:
1266: end: *mut T,
1267: marker: marker::ContravariantLifetime<'a>,
1268: marker2: marker::NoCopy
libcore/kinds.rs:274:4-274:4 -struct- definition:
pub struct NoShare;
/// A type which is considered managed by the GC. This is typically
/// embedded in other types.
references:- 7272: #[lang="no_share_bound"]
273: #[deriving(Eq,Clone)]
274: pub struct NoShare;
libcore/cell.rs:
66: nocopy: marker::NoCopy,
67: noshare: marker::NoShare,
68: }
libcore/kinds.rs:
272: #[lang="no_share_bound"]
273: #[deriving(Eq,Clone)]
274: pub struct NoShare;
libcore/kinds.rs:180:4-180:4 -struct- definition:
pub struct ContravariantType<T>;
/// A marker type whose type parameter `T` is considered to be
/// invariant with respect to the type itself. This is (typically)
references:- 5178: #[lang="contravariant_type"]
179: #[deriving(Eq,Clone)]
180: pub struct ContravariantType<T>;
libcore/kinds.rs:252:4-252:4 -struct- definition:
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
references:- 5250: #[lang="invariant_lifetime"]
251: #[deriving(Eq,Clone)]
252: pub struct InvariantLifetime<'a>;
libcore/kinds.rs:225:4-225:4 -struct- definition:
pub struct CovariantLifetime<'a>;
/// As `ContravariantType`, but for lifetime parameters. Using
/// `ContravariantLifetime<'a>` indicates that it is ok to
references:- 5223: #[lang="covariant_lifetime"]
224: #[deriving(Eq,Clone)]
225: pub struct CovariantLifetime<'a>;