]> git.lizzy.rs Git - rust.git/blob - src/libcore/marker.rs
Add 'feature' and 'since' to stability attributes
[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(feature = "grandfathered", since = "1.0.0")]
27
28 use clone::Clone;
29
30 /// Types able to be transferred across task boundaries.
31 #[unstable(feature = "unnamed_feature", since = "1.0.0",
32            reason = "will be overhauled with new lifetime rules; see RFC 458")]
33 #[lang="send"]
34 pub unsafe trait Send: 'static {
35     // empty.
36 }
37
38 /// Types with a constant size known at compile-time.
39 #[stable(feature = "grandfathered", since = "1.0.0")]
40 #[lang="sized"]
41 pub trait Sized {
42     // Empty.
43 }
44
45 /// Types that can be copied by simply copying bits (i.e. `memcpy`).
46 ///
47 /// By default, variable bindings have 'move semantics.' In other
48 /// words:
49 ///
50 /// ```
51 /// #[derive(Show)]
52 /// struct Foo;
53 ///
54 /// let x = Foo;
55 ///
56 /// let y = x;
57 ///
58 /// // `x` has moved into `y`, and so cannot be used
59 ///
60 /// // println!("{:?}", x); // error: use of moved value
61 /// ```
62 ///
63 /// However, if a type implements `Copy`, it instead has 'copy semantics':
64 ///
65 /// ```
66 /// // we can just derive a `Copy` implementation
67 /// #[derive(Show, Copy)]
68 /// struct Foo;
69 ///
70 /// let x = Foo;
71 ///
72 /// let y = x;
73 ///
74 /// // `y` is a copy of `x`
75 ///
76 /// println!("{:?}", x); // A-OK!
77 /// ```
78 ///
79 /// It's important to note that in these two examples, the only difference is if you are allowed to
80 /// access `x` after the assignment: a move is also a bitwise copy under the hood.
81 ///
82 /// ## When can my type be `Copy`?
83 ///
84 /// A type can implement `Copy` if all of its components implement `Copy`. For example, this
85 /// `struct` can be `Copy`:
86 ///
87 /// ```
88 /// struct Point {
89 ///    x: i32,
90 ///    y: i32,
91 /// }
92 /// ```
93 ///
94 /// A `struct` can be `Copy`, and `i32` is `Copy`, so therefore, `Point` is eligible to be `Copy`.
95 ///
96 /// ```
97 /// # struct Point;
98 /// struct PointList {
99 ///     points: Vec<Point>,
100 /// }
101 /// ```
102 ///
103 /// The `PointList` `struct` cannot implement `Copy`, because `Vec<T>` is not `Copy`. If we
104 /// attempt to derive a `Copy` implementation, we'll get an error.
105 ///
106 /// ```text
107 /// error: the trait `Copy` may not be implemented for this type; field `points` does not implement
108 /// `Copy`
109 /// ```
110 ///
111 /// ## How can I implement `Copy`?
112 ///
113 /// There are two ways to implement `Copy` on your type:
114 ///
115 /// ```
116 /// #[derive(Copy)]
117 /// struct MyStruct;
118 /// ```
119 ///
120 /// and
121 ///
122 /// ```
123 /// struct MyStruct;
124 /// impl Copy for MyStruct {}
125 /// ```
126 ///
127 /// There is a small difference between the two: the `derive` strategy will also place a `Copy`
128 /// bound on type parameters, which isn't always desired.
129 ///
130 /// ## When can my type _not_ be `Copy`?
131 ///
132 /// Some types can't be copied safely. For example, copying `&mut T` would create an aliased
133 /// mutable reference, and copying `String` would result in two attempts to free the same buffer.
134 ///
135 /// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's
136 /// managing some resource besides its own `size_of::<T>()` bytes.
137 ///
138 /// ## When should my type be `Copy`?
139 ///
140 /// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing
141 /// to consider though: if you think your type may _not_ be able to implement `Copy` in the future,
142 /// then it might be prudent to not implement `Copy`. This is because removing `Copy` is a breaking
143 /// change: that second example would fail to compile if we made `Foo` non-`Copy`.
144 #[stable(feature = "grandfathered", since = "1.0.0")]
145 #[lang="copy"]
146 pub trait Copy {
147     // Empty.
148 }
149
150 /// Types that can be safely shared between tasks when aliased.
151 ///
152 /// The precise definition is: a type `T` is `Sync` if `&T` is
153 /// thread-safe. In other words, there is no possibility of data races
154 /// when passing `&T` references between tasks.
155 ///
156 /// As one would expect, primitive types like `u8` and `f64` are all
157 /// `Sync`, and so are simple aggregate types containing them (like
158 /// tuples, structs and enums). More instances of basic `Sync` types
159 /// include "immutable" types like `&T` and those with simple
160 /// inherited mutability, such as `Box<T>`, `Vec<T>` and most other
161 /// collection types. (Generic parameters need to be `Sync` for their
162 /// container to be `Sync`.)
163 ///
164 /// A somewhat surprising consequence of the definition is `&mut T` is
165 /// `Sync` (if `T` is `Sync`) even though it seems that it might
166 /// provide unsynchronised mutation. The trick is a mutable reference
167 /// stored in an aliasable reference (that is, `& &mut T`) becomes
168 /// read-only, as if it were a `& &T`, hence there is no risk of a data
169 /// race.
170 ///
171 /// Types that are not `Sync` are those that have "interior
172 /// mutability" in a non-thread-safe way, such as `Cell` and `RefCell`
173 /// in `std::cell`. These types allow for mutation of their contents
174 /// even when in an immutable, aliasable slot, e.g. the contents of
175 /// `&Cell<T>` can be `.set`, and do not ensure data races are
176 /// impossible, hence they cannot be `Sync`. A higher level example
177 /// of a non-`Sync` type is the reference counted pointer
178 /// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new
179 /// reference, which modifies the reference counts in a non-atomic
180 /// way.
181 ///
182 /// For cases when one does need thread-safe interior mutability,
183 /// types like the atomics in `std::sync` and `Mutex` & `RWLock` in
184 /// the `sync` crate do ensure that any mutation cannot cause data
185 /// races.  Hence these types are `Sync`.
186 ///
187 /// Users writing their own types with interior mutability (or anything
188 /// else that is not thread-safe) should use the `NoSync` marker type
189 /// (from `std::marker`) to ensure that the compiler doesn't
190 /// consider the user-defined type to be `Sync`.  Any types with
191 /// interior mutability must also use the `std::cell::UnsafeCell` wrapper
192 /// around the value(s) which can be mutated when behind a `&`
193 /// reference; not doing this is undefined behaviour (for example,
194 /// `transmute`-ing from `&T` to `&mut T` is illegal).
195 #[unstable(feature = "unnamed_feature", since = "1.0.0",
196            reason = "will be overhauled with new lifetime rules; see RFC 458")]
197 #[lang="sync"]
198 pub unsafe trait Sync {
199     // Empty
200 }
201
202
203 /// A marker type whose type parameter `T` is considered to be
204 /// covariant with respect to the type itself. This is (typically)
205 /// used to indicate that an instance of the type `T` is being stored
206 /// into memory and read from, even though that may not be apparent.
207 ///
208 /// For more information about variance, refer to this Wikipedia
209 /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
210 ///
211 /// *Note:* It is very unusual to have to add a covariant constraint.
212 /// If you are not sure, you probably want to use `InvariantType`.
213 ///
214 /// # Example
215 ///
216 /// Given a struct `S` that includes a type parameter `T`
217 /// but does not actually *reference* that type parameter:
218 ///
219 /// ```ignore
220 /// use std::mem;
221 ///
222 /// struct S<T> { x: *() }
223 /// fn get<T>(s: &S<T>) -> T {
224 ///    unsafe {
225 ///        let x: *T = mem::transmute(s.x);
226 ///        *x
227 ///    }
228 /// }
229 /// ```
230 ///
231 /// The type system would currently infer that the value of
232 /// the type parameter `T` is irrelevant, and hence a `S<int>` is
233 /// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
234 /// any `U`). But this is incorrect because `get()` converts the
235 /// `*()` into a `*T` and reads from it. Therefore, we should include the
236 /// a marker field `CovariantType<T>` to inform the type checker that
237 /// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
238 /// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
239 /// for some lifetime `'a`, but not the other way around).
240 #[unstable(feature = "unnamed_feature", since = "1.0.0",
241            reason = "likely to change with new variance strategy")]
242 #[lang="covariant_type"]
243 #[derive(PartialEq, Eq, PartialOrd, Ord)]
244 pub struct CovariantType<T: ?Sized>;
245
246 impl<T: ?Sized> Copy for CovariantType<T> {}
247 impl<T: ?Sized> Clone for CovariantType<T> {
248     fn clone(&self) -> CovariantType<T> { *self }
249 }
250
251 /// A marker type whose type parameter `T` is considered to be
252 /// contravariant with respect to the type itself. This is (typically)
253 /// used to indicate that an instance of the type `T` will be consumed
254 /// (but not read from), even though that may not be apparent.
255 ///
256 /// For more information about variance, refer to this Wikipedia
257 /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
258 ///
259 /// *Note:* It is very unusual to have to add a contravariant constraint.
260 /// If you are not sure, you probably want to use `InvariantType`.
261 ///
262 /// # Example
263 ///
264 /// Given a struct `S` that includes a type parameter `T`
265 /// but does not actually *reference* that type parameter:
266 ///
267 /// ```
268 /// use std::mem;
269 ///
270 /// struct S<T> { x: *const () }
271 /// fn get<T>(s: &S<T>, v: T) {
272 ///    unsafe {
273 ///        let x: fn(T) = mem::transmute(s.x);
274 ///        x(v)
275 ///    }
276 /// }
277 /// ```
278 ///
279 /// The type system would currently infer that the value of
280 /// the type parameter `T` is irrelevant, and hence a `S<int>` is
281 /// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
282 /// any `U`). But this is incorrect because `get()` converts the
283 /// `*()` into a `fn(T)` and then passes a value of type `T` to it.
284 ///
285 /// Supplying a `ContravariantType` marker would correct the
286 /// problem, because it would mark `S` so that `S<T>` is only a
287 /// subtype of `S<U>` if `U` is a subtype of `T`; given that the
288 /// function requires arguments of type `T`, it must also accept
289 /// arguments of type `U`, hence such a conversion is safe.
290 #[unstable(feature = "unnamed_feature", since = "1.0.0",
291            reason = "likely to change with new variance strategy")]
292 #[lang="contravariant_type"]
293 #[derive(PartialEq, Eq, PartialOrd, Ord)]
294 pub struct ContravariantType<T: ?Sized>;
295
296 impl<T: ?Sized> Copy for ContravariantType<T> {}
297 impl<T: ?Sized> Clone for ContravariantType<T> {
298     fn clone(&self) -> ContravariantType<T> { *self }
299 }
300
301 /// A marker type whose type parameter `T` is considered to be
302 /// invariant with respect to the type itself. This is (typically)
303 /// used to indicate that instances of the type `T` may be read or
304 /// written, even though that may not be apparent.
305 ///
306 /// For more information about variance, refer to this Wikipedia
307 /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
308 ///
309 /// # Example
310 ///
311 /// The Cell type is an example which uses unsafe code to achieve
312 /// "interior" mutability:
313 ///
314 /// ```
315 /// struct Cell<T> { value: T }
316 /// ```
317 ///
318 /// The type system would infer that `value` is only read here and
319 /// never written, but in fact `Cell` uses unsafe code to achieve
320 /// interior mutability.
321 #[unstable(feature = "unnamed_feature", since = "1.0.0",
322            reason = "likely to change with new variance strategy")]
323 #[lang="invariant_type"]
324 #[derive(PartialEq, Eq, PartialOrd, Ord)]
325 pub struct InvariantType<T: ?Sized>;
326
327 #[unstable(feature = "unnamed_feature", since = "1.0.0",
328            reason = "likely to change with new variance strategy")]
329 impl<T: ?Sized> Copy for InvariantType<T> {}
330 #[unstable(feature = "unnamed_feature", since = "1.0.0",
331            reason = "likely to change with new variance strategy")]
332 impl<T: ?Sized> Clone for InvariantType<T> {
333     fn clone(&self) -> InvariantType<T> { *self }
334 }
335
336 /// As `CovariantType`, but for lifetime parameters. Using
337 /// `CovariantLifetime<'a>` indicates that it is ok to substitute
338 /// a *longer* lifetime for `'a` than the one you originally
339 /// started with (e.g., you could convert any lifetime `'foo` to
340 /// `'static`). You almost certainly want `ContravariantLifetime`
341 /// instead, or possibly `InvariantLifetime`. The only case where
342 /// it would be appropriate is that you have a (type-casted, and
343 /// hence hidden from the type system) function pointer with a
344 /// signature like `fn(&'a T)` (and no other uses of `'a`). In
345 /// this case, it is ok to substitute a larger lifetime for `'a`
346 /// (e.g., `fn(&'static T)`), because the function is only
347 /// becoming more selective in terms of what it accepts as
348 /// argument.
349 ///
350 /// For more information about variance, refer to this Wikipedia
351 /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
352 #[unstable(feature = "unnamed_feature", since = "1.0.0",
353            reason = "likely to change with new variance strategy")]
354 #[lang="covariant_lifetime"]
355 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
356 pub struct CovariantLifetime<'a>;
357
358 /// As `ContravariantType`, but for lifetime parameters. Using
359 /// `ContravariantLifetime<'a>` indicates that it is ok to
360 /// substitute a *shorter* lifetime for `'a` than the one you
361 /// originally started with (e.g., you could convert `'static` to
362 /// any lifetime `'foo`). This is appropriate for cases where you
363 /// have an unsafe pointer that is actually a pointer into some
364 /// memory with lifetime `'a`, and thus you want to limit the
365 /// lifetime of your data structure to `'a`. An example of where
366 /// this is used is the iterator for vectors.
367 ///
368 /// For more information about variance, refer to this Wikipedia
369 /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
370 #[unstable(feature = "unnamed_feature", since = "1.0.0",
371            reason = "likely to change with new variance strategy")]
372 #[lang="contravariant_lifetime"]
373 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
374 pub struct ContravariantLifetime<'a>;
375
376 /// As `InvariantType`, but for lifetime parameters. Using
377 /// `InvariantLifetime<'a>` indicates that it is not ok to
378 /// substitute any other lifetime for `'a` besides its original
379 /// value. This is appropriate for cases where you have an unsafe
380 /// pointer that is actually a pointer into memory with lifetime `'a`,
381 /// and this pointer is itself stored in an inherently mutable
382 /// location (such as a `Cell`).
383 #[unstable(feature = "unnamed_feature", since = "1.0.0",
384            reason = "likely to change with new variance strategy")]
385 #[lang="invariant_lifetime"]
386 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
387 pub struct InvariantLifetime<'a>;
388
389 /// A type which is considered "not sendable", meaning that it cannot
390 /// be safely sent between tasks, even if it is owned. This is
391 /// typically embedded in other types, such as `Gc`, to ensure that
392 /// their instances remain thread-local.
393 #[unstable(feature = "unnamed_feature", since = "1.0.0",
394            reason = "likely to change with new variance strategy")]
395 #[lang="no_send_bound"]
396 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
397 #[cfg(stage0)] // NOTE remove impl after next snapshot
398 pub struct NoSend;
399
400 /// A type which is considered "not POD", meaning that it is not
401 /// implicitly copyable. This is typically embedded in other types to
402 /// ensure that they are never copied, even if they lack a destructor.
403 #[unstable(feature = "unnamed_feature", since = "1.0.0",
404            reason = "likely to change with new variance strategy")]
405 #[lang="no_copy_bound"]
406 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
407 #[allow(missing_copy_implementations)]
408 pub struct NoCopy;
409
410 /// A type which is considered "not sync", meaning that
411 /// its contents are not threadsafe, hence they cannot be
412 /// shared between tasks.
413 #[unstable(feature = "unnamed_feature", since = "1.0.0",
414            reason = "likely to change with new variance strategy")]
415 #[lang="no_sync_bound"]
416 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
417 #[cfg(stage0)] // NOTE remove impl after next snapshot
418 pub struct NoSync;
419
420 /// A type which is considered managed by the GC. This is typically
421 /// embedded in other types.
422 #[unstable(feature = "unnamed_feature", since = "1.0.0",
423            reason = "likely to change with new variance strategy")]
424 #[lang="managed_bound"]
425 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
426 #[allow(missing_copy_implementations)]
427 pub struct Managed;