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