]>
Commit | Line | Data |
---|---|---|
9e0c209e | 1 | //! Primitive traits and types representing basic properties of types. |
1a4d82fc JJ |
2 | //! |
3 | //! Rust types can be classified in various useful ways according to | |
9e0c209e SL |
4 | //! their intrinsic properties. These classifications are represented |
5 | //! as traits. | |
1a4d82fc | 6 | |
85aaf69f | 7 | #![stable(feature = "rust1", since = "1.0.0")] |
1a4d82fc | 8 | |
48663c56 XL |
9 | use crate::cell::UnsafeCell; |
10 | use crate::cmp; | |
f9f354fc | 11 | use crate::fmt::Debug; |
48663c56 XL |
12 | use crate::hash::Hash; |
13 | use crate::hash::Hasher; | |
1a4d82fc | 14 | |
92a42be0 | 15 | /// Types that can be transferred across thread boundaries. |
9cc50fc6 | 16 | /// |
9e0c209e SL |
17 | /// This trait is automatically implemented when the compiler determines it's |
18 | /// appropriate. | |
19 | /// | |
20 | /// An example of a non-`Send` type is the reference-counting pointer | |
476ff2be | 21 | /// [`rc::Rc`][`Rc`]. If two threads attempt to clone [`Rc`]s that point to the same |
9e0c209e | 22 | /// reference-counted value, they might try to update the reference count at the |
476ff2be | 23 | /// same time, which is [undefined behavior][ub] because [`Rc`] doesn't use atomic |
9e0c209e SL |
24 | /// operations. Its cousin [`sync::Arc`][arc] does use atomic operations (incurring |
25 | /// some overhead) and thus is `Send`. | |
26 | /// | |
27 | /// See [the Nomicon](../../nomicon/send-and-sync.html) for more details. | |
28 | /// | |
476ff2be | 29 | /// [`Rc`]: ../../std/rc/struct.Rc.html |
9e0c209e | 30 | /// [arc]: ../../std/sync/struct.Arc.html |
8bb4bdeb | 31 | /// [ub]: ../../reference/behavior-considered-undefined.html |
85aaf69f | 32 | #[stable(feature = "rust1", since = "1.0.0")] |
3c0e092e | 33 | #[cfg_attr(not(test), rustc_diagnostic_item = "Send")] |
8faf50e0 | 34 | #[rustc_on_unimplemented( |
dfeec247 XL |
35 | message = "`{Self}` cannot be sent between threads safely", |
36 | label = "`{Self}` cannot be sent between threads safely" | |
8faf50e0 | 37 | )] |
2c00a5a8 | 38 | pub unsafe auto trait Send { |
9346a6ac AL |
39 | // empty. |
40 | } | |
41 | ||
92a42be0 | 42 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 43 | impl<T: ?Sized> !Send for *const T {} |
92a42be0 | 44 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 45 | impl<T: ?Sized> !Send for *mut T {} |
c34b1796 | 46 | |
2b03887a FG |
47 | // Most instances arise automatically, but this instance is needed to link up `T: Sync` with |
48 | // `&T: Send` (and it also removes the unsound default instance `T Send` -> `&T: Send` that would | |
49 | // otherwise exist). | |
50 | #[stable(feature = "rust1", since = "1.0.0")] | |
51 | unsafe impl<T: Sync + ?Sized> Send for &T {} | |
52 | ||
9e0c209e | 53 | /// Types with a constant size known at compile time. |
b039eaaf | 54 | /// |
9e0c209e SL |
55 | /// All type parameters have an implicit bound of `Sized`. The special syntax |
56 | /// `?Sized` can be used to remove this bound if it's not appropriate. | |
b039eaaf SL |
57 | /// |
58 | /// ``` | |
92a42be0 | 59 | /// # #![allow(dead_code)] |
b039eaaf SL |
60 | /// struct Foo<T>(T); |
61 | /// struct Bar<T: ?Sized>(T); | |
62 | /// | |
63 | /// // struct FooUse(Foo<[i32]>); // error: Sized is not implemented for [i32] | |
64 | /// struct BarUse(Bar<[i32]>); // OK | |
65 | /// ``` | |
9e0c209e | 66 | /// |
0531ce1d XL |
67 | /// The one exception is the implicit `Self` type of a trait. A trait does not |
68 | /// have an implicit `Sized` bound as this is incompatible with [trait object]s | |
69 | /// where, by definition, the trait needs to work with all possible implementors, | |
70 | /// and thus could be any size. | |
71 | /// | |
72 | /// Although Rust will let you bind `Sized` to a trait, you won't | |
73 | /// be able to use it to form a trait object later: | |
9e0c209e SL |
74 | /// |
75 | /// ``` | |
76 | /// # #![allow(unused_variables)] | |
77 | /// trait Foo { } | |
78 | /// trait Bar: Sized { } | |
79 | /// | |
80 | /// struct Impl; | |
81 | /// impl Foo for Impl { } | |
82 | /// impl Bar for Impl { } | |
83 | /// | |
48663c56 XL |
84 | /// let x: &dyn Foo = &Impl; // OK |
85 | /// // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot | |
86 | /// // be made into an object | |
9e0c209e SL |
87 | /// ``` |
88 | /// | |
9fa01778 | 89 | /// [trait object]: ../../book/ch17-02-trait-objects.html |
2b03887a | 90 | #[doc(alias = "?", alias = "?Sized")] |
85aaf69f | 91 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 92 | #[lang = "sized"] |
8faf50e0 | 93 | #[rustc_on_unimplemented( |
dfeec247 | 94 | message = "the size for values of type `{Self}` cannot be known at compilation time", |
3dfed10e | 95 | label = "doesn't have a size known at compile-time" |
8faf50e0 | 96 | )] |
c34b1796 | 97 | #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable |
f9f354fc | 98 | #[rustc_specialization_trait] |
f25598a0 | 99 | #[rustc_deny_explicit_impl] |
9346a6ac AL |
100 | pub trait Sized { |
101 | // Empty. | |
102 | } | |
103 | ||
9e0c209e SL |
104 | /// Types that can be "unsized" to a dynamically-sized type. |
105 | /// | |
106 | /// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and | |
60c5eb7d | 107 | /// `Unsize<dyn fmt::Debug>`. |
9e0c209e SL |
108 | /// |
109 | /// All implementations of `Unsize` are provided automatically by the compiler. | |
c295e0f8 | 110 | /// Those implementations are: |
9e0c209e | 111 | /// |
c295e0f8 XL |
112 | /// - Arrays `[T; N]` implement `Unsize<[T]>`. |
113 | /// - Types implementing a trait `Trait` also implement `Unsize<dyn Trait>`. | |
114 | /// - Structs `Foo<..., T, ...>` implement `Unsize<Foo<..., U, ...>>` if all of these conditions | |
115 | /// are met: | |
116 | /// - `T: Unsize<U>`. | |
117 | /// - Only the last field of `Foo` has a type involving `T`. | |
118 | /// - `Bar<T>: Unsize<Bar<U>>`, where `Bar<T>` stands for the actual type of that last field. | |
32a655c1 | 119 | /// |
1b1a35ee XL |
120 | /// `Unsize` is used along with [`ops::CoerceUnsized`] to allow |
121 | /// "user-defined" containers such as [`Rc`] to contain dynamically-sized | |
32a655c1 SL |
122 | /// types. See the [DST coercion RFC][RFC982] and [the nomicon entry on coercion][nomicon-coerce] |
123 | /// for more details. | |
9e0c209e | 124 | /// |
1b1a35ee XL |
125 | /// [`ops::CoerceUnsized`]: crate::ops::CoerceUnsized |
126 | /// [`Rc`]: ../../std/rc/struct.Rc.html | |
9e0c209e | 127 | /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md |
7cac9316 | 128 | /// [nomicon-coerce]: ../../nomicon/coercions.html |
f25598a0 | 129 | #[unstable(feature = "unsize", issue = "18598")] |
ea8adc8c | 130 | #[lang = "unsize"] |
f25598a0 | 131 | #[rustc_deny_explicit_impl] |
e9174d1e | 132 | pub trait Unsize<T: ?Sized> { |
1a4d82fc JJ |
133 | // Empty. |
134 | } | |
135 | ||
e74abb32 XL |
136 | /// Required trait for constants used in pattern matches. |
137 | /// | |
138 | /// Any type that derives `PartialEq` automatically implements this trait, | |
139 | /// *regardless* of whether its type-parameters implement `Eq`. | |
140 | /// | |
141 | /// If a `const` item contains some type that does not implement this trait, | |
142 | /// then that type either (1.) does not implement `PartialEq` (which means the | |
143 | /// constant will not provide that comparison method, which code generation | |
144 | /// assumes is available), or (2.) it implements *its own* version of | |
145 | /// `PartialEq` (which we assume does not conform to a structural-equality | |
146 | /// comparison). | |
147 | /// | |
148 | /// In either of the two scenarios above, we reject usage of such a constant in | |
149 | /// a pattern match. | |
150 | /// | |
dfeec247 | 151 | /// See also the [structural match RFC][RFC1445], and [issue 63438] which |
e74abb32 XL |
152 | /// motivated migrating from attribute-based design to this trait. |
153 | /// | |
154 | /// [RFC1445]: https://github.com/rust-lang/rfcs/blob/master/text/1445-restrict-constants-in-patterns.md | |
155 | /// [issue 63438]: https://github.com/rust-lang/rust/issues/63438 | |
e74abb32 | 156 | #[unstable(feature = "structural_match", issue = "31434")] |
dfeec247 | 157 | #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")] |
e74abb32 XL |
158 | #[lang = "structural_peq"] |
159 | pub trait StructuralPartialEq { | |
160 | // Empty. | |
161 | } | |
162 | ||
163 | /// Required trait for constants used in pattern matches. | |
164 | /// | |
165 | /// Any type that derives `Eq` automatically implements this trait, *regardless* | |
fc512014 | 166 | /// of whether its type parameters implement `Eq`. |
e74abb32 | 167 | /// |
fc512014 | 168 | /// This is a hack to work around a limitation in our type system. |
e74abb32 | 169 | /// |
fc512014 | 170 | /// # Background |
e74abb32 XL |
171 | /// |
172 | /// We want to require that types of consts used in pattern matches | |
173 | /// have the attribute `#[derive(PartialEq, Eq)]`. | |
174 | /// | |
175 | /// In a more ideal world, we could check that requirement by just checking that | |
fc512014 XL |
176 | /// the given type implements both the `StructuralPartialEq` trait *and* |
177 | /// the `Eq` trait. However, you can have ADTs that *do* `derive(PartialEq, Eq)`, | |
e74abb32 XL |
178 | /// and be a case that we want the compiler to accept, and yet the constant's |
179 | /// type fails to implement `Eq`. | |
180 | /// | |
181 | /// Namely, a case like this: | |
182 | /// | |
183 | /// ```rust | |
184 | /// #[derive(PartialEq, Eq)] | |
185 | /// struct Wrap<X>(X); | |
fc512014 | 186 | /// |
e74abb32 | 187 | /// fn higher_order(_: &()) { } |
fc512014 | 188 | /// |
e74abb32 | 189 | /// const CFN: Wrap<fn(&())> = Wrap(higher_order); |
fc512014 | 190 | /// |
e74abb32 XL |
191 | /// fn main() { |
192 | /// match CFN { | |
193 | /// CFN => {} | |
194 | /// _ => {} | |
195 | /// } | |
196 | /// } | |
197 | /// ``` | |
198 | /// | |
199 | /// (The problem in the above code is that `Wrap<fn(&())>` does not implement | |
200 | /// `PartialEq`, nor `Eq`, because `for<'a> fn(&'a _)` does not implement those | |
201 | /// traits.) | |
202 | /// | |
203 | /// Therefore, we cannot rely on naive check for `StructuralPartialEq` and | |
204 | /// mere `Eq`. | |
205 | /// | |
206 | /// As a hack to work around this, we use two separate traits injected by each | |
207 | /// of the two derives (`#[derive(PartialEq)]` and `#[derive(Eq)]`) and check | |
208 | /// that both of them are present as part of structural-match checking. | |
e74abb32 | 209 | #[unstable(feature = "structural_match", issue = "31434")] |
dfeec247 | 210 | #[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")] |
e74abb32 XL |
211 | #[lang = "structural_teq"] |
212 | pub trait StructuralEq { | |
213 | // Empty. | |
214 | } | |
215 | ||
9e0c209e | 216 | /// Types whose values can be duplicated simply by copying bits. |
85aaf69f SL |
217 | /// |
218 | /// By default, variable bindings have 'move semantics.' In other | |
219 | /// words: | |
220 | /// | |
221 | /// ``` | |
222 | /// #[derive(Debug)] | |
223 | /// struct Foo; | |
224 | /// | |
225 | /// let x = Foo; | |
226 | /// | |
227 | /// let y = x; | |
228 | /// | |
229 | /// // `x` has moved into `y`, and so cannot be used | |
230 | /// | |
5e7ed085 | 231 | /// // println!("{x:?}"); // error: use of moved value |
85aaf69f SL |
232 | /// ``` |
233 | /// | |
234 | /// However, if a type implements `Copy`, it instead has 'copy semantics': | |
235 | /// | |
236 | /// ``` | |
9e0c209e SL |
237 | /// // We can derive a `Copy` implementation. `Clone` is also required, as it's |
238 | /// // a supertrait of `Copy`. | |
c34b1796 | 239 | /// #[derive(Debug, Copy, Clone)] |
85aaf69f SL |
240 | /// struct Foo; |
241 | /// | |
242 | /// let x = Foo; | |
243 | /// | |
244 | /// let y = x; | |
245 | /// | |
246 | /// // `y` is a copy of `x` | |
247 | /// | |
5e7ed085 | 248 | /// println!("{x:?}"); // A-OK! |
85aaf69f SL |
249 | /// ``` |
250 | /// | |
9e0c209e SL |
251 | /// It's important to note that in these two examples, the only difference is whether you |
252 | /// are allowed to access `x` after the assignment. Under the hood, both a copy and a move | |
253 | /// can result in bits being copied in memory, although this is sometimes optimized away. | |
254 | /// | |
255 | /// ## How can I implement `Copy`? | |
256 | /// | |
257 | /// There are two ways to implement `Copy` on your type. The simplest is to use `derive`: | |
258 | /// | |
259 | /// ``` | |
260 | /// #[derive(Copy, Clone)] | |
261 | /// struct MyStruct; | |
262 | /// ``` | |
263 | /// | |
264 | /// You can also implement `Copy` and `Clone` manually: | |
265 | /// | |
266 | /// ``` | |
267 | /// struct MyStruct; | |
268 | /// | |
269 | /// impl Copy for MyStruct { } | |
270 | /// | |
271 | /// impl Clone for MyStruct { | |
272 | /// fn clone(&self) -> MyStruct { | |
273 | /// *self | |
274 | /// } | |
275 | /// } | |
276 | /// ``` | |
277 | /// | |
278 | /// There is a small difference between the two: the `derive` strategy will also place a `Copy` | |
279 | /// bound on type parameters, which isn't always desired. | |
280 | /// | |
281 | /// ## What's the difference between `Copy` and `Clone`? | |
282 | /// | |
283 | /// Copies happen implicitly, for example as part of an assignment `y = x`. The behavior of | |
284 | /// `Copy` is not overloadable; it is always a simple bit-wise copy. | |
285 | /// | |
476ff2be | 286 | /// Cloning is an explicit action, `x.clone()`. The implementation of [`Clone`] can |
9e0c209e | 287 | /// provide any type-specific behavior necessary to duplicate values safely. For example, |
476ff2be SL |
288 | /// the implementation of [`Clone`] for [`String`] needs to copy the pointed-to string |
289 | /// buffer in the heap. A simple bitwise copy of [`String`] values would merely copy the | |
290 | /// pointer, leading to a double free down the line. For this reason, [`String`] is [`Clone`] | |
9e0c209e SL |
291 | /// but not `Copy`. |
292 | /// | |
476ff2be | 293 | /// [`Clone`] is a supertrait of `Copy`, so everything which is `Copy` must also implement |
041b39d2 | 294 | /// [`Clone`]. If a type is `Copy` then its [`Clone`] implementation only needs to return `*self` |
9e0c209e SL |
295 | /// (see the example above). |
296 | /// | |
85aaf69f SL |
297 | /// ## When can my type be `Copy`? |
298 | /// | |
299 | /// A type can implement `Copy` if all of its components implement `Copy`. For example, this | |
9e0c209e | 300 | /// struct can be `Copy`: |
85aaf69f SL |
301 | /// |
302 | /// ``` | |
92a42be0 | 303 | /// # #[allow(dead_code)] |
3dfed10e | 304 | /// #[derive(Copy, Clone)] |
85aaf69f SL |
305 | /// struct Point { |
306 | /// x: i32, | |
307 | /// y: i32, | |
308 | /// } | |
309 | /// ``` | |
310 | /// | |
476ff2be | 311 | /// A struct can be `Copy`, and [`i32`] is `Copy`, therefore `Point` is eligible to be `Copy`. |
9e0c209e | 312 | /// By contrast, consider |
85aaf69f SL |
313 | /// |
314 | /// ``` | |
92a42be0 | 315 | /// # #![allow(dead_code)] |
85aaf69f SL |
316 | /// # struct Point; |
317 | /// struct PointList { | |
318 | /// points: Vec<Point>, | |
319 | /// } | |
320 | /// ``` | |
321 | /// | |
9e0c209e | 322 | /// The struct `PointList` cannot implement `Copy`, because [`Vec<T>`] is not `Copy`. If we |
62682a34 | 323 | /// attempt to derive a `Copy` implementation, we'll get an error: |
85aaf69f SL |
324 | /// |
325 | /// ```text | |
62682a34 | 326 | /// the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy` |
85aaf69f SL |
327 | /// ``` |
328 | /// | |
3dfed10e XL |
329 | /// Shared references (`&T`) are also `Copy`, so a type can be `Copy`, even when it holds |
330 | /// shared references of types `T` that are *not* `Copy`. Consider the following struct, | |
331 | /// which can implement `Copy`, because it only holds a *shared reference* to our non-`Copy` | |
332 | /// type `PointList` from above: | |
333 | /// | |
334 | /// ``` | |
335 | /// # #![allow(dead_code)] | |
336 | /// # struct PointList; | |
337 | /// #[derive(Copy, Clone)] | |
338 | /// struct PointListWrapper<'a> { | |
339 | /// point_list_ref: &'a PointList, | |
340 | /// } | |
341 | /// ``` | |
342 | /// | |
9e0c209e | 343 | /// ## When *can't* my type be `Copy`? |
3157f602 XL |
344 | /// |
345 | /// Some types can't be copied safely. For example, copying `&mut T` would create an aliased | |
476ff2be SL |
346 | /// mutable reference. Copying [`String`] would duplicate responsibility for managing the |
347 | /// [`String`]'s buffer, leading to a double free. | |
3157f602 | 348 | /// |
9e0c209e | 349 | /// Generalizing the latter case, any type implementing [`Drop`] can't be `Copy`, because it's |
cc61c64b | 350 | /// managing some resource besides its own [`size_of::<T>`] bytes. |
3157f602 | 351 | /// |
32a655c1 SL |
352 | /// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get |
353 | /// the error [E0204]. | |
85aaf69f | 354 | /// |
f2b60f7d | 355 | /// [E0204]: ../../error_codes/E0204.html |
85aaf69f | 356 | /// |
9e0c209e | 357 | /// ## When *should* my type be `Copy`? |
85aaf69f | 358 | /// |
9e0c209e SL |
359 | /// Generally speaking, if your type _can_ implement `Copy`, it should. Keep in mind, though, |
360 | /// that implementing `Copy` is part of the public API of your type. If the type might become | |
361 | /// non-`Copy` in the future, it could be prudent to omit the `Copy` implementation now, to | |
362 | /// avoid a breaking API change. | |
85aaf69f | 363 | /// |
83c7162d XL |
364 | /// ## Additional implementors |
365 | /// | |
366 | /// In addition to the [implementors listed below][impls], | |
367 | /// the following types also implement `Copy`: | |
368 | /// | |
0731742a XL |
369 | /// * Function item types (i.e., the distinct types defined for each function) |
370 | /// * Function pointer types (e.g., `fn() -> i32`) | |
83c7162d XL |
371 | /// * Closure types, if they capture no value from the environment |
372 | /// or if all such captured values implement `Copy` themselves. | |
373 | /// Note that variables captured by shared reference always implement `Copy` | |
374 | /// (even if the referent doesn't), | |
375 | /// while variables captured by mutable reference never implement `Copy`. | |
376 | /// | |
9e0c209e SL |
377 | /// [`Vec<T>`]: ../../std/vec/struct.Vec.html |
378 | /// [`String`]: ../../std/string/struct.String.html | |
1b1a35ee | 379 | /// [`size_of::<T>`]: crate::mem::size_of |
83c7162d | 380 | /// [impls]: #implementors |
85aaf69f | 381 | #[stable(feature = "rust1", since = "1.0.0")] |
d9579d0f | 382 | #[lang = "copy"] |
f9f354fc XL |
383 | // FIXME(matthewjasper) This allows copying a type that doesn't implement |
384 | // `Copy` because of unsatisfied lifetime bounds (copying `A<'_>` when only | |
385 | // `A<'static>: Copy` and `A<'_>: Clone`). | |
386 | // We have this attribute here for now only because there are quite a few | |
387 | // existing specializations on `Copy` that already exist in the standard | |
388 | // library, and there's no way to safely have this behavior right now. | |
389 | #[rustc_unsafe_specialization_marker] | |
c295e0f8 | 390 | #[rustc_diagnostic_item = "Copy"] |
dfeec247 | 391 | pub trait Copy: Clone { |
1a4d82fc JJ |
392 | // Empty. |
393 | } | |
394 | ||
416331ca | 395 | /// Derive macro generating an impl of the trait `Copy`. |
416331ca | 396 | #[rustc_builtin_macro] |
416331ca XL |
397 | #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] |
398 | #[allow_internal_unstable(core_intrinsics, derive_clone_copy)] | |
dfeec247 XL |
399 | pub macro Copy($item:item) { |
400 | /* compiler built-in */ | |
401 | } | |
416331ca | 402 | |
9e0c209e SL |
403 | /// Types for which it is safe to share references between threads. |
404 | /// | |
405 | /// This trait is automatically implemented when the compiler determines | |
406 | /// it's appropriate. | |
1a4d82fc | 407 | /// |
1b1a35ee XL |
408 | /// The precise definition is: a type `T` is [`Sync`] if and only if `&T` is |
409 | /// [`Send`]. In other words, if there is no possibility of | |
9e0c209e SL |
410 | /// [undefined behavior][ub] (including data races) when passing |
411 | /// `&T` references between threads. | |
412 | /// | |
1b1a35ee XL |
413 | /// As one would expect, primitive types like [`u8`] and [`f64`] |
414 | /// are all [`Sync`], and so are simple aggregate types containing them, | |
415 | /// like tuples, structs and enums. More examples of basic [`Sync`] | |
9e0c209e SL |
416 | /// types include "immutable" types like `&T`, and those with simple |
417 | /// inherited mutability, such as [`Box<T>`][box], [`Vec<T>`][vec] and | |
1b1a35ee XL |
418 | /// most other collection types. (Generic parameters need to be [`Sync`] |
419 | /// for their container to be [`Sync`].) | |
9e0c209e SL |
420 | /// |
421 | /// A somewhat surprising consequence of the definition is that `&mut T` | |
422 | /// is `Sync` (if `T` is `Sync`) even though it seems like that might | |
423 | /// provide unsynchronized mutation. The trick is that a mutable | |
424 | /// reference behind a shared reference (that is, `& &mut T`) | |
425 | /// becomes read-only, as if it were a `& &T`. Hence there is no risk | |
426 | /// of a data race. | |
1a4d82fc JJ |
427 | /// |
428 | /// Types that are not `Sync` are those that have "interior | |
1b1a35ee XL |
429 | /// mutability" in a non-thread-safe form, such as [`Cell`][cell] |
430 | /// and [`RefCell`][refcell]. These types allow for mutation of | |
9e0c209e | 431 | /// their contents even through an immutable, shared reference. For |
476ff2be SL |
432 | /// example the `set` method on [`Cell<T>`][cell] takes `&self`, so it requires |
433 | /// only a shared reference [`&Cell<T>`][cell]. The method performs no | |
434 | /// synchronization, thus [`Cell`][cell] cannot be `Sync`. | |
1a4d82fc | 435 | /// |
9e0c209e | 436 | /// Another example of a non-`Sync` type is the reference-counting |
1b1a35ee | 437 | /// pointer [`Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone |
476ff2be | 438 | /// a new [`Rc<T>`][rc], modifying the reference counts in a non-atomic way. |
9cc50fc6 | 439 | /// |
9e0c209e SL |
440 | /// For cases when one does need thread-safe interior mutability, |
441 | /// Rust provides [atomic data types], as well as explicit locking via | |
ff7c6d11 | 442 | /// [`sync::Mutex`][mutex] and [`sync::RwLock`][rwlock]. These types |
9e0c209e SL |
443 | /// ensure that any mutation cannot cause data races, hence the types |
444 | /// are `Sync`. Likewise, [`sync::Arc`][arc] provides a thread-safe | |
476ff2be | 445 | /// analogue of [`Rc`][rc]. |
9e0c209e SL |
446 | /// |
447 | /// Any types with interior mutability must also use the | |
448 | /// [`cell::UnsafeCell`][unsafecell] wrapper around the value(s) which | |
449 | /// can be mutated through a shared reference. Failing to doing this is | |
450 | /// [undefined behavior][ub]. For example, [`transmute`][transmute]-ing | |
451 | /// from `&T` to `&mut T` is invalid. | |
452 | /// | |
1b1a35ee | 453 | /// See [the Nomicon][nomicon-send-and-sync] for more details about `Sync`. |
9e0c209e | 454 | /// |
9e0c209e SL |
455 | /// [box]: ../../std/boxed/struct.Box.html |
456 | /// [vec]: ../../std/vec/struct.Vec.html | |
1b1a35ee XL |
457 | /// [cell]: crate::cell::Cell |
458 | /// [refcell]: crate::cell::RefCell | |
9e0c209e SL |
459 | /// [rc]: ../../std/rc/struct.Rc.html |
460 | /// [arc]: ../../std/sync/struct.Arc.html | |
1b1a35ee | 461 | /// [atomic data types]: crate::sync::atomic |
9e0c209e SL |
462 | /// [mutex]: ../../std/sync/struct.Mutex.html |
463 | /// [rwlock]: ../../std/sync/struct.RwLock.html | |
1b1a35ee | 464 | /// [unsafecell]: crate::cell::UnsafeCell |
8bb4bdeb | 465 | /// [ub]: ../../reference/behavior-considered-undefined.html |
1b1a35ee XL |
466 | /// [transmute]: crate::mem::transmute |
467 | /// [nomicon-send-and-sync]: ../../nomicon/send-and-sync.html | |
9346a6ac | 468 | #[stable(feature = "rust1", since = "1.0.0")] |
c295e0f8 | 469 | #[cfg_attr(not(test), rustc_diagnostic_item = "Sync")] |
d9579d0f | 470 | #[lang = "sync"] |
0531ce1d | 471 | #[rustc_on_unimplemented( |
dfeec247 XL |
472 | message = "`{Self}` cannot be shared between threads safely", |
473 | label = "`{Self}` cannot be shared between threads safely" | |
0531ce1d | 474 | )] |
2c00a5a8 | 475 | pub unsafe auto trait Sync { |
0531ce1d XL |
476 | // FIXME(estebank): once support to add notes in `rustc_on_unimplemented` |
477 | // lands in beta, and it has been extended to check whether a closure is | |
478 | // anywhere in the requirement chain, extend it as such (#48534): | |
479 | // ``` | |
480 | // on( | |
481 | // closure, | |
482 | // note="`{Self}` cannot be shared safely, consider marking the closure `move`" | |
483 | // ), | |
484 | // ``` | |
485 | ||
9346a6ac AL |
486 | // Empty |
487 | } | |
488 | ||
92a42be0 | 489 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 490 | impl<T: ?Sized> !Sync for *const T {} |
92a42be0 | 491 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 492 | impl<T: ?Sized> !Sync for *mut T {} |
c34b1796 | 493 | |
9e0c209e | 494 | /// Zero-sized type used to mark things that "act like" they own a `T`. |
9346a6ac | 495 | /// |
9e0c209e SL |
496 | /// Adding a `PhantomData<T>` field to your type tells the compiler that your |
497 | /// type acts as though it stores a value of type `T`, even though it doesn't | |
498 | /// really. This information is used when computing certain safety properties. | |
9cc50fc6 | 499 | /// |
9e0c209e SL |
500 | /// For a more in-depth explanation of how to use `PhantomData<T>`, please see |
501 | /// [the Nomicon](../../nomicon/phantom-data.html). | |
9cc50fc6 | 502 | /// |
e9174d1e SL |
503 | /// # A ghastly note 👻👻👻 |
504 | /// | |
9e0c209e SL |
505 | /// Though they both have scary names, `PhantomData` and 'phantom types' are |
506 | /// related, but not identical. A phantom type parameter is simply a type | |
507 | /// parameter which is never used. In Rust, this often causes the compiler to | |
508 | /// complain, and the solution is to add a "dummy" use by way of `PhantomData`. | |
1a4d82fc | 509 | /// |
c34b1796 | 510 | /// # Examples |
1a4d82fc | 511 | /// |
9e0c209e | 512 | /// ## Unused lifetime parameters |
1a4d82fc | 513 | /// |
9e0c209e SL |
514 | /// Perhaps the most common use case for `PhantomData` is a struct that has an |
515 | /// unused lifetime parameter, typically as part of some unsafe code. For | |
516 | /// example, here is a struct `Slice` that has two pointers of type `*const T`, | |
517 | /// presumably pointing into an array somewhere: | |
85aaf69f | 518 | /// |
041b39d2 | 519 | /// ```compile_fail,E0392 |
9346a6ac AL |
520 | /// struct Slice<'a, T> { |
521 | /// start: *const T, | |
522 | /// end: *const T, | |
1a4d82fc JJ |
523 | /// } |
524 | /// ``` | |
525 | /// | |
9346a6ac AL |
526 | /// The intention is that the underlying data is only valid for the |
527 | /// lifetime `'a`, so `Slice` should not outlive `'a`. However, this | |
528 | /// intent is not expressed in the code, since there are no uses of | |
529 | /// the lifetime `'a` and hence it is not clear what data it applies | |
530 | /// to. We can correct this by telling the compiler to act *as if* the | |
9e0c209e | 531 | /// `Slice` struct contained a reference `&'a T`: |
1a4d82fc | 532 | /// |
c34b1796 | 533 | /// ``` |
9346a6ac | 534 | /// use std::marker::PhantomData; |
1a4d82fc | 535 | /// |
92a42be0 | 536 | /// # #[allow(dead_code)] |
9cc50fc6 | 537 | /// struct Slice<'a, T: 'a> { |
9346a6ac AL |
538 | /// start: *const T, |
539 | /// end: *const T, | |
9e0c209e | 540 | /// phantom: PhantomData<&'a T>, |
9346a6ac | 541 | /// } |
c34b1796 | 542 | /// ``` |
1a4d82fc | 543 | /// |
9e0c209e SL |
544 | /// This also in turn requires the annotation `T: 'a`, indicating |
545 | /// that any references in `T` are valid over the lifetime `'a`. | |
546 | /// | |
547 | /// When initializing a `Slice` you simply provide the value | |
548 | /// `PhantomData` for the field `phantom`: | |
549 | /// | |
550 | /// ``` | |
551 | /// # #![allow(dead_code)] | |
552 | /// # use std::marker::PhantomData; | |
553 | /// # struct Slice<'a, T: 'a> { | |
554 | /// # start: *const T, | |
555 | /// # end: *const T, | |
556 | /// # phantom: PhantomData<&'a T>, | |
557 | /// # } | |
416331ca | 558 | /// fn borrow_vec<T>(vec: &Vec<T>) -> Slice<'_, T> { |
9e0c209e SL |
559 | /// let ptr = vec.as_ptr(); |
560 | /// Slice { | |
561 | /// start: ptr, | |
b7449926 | 562 | /// end: unsafe { ptr.add(vec.len()) }, |
9e0c209e SL |
563 | /// phantom: PhantomData, |
564 | /// } | |
565 | /// } | |
566 | /// ``` | |
1a4d82fc | 567 | /// |
9346a6ac | 568 | /// ## Unused type parameters |
1a4d82fc | 569 | /// |
9e0c209e | 570 | /// It sometimes happens that you have unused type parameters which |
9346a6ac AL |
571 | /// indicate what type of data a struct is "tied" to, even though that |
572 | /// data is not actually found in the struct itself. Here is an | |
9e0c209e SL |
573 | /// example where this arises with [FFI]. The foreign interface uses |
574 | /// handles of type `*mut ()` to refer to Rust values of different | |
575 | /// types. We track the Rust type using a phantom type parameter on | |
576 | /// the struct `ExternalResource` which wraps a handle. | |
577 | /// | |
9fa01778 | 578 | /// [FFI]: ../../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code |
c34b1796 AL |
579 | /// |
580 | /// ``` | |
92a42be0 | 581 | /// # #![allow(dead_code)] |
9e0c209e | 582 | /// # trait ResType { } |
c34b1796 AL |
583 | /// # struct ParamType; |
584 | /// # mod foreign_lib { | |
9e0c209e SL |
585 | /// # pub fn new(_: usize) -> *mut () { 42 as *mut () } |
586 | /// # pub fn do_stuff(_: *mut (), _: usize) {} | |
c34b1796 AL |
587 | /// # } |
588 | /// # fn convert_params(_: ParamType) -> usize { 42 } | |
589 | /// use std::marker::PhantomData; | |
590 | /// use std::mem; | |
591 | /// | |
592 | /// struct ExternalResource<R> { | |
593 | /// resource_handle: *mut (), | |
594 | /// resource_type: PhantomData<R>, | |
595 | /// } | |
596 | /// | |
597 | /// impl<R: ResType> ExternalResource<R> { | |
1b1a35ee | 598 | /// fn new() -> Self { |
c34b1796 | 599 | /// let size_of_res = mem::size_of::<R>(); |
1b1a35ee | 600 | /// Self { |
c34b1796 AL |
601 | /// resource_handle: foreign_lib::new(size_of_res), |
602 | /// resource_type: PhantomData, | |
603 | /// } | |
604 | /// } | |
605 | /// | |
606 | /// fn do_stuff(&self, param: ParamType) { | |
607 | /// let foreign_params = convert_params(param); | |
608 | /// foreign_lib::do_stuff(self.resource_handle, foreign_params); | |
609 | /// } | |
610 | /// } | |
611 | /// ``` | |
612 | /// | |
9e0c209e | 613 | /// ## Ownership and the drop check |
9346a6ac | 614 | /// |
9e0c209e SL |
615 | /// Adding a field of type `PhantomData<T>` indicates that your |
616 | /// type owns data of type `T`. This in turn implies that when your | |
617 | /// type is dropped, it may drop one or more instances of the type | |
618 | /// `T`. This has bearing on the Rust compiler's [drop check] | |
619 | /// analysis. | |
9346a6ac AL |
620 | /// |
621 | /// If your struct does not in fact *own* the data of type `T`, it is | |
622 | /// better to use a reference type, like `PhantomData<&'a T>` | |
623 | /// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so | |
624 | /// as not to indicate ownership. | |
9e0c209e | 625 | /// |
f25598a0 FG |
626 | /// ## Layout |
627 | /// | |
628 | /// For all `T`, the following are guaranteed: | |
629 | /// * `size_of::<PhantomData<T>>() == 0` | |
630 | /// * `align_of::<PhantomData<T>>() == 1` | |
631 | /// | |
9e0c209e | 632 | /// [drop check]: ../../nomicon/dropck.html |
d9579d0f | 633 | #[lang = "phantom_data"] |
85aaf69f | 634 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 635 | pub struct PhantomData<T: ?Sized>; |
1a4d82fc | 636 | |
2b03887a FG |
637 | #[stable(feature = "rust1", since = "1.0.0")] |
638 | impl<T: ?Sized> Hash for PhantomData<T> { | |
639 | #[inline] | |
640 | fn hash<H: Hasher>(&self, _: &mut H) {} | |
641 | } | |
642 | ||
643 | #[stable(feature = "rust1", since = "1.0.0")] | |
644 | impl<T: ?Sized> cmp::PartialEq for PhantomData<T> { | |
645 | fn eq(&self, _other: &PhantomData<T>) -> bool { | |
646 | true | |
647 | } | |
648 | } | |
649 | ||
650 | #[stable(feature = "rust1", since = "1.0.0")] | |
651 | impl<T: ?Sized> cmp::Eq for PhantomData<T> {} | |
1a4d82fc | 652 | |
2b03887a FG |
653 | #[stable(feature = "rust1", since = "1.0.0")] |
654 | impl<T: ?Sized> cmp::PartialOrd for PhantomData<T> { | |
655 | fn partial_cmp(&self, _other: &PhantomData<T>) -> Option<cmp::Ordering> { | |
656 | Option::Some(cmp::Ordering::Equal) | |
657 | } | |
85aaf69f | 658 | } |
cc61c64b | 659 | |
2b03887a FG |
660 | #[stable(feature = "rust1", since = "1.0.0")] |
661 | impl<T: ?Sized> cmp::Ord for PhantomData<T> { | |
662 | fn cmp(&self, _other: &PhantomData<T>) -> cmp::Ordering { | |
663 | cmp::Ordering::Equal | |
664 | } | |
665 | } | |
666 | ||
667 | #[stable(feature = "rust1", since = "1.0.0")] | |
668 | impl<T: ?Sized> Copy for PhantomData<T> {} | |
669 | ||
670 | #[stable(feature = "rust1", since = "1.0.0")] | |
671 | impl<T: ?Sized> Clone for PhantomData<T> { | |
672 | fn clone(&self) -> Self { | |
673 | Self | |
674 | } | |
675 | } | |
676 | ||
677 | #[stable(feature = "rust1", since = "1.0.0")] | |
678 | #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] | |
679 | impl<T: ?Sized> const Default for PhantomData<T> { | |
680 | fn default() -> Self { | |
681 | Self | |
682 | } | |
683 | } | |
684 | ||
685 | #[unstable(feature = "structural_match", issue = "31434")] | |
686 | impl<T: ?Sized> StructuralPartialEq for PhantomData<T> {} | |
687 | ||
688 | #[unstable(feature = "structural_match", issue = "31434")] | |
689 | impl<T: ?Sized> StructuralEq for PhantomData<T> {} | |
690 | ||
f9f354fc XL |
691 | /// Compiler-internal trait used to indicate the type of enum discriminants. |
692 | /// | |
693 | /// This trait is automatically implemented for every type and does not add any | |
694 | /// guarantees to [`mem::Discriminant`]. It is **undefined behavior** to transmute | |
695 | /// between `DiscriminantKind::Discriminant` and `mem::Discriminant`. | |
696 | /// | |
1b1a35ee | 697 | /// [`mem::Discriminant`]: crate::mem::Discriminant |
f9f354fc XL |
698 | #[unstable( |
699 | feature = "discriminant_kind", | |
700 | issue = "none", | |
701 | reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead" | |
702 | )] | |
f035d41b | 703 | #[lang = "discriminant_kind"] |
f25598a0 | 704 | #[rustc_deny_explicit_impl] |
f9f354fc | 705 | pub trait DiscriminantKind { |
f035d41b | 706 | /// The type of the discriminant, which must satisfy the trait |
f9f354fc | 707 | /// bounds required by `mem::Discriminant`. |
1b1a35ee | 708 | #[lang = "discriminant_type"] |
f9f354fc XL |
709 | type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin; |
710 | } | |
711 | ||
cc61c64b XL |
712 | /// Compiler-internal trait used to determine whether a type contains |
713 | /// any `UnsafeCell` internally, but not through an indirection. | |
714 | /// This affects, for example, whether a `static` of that type is | |
715 | /// placed in read-only static memory or writable static memory. | |
7cac9316 | 716 | #[lang = "freeze"] |
0731742a | 717 | pub(crate) unsafe auto trait Freeze {} |
cc61c64b XL |
718 | |
719 | impl<T: ?Sized> !Freeze for UnsafeCell<T> {} | |
720 | unsafe impl<T: ?Sized> Freeze for PhantomData<T> {} | |
721 | unsafe impl<T: ?Sized> Freeze for *const T {} | |
722 | unsafe impl<T: ?Sized> Freeze for *mut T {} | |
0bf4aa26 XL |
723 | unsafe impl<T: ?Sized> Freeze for &T {} |
724 | unsafe impl<T: ?Sized> Freeze for &mut T {} | |
0531ce1d | 725 | |
e1599b0c | 726 | /// Types that can be safely moved after being pinned. |
0531ce1d | 727 | /// |
1b1a35ee XL |
728 | /// Rust itself has no notion of immovable types, and considers moves (e.g., |
729 | /// through assignment or [`mem::replace`]) to always be safe. | |
b7449926 | 730 | /// |
1b1a35ee XL |
731 | /// The [`Pin`][Pin] type is used instead to prevent moves through the type |
732 | /// system. Pointers `P<T>` wrapped in the [`Pin<P<T>>`][Pin] wrapper can't be | |
733 | /// moved out of. See the [`pin` module] documentation for more information on | |
734 | /// pinning. | |
b7449926 | 735 | /// |
1b1a35ee XL |
736 | /// Implementing the `Unpin` trait for `T` lifts the restrictions of pinning off |
737 | /// the type, which then allows moving `T` out of [`Pin<P<T>>`][Pin] with | |
738 | /// functions such as [`mem::replace`]. | |
0731742a XL |
739 | /// |
740 | /// `Unpin` has no consequence at all for non-pinned data. In particular, | |
741 | /// [`mem::replace`] happily moves `!Unpin` data (it works for any `&mut T`, not | |
1b1a35ee XL |
742 | /// just when `T: Unpin`). However, you cannot use [`mem::replace`] on data |
743 | /// wrapped inside a [`Pin<P<T>>`][Pin] because you cannot get the `&mut T` you | |
744 | /// need for that, and *that* is what makes this system work. | |
b7449926 XL |
745 | /// |
746 | /// So this, for example, can only be done on types implementing `Unpin`: | |
747 | /// | |
748 | /// ```rust | |
f9f354fc | 749 | /// # #![allow(unused_must_use)] |
0731742a | 750 | /// use std::mem; |
0bf4aa26 | 751 | /// use std::pin::Pin; |
b7449926 XL |
752 | /// |
753 | /// let mut string = "this".to_string(); | |
0bf4aa26 | 754 | /// let mut pinned_string = Pin::new(&mut string); |
b7449926 | 755 | /// |
0731742a XL |
756 | /// // We need a mutable reference to call `mem::replace`. |
757 | /// // We can obtain such a reference by (implicitly) invoking `Pin::deref_mut`, | |
758 | /// // but that is only possible because `String` implements `Unpin`. | |
759 | /// mem::replace(&mut *pinned_string, "other".to_string()); | |
b7449926 | 760 | /// ``` |
0531ce1d XL |
761 | /// |
762 | /// This trait is automatically implemented for almost every type. | |
83c7162d | 763 | /// |
1b1a35ee XL |
764 | /// [`mem::replace`]: crate::mem::replace |
765 | /// [Pin]: crate::pin::Pin | |
766 | /// [`pin` module]: crate::pin | |
0731742a | 767 | #[stable(feature = "pin", since = "1.33.0")] |
74b04a01 | 768 | #[rustc_on_unimplemented( |
cdc7bbd5 | 769 | note = "consider using `Box::pin`", |
74b04a01 XL |
770 | message = "`{Self}` cannot be unpinned" |
771 | )] | |
532ac7d7 | 772 | #[lang = "unpin"] |
94b46f34 XL |
773 | pub auto trait Unpin {} |
774 | ||
0731742a | 775 | /// A marker type which does not implement `Unpin`. |
94b46f34 | 776 | /// |
0731742a XL |
777 | /// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default. |
778 | #[stable(feature = "pin", since = "1.33.0")] | |
fc512014 | 779 | #[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
0731742a | 780 | pub struct PhantomPinned; |
94b46f34 | 781 | |
0731742a XL |
782 | #[stable(feature = "pin", since = "1.33.0")] |
783 | impl !Unpin for PhantomPinned {} | |
83c7162d | 784 | |
0731742a | 785 | #[stable(feature = "pin", since = "1.33.0")] |
8faf50e0 XL |
786 | impl<'a, T: ?Sized + 'a> Unpin for &'a T {} |
787 | ||
0731742a | 788 | #[stable(feature = "pin", since = "1.33.0")] |
8faf50e0 XL |
789 | impl<'a, T: ?Sized + 'a> Unpin for &'a mut T {} |
790 | ||
416331ca XL |
791 | #[stable(feature = "pin_raw", since = "1.38.0")] |
792 | impl<T: ?Sized> Unpin for *const T {} | |
793 | ||
794 | #[stable(feature = "pin_raw", since = "1.38.0")] | |
795 | impl<T: ?Sized> Unpin for *mut T {} | |
796 | ||
5e7ed085 FG |
797 | /// A marker for types that can be dropped. |
798 | /// | |
799 | /// This should be used for `~const` bounds, | |
800 | /// as non-const bounds will always hold for every type. | |
801 | #[unstable(feature = "const_trait_impl", issue = "67792")] | |
04454e1e FG |
802 | #[lang = "destruct"] |
803 | #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] | |
2b03887a | 804 | #[const_trait] |
f25598a0 | 805 | #[rustc_deny_explicit_impl] |
5e7ed085 FG |
806 | pub trait Destruct {} |
807 | ||
f2b60f7d FG |
808 | /// A marker for tuple types. |
809 | /// | |
810 | /// The implementation of this trait is built-in and cannot be implemented | |
811 | /// for any user type. | |
812 | #[unstable(feature = "tuple_trait", issue = "none")] | |
2b03887a | 813 | #[lang = "tuple_trait"] |
f2b60f7d | 814 | #[rustc_on_unimplemented(message = "`{Self}` is not a tuple")] |
f25598a0 | 815 | #[rustc_deny_explicit_impl] |
f2b60f7d FG |
816 | pub trait Tuple {} |
817 | ||
487cf647 FG |
818 | /// A marker for things |
819 | #[unstable(feature = "pointer_sized_trait", issue = "none")] | |
f25598a0 | 820 | #[lang = "pointer_sized"] |
487cf647 FG |
821 | #[rustc_on_unimplemented( |
822 | message = "`{Self}` needs to be a pointer-sized type", | |
823 | label = "`{Self}` needs to be a pointer-sized type" | |
824 | )] | |
825 | pub trait PointerSized {} | |
826 | ||
83c7162d XL |
827 | /// Implementations of `Copy` for primitive types. |
828 | /// | |
829 | /// Implementations that cannot be described in Rust | |
ba9703b0 XL |
830 | /// are implemented in `traits::SelectionContext::copy_clone_conditions()` |
831 | /// in `rustc_trait_selection`. | |
83c7162d XL |
832 | mod copy_impls { |
833 | ||
834 | use super::Copy; | |
835 | ||
836 | macro_rules! impl_copy { | |
837 | ($($t:ty)*) => { | |
838 | $( | |
839 | #[stable(feature = "rust1", since = "1.0.0")] | |
840 | impl Copy for $t {} | |
841 | )* | |
842 | } | |
843 | } | |
844 | ||
845 | impl_copy! { | |
846 | usize u8 u16 u32 u64 u128 | |
847 | isize i8 i16 i32 i64 i128 | |
848 | f32 f64 | |
849 | bool char | |
850 | } | |
851 | ||
852 | #[unstable(feature = "never_type", issue = "35121")] | |
853 | impl Copy for ! {} | |
854 | ||
855 | #[stable(feature = "rust1", since = "1.0.0")] | |
856 | impl<T: ?Sized> Copy for *const T {} | |
857 | ||
858 | #[stable(feature = "rust1", since = "1.0.0")] | |
859 | impl<T: ?Sized> Copy for *mut T {} | |
860 | ||
ba9703b0 | 861 | /// Shared references can be copied, but mutable references *cannot*! |
83c7162d | 862 | #[stable(feature = "rust1", since = "1.0.0")] |
0bf4aa26 | 863 | impl<T: ?Sized> Copy for &T {} |
83c7162d | 864 | } |