1 | //! Primitive traits and types representing basic properties of types. |
2 | //! |
3 | //! Rust types can be classified in various useful ways according to |
4 | //! their intrinsic properties. These classifications are represented |
5 | //! as traits. |
6 | |
7 | #![stable (feature = "rust1" , since = "1.0.0" )] |
8 | |
9 | mod variance; |
10 | |
11 | #[unstable (feature = "phantom_variance_markers" , issue = "135806" )] |
12 | pub use self::variance::{ |
13 | PhantomContravariant, PhantomContravariantLifetime, PhantomCovariant, PhantomCovariantLifetime, |
14 | PhantomInvariant, PhantomInvariantLifetime, Variance, variance, |
15 | }; |
16 | use crate::cell::UnsafeCell; |
17 | use crate::cmp; |
18 | use crate::fmt::Debug; |
19 | use crate::hash::{Hash, Hasher}; |
20 | |
21 | /// Implements a given marker trait for multiple types at the same time. |
22 | /// |
23 | /// The basic syntax looks like this: |
24 | /// ```ignore private macro |
25 | /// marker_impls! { MarkerTrait for u8, i8 } |
26 | /// ``` |
27 | /// You can also implement `unsafe` traits |
28 | /// ```ignore private macro |
29 | /// marker_impls! { unsafe MarkerTrait for u8, i8 } |
30 | /// ``` |
31 | /// Add attributes to all impls: |
32 | /// ```ignore private macro |
33 | /// marker_impls! { |
34 | /// #[allow(lint)] |
35 | /// #[unstable(feature = "marker_trait" , issue = "none" )] |
36 | /// MarkerTrait for u8, i8 |
37 | /// } |
38 | /// ``` |
39 | /// And use generics: |
40 | /// ```ignore private macro |
41 | /// marker_impls! { |
42 | /// MarkerTrait for |
43 | /// u8, i8, |
44 | /// {T: ?Sized} *const T, |
45 | /// {T: ?Sized} *mut T, |
46 | /// {T: MarkerTrait} PhantomData<T>, |
47 | /// u32, |
48 | /// } |
49 | /// ``` |
50 | #[unstable (feature = "internal_impls_macro" , issue = "none" )] |
51 | // Allow implementations of `UnsizedConstParamTy` even though std cannot use that feature. |
52 | #[allow_internal_unstable (unsized_const_params)] |
53 | macro marker_impls { |
54 | ( $(#[$($meta:tt)*])* $Trait:ident for $({$($bounds:tt)*})? $T:ty $(, $($rest:tt)*)? ) => { |
55 | $(#[$($meta)*])* impl< $($($bounds)*)? > $Trait for $T {} |
56 | marker_impls! { $(#[$($meta)*])* $Trait for $($($rest)*)? } |
57 | }, |
58 | ( $(#[$($meta:tt)*])* $Trait:ident for ) => {}, |
59 | |
60 | ( $(#[$($meta:tt)*])* unsafe $Trait:ident for $({$($bounds:tt)*})? $T:ty $(, $($rest:tt)*)? ) => { |
61 | $(#[$($meta)*])* unsafe impl< $($($bounds)*)? > $Trait for $T {} |
62 | marker_impls! { $(#[$($meta)*])* unsafe $Trait for $($($rest)*)? } |
63 | }, |
64 | ( $(#[$($meta:tt)*])* unsafe $Trait:ident for ) => {}, |
65 | } |
66 | |
67 | /// Types that can be transferred across thread boundaries. |
68 | /// |
69 | /// This trait is automatically implemented when the compiler determines it's |
70 | /// appropriate. |
71 | /// |
72 | /// An example of a non-`Send` type is the reference-counting pointer |
73 | /// [`rc::Rc`][`Rc`]. If two threads attempt to clone [`Rc`]s that point to the same |
74 | /// reference-counted value, they might try to update the reference count at the |
75 | /// same time, which is [undefined behavior][ub] because [`Rc`] doesn't use atomic |
76 | /// operations. Its cousin [`sync::Arc`][arc] does use atomic operations (incurring |
77 | /// some overhead) and thus is `Send`. |
78 | /// |
79 | /// See [the Nomicon](../../nomicon/send-and-sync.html) and the [`Sync`] trait for more details. |
80 | /// |
81 | /// [`Rc`]: ../../std/rc/struct.Rc.html |
82 | /// [arc]: ../../std/sync/struct.Arc.html |
83 | /// [ub]: ../../reference/behavior-considered-undefined.html |
84 | #[stable (feature = "rust1" , since = "1.0.0" )] |
85 | #[rustc_diagnostic_item = "Send" ] |
86 | #[diagnostic::on_unimplemented( |
87 | message = "`{Self}` cannot be sent between threads safely" , |
88 | label = "`{Self}` cannot be sent between threads safely" |
89 | )] |
90 | pub unsafe auto trait Send { |
91 | // empty. |
92 | } |
93 | |
94 | #[stable (feature = "rust1" , since = "1.0.0" )] |
95 | impl<T: ?Sized> !Send for *const T {} |
96 | #[stable (feature = "rust1" , since = "1.0.0" )] |
97 | impl<T: ?Sized> !Send for *mut T {} |
98 | |
99 | // Most instances arise automatically, but this instance is needed to link up `T: Sync` with |
100 | // `&T: Send` (and it also removes the unsound default instance `T Send` -> `&T: Send` that would |
101 | // otherwise exist). |
102 | #[stable (feature = "rust1" , since = "1.0.0" )] |
103 | unsafe impl<T: Sync + ?Sized> Send for &T {} |
104 | |
105 | /// Types with a constant size known at compile time. |
106 | /// |
107 | /// All type parameters have an implicit bound of `Sized`. The special syntax |
108 | /// `?Sized` can be used to remove this bound if it's not appropriate. |
109 | /// |
110 | /// ``` |
111 | /// # #![allow (dead_code)] |
112 | /// struct Foo<T>(T); |
113 | /// struct Bar<T: ?Sized>(T); |
114 | /// |
115 | /// // struct FooUse(Foo<[i32]>); // error: Sized is not implemented for [i32] |
116 | /// struct BarUse(Bar<[i32]>); // OK |
117 | /// ``` |
118 | /// |
119 | /// The one exception is the implicit `Self` type of a trait. A trait does not |
120 | /// have an implicit `Sized` bound as this is incompatible with [trait object]s |
121 | /// where, by definition, the trait needs to work with all possible implementors, |
122 | /// and thus could be any size. |
123 | /// |
124 | /// Although Rust will let you bind `Sized` to a trait, you won't |
125 | /// be able to use it to form a trait object later: |
126 | /// |
127 | /// ``` |
128 | /// # #![allow(unused_variables)] |
129 | /// trait Foo { } |
130 | /// trait Bar: Sized { } |
131 | /// |
132 | /// struct Impl; |
133 | /// impl Foo for Impl { } |
134 | /// impl Bar for Impl { } |
135 | /// |
136 | /// let x: &dyn Foo = &Impl; // OK |
137 | /// // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot |
138 | /// // be made into an object |
139 | /// ``` |
140 | /// |
141 | /// [trait object]: ../../book/ch17-02-trait-objects.html |
142 | #[doc (alias = "?" , alias = "?Sized" )] |
143 | #[stable (feature = "rust1" , since = "1.0.0" )] |
144 | #[lang = "sized" ] |
145 | #[diagnostic::on_unimplemented( |
146 | message = "the size for values of type `{Self}` cannot be known at compilation time" , |
147 | label = "doesn't have a size known at compile-time" |
148 | )] |
149 | #[fundamental ] // for Default, for example, which requires that `[T]: !Default` be evaluatable |
150 | #[rustc_specialization_trait ] |
151 | #[rustc_deny_explicit_impl ] |
152 | #[rustc_do_not_implement_via_object] |
153 | #[rustc_coinductive ] |
154 | pub trait Sized { |
155 | // Empty. |
156 | } |
157 | |
158 | /// Types that can be "unsized" to a dynamically-sized type. |
159 | /// |
160 | /// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and |
161 | /// `Unsize<dyn fmt::Debug>`. |
162 | /// |
163 | /// All implementations of `Unsize` are provided automatically by the compiler. |
164 | /// Those implementations are: |
165 | /// |
166 | /// - Arrays `[T; N]` implement `Unsize<[T]>`. |
167 | /// - A type implements `Unsize<dyn Trait + 'a>` if all of these conditions are met: |
168 | /// - The type implements `Trait`. |
169 | /// - `Trait` is dyn-compatible[^1]. |
170 | /// - The type is sized. |
171 | /// - The type outlives `'a`. |
172 | /// - Structs `Foo<..., T1, ..., Tn, ...>` implement `Unsize<Foo<..., U1, ..., Un, ...>>` |
173 | /// where any number of (type and const) parameters may be changed if all of these conditions |
174 | /// are met: |
175 | /// - Only the last field of `Foo` has a type involving the parameters `T1`, ..., `Tn`. |
176 | /// - All other parameters of the struct are equal. |
177 | /// - `Field<T1, ..., Tn>: Unsize<Field<U1, ..., Un>>`, where `Field<...>` stands for the actual |
178 | /// type of the struct's last field. |
179 | /// |
180 | /// `Unsize` is used along with [`ops::CoerceUnsized`] to allow |
181 | /// "user-defined" containers such as [`Rc`] to contain dynamically-sized |
182 | /// types. See the [DST coercion RFC][RFC982] and [the nomicon entry on coercion][nomicon-coerce] |
183 | /// for more details. |
184 | /// |
185 | /// [`ops::CoerceUnsized`]: crate::ops::CoerceUnsized |
186 | /// [`Rc`]: ../../std/rc/struct.Rc.html |
187 | /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md |
188 | /// [nomicon-coerce]: ../../nomicon/coercions.html |
189 | /// [^1]: Formerly known as *object safe*. |
190 | #[unstable (feature = "unsize" , issue = "18598" )] |
191 | #[lang = "unsize" ] |
192 | #[rustc_deny_explicit_impl ] |
193 | #[rustc_do_not_implement_via_object] |
194 | pub trait Unsize<T: ?Sized> { |
195 | // Empty. |
196 | } |
197 | |
198 | /// Required trait for constants used in pattern matches. |
199 | /// |
200 | /// Constants are only allowed as patterns if (a) their type implements |
201 | /// `PartialEq`, and (b) interpreting the value of the constant as a pattern |
202 | /// is equialent to calling `PartialEq`. This ensures that constants used as |
203 | /// patterns cannot expose implementation details in an unexpected way or |
204 | /// cause semver hazards. |
205 | /// |
206 | /// This trait ensures point (b). |
207 | /// Any type that derives `PartialEq` automatically implements this trait. |
208 | /// |
209 | /// Implementing this trait (which is unstable) is a way for type authors to explicitly allow |
210 | /// comparing const values of this type; that operation will recursively compare all fields |
211 | /// (including private fields), even if that behavior differs from `PartialEq`. This can make it |
212 | /// semver-breaking to add further private fields to a type. |
213 | #[unstable (feature = "structural_match" , issue = "31434" )] |
214 | #[diagnostic::on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`" )] |
215 | #[lang = "structural_peq" ] |
216 | pub trait StructuralPartialEq { |
217 | // Empty. |
218 | } |
219 | |
220 | marker_impls! { |
221 | #[unstable (feature = "structural_match" , issue = "31434" )] |
222 | StructuralPartialEq for |
223 | usize, u8, u16, u32, u64, u128, |
224 | isize, i8, i16, i32, i64, i128, |
225 | bool, |
226 | char, |
227 | str /* Technically requires `[u8]: StructuralPartialEq` */, |
228 | (), |
229 | {T, const N: usize} [T; N], |
230 | {T} [T], |
231 | {T: ?Sized} &T, |
232 | } |
233 | |
234 | /// Types whose values can be duplicated simply by copying bits. |
235 | /// |
236 | /// By default, variable bindings have 'move semantics.' In other |
237 | /// words: |
238 | /// |
239 | /// ``` |
240 | /// #[derive(Debug)] |
241 | /// struct Foo; |
242 | /// |
243 | /// let x = Foo; |
244 | /// |
245 | /// let y = x; |
246 | /// |
247 | /// // `x` has moved into `y`, and so cannot be used |
248 | /// |
249 | /// // println!("{x:?}"); // error: use of moved value |
250 | /// ``` |
251 | /// |
252 | /// However, if a type implements `Copy`, it instead has 'copy semantics': |
253 | /// |
254 | /// ``` |
255 | /// // We can derive a `Copy` implementation. `Clone` is also required, as it's |
256 | /// // a supertrait of `Copy`. |
257 | /// #[derive(Debug, Copy, Clone)] |
258 | /// struct Foo; |
259 | /// |
260 | /// let x = Foo; |
261 | /// |
262 | /// let y = x; |
263 | /// |
264 | /// // `y` is a copy of `x` |
265 | /// |
266 | /// println!("{x:?}" ); // A-OK! |
267 | /// ``` |
268 | /// |
269 | /// It's important to note that in these two examples, the only difference is whether you |
270 | /// are allowed to access `x` after the assignment. Under the hood, both a copy and a move |
271 | /// can result in bits being copied in memory, although this is sometimes optimized away. |
272 | /// |
273 | /// ## How can I implement `Copy`? |
274 | /// |
275 | /// There are two ways to implement `Copy` on your type. The simplest is to use `derive`: |
276 | /// |
277 | /// ``` |
278 | /// #[derive(Copy, Clone)] |
279 | /// struct MyStruct; |
280 | /// ``` |
281 | /// |
282 | /// You can also implement `Copy` and `Clone` manually: |
283 | /// |
284 | /// ``` |
285 | /// struct MyStruct; |
286 | /// |
287 | /// impl Copy for MyStruct { } |
288 | /// |
289 | /// impl Clone for MyStruct { |
290 | /// fn clone(&self) -> MyStruct { |
291 | /// *self |
292 | /// } |
293 | /// } |
294 | /// ``` |
295 | /// |
296 | /// There is a small difference between the two. The `derive` strategy will also place a `Copy` |
297 | /// bound on type parameters: |
298 | /// |
299 | /// ``` |
300 | /// #[derive(Clone)] |
301 | /// struct MyStruct<T>(T); |
302 | /// |
303 | /// impl<T: Copy> Copy for MyStruct<T> { } |
304 | /// ``` |
305 | /// |
306 | /// This isn't always desired. For example, shared references (`&T`) can be copied regardless of |
307 | /// whether `T` is `Copy`. Likewise, a generic struct containing markers such as [`PhantomData`] |
308 | /// could potentially be duplicated with a bit-wise copy. |
309 | /// |
310 | /// ## What's the difference between `Copy` and `Clone`? |
311 | /// |
312 | /// Copies happen implicitly, for example as part of an assignment `y = x`. The behavior of |
313 | /// `Copy` is not overloadable; it is always a simple bit-wise copy. |
314 | /// |
315 | /// Cloning is an explicit action, `x.clone()`. The implementation of [`Clone`] can |
316 | /// provide any type-specific behavior necessary to duplicate values safely. For example, |
317 | /// the implementation of [`Clone`] for [`String`] needs to copy the pointed-to string |
318 | /// buffer in the heap. A simple bitwise copy of [`String`] values would merely copy the |
319 | /// pointer, leading to a double free down the line. For this reason, [`String`] is [`Clone`] |
320 | /// but not `Copy`. |
321 | /// |
322 | /// [`Clone`] is a supertrait of `Copy`, so everything which is `Copy` must also implement |
323 | /// [`Clone`]. If a type is `Copy` then its [`Clone`] implementation only needs to return `*self` |
324 | /// (see the example above). |
325 | /// |
326 | /// ## When can my type be `Copy`? |
327 | /// |
328 | /// A type can implement `Copy` if all of its components implement `Copy`. For example, this |
329 | /// struct can be `Copy`: |
330 | /// |
331 | /// ``` |
332 | /// # #[allow (dead_code)] |
333 | /// #[derive(Copy, Clone)] |
334 | /// struct Point { |
335 | /// x: i32, |
336 | /// y: i32, |
337 | /// } |
338 | /// ``` |
339 | /// |
340 | /// A struct can be `Copy`, and [`i32`] is `Copy`, therefore `Point` is eligible to be `Copy`. |
341 | /// By contrast, consider |
342 | /// |
343 | /// ``` |
344 | /// # #![allow(dead_code)] |
345 | /// # struct Point; |
346 | /// struct PointList { |
347 | /// points: Vec<Point>, |
348 | /// } |
349 | /// ``` |
350 | /// |
351 | /// The struct `PointList` cannot implement `Copy`, because [`Vec<T>`] is not `Copy`. If we |
352 | /// attempt to derive a `Copy` implementation, we'll get an error: |
353 | /// |
354 | /// ```text |
355 | /// the trait `Copy` cannot be implemented for this type; field `points` does not implement `Copy` |
356 | /// ``` |
357 | /// |
358 | /// Shared references (`&T`) are also `Copy`, so a type can be `Copy`, even when it holds |
359 | /// shared references of types `T` that are *not* `Copy`. Consider the following struct, |
360 | /// which can implement `Copy`, because it only holds a *shared reference* to our non-`Copy` |
361 | /// type `PointList` from above: |
362 | /// |
363 | /// ``` |
364 | /// # #![allow(dead_code)] |
365 | /// # struct PointList; |
366 | /// #[derive(Copy, Clone)] |
367 | /// struct PointListWrapper<'a> { |
368 | /// point_list_ref: &'a PointList, |
369 | /// } |
370 | /// ``` |
371 | /// |
372 | /// ## When *can't* my type be `Copy`? |
373 | /// |
374 | /// Some types can't be copied safely. For example, copying `&mut T` would create an aliased |
375 | /// mutable reference. Copying [`String`] would duplicate responsibility for managing the |
376 | /// [`String`]'s buffer, leading to a double free. |
377 | /// |
378 | /// Generalizing the latter case, any type implementing [`Drop`] can't be `Copy`, because it's |
379 | /// managing some resource besides its own [`size_of::<T>`] bytes. |
380 | /// |
381 | /// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get |
382 | /// the error [E0204]. |
383 | /// |
384 | /// [E0204]: ../../error_codes/E0204.html |
385 | /// |
386 | /// ## When *should* my type be `Copy`? |
387 | /// |
388 | /// Generally speaking, if your type _can_ implement `Copy`, it should. Keep in mind, though, |
389 | /// that implementing `Copy` is part of the public API of your type. If the type might become |
390 | /// non-`Copy` in the future, it could be prudent to omit the `Copy` implementation now, to |
391 | /// avoid a breaking API change. |
392 | /// |
393 | /// ## Additional implementors |
394 | /// |
395 | /// In addition to the [implementors listed below][impls], |
396 | /// the following types also implement `Copy`: |
397 | /// |
398 | /// * Function item types (i.e., the distinct types defined for each function) |
399 | /// * Function pointer types (e.g., `fn() -> i32`) |
400 | /// * Closure types, if they capture no value from the environment |
401 | /// or if all such captured values implement `Copy` themselves. |
402 | /// Note that variables captured by shared reference always implement `Copy` |
403 | /// (even if the referent doesn't), |
404 | /// while variables captured by mutable reference never implement `Copy`. |
405 | /// |
406 | /// [`Vec<T>`]: ../../std/vec/struct.Vec.html |
407 | /// [`String`]: ../../std/string/struct.String.html |
408 | /// [`size_of::<T>`]: size_of |
409 | /// [impls]: #implementors |
410 | #[stable (feature = "rust1" , since = "1.0.0" )] |
411 | #[lang = "copy" ] |
412 | // FIXME(matthewjasper) This allows copying a type that doesn't implement |
413 | // `Copy` because of unsatisfied lifetime bounds (copying `A<'_>` when only |
414 | // `A<'static>: Copy` and `A<'_>: Clone`). |
415 | // We have this attribute here for now only because there are quite a few |
416 | // existing specializations on `Copy` that already exist in the standard |
417 | // library, and there's no way to safely have this behavior right now. |
418 | #[rustc_unsafe_specialization_marker ] |
419 | #[rustc_diagnostic_item = "Copy" ] |
420 | pub trait Copy: Clone { |
421 | // Empty. |
422 | } |
423 | |
424 | /// Derive macro generating an impl of the trait `Copy`. |
425 | #[rustc_builtin_macro ] |
426 | #[stable (feature = "builtin_macro_prelude" , since = "1.38.0" )] |
427 | #[allow_internal_unstable (core_intrinsics, derive_clone_copy)] |
428 | pub macro Copy($item:item) { |
429 | /* compiler built-in */ |
430 | } |
431 | |
432 | // Implementations of `Copy` for primitive types. |
433 | // |
434 | // Implementations that cannot be described in Rust |
435 | // are implemented in `traits::SelectionContext::copy_clone_conditions()` |
436 | // in `rustc_trait_selection`. |
437 | marker_impls! { |
438 | #[stable (feature = "rust1" , since = "1.0.0" )] |
439 | Copy for |
440 | usize, u8, u16, u32, u64, u128, |
441 | isize, i8, i16, i32, i64, i128, |
442 | f16, f32, f64, f128, |
443 | bool, char, |
444 | {T: ?Sized} *const T, |
445 | {T: ?Sized} *mut T, |
446 | |
447 | } |
448 | |
449 | #[unstable (feature = "never_type" , issue = "35121" )] |
450 | impl Copy for ! {} |
451 | |
452 | /// Shared references can be copied, but mutable references *cannot*! |
453 | #[stable (feature = "rust1" , since = "1.0.0" )] |
454 | impl<T: ?Sized> Copy for &T {} |
455 | |
456 | /// Marker trait for the types that are allowed in union fields and unsafe |
457 | /// binder types. |
458 | /// |
459 | /// Implemented for: |
460 | /// * `&T`, `&mut T` for all `T`, |
461 | /// * `ManuallyDrop<T>` for all `T`, |
462 | /// * tuples and arrays whose elements implement `BikeshedGuaranteedNoDrop`, |
463 | /// * or otherwise, all types that are `Copy`. |
464 | /// |
465 | /// Notably, this doesn't include all trivially-destructible types for semver |
466 | /// reasons. |
467 | /// |
468 | /// Bikeshed name for now. This trait does not do anything other than reflect the |
469 | /// set of types that are allowed within unions for field validity. |
470 | #[unstable (feature = "bikeshed_guaranteed_no_drop" , issue = "none" )] |
471 | #[lang = "bikeshed_guaranteed_no_drop" ] |
472 | #[rustc_deny_explicit_impl ] |
473 | #[rustc_do_not_implement_via_object] |
474 | #[doc (hidden)] |
475 | pub trait BikeshedGuaranteedNoDrop {} |
476 | |
477 | /// Types for which it is safe to share references between threads. |
478 | /// |
479 | /// This trait is automatically implemented when the compiler determines |
480 | /// it's appropriate. |
481 | /// |
482 | /// The precise definition is: a type `T` is [`Sync`] if and only if `&T` is |
483 | /// [`Send`]. In other words, if there is no possibility of |
484 | /// [undefined behavior][ub] (including data races) when passing |
485 | /// `&T` references between threads. |
486 | /// |
487 | /// As one would expect, primitive types like [`u8`] and [`f64`] |
488 | /// are all [`Sync`], and so are simple aggregate types containing them, |
489 | /// like tuples, structs and enums. More examples of basic [`Sync`] |
490 | /// types include "immutable" types like `&T`, and those with simple |
491 | /// inherited mutability, such as [`Box<T>`][box], [`Vec<T>`][vec] and |
492 | /// most other collection types. (Generic parameters need to be [`Sync`] |
493 | /// for their container to be [`Sync`].) |
494 | /// |
495 | /// A somewhat surprising consequence of the definition is that `&mut T` |
496 | /// is `Sync` (if `T` is `Sync`) even though it seems like that might |
497 | /// provide unsynchronized mutation. The trick is that a mutable |
498 | /// reference behind a shared reference (that is, `& &mut T`) |
499 | /// becomes read-only, as if it were a `& &T`. Hence there is no risk |
500 | /// of a data race. |
501 | /// |
502 | /// A shorter overview of how [`Sync`] and [`Send`] relate to referencing: |
503 | /// * `&T` is [`Send`] if and only if `T` is [`Sync`] |
504 | /// * `&mut T` is [`Send`] if and only if `T` is [`Send`] |
505 | /// * `&T` and `&mut T` are [`Sync`] if and only if `T` is [`Sync`] |
506 | /// |
507 | /// Types that are not `Sync` are those that have "interior |
508 | /// mutability" in a non-thread-safe form, such as [`Cell`][cell] |
509 | /// and [`RefCell`][refcell]. These types allow for mutation of |
510 | /// their contents even through an immutable, shared reference. For |
511 | /// example the `set` method on [`Cell<T>`][cell] takes `&self`, so it requires |
512 | /// only a shared reference [`&Cell<T>`][cell]. The method performs no |
513 | /// synchronization, thus [`Cell`][cell] cannot be `Sync`. |
514 | /// |
515 | /// Another example of a non-`Sync` type is the reference-counting |
516 | /// pointer [`Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone |
517 | /// a new [`Rc<T>`][rc], modifying the reference counts in a non-atomic way. |
518 | /// |
519 | /// For cases when one does need thread-safe interior mutability, |
520 | /// Rust provides [atomic data types], as well as explicit locking via |
521 | /// [`sync::Mutex`][mutex] and [`sync::RwLock`][rwlock]. These types |
522 | /// ensure that any mutation cannot cause data races, hence the types |
523 | /// are `Sync`. Likewise, [`sync::Arc`][arc] provides a thread-safe |
524 | /// analogue of [`Rc`][rc]. |
525 | /// |
526 | /// Any types with interior mutability must also use the |
527 | /// [`cell::UnsafeCell`][unsafecell] wrapper around the value(s) which |
528 | /// can be mutated through a shared reference. Failing to doing this is |
529 | /// [undefined behavior][ub]. For example, [`transmute`][transmute]-ing |
530 | /// from `&T` to `&mut T` is invalid. |
531 | /// |
532 | /// See [the Nomicon][nomicon-send-and-sync] for more details about `Sync`. |
533 | /// |
534 | /// [box]: ../../std/boxed/struct.Box.html |
535 | /// [vec]: ../../std/vec/struct.Vec.html |
536 | /// [cell]: crate::cell::Cell |
537 | /// [refcell]: crate::cell::RefCell |
538 | /// [rc]: ../../std/rc/struct.Rc.html |
539 | /// [arc]: ../../std/sync/struct.Arc.html |
540 | /// [atomic data types]: crate::sync::atomic |
541 | /// [mutex]: ../../std/sync/struct.Mutex.html |
542 | /// [rwlock]: ../../std/sync/struct.RwLock.html |
543 | /// [unsafecell]: crate::cell::UnsafeCell |
544 | /// [ub]: ../../reference/behavior-considered-undefined.html |
545 | /// [transmute]: crate::mem::transmute |
546 | /// [nomicon-send-and-sync]: ../../nomicon/send-and-sync.html |
547 | #[stable (feature = "rust1" , since = "1.0.0" )] |
548 | #[rustc_diagnostic_item = "Sync" ] |
549 | #[lang = "sync" ] |
550 | #[rustc_on_unimplemented ( |
551 | on( |
552 | _Self = "core::cell::once::OnceCell<T>" , |
553 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead" |
554 | ), |
555 | on( |
556 | _Self = "core::cell::Cell<u8>" , |
557 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU8` instead" , |
558 | ), |
559 | on( |
560 | _Self = "core::cell::Cell<u16>" , |
561 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU16` instead" , |
562 | ), |
563 | on( |
564 | _Self = "core::cell::Cell<u32>" , |
565 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU32` instead" , |
566 | ), |
567 | on( |
568 | _Self = "core::cell::Cell<u64>" , |
569 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicU64` instead" , |
570 | ), |
571 | on( |
572 | _Self = "core::cell::Cell<usize>" , |
573 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicUsize` instead" , |
574 | ), |
575 | on( |
576 | _Self = "core::cell::Cell<i8>" , |
577 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI8` instead" , |
578 | ), |
579 | on( |
580 | _Self = "core::cell::Cell<i16>" , |
581 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI16` instead" , |
582 | ), |
583 | on( |
584 | _Self = "core::cell::Cell<i32>" , |
585 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead" , |
586 | ), |
587 | on( |
588 | _Self = "core::cell::Cell<i64>" , |
589 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI64` instead" , |
590 | ), |
591 | on( |
592 | _Self = "core::cell::Cell<isize>" , |
593 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicIsize` instead" , |
594 | ), |
595 | on( |
596 | _Self = "core::cell::Cell<bool>" , |
597 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicBool` instead" , |
598 | ), |
599 | on( |
600 | all( |
601 | _Self = "core::cell::Cell<T>" , |
602 | not(_Self = "core::cell::Cell<u8>" ), |
603 | not(_Self = "core::cell::Cell<u16>" ), |
604 | not(_Self = "core::cell::Cell<u32>" ), |
605 | not(_Self = "core::cell::Cell<u64>" ), |
606 | not(_Self = "core::cell::Cell<usize>" ), |
607 | not(_Self = "core::cell::Cell<i8>" ), |
608 | not(_Self = "core::cell::Cell<i16>" ), |
609 | not(_Self = "core::cell::Cell<i32>" ), |
610 | not(_Self = "core::cell::Cell<i64>" ), |
611 | not(_Self = "core::cell::Cell<isize>" ), |
612 | not(_Self = "core::cell::Cell<bool>" ) |
613 | ), |
614 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`" , |
615 | ), |
616 | on( |
617 | _Self = "core::cell::RefCell<T>" , |
618 | note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead" , |
619 | ), |
620 | message = "`{Self}` cannot be shared between threads safely" , |
621 | label = "`{Self}` cannot be shared between threads safely" |
622 | )] |
623 | pub unsafe auto trait Sync { |
624 | // FIXME(estebank): once support to add notes in `rustc_on_unimplemented` |
625 | // lands in beta, and it has been extended to check whether a closure is |
626 | // anywhere in the requirement chain, extend it as such (#48534): |
627 | // ``` |
628 | // on( |
629 | // closure, |
630 | // note="`{Self}` cannot be shared safely, consider marking the closure `move`" |
631 | // ), |
632 | // ``` |
633 | |
634 | // Empty |
635 | } |
636 | |
637 | #[stable (feature = "rust1" , since = "1.0.0" )] |
638 | impl<T: ?Sized> !Sync for *const T {} |
639 | #[stable (feature = "rust1" , since = "1.0.0" )] |
640 | impl<T: ?Sized> !Sync for *mut T {} |
641 | |
642 | /// Zero-sized type used to mark things that "act like" they own a `T`. |
643 | /// |
644 | /// Adding a `PhantomData<T>` field to your type tells the compiler that your |
645 | /// type acts as though it stores a value of type `T`, even though it doesn't |
646 | /// really. This information is used when computing certain safety properties. |
647 | /// |
648 | /// For a more in-depth explanation of how to use `PhantomData<T>`, please see |
649 | /// [the Nomicon](../../nomicon/phantom-data.html). |
650 | /// |
651 | /// # A ghastly note 👻👻👻 |
652 | /// |
653 | /// Though they both have scary names, `PhantomData` and 'phantom types' are |
654 | /// related, but not identical. A phantom type parameter is simply a type |
655 | /// parameter which is never used. In Rust, this often causes the compiler to |
656 | /// complain, and the solution is to add a "dummy" use by way of `PhantomData`. |
657 | /// |
658 | /// # Examples |
659 | /// |
660 | /// ## Unused lifetime parameters |
661 | /// |
662 | /// Perhaps the most common use case for `PhantomData` is a struct that has an |
663 | /// unused lifetime parameter, typically as part of some unsafe code. For |
664 | /// example, here is a struct `Slice` that has two pointers of type `*const T`, |
665 | /// presumably pointing into an array somewhere: |
666 | /// |
667 | /// ```compile_fail,E0392 |
668 | /// struct Slice<'a, T> { |
669 | /// start: *const T, |
670 | /// end: *const T, |
671 | /// } |
672 | /// ``` |
673 | /// |
674 | /// The intention is that the underlying data is only valid for the |
675 | /// lifetime `'a`, so `Slice` should not outlive `'a`. However, this |
676 | /// intent is not expressed in the code, since there are no uses of |
677 | /// the lifetime `'a` and hence it is not clear what data it applies |
678 | /// to. We can correct this by telling the compiler to act *as if* the |
679 | /// `Slice` struct contained a reference `&'a T`: |
680 | /// |
681 | /// ``` |
682 | /// use std::marker::PhantomData; |
683 | /// |
684 | /// # #[allow (dead_code)] |
685 | /// struct Slice<'a, T> { |
686 | /// start: *const T, |
687 | /// end: *const T, |
688 | /// phantom: PhantomData<&'a T>, |
689 | /// } |
690 | /// ``` |
691 | /// |
692 | /// This also in turn infers the lifetime bound `T: 'a`, indicating |
693 | /// that any references in `T` are valid over the lifetime `'a`. |
694 | /// |
695 | /// When initializing a `Slice` you simply provide the value |
696 | /// `PhantomData` for the field `phantom`: |
697 | /// |
698 | /// ``` |
699 | /// # #![allow(dead_code)] |
700 | /// # use std::marker::PhantomData; |
701 | /// # struct Slice<'a, T> { |
702 | /// # start: *const T, |
703 | /// # end: *const T, |
704 | /// # phantom: PhantomData<&'a T>, |
705 | /// # } |
706 | /// fn borrow_vec<T>(vec: &Vec<T>) -> Slice<'_, T> { |
707 | /// let ptr = vec.as_ptr(); |
708 | /// Slice { |
709 | /// start: ptr, |
710 | /// end: unsafe { ptr.add(vec.len()) }, |
711 | /// phantom: PhantomData, |
712 | /// } |
713 | /// } |
714 | /// ``` |
715 | /// |
716 | /// ## Unused type parameters |
717 | /// |
718 | /// It sometimes happens that you have unused type parameters which |
719 | /// indicate what type of data a struct is "tied" to, even though that |
720 | /// data is not actually found in the struct itself. Here is an |
721 | /// example where this arises with [FFI]. The foreign interface uses |
722 | /// handles of type `*mut ()` to refer to Rust values of different |
723 | /// types. We track the Rust type using a phantom type parameter on |
724 | /// the struct `ExternalResource` which wraps a handle. |
725 | /// |
726 | /// [FFI]: ../../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code |
727 | /// |
728 | /// ``` |
729 | /// # #![allow(dead_code)] |
730 | /// # trait ResType { } |
731 | /// # struct ParamType; |
732 | /// # mod foreign_lib { |
733 | /// # pub fn new(_: usize) -> *mut () { 42 as *mut () } |
734 | /// # pub fn do_stuff(_: *mut (), _: usize) {} |
735 | /// # } |
736 | /// # fn convert_params(_: ParamType) -> usize { 42 } |
737 | /// use std::marker::PhantomData; |
738 | /// |
739 | /// struct ExternalResource<R> { |
740 | /// resource_handle: *mut (), |
741 | /// resource_type: PhantomData<R>, |
742 | /// } |
743 | /// |
744 | /// impl<R: ResType> ExternalResource<R> { |
745 | /// fn new() -> Self { |
746 | /// let size_of_res = size_of::<R>(); |
747 | /// Self { |
748 | /// resource_handle: foreign_lib::new(size_of_res), |
749 | /// resource_type: PhantomData, |
750 | /// } |
751 | /// } |
752 | /// |
753 | /// fn do_stuff(&self, param: ParamType) { |
754 | /// let foreign_params = convert_params(param); |
755 | /// foreign_lib::do_stuff(self.resource_handle, foreign_params); |
756 | /// } |
757 | /// } |
758 | /// ``` |
759 | /// |
760 | /// ## Ownership and the drop check |
761 | /// |
762 | /// The exact interaction of `PhantomData` with drop check **may change in the future**. |
763 | /// |
764 | /// Currently, adding a field of type `PhantomData<T>` indicates that your type *owns* data of type |
765 | /// `T` in very rare circumstances. This in turn has effects on the Rust compiler's [drop check] |
766 | /// analysis. For the exact rules, see the [drop check] documentation. |
767 | /// |
768 | /// ## Layout |
769 | /// |
770 | /// For all `T`, the following are guaranteed: |
771 | /// * `size_of::<PhantomData<T>>() == 0` |
772 | /// * `align_of::<PhantomData<T>>() == 1` |
773 | /// |
774 | /// [drop check]: Drop#drop-check |
775 | #[lang = "phantom_data" ] |
776 | #[stable (feature = "rust1" , since = "1.0.0" )] |
777 | pub struct PhantomData<T: ?Sized>; |
778 | |
779 | #[stable (feature = "rust1" , since = "1.0.0" )] |
780 | impl<T: ?Sized> Hash for PhantomData<T> { |
781 | #[inline ] |
782 | fn hash<H: Hasher>(&self, _: &mut H) {} |
783 | } |
784 | |
785 | #[stable (feature = "rust1" , since = "1.0.0" )] |
786 | impl<T: ?Sized> cmp::PartialEq for PhantomData<T> { |
787 | fn eq(&self, _other: &PhantomData<T>) -> bool { |
788 | true |
789 | } |
790 | } |
791 | |
792 | #[stable (feature = "rust1" , since = "1.0.0" )] |
793 | impl<T: ?Sized> cmp::Eq for PhantomData<T> {} |
794 | |
795 | #[stable (feature = "rust1" , since = "1.0.0" )] |
796 | impl<T: ?Sized> cmp::PartialOrd for PhantomData<T> { |
797 | fn partial_cmp(&self, _other: &PhantomData<T>) -> Option<cmp::Ordering> { |
798 | Option::Some(cmp::Ordering::Equal) |
799 | } |
800 | } |
801 | |
802 | #[stable (feature = "rust1" , since = "1.0.0" )] |
803 | impl<T: ?Sized> cmp::Ord for PhantomData<T> { |
804 | fn cmp(&self, _other: &PhantomData<T>) -> cmp::Ordering { |
805 | cmp::Ordering::Equal |
806 | } |
807 | } |
808 | |
809 | #[stable (feature = "rust1" , since = "1.0.0" )] |
810 | impl<T: ?Sized> Copy for PhantomData<T> {} |
811 | |
812 | #[stable (feature = "rust1" , since = "1.0.0" )] |
813 | impl<T: ?Sized> Clone for PhantomData<T> { |
814 | fn clone(&self) -> Self { |
815 | Self |
816 | } |
817 | } |
818 | |
819 | #[stable (feature = "rust1" , since = "1.0.0" )] |
820 | impl<T: ?Sized> Default for PhantomData<T> { |
821 | fn default() -> Self { |
822 | Self |
823 | } |
824 | } |
825 | |
826 | #[unstable (feature = "structural_match" , issue = "31434" )] |
827 | impl<T: ?Sized> StructuralPartialEq for PhantomData<T> {} |
828 | |
829 | /// Compiler-internal trait used to indicate the type of enum discriminants. |
830 | /// |
831 | /// This trait is automatically implemented for every type and does not add any |
832 | /// guarantees to [`mem::Discriminant`]. It is **undefined behavior** to transmute |
833 | /// between `DiscriminantKind::Discriminant` and `mem::Discriminant`. |
834 | /// |
835 | /// [`mem::Discriminant`]: crate::mem::Discriminant |
836 | #[unstable ( |
837 | feature = "discriminant_kind" , |
838 | issue = "none" , |
839 | reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead" |
840 | )] |
841 | #[lang = "discriminant_kind" ] |
842 | #[rustc_deny_explicit_impl ] |
843 | #[rustc_do_not_implement_via_object] |
844 | pub trait DiscriminantKind { |
845 | /// The type of the discriminant, which must satisfy the trait |
846 | /// bounds required by `mem::Discriminant`. |
847 | #[lang = "discriminant_type" ] |
848 | type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin; |
849 | } |
850 | |
851 | /// Used to determine whether a type contains |
852 | /// any `UnsafeCell` internally, but not through an indirection. |
853 | /// This affects, for example, whether a `static` of that type is |
854 | /// placed in read-only static memory or writable static memory. |
855 | /// This can be used to declare that a constant with a generic type |
856 | /// will not contain interior mutability, and subsequently allow |
857 | /// placing the constant behind references. |
858 | /// |
859 | /// # Safety |
860 | /// |
861 | /// This trait is a core part of the language, it is just expressed as a trait in libcore for |
862 | /// convenience. Do *not* implement it for other types. |
863 | // FIXME: Eventually this trait should become `#[rustc_deny_explicit_impl]`. |
864 | // That requires porting the impls below to native internal impls. |
865 | #[lang = "freeze" ] |
866 | #[unstable (feature = "freeze" , issue = "121675" )] |
867 | pub unsafe auto trait Freeze {} |
868 | |
869 | #[unstable (feature = "freeze" , issue = "121675" )] |
870 | impl<T: ?Sized> !Freeze for UnsafeCell<T> {} |
871 | marker_impls! { |
872 | #[unstable (feature = "freeze" , issue = "121675" )] |
873 | unsafe Freeze for |
874 | {T: ?Sized} PhantomData<T>, |
875 | {T: ?Sized} *const T, |
876 | {T: ?Sized} *mut T, |
877 | {T: ?Sized} &T, |
878 | {T: ?Sized} &mut T, |
879 | } |
880 | |
881 | /// Types that do not require any pinning guarantees. |
882 | /// |
883 | /// For information on what "pinning" is, see the [`pin` module] documentation. |
884 | /// |
885 | /// Implementing the `Unpin` trait for `T` expresses the fact that `T` is pinning-agnostic: |
886 | /// it shall not expose nor rely on any pinning guarantees. This, in turn, means that a |
887 | /// `Pin`-wrapped pointer to such a type can feature a *fully unrestricted* API. |
888 | /// In other words, if `T: Unpin`, a value of type `T` will *not* be bound by the invariants |
889 | /// which pinning otherwise offers, even when "pinned" by a [`Pin<Ptr>`] pointing at it. |
890 | /// When a value of type `T` is pointed at by a [`Pin<Ptr>`], [`Pin`] will not restrict access |
891 | /// to the pointee value like it normally would, thus allowing the user to do anything that they |
892 | /// normally could with a non-[`Pin`]-wrapped `Ptr` to that value. |
893 | /// |
894 | /// The idea of this trait is to alleviate the reduced ergonomics of APIs that require the use |
895 | /// of [`Pin`] for soundness for some types, but which also want to be used by other types that |
896 | /// don't care about pinning. The prime example of such an API is [`Future::poll`]. There are many |
897 | /// [`Future`] types that don't care about pinning. These futures can implement `Unpin` and |
898 | /// therefore get around the pinning related restrictions in the API, while still allowing the |
899 | /// subset of [`Future`]s which *do* require pinning to be implemented soundly. |
900 | /// |
901 | /// For more discussion on the consequences of [`Unpin`] within the wider scope of the pinning |
902 | /// system, see the [section about `Unpin`] in the [`pin` module]. |
903 | /// |
904 | /// `Unpin` has no consequence at all for non-pinned data. In particular, [`mem::replace`] happily |
905 | /// moves `!Unpin` data, which would be immovable when pinned ([`mem::replace`] works for any |
906 | /// `&mut T`, not just when `T: Unpin`). |
907 | /// |
908 | /// *However*, you cannot use [`mem::replace`] on `!Unpin` data which is *pinned* by being wrapped |
909 | /// inside a [`Pin<Ptr>`] pointing at it. This is because you cannot (safely) use a |
910 | /// [`Pin<Ptr>`] to get a `&mut T` to its pointee value, which you would need to call |
911 | /// [`mem::replace`], and *that* is what makes this system work. |
912 | /// |
913 | /// So this, for example, can only be done on types implementing `Unpin`: |
914 | /// |
915 | /// ```rust |
916 | /// # #![allow (unused_must_use)] |
917 | /// use std::mem; |
918 | /// use std::pin::Pin; |
919 | /// |
920 | /// let mut string = "this" .to_string(); |
921 | /// let mut pinned_string = Pin::new(&mut string); |
922 | /// |
923 | /// // We need a mutable reference to call `mem::replace`. |
924 | /// // We can obtain such a reference by (implicitly) invoking `Pin::deref_mut`, |
925 | /// // but that is only possible because `String` implements `Unpin`. |
926 | /// mem::replace(&mut *pinned_string, "other" .to_string()); |
927 | /// ``` |
928 | /// |
929 | /// This trait is automatically implemented for almost every type. The compiler is free |
930 | /// to take the conservative stance of marking types as [`Unpin`] so long as all of the types that |
931 | /// compose its fields are also [`Unpin`]. This is because if a type implements [`Unpin`], then it |
932 | /// is unsound for that type's implementation to rely on pinning-related guarantees for soundness, |
933 | /// *even* when viewed through a "pinning" pointer! It is the responsibility of the implementor of |
934 | /// a type that relies upon pinning for soundness to ensure that type is *not* marked as [`Unpin`] |
935 | /// by adding [`PhantomPinned`] field. For more details, see the [`pin` module] docs. |
936 | /// |
937 | /// [`mem::replace`]: crate::mem::replace "mem replace" |
938 | /// [`Future`]: crate::future::Future "Future" |
939 | /// [`Future::poll`]: crate::future::Future::poll "Future poll" |
940 | /// [`Pin`]: crate::pin::Pin "Pin" |
941 | /// [`Pin<Ptr>`]: crate::pin::Pin "Pin" |
942 | /// [`pin` module]: crate::pin "pin module" |
943 | /// [section about `Unpin`]: crate::pin#unpin "pin module docs about unpin" |
944 | /// [`unsafe`]: ../../std/keyword.unsafe.html "keyword unsafe" |
945 | #[stable (feature = "pin" , since = "1.33.0" )] |
946 | #[diagnostic::on_unimplemented( |
947 | note = "consider using the `pin!` macro \nconsider using `Box::pin` if you need to access the pinned value outside of the current scope" , |
948 | message = "`{Self}` cannot be unpinned" |
949 | )] |
950 | #[lang = "unpin" ] |
951 | pub auto trait Unpin {} |
952 | |
953 | /// A marker type which does not implement `Unpin`. |
954 | /// |
955 | /// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default. |
956 | #[stable (feature = "pin" , since = "1.33.0" )] |
957 | #[derive (Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] |
958 | pub struct PhantomPinned; |
959 | |
960 | #[stable (feature = "pin" , since = "1.33.0" )] |
961 | impl !Unpin for PhantomPinned {} |
962 | |
963 | marker_impls! { |
964 | #[stable (feature = "pin" , since = "1.33.0" )] |
965 | Unpin for |
966 | {T: ?Sized} &T, |
967 | {T: ?Sized} &mut T, |
968 | } |
969 | |
970 | marker_impls! { |
971 | #[stable (feature = "pin_raw" , since = "1.38.0" )] |
972 | Unpin for |
973 | {T: ?Sized} *const T, |
974 | {T: ?Sized} *mut T, |
975 | } |
976 | |
977 | /// A marker for types that can be dropped. |
978 | /// |
979 | /// This should be used for `~const` bounds, |
980 | /// as non-const bounds will always hold for every type. |
981 | #[unstable (feature = "const_destruct" , issue = "133214" )] |
982 | #[rustc_const_unstable (feature = "const_destruct" , issue = "133214" )] |
983 | #[lang = "destruct" ] |
984 | #[rustc_on_unimplemented (message = "can't drop `{Self}`" , append_const_msg)] |
985 | #[rustc_deny_explicit_impl ] |
986 | #[rustc_do_not_implement_via_object] |
987 | #[const_trait ] |
988 | pub trait Destruct {} |
989 | |
990 | /// A marker for tuple types. |
991 | /// |
992 | /// The implementation of this trait is built-in and cannot be implemented |
993 | /// for any user type. |
994 | #[unstable (feature = "tuple_trait" , issue = "none" )] |
995 | #[lang = "tuple_trait" ] |
996 | #[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple" )] |
997 | #[rustc_deny_explicit_impl ] |
998 | #[rustc_do_not_implement_via_object] |
999 | pub trait Tuple {} |
1000 | |
1001 | /// A marker for pointer-like types. |
1002 | /// |
1003 | /// This trait can only be implemented for types that are certain to have |
1004 | /// the same size and alignment as a [`usize`] or [`*const ()`](pointer). |
1005 | /// To ensure this, there are special requirements on implementations |
1006 | /// of `PointerLike` (other than the already-provided implementations |
1007 | /// for built-in types): |
1008 | /// |
1009 | /// * The type must have `#[repr(transparent)]`. |
1010 | /// * The type’s sole non-zero-sized field must itself implement `PointerLike`. |
1011 | #[unstable (feature = "pointer_like_trait" , issue = "none" )] |
1012 | #[lang = "pointer_like" ] |
1013 | #[diagnostic::on_unimplemented( |
1014 | message = "`{Self}` needs to have the same ABI as a pointer" , |
1015 | label = "`{Self}` needs to be a pointer-like type" |
1016 | )] |
1017 | #[rustc_do_not_implement_via_object] |
1018 | pub trait PointerLike {} |
1019 | |
1020 | marker_impls! { |
1021 | #[unstable (feature = "pointer_like_trait" , issue = "none" )] |
1022 | PointerLike for |
1023 | isize, |
1024 | usize, |
1025 | {T} &T, |
1026 | {T} &mut T, |
1027 | {T} *const T, |
1028 | {T} *mut T, |
1029 | {T: PointerLike} crate::pin::Pin<T>, |
1030 | } |
1031 | |
1032 | /// A marker for types which can be used as types of `const` generic parameters. |
1033 | /// |
1034 | /// These types must have a proper equivalence relation (`Eq`) and it must be automatically |
1035 | /// derived (`StructuralPartialEq`). There's a hard-coded check in the compiler ensuring |
1036 | /// that all fields are also `ConstParamTy`, which implies that recursively, all fields |
1037 | /// are `StructuralPartialEq`. |
1038 | #[lang = "const_param_ty" ] |
1039 | #[unstable (feature = "unsized_const_params" , issue = "95174" )] |
1040 | #[diagnostic::on_unimplemented(message = "`{Self}` can't be used as a const parameter type" )] |
1041 | #[allow (multiple_supertrait_upcastable)] |
1042 | // We name this differently than the derive macro so that the `adt_const_params` can |
1043 | // be used independently of `unsized_const_params` without requiring a full path |
1044 | // to the derive macro every time it is used. This should be renamed on stabilization. |
1045 | pub trait ConstParamTy_: UnsizedConstParamTy + StructuralPartialEq + Eq {} |
1046 | |
1047 | /// Derive macro generating an impl of the trait `ConstParamTy`. |
1048 | #[rustc_builtin_macro ] |
1049 | #[allow_internal_unstable (unsized_const_params)] |
1050 | #[unstable (feature = "adt_const_params" , issue = "95174" )] |
1051 | pub macro ConstParamTy($item:item) { |
1052 | /* compiler built-in */ |
1053 | } |
1054 | |
1055 | #[lang = "unsized_const_param_ty" ] |
1056 | #[unstable (feature = "unsized_const_params" , issue = "95174" )] |
1057 | #[diagnostic::on_unimplemented(message = "`{Self}` can't be used as a const parameter type" )] |
1058 | /// A marker for types which can be used as types of `const` generic parameters. |
1059 | /// |
1060 | /// Equivalent to [`ConstParamTy_`] except that this is used by |
1061 | /// the `unsized_const_params` to allow for fake unstable impls. |
1062 | pub trait UnsizedConstParamTy: StructuralPartialEq + Eq {} |
1063 | |
1064 | /// Derive macro generating an impl of the trait `ConstParamTy`. |
1065 | #[rustc_builtin_macro ] |
1066 | #[allow_internal_unstable (unsized_const_params)] |
1067 | #[unstable (feature = "unsized_const_params" , issue = "95174" )] |
1068 | pub macro UnsizedConstParamTy($item:item) { |
1069 | /* compiler built-in */ |
1070 | } |
1071 | |
1072 | // FIXME(adt_const_params): handle `ty::FnDef`/`ty::Closure` |
1073 | marker_impls! { |
1074 | #[unstable (feature = "adt_const_params" , issue = "95174" )] |
1075 | ConstParamTy_ for |
1076 | usize, u8, u16, u32, u64, u128, |
1077 | isize, i8, i16, i32, i64, i128, |
1078 | bool, |
1079 | char, |
1080 | (), |
1081 | {T: ConstParamTy_, const N: usize} [T; N], |
1082 | } |
1083 | |
1084 | marker_impls! { |
1085 | #[unstable (feature = "unsized_const_params" , issue = "95174" )] |
1086 | UnsizedConstParamTy for |
1087 | usize, u8, u16, u32, u64, u128, |
1088 | isize, i8, i16, i32, i64, i128, |
1089 | bool, |
1090 | char, |
1091 | (), |
1092 | {T: UnsizedConstParamTy, const N: usize} [T; N], |
1093 | |
1094 | str, |
1095 | {T: UnsizedConstParamTy} [T], |
1096 | {T: UnsizedConstParamTy + ?Sized} &T, |
1097 | } |
1098 | |
1099 | /// A common trait implemented by all function pointers. |
1100 | // |
1101 | // Note that while the trait is internal and unstable it is nevertheless |
1102 | // exposed as a public bound of the stable `core::ptr::fn_addr_eq` function. |
1103 | #[unstable ( |
1104 | feature = "fn_ptr_trait" , |
1105 | issue = "none" , |
1106 | reason = "internal trait for implementing various traits for all function pointers" |
1107 | )] |
1108 | #[lang = "fn_ptr_trait" ] |
1109 | #[rustc_deny_explicit_impl ] |
1110 | #[rustc_do_not_implement_via_object] |
1111 | pub trait FnPtr: Copy + Clone { |
1112 | /// Returns the address of the function pointer. |
1113 | #[lang = "fn_ptr_addr" ] |
1114 | fn addr(self) -> *const (); |
1115 | } |
1116 | |
1117 | /// Derive macro that makes a smart pointer usable with trait objects. |
1118 | /// |
1119 | /// # What this macro does |
1120 | /// |
1121 | /// This macro is intended to be used with user-defined pointer types, and makes it possible to |
1122 | /// perform coercions on the pointee of the user-defined pointer. There are two aspects to this: |
1123 | /// |
1124 | /// ## Unsizing coercions of the pointee |
1125 | /// |
1126 | /// By using the macro, the following example will compile: |
1127 | /// ``` |
1128 | /// #![feature(derive_coerce_pointee)] |
1129 | /// use std::marker::CoercePointee; |
1130 | /// use std::ops::Deref; |
1131 | /// |
1132 | /// #[derive(CoercePointee)] |
1133 | /// #[repr(transparent)] |
1134 | /// struct MySmartPointer<T: ?Sized>(Box<T>); |
1135 | /// |
1136 | /// impl<T: ?Sized> Deref for MySmartPointer<T> { |
1137 | /// type Target = T; |
1138 | /// fn deref(&self) -> &T { |
1139 | /// &self.0 |
1140 | /// } |
1141 | /// } |
1142 | /// |
1143 | /// trait MyTrait {} |
1144 | /// |
1145 | /// impl MyTrait for i32 {} |
1146 | /// |
1147 | /// fn main() { |
1148 | /// let ptr: MySmartPointer<i32> = MySmartPointer(Box::new(4)); |
1149 | /// |
1150 | /// // This coercion would be an error without the derive. |
1151 | /// let ptr: MySmartPointer<dyn MyTrait> = ptr; |
1152 | /// } |
1153 | /// ``` |
1154 | /// Without the `#[derive(CoercePointee)]` macro, this example would fail with the following error: |
1155 | /// ```text |
1156 | /// error[E0308]: mismatched types |
1157 | /// --> src/main.rs:11:44 |
1158 | /// | |
1159 | /// 11 | let ptr: MySmartPointer<dyn MyTrait> = ptr; |
1160 | /// | --------------------------- ^^^ expected `MySmartPointer<dyn MyTrait>`, found `MySmartPointer<i32>` |
1161 | /// | | |
1162 | /// | expected due to this |
1163 | /// | |
1164 | /// = note: expected struct `MySmartPointer<dyn MyTrait>` |
1165 | /// found struct `MySmartPointer<i32>` |
1166 | /// = help: `i32` implements `MyTrait` so you could box the found value and coerce it to the trait object `Box<dyn MyTrait>`, you will have to change the expected type as well |
1167 | /// ``` |
1168 | /// |
1169 | /// ## Dyn compatibility |
1170 | /// |
1171 | /// This macro allows you to dispatch on the user-defined pointer type. That is, traits using the |
1172 | /// type as a receiver are dyn-compatible. For example, this compiles: |
1173 | /// |
1174 | /// ``` |
1175 | /// #![feature(arbitrary_self_types, derive_coerce_pointee)] |
1176 | /// use std::marker::CoercePointee; |
1177 | /// use std::ops::Deref; |
1178 | /// |
1179 | /// #[derive(CoercePointee)] |
1180 | /// #[repr(transparent)] |
1181 | /// struct MySmartPointer<T: ?Sized>(Box<T>); |
1182 | /// |
1183 | /// impl<T: ?Sized> Deref for MySmartPointer<T> { |
1184 | /// type Target = T; |
1185 | /// fn deref(&self) -> &T { |
1186 | /// &self.0 |
1187 | /// } |
1188 | /// } |
1189 | /// |
1190 | /// // You can always define this trait. (as long as you have #![feature(arbitrary_self_types)]) |
1191 | /// trait MyTrait { |
1192 | /// fn func(self: MySmartPointer<Self>); |
1193 | /// } |
1194 | /// |
1195 | /// // But using `dyn MyTrait` requires #[derive(CoercePointee)]. |
1196 | /// fn call_func(value: MySmartPointer<dyn MyTrait>) { |
1197 | /// value.func(); |
1198 | /// } |
1199 | /// ``` |
1200 | /// If you remove the `#[derive(CoercePointee)]` annotation from the struct, then the above example |
1201 | /// will fail with this error message: |
1202 | /// ```text |
1203 | /// error[E0038]: the trait `MyTrait` is not dyn compatible |
1204 | /// --> src/lib.rs:21:36 |
1205 | /// | |
1206 | /// 17 | fn func(self: MySmartPointer<Self>); |
1207 | /// | -------------------- help: consider changing method `func`'s `self` parameter to be `&self`: `&Self` |
1208 | /// ... |
1209 | /// 21 | fn call_func(value: MySmartPointer<dyn MyTrait>) { |
1210 | /// | ^^^^^^^^^^^ `MyTrait` is not dyn compatible |
1211 | /// | |
1212 | /// note: for a trait to be dyn compatible it needs to allow building a vtable |
1213 | /// for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> |
1214 | /// --> src/lib.rs:17:19 |
1215 | /// | |
1216 | /// 16 | trait MyTrait { |
1217 | /// | ------- this trait is not dyn compatible... |
1218 | /// 17 | fn func(self: MySmartPointer<Self>); |
1219 | /// | ^^^^^^^^^^^^^^^^^^^^ ...because method `func`'s `self` parameter cannot be dispatched on |
1220 | /// ``` |
1221 | /// |
1222 | /// # Requirements for using the macro |
1223 | /// |
1224 | /// This macro can only be used if: |
1225 | /// * The type is a `#[repr(transparent)]` struct. |
1226 | /// * The type of its non-zero-sized field must either be a standard library pointer type |
1227 | /// (reference, raw pointer, `NonNull`, `Box`, `Rc`, `Arc`, etc.) or another user-defined type |
1228 | /// also using the `#[derive(CoercePointee)]` macro. |
1229 | /// * Zero-sized fields must not mention any generic parameters unless the zero-sized field has |
1230 | /// type [`PhantomData`]. |
1231 | /// |
1232 | /// ## Multiple type parameters |
1233 | /// |
1234 | /// If the type has multiple type parameters, then you must explicitly specify which one should be |
1235 | /// used for dynamic dispatch. For example: |
1236 | /// ``` |
1237 | /// # #![feature(derive_coerce_pointee)] |
1238 | /// # use std::marker::{CoercePointee, PhantomData}; |
1239 | /// #[derive(CoercePointee)] |
1240 | /// #[repr(transparent)] |
1241 | /// struct MySmartPointer<#[pointee] T: ?Sized, U> { |
1242 | /// ptr: Box<T>, |
1243 | /// _phantom: PhantomData<U>, |
1244 | /// } |
1245 | /// ``` |
1246 | /// Specifying `#[pointee]` when the struct has only one type parameter is allowed, but not required. |
1247 | /// |
1248 | /// # Examples |
1249 | /// |
1250 | /// A custom implementation of the `Rc` type: |
1251 | /// ``` |
1252 | /// #![feature(derive_coerce_pointee)] |
1253 | /// use std::marker::CoercePointee; |
1254 | /// use std::ops::Deref; |
1255 | /// use std::ptr::NonNull; |
1256 | /// |
1257 | /// #[derive(CoercePointee)] |
1258 | /// #[repr(transparent)] |
1259 | /// pub struct Rc<T: ?Sized> { |
1260 | /// inner: NonNull<RcInner<T>>, |
1261 | /// } |
1262 | /// |
1263 | /// struct RcInner<T: ?Sized> { |
1264 | /// refcount: usize, |
1265 | /// value: T, |
1266 | /// } |
1267 | /// |
1268 | /// impl<T: ?Sized> Deref for Rc<T> { |
1269 | /// type Target = T; |
1270 | /// fn deref(&self) -> &T { |
1271 | /// let ptr = self.inner.as_ptr(); |
1272 | /// unsafe { &(*ptr).value } |
1273 | /// } |
1274 | /// } |
1275 | /// |
1276 | /// impl<T> Rc<T> { |
1277 | /// pub fn new(value: T) -> Self { |
1278 | /// let inner = Box::new(RcInner { |
1279 | /// refcount: 1, |
1280 | /// value, |
1281 | /// }); |
1282 | /// Self { |
1283 | /// inner: NonNull::from(Box::leak(inner)), |
1284 | /// } |
1285 | /// } |
1286 | /// } |
1287 | /// |
1288 | /// impl<T: ?Sized> Clone for Rc<T> { |
1289 | /// fn clone(&self) -> Self { |
1290 | /// // A real implementation would handle overflow here. |
1291 | /// unsafe { (*self.inner.as_ptr()).refcount += 1 }; |
1292 | /// Self { inner: self.inner } |
1293 | /// } |
1294 | /// } |
1295 | /// |
1296 | /// impl<T: ?Sized> Drop for Rc<T> { |
1297 | /// fn drop(&mut self) { |
1298 | /// let ptr = self.inner.as_ptr(); |
1299 | /// unsafe { (*ptr).refcount -= 1 }; |
1300 | /// if unsafe { (*ptr).refcount } == 0 { |
1301 | /// drop(unsafe { Box::from_raw(ptr) }); |
1302 | /// } |
1303 | /// } |
1304 | /// } |
1305 | /// ``` |
1306 | #[rustc_builtin_macro (CoercePointee, attributes(pointee))] |
1307 | #[allow_internal_unstable (dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated)] |
1308 | #[rustc_diagnostic_item = "CoercePointee" ] |
1309 | #[unstable (feature = "derive_coerce_pointee" , issue = "123430" )] |
1310 | pub macro CoercePointee($item:item) { |
1311 | /* compiler built-in */ |
1312 | } |
1313 | |
1314 | /// A trait that is implemented for ADTs with `derive(CoercePointee)` so that |
1315 | /// the compiler can enforce the derive impls are valid post-expansion, since |
1316 | /// the derive has stricter requirements than if the impls were written by hand. |
1317 | /// |
1318 | /// This trait is not intended to be implemented by users or used other than |
1319 | /// validation, so it should never be stabilized. |
1320 | #[lang = "coerce_pointee_validated" ] |
1321 | #[unstable (feature = "coerce_pointee_validated" , issue = "none" )] |
1322 | #[doc (hidden)] |
1323 | pub trait CoercePointeeValidated { |
1324 | /* compiler built-in */ |
1325 | } |
1326 | |