rust/library/core/src/marker.rs

834 lines
30 KiB
Rust
Raw Normal View History

2016-09-11 17:09:05 -05:00
//! Primitive traits and types representing basic properties of types.
//!
//! Rust types can be classified in various useful ways according to
2016-09-11 17:09:05 -05:00
//! their intrinsic properties. These classifications are represented
//! as traits.
2015-01-23 23:48:20 -06:00
#![stable(feature = "rust1", since = "1.0.0")]
2019-04-14 21:23:21 -05:00
use crate::cell::UnsafeCell;
use crate::cmp;
use crate::fmt::Debug;
2019-04-14 21:23:21 -05:00
use crate::hash::Hash;
use crate::hash::Hasher;
2015-11-05 12:29:46 -06:00
/// Types that can be transferred across thread boundaries.
///
2016-09-11 17:09:05 -05:00
/// This trait is automatically implemented when the compiler determines it's
/// appropriate.
///
/// An example of a non-`Send` type is the reference-counting pointer
2016-11-10 16:13:37 -06:00
/// [`rc::Rc`][`Rc`]. If two threads attempt to clone [`Rc`]s that point to the same
2016-09-11 17:09:05 -05:00
/// reference-counted value, they might try to update the reference count at the
2016-11-10 16:13:37 -06:00
/// same time, which is [undefined behavior][ub] because [`Rc`] doesn't use atomic
2016-09-11 17:09:05 -05:00
/// operations. Its cousin [`sync::Arc`][arc] does use atomic operations (incurring
/// some overhead) and thus is `Send`.
///
/// See [the Nomicon](../../nomicon/send-and-sync.html) for more details.
///
2016-11-10 16:13:37 -06:00
/// [`Rc`]: ../../std/rc/struct.Rc.html
2016-09-11 17:09:05 -05:00
/// [arc]: ../../std/sync/struct.Arc.html
/// [ub]: ../../reference/behavior-considered-undefined.html
2015-02-18 16:30:14 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "send_trait")]
#[rustc_on_unimplemented(
2019-12-22 16:42:04 -06:00
message = "`{Self}` cannot be sent between threads safely",
label = "`{Self}` cannot be sent between threads safely"
)]
pub unsafe auto trait Send {
// empty.
}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> !Send for *const T {}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> !Send for *mut T {}
2016-09-11 17:09:05 -05:00
/// Types with a constant size known at compile time.
///
2016-09-11 17:09:05 -05:00
/// All type parameters have an implicit bound of `Sized`. The special syntax
/// `?Sized` can be used to remove this bound if it's not appropriate.
///
/// ```
2015-11-03 09:27:03 -06:00
/// # #![allow(dead_code)]
/// struct Foo<T>(T);
/// struct Bar<T: ?Sized>(T);
///
/// // struct FooUse(Foo<[i32]>); // error: Sized is not implemented for [i32]
/// struct BarUse(Bar<[i32]>); // OK
/// ```
2016-09-11 17:09:05 -05:00
///
/// The one exception is the implicit `Self` type of a trait. A trait does not
/// have an implicit `Sized` bound as this is incompatible with [trait object]s
/// where, by definition, the trait needs to work with all possible implementors,
/// and thus could be any size.
///
/// Although Rust will let you bind `Sized` to a trait, you won't
/// be able to use it to form a trait object later:
2016-09-11 17:09:05 -05:00
///
/// ```
/// # #![allow(unused_variables)]
/// trait Foo { }
/// trait Bar: Sized { }
///
/// struct Impl;
/// impl Foo for Impl { }
/// impl Bar for Impl { }
///
/// let x: &dyn Foo = &Impl; // OK
/// // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot
/// // be made into an object
2016-09-11 17:09:05 -05:00
/// ```
///
/// [trait object]: ../../book/ch17-02-trait-objects.html
2015-01-23 23:48:20 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "sized"]
#[rustc_on_unimplemented(
2019-12-22 16:42:04 -06:00
message = "the size for values of type `{Self}` cannot be known at compilation time",
2020-07-10 18:05:35 -05:00
label = "doesn't have a size known at compile-time"
)]
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
2020-04-22 14:45:35 -05:00
#[rustc_specialization_trait]
pub trait Sized {
// Empty.
}
2016-09-11 17:09:05 -05:00
/// Types that can be "unsized" to a dynamically-sized type.
///
/// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and
/// `Unsize<dyn fmt::Debug>`.
2016-09-11 17:09:05 -05:00
///
/// All implementations of `Unsize` are provided automatically by the compiler.
///
/// `Unsize` is implemented for:
///
/// - `[T; N]` is `Unsize<[T]>`
/// - `T` is `Unsize<dyn Trait>` when `T: Trait`
/// - `Foo<..., T, ...>` is `Unsize<Foo<..., U, ...>>` if:
/// - `T: Unsize<U>`
/// - Foo is a struct
/// - Only the last field of `Foo` has a type involving `T`
/// - `T` is not part of the type of any other fields
/// - `Bar<T>: Unsize<Bar<U>>`, if the last field of `Foo` has type `Bar<T>`
///
2020-09-02 17:22:40 -05:00
/// `Unsize` is used along with [`ops::CoerceUnsized`] to allow
/// "user-defined" containers such as [`Rc`] to contain dynamically-sized
/// types. See the [DST coercion RFC][RFC982] and [the nomicon entry on coercion][nomicon-coerce]
/// for more details.
2016-09-11 17:09:05 -05:00
///
2020-09-02 17:22:40 -05:00
/// [`ops::CoerceUnsized`]: crate::ops::CoerceUnsized
/// [`Rc`]: ../../std/rc/struct.Rc.html
2016-09-11 17:09:05 -05:00
/// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
/// [nomicon-coerce]: ../../nomicon/coercions.html
#[unstable(feature = "unsize", issue = "27732")]
2017-09-28 03:30:25 -05:00
#[lang = "unsize"]
pub trait Unsize<T: ?Sized> {
// Empty.
}
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
/// Required trait for constants used in pattern matches.
///
/// Any type that derives `PartialEq` automatically implements this trait,
/// *regardless* of whether its type-parameters implement `Eq`.
///
/// If a `const` item contains some type that does not implement this trait,
/// then that type either (1.) does not implement `PartialEq` (which means the
/// constant will not provide that comparison method, which code generation
/// assumes is available), or (2.) it implements *its own* version of
/// `PartialEq` (which we assume does not conform to a structural-equality
/// comparison).
///
/// In either of the two scenarios above, we reject usage of such a constant in
/// a pattern match.
///
/// See also the [structural match RFC][RFC1445], and [issue 63438] which
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
/// motivated migrating from attribute-based design to this trait.
///
/// [RFC1445]: https://github.com/rust-lang/rfcs/blob/master/text/1445-restrict-constants-in-patterns.md
/// [issue 63438]: https://github.com/rust-lang/rust/issues/63438
#[unstable(feature = "structural_match", issue = "31434")]
2019-12-22 16:42:04 -06:00
#[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(PartialEq)]`")]
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
#[lang = "structural_peq"]
pub trait StructuralPartialEq {
// Empty.
}
/// Required trait for constants used in pattern matches.
///
/// Any type that derives `Eq` automatically implements this trait, *regardless*
2020-11-05 19:11:29 -06:00
/// of whether its type parameters implement `Eq`.
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
///
2020-11-05 19:11:29 -06:00
/// This is a hack to work around a limitation in our type system.
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
///
2020-11-05 19:11:29 -06:00
/// # Background
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
///
/// We want to require that types of consts used in pattern matches
/// have the attribute `#[derive(PartialEq, Eq)]`.
///
/// In a more ideal world, we could check that requirement by just checking that
2020-11-05 19:11:29 -06:00
/// the given type implements both the `StructuralPartialEq` trait *and*
/// the `Eq` trait. However, you can have ADTs that *do* `derive(PartialEq, Eq)`,
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
/// and be a case that we want the compiler to accept, and yet the constant's
/// type fails to implement `Eq`.
///
/// Namely, a case like this:
///
/// ```rust
/// #[derive(PartialEq, Eq)]
/// struct Wrap<X>(X);
2020-11-05 19:11:29 -06:00
///
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
/// fn higher_order(_: &()) { }
2020-11-05 19:11:29 -06:00
///
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
/// const CFN: Wrap<fn(&())> = Wrap(higher_order);
2020-11-05 19:11:29 -06:00
///
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
/// fn main() {
/// match CFN {
/// CFN => {}
/// _ => {}
/// }
/// }
/// ```
///
/// (The problem in the above code is that `Wrap<fn(&())>` does not implement
/// `PartialEq`, nor `Eq`, because `for<'a> fn(&'a _)` does not implement those
/// traits.)
///
/// Therefore, we cannot rely on naive check for `StructuralPartialEq` and
/// mere `Eq`.
///
/// As a hack to work around this, we use two separate traits injected by each
/// of the two derives (`#[derive(PartialEq)]` and `#[derive(Eq)]`) and check
/// that both of them are present as part of structural-match checking.
#[unstable(feature = "structural_match", issue = "31434")]
2019-12-22 16:42:04 -06:00
#[rustc_on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
#[lang = "structural_teq"]
pub trait StructuralEq {
// Empty.
}
2016-09-11 17:09:05 -05:00
/// Types whose values can be duplicated simply by copying bits.
///
/// By default, variable bindings have 'move semantics.' In other
/// words:
///
/// ```
2015-01-28 07:34:18 -06:00
/// #[derive(Debug)]
/// struct Foo;
///
/// let x = Foo;
///
/// let y = x;
///
/// // `x` has moved into `y`, and so cannot be used
///
/// // println!("{:?}", x); // error: use of moved value
/// ```
///
/// However, if a type implements `Copy`, it instead has 'copy semantics':
///
/// ```
2016-09-11 17:09:05 -05:00
/// // We can derive a `Copy` implementation. `Clone` is also required, as it's
/// // a supertrait of `Copy`.
/// #[derive(Debug, Copy, Clone)]
/// struct Foo;
///
/// let x = Foo;
///
/// let y = x;
///
/// // `y` is a copy of `x`
///
/// println!("{:?}", x); // A-OK!
/// ```
///
2016-09-11 17:09:05 -05:00
/// It's important to note that in these two examples, the only difference is whether you
/// are allowed to access `x` after the assignment. Under the hood, both a copy and a move
/// can result in bits being copied in memory, although this is sometimes optimized away.
///
/// ## How can I implement `Copy`?
///
/// There are two ways to implement `Copy` on your type. The simplest is to use `derive`:
///
/// ```
/// #[derive(Copy, Clone)]
/// struct MyStruct;
/// ```
///
/// You can also implement `Copy` and `Clone` manually:
///
/// ```
/// struct MyStruct;
///
/// impl Copy for MyStruct { }
///
/// impl Clone for MyStruct {
/// fn clone(&self) -> MyStruct {
/// *self
/// }
/// }
/// ```
///
/// There is a small difference between the two: the `derive` strategy will also place a `Copy`
/// bound on type parameters, which isn't always desired.
///
/// ## What's the difference between `Copy` and `Clone`?
///
/// Copies happen implicitly, for example as part of an assignment `y = x`. The behavior of
/// `Copy` is not overloadable; it is always a simple bit-wise copy.
///
2016-11-10 16:13:37 -06:00
/// Cloning is an explicit action, `x.clone()`. The implementation of [`Clone`] can
2016-09-11 17:09:05 -05:00
/// provide any type-specific behavior necessary to duplicate values safely. For example,
2016-11-10 16:13:37 -06:00
/// the implementation of [`Clone`] for [`String`] needs to copy the pointed-to string
/// buffer in the heap. A simple bitwise copy of [`String`] values would merely copy the
/// pointer, leading to a double free down the line. For this reason, [`String`] is [`Clone`]
2016-09-11 17:09:05 -05:00
/// but not `Copy`.
///
2016-11-10 16:13:37 -06:00
/// [`Clone`] is a supertrait of `Copy`, so everything which is `Copy` must also implement
2017-06-04 21:56:16 -05:00
/// [`Clone`]. If a type is `Copy` then its [`Clone`] implementation only needs to return `*self`
2016-09-11 17:09:05 -05:00
/// (see the example above).
///
/// ## When can my type be `Copy`?
///
/// A type can implement `Copy` if all of its components implement `Copy`. For example, this
2016-09-11 17:09:05 -05:00
/// struct can be `Copy`:
///
/// ```
2015-11-03 09:27:03 -06:00
/// # #[allow(dead_code)]
/// #[derive(Copy, Clone)]
/// struct Point {
/// x: i32,
/// y: i32,
/// }
/// ```
///
2016-11-10 16:13:37 -06:00
/// A struct can be `Copy`, and [`i32`] is `Copy`, therefore `Point` is eligible to be `Copy`.
2016-09-11 17:09:05 -05:00
/// By contrast, consider
///
/// ```
2015-11-03 09:27:03 -06:00
/// # #![allow(dead_code)]
/// # struct Point;
/// struct PointList {
/// points: Vec<Point>,
/// }
/// ```
///
2016-09-11 17:09:05 -05:00
/// The struct `PointList` cannot implement `Copy`, because [`Vec<T>`] is not `Copy`. If we
/// attempt to derive a `Copy` implementation, we'll get an error:
///
/// ```text
/// the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy`
/// ```
///
/// Shared references (`&T`) are also `Copy`, so a type can be `Copy`, even when it holds
/// shared references of types `T` that are *not* `Copy`. Consider the following struct,
/// which can implement `Copy`, because it only holds a *shared reference* to our non-`Copy`
/// type `PointList` from above:
///
/// ```
/// # #![allow(dead_code)]
/// # struct PointList;
/// #[derive(Copy, Clone)]
/// struct PointListWrapper<'a> {
/// point_list_ref: &'a PointList,
/// }
/// ```
///
2016-09-11 17:09:05 -05:00
/// ## When *can't* my type be `Copy`?
///
/// Some types can't be copied safely. For example, copying `&mut T` would create an aliased
2016-11-10 16:13:37 -06:00
/// mutable reference. Copying [`String`] would duplicate responsibility for managing the
/// [`String`]'s buffer, leading to a double free.
///
2016-09-09 09:07:44 -05:00
/// Generalizing the latter case, any type implementing [`Drop`] can't be `Copy`, because it's
/// managing some resource besides its own [`size_of::<T>`] bytes.
///
/// If you try to implement `Copy` on a struct or enum containing non-`Copy` data, you will get
/// the error [E0204].
///
2016-10-20 18:49:47 -05:00
/// [E0204]: ../../error-index.html#E0204
///
2016-09-11 17:09:05 -05:00
/// ## When *should* my type be `Copy`?
///
2016-09-11 17:09:05 -05:00
/// Generally speaking, if your type _can_ implement `Copy`, it should. Keep in mind, though,
/// that implementing `Copy` is part of the public API of your type. If the type might become
/// non-`Copy` in the future, it could be prudent to omit the `Copy` implementation now, to
/// avoid a breaking API change.
2016-09-09 09:07:44 -05:00
///
/// ## Additional implementors
///
/// In addition to the [implementors listed below][impls],
/// the following types also implement `Copy`:
///
/// * Function item types (i.e., the distinct types defined for each function)
/// * Function pointer types (e.g., `fn() -> i32`)
/// * Array types, for all sizes, if the item type also implements `Copy` (e.g., `[i32; 123456]`)
/// * Tuple types, if each component also implements `Copy` (e.g., `()`, `(i32, bool)`)
/// * Closure types, if they capture no value from the environment
/// or if all such captured values implement `Copy` themselves.
/// Note that variables captured by shared reference always implement `Copy`
/// (even if the referent doesn't),
/// while variables captured by mutable reference never implement `Copy`.
///
2016-09-09 09:07:44 -05:00
/// [`Vec<T>`]: ../../std/vec/struct.Vec.html
/// [`String`]: ../../std/string/struct.String.html
2020-09-02 17:22:40 -05:00
/// [`size_of::<T>`]: crate::mem::size_of
/// [impls]: #implementors
2015-01-23 23:48:20 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "copy"]
// FIXME(matthewjasper) This allows copying a type that doesn't implement
// `Copy` because of unsatisfied lifetime bounds (copying `A<'_>` when only
// `A<'static>: Copy` and `A<'_>: Clone`).
// We have this attribute here for now only because there are quite a few
// existing specializations on `Copy` that already exist in the standard
// library, and there's no way to safely have this behavior right now.
#[rustc_unsafe_specialization_marker]
2019-12-22 16:42:04 -06:00
pub trait Copy: Clone {
// Empty.
}
/// Derive macro generating an impl of the trait `Copy`.
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
2019-12-22 16:42:04 -06:00
pub macro Copy($item:item) {
/* compiler built-in */
}
2016-09-11 17:09:05 -05:00
/// Types for which it is safe to share references between threads.
///
/// This trait is automatically implemented when the compiler determines
/// it's appropriate.
///
2020-09-02 17:22:40 -05:00
/// The precise definition is: a type `T` is [`Sync`] if and only if `&T` is
/// [`Send`]. In other words, if there is no possibility of
2016-09-11 17:09:05 -05:00
/// [undefined behavior][ub] (including data races) when passing
/// `&T` references between threads.
///
2020-09-02 17:22:40 -05:00
/// As one would expect, primitive types like [`u8`] and [`f64`]
/// are all [`Sync`], and so are simple aggregate types containing them,
/// like tuples, structs and enums. More examples of basic [`Sync`]
2016-09-11 17:09:05 -05:00
/// types include "immutable" types like `&T`, and those with simple
/// inherited mutability, such as [`Box<T>`][box], [`Vec<T>`][vec] and
2020-09-02 17:22:40 -05:00
/// most other collection types. (Generic parameters need to be [`Sync`]
/// for their container to be [`Sync`].)
2016-09-11 17:09:05 -05:00
///
/// A somewhat surprising consequence of the definition is that `&mut T`
/// is `Sync` (if `T` is `Sync`) even though it seems like that might
/// provide unsynchronized mutation. The trick is that a mutable
/// reference behind a shared reference (that is, `& &mut T`)
/// becomes read-only, as if it were a `& &T`. Hence there is no risk
/// of a data race.
///
/// Types that are not `Sync` are those that have "interior
2020-09-02 17:22:40 -05:00
/// mutability" in a non-thread-safe form, such as [`Cell`][cell]
/// and [`RefCell`][refcell]. These types allow for mutation of
2016-09-11 17:09:05 -05:00
/// their contents even through an immutable, shared reference. For
2016-11-10 16:13:37 -06:00
/// example the `set` method on [`Cell<T>`][cell] takes `&self`, so it requires
/// only a shared reference [`&Cell<T>`][cell]. The method performs no
/// synchronization, thus [`Cell`][cell] cannot be `Sync`.
///
2016-09-11 17:09:05 -05:00
/// Another example of a non-`Sync` type is the reference-counting
2020-09-02 17:22:40 -05:00
/// pointer [`Rc`][rc]. Given any reference [`&Rc<T>`][rc], you can clone
2016-11-10 16:13:37 -06:00
/// a new [`Rc<T>`][rc], modifying the reference counts in a non-atomic way.
2016-09-09 09:07:44 -05:00
///
2016-09-11 17:09:05 -05:00
/// For cases when one does need thread-safe interior mutability,
/// Rust provides [atomic data types], as well as explicit locking via
2017-11-24 03:04:57 -06:00
/// [`sync::Mutex`][mutex] and [`sync::RwLock`][rwlock]. These types
2016-09-11 17:09:05 -05:00
/// ensure that any mutation cannot cause data races, hence the types
/// are `Sync`. Likewise, [`sync::Arc`][arc] provides a thread-safe
2020-09-02 17:48:35 -05:00
/// analogue of [`Rc`][rc].
2016-09-11 17:09:05 -05:00
///
/// Any types with interior mutability must also use the
/// [`cell::UnsafeCell`][unsafecell] wrapper around the value(s) which
/// can be mutated through a shared reference. Failing to doing this is
/// [undefined behavior][ub]. For example, [`transmute`][transmute]-ing
/// from `&T` to `&mut T` is invalid.
///
2020-09-02 17:22:40 -05:00
/// See [the Nomicon][nomicon-send-and-sync] for more details about `Sync`.
2016-09-11 17:09:05 -05:00
///
/// [box]: ../../std/boxed/struct.Box.html
/// [vec]: ../../std/vec/struct.Vec.html
2020-09-02 17:22:40 -05:00
/// [cell]: crate::cell::Cell
/// [refcell]: crate::cell::RefCell
2016-09-11 17:09:05 -05:00
/// [rc]: ../../std/rc/struct.Rc.html
/// [arc]: ../../std/sync/struct.Arc.html
2020-09-02 17:22:40 -05:00
/// [atomic data types]: crate::sync::atomic
2016-09-11 17:09:05 -05:00
/// [mutex]: ../../std/sync/struct.Mutex.html
/// [rwlock]: ../../std/sync/struct.RwLock.html
2020-09-02 17:22:40 -05:00
/// [unsafecell]: crate::cell::UnsafeCell
/// [ub]: ../../reference/behavior-considered-undefined.html
2020-09-02 17:22:40 -05:00
/// [transmute]: crate::mem::transmute
/// [nomicon-send-and-sync]: ../../nomicon/send-and-sync.html
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "sync_trait")]
#[lang = "sync"]
#[rustc_on_unimplemented(
2019-12-22 16:42:04 -06:00
message = "`{Self}` cannot be shared between threads safely",
label = "`{Self}` cannot be shared between threads safely"
)]
pub unsafe auto trait Sync {
// FIXME(estebank): once support to add notes in `rustc_on_unimplemented`
// lands in beta, and it has been extended to check whether a closure is
// anywhere in the requirement chain, extend it as such (#48534):
// ```
// on(
// closure,
// note="`{Self}` cannot be shared safely, consider marking the closure `move`"
// ),
// ```
// Empty
}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> !Sync for *const T {}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> !Sync for *mut T {}
2019-12-22 16:42:04 -06:00
macro_rules! impls {
($t: ident) => {
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> Hash for $t<T> {
2015-02-18 17:58:07 -06:00
#[inline]
2019-12-22 16:42:04 -06:00
fn hash<H: Hasher>(&self, _: &mut H) {}
2015-02-18 17:58:07 -06:00
}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> cmp::PartialEq for $t<T> {
fn eq(&self, _other: &$t<T>) -> bool {
true
}
}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> cmp::Eq for $t<T> {}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> cmp::PartialOrd for $t<T> {
fn partial_cmp(&self, _other: &$t<T>) -> Option<cmp::Ordering> {
Option::Some(cmp::Ordering::Equal)
}
}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> cmp::Ord for $t<T> {
fn cmp(&self, _other: &$t<T>) -> cmp::Ordering {
cmp::Ordering::Equal
}
}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> Copy for $t<T> {}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> Clone for $t<T> {
2020-01-05 22:33:31 -06:00
fn clone(&self) -> Self {
Self
}
}
2015-10-27 08:42:38 -05:00
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> Default for $t<T> {
2020-01-05 22:33:31 -06:00
fn default() -> Self {
Self
2015-10-27 08:42:38 -05:00
}
}
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
#[unstable(feature = "structural_match", issue = "31434")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> StructuralPartialEq for $t<T> {}
Migrate from `#[structural_match]` attribute a lang-item trait. (Or more precisely, a pair of such traits: one for `derive(PartialEq)` and one for `derive(Eq)`.) ((The addition of the second marker trait, `StructuralEq`, is largely a hack to work-around `fn (&T)` not implementing `PartialEq` and `Eq`; see also issue rust-lang/rust#46989; otherwise I would just check if `Eq` is implemented.)) Note: this does not use trait fulfillment error-reporting machinery; it just uses the trait system to determine if the ADT was tagged or not. (Nonetheless, I have kept an `on_unimplemented` message on the new trait for structural_match check, even though it is currently not used.) Note also: this does *not* resolve the ICE from rust-lang/rust#65466, as noted in a comment added in this commit. Further work is necessary to resolve that and other problems with the structural match checking, especially to do so without breaking stable code (adapted from test fn-ptr-is-structurally-matchable.rs): ```rust fn r_sm_to(_: &SM) {} fn main() { const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to); let input: Wrap<fn(&SM)> = Wrap(r_sm_to); match Wrap(input) { Wrap(CFN6) => {} Wrap(_) => {} }; } ``` where we would hit a problem with the strategy of unconditionally checking for `PartialEq` because the type `for <'a> fn(&'a SM)` does not currently even *implement* `PartialEq`. ---- added review feedback: * use an or-pattern * eschew `return` when tail position will do. * don't need fresh_expansion; just add `structural_match` to appropriate `allow_internal_unstable` attributes. also fixed example in doc comment so that it actually compiles.
2019-10-17 03:54:37 -05:00
#[unstable(feature = "structural_match", issue = "31434")]
2019-12-22 16:42:04 -06:00
impl<T: ?Sized> StructuralEq for $t<T> {}
};
}
2016-09-11 17:09:05 -05:00
/// Zero-sized type used to mark things that "act like" they own a `T`.
///
2016-09-11 17:09:05 -05:00
/// Adding a `PhantomData<T>` field to your type tells the compiler that your
/// type acts as though it stores a value of type `T`, even though it doesn't
/// really. This information is used when computing certain safety properties.
///
2016-09-11 17:09:05 -05:00
/// For a more in-depth explanation of how to use `PhantomData<T>`, please see
/// [the Nomicon](../../nomicon/phantom-data.html).
///
/// # A ghastly note 👻👻👻
///
2016-09-11 17:09:05 -05:00
/// Though they both have scary names, `PhantomData` and 'phantom types' are
/// related, but not identical. A phantom type parameter is simply a type
/// parameter which is never used. In Rust, this often causes the compiler to
/// complain, and the solution is to add a "dummy" use by way of `PhantomData`.
///
2015-03-01 22:14:45 -06:00
/// # Examples
///
2016-09-11 17:09:05 -05:00
/// ## Unused lifetime parameters
///
2016-09-11 17:09:05 -05:00
/// Perhaps the most common use case for `PhantomData` is a struct that has an
/// unused lifetime parameter, typically as part of some unsafe code. For
/// example, here is a struct `Slice` that has two pointers of type `*const T`,
/// presumably pointing into an array somewhere:
///
/// ```compile_fail,E0392
/// struct Slice<'a, T> {
/// start: *const T,
/// end: *const T,
/// }
/// ```
///
/// The intention is that the underlying data is only valid for the
/// lifetime `'a`, so `Slice` should not outlive `'a`. However, this
/// intent is not expressed in the code, since there are no uses of
/// the lifetime `'a` and hence it is not clear what data it applies
/// to. We can correct this by telling the compiler to act *as if* the
2016-09-11 17:09:05 -05:00
/// `Slice` struct contained a reference `&'a T`:
///
/// ```
/// use std::marker::PhantomData;
///
2015-11-03 09:27:03 -06:00
/// # #[allow(dead_code)]
/// struct Slice<'a, T: 'a> {
/// start: *const T,
/// end: *const T,
2016-09-11 17:09:05 -05:00
/// phantom: PhantomData<&'a T>,
/// }
/// ```
///
2016-09-11 17:09:05 -05:00
/// This also in turn requires the annotation `T: 'a`, indicating
/// that any references in `T` are valid over the lifetime `'a`.
///
/// When initializing a `Slice` you simply provide the value
/// `PhantomData` for the field `phantom`:
///
/// ```
/// # #![allow(dead_code)]
/// # use std::marker::PhantomData;
/// # struct Slice<'a, T: 'a> {
/// # start: *const T,
/// # end: *const T,
/// # phantom: PhantomData<&'a T>,
/// # }
2019-06-25 12:43:18 -05:00
/// fn borrow_vec<T>(vec: &Vec<T>) -> Slice<'_, T> {
2016-09-11 17:09:05 -05:00
/// let ptr = vec.as_ptr();
/// Slice {
/// start: ptr,
/// end: unsafe { ptr.add(vec.len()) },
2016-09-11 17:09:05 -05:00
/// phantom: PhantomData,
/// }
/// }
/// ```
///
/// ## Unused type parameters
///
2016-09-11 17:09:05 -05:00
/// It sometimes happens that you have unused type parameters which
/// indicate what type of data a struct is "tied" to, even though that
/// data is not actually found in the struct itself. Here is an
2016-09-11 17:09:05 -05:00
/// example where this arises with [FFI]. The foreign interface uses
/// handles of type `*mut ()` to refer to Rust values of different
/// types. We track the Rust type using a phantom type parameter on
/// the struct `ExternalResource` which wraps a handle.
///
/// [FFI]: ../../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code
2015-03-01 22:14:45 -06:00
///
/// ```
2015-11-03 09:27:03 -06:00
/// # #![allow(dead_code)]
2016-09-11 17:09:05 -05:00
/// # trait ResType { }
2015-03-01 22:14:45 -06:00
/// # struct ParamType;
/// # mod foreign_lib {
2016-09-11 17:09:05 -05:00
/// # pub fn new(_: usize) -> *mut () { 42 as *mut () }
/// # pub fn do_stuff(_: *mut (), _: usize) {}
2015-03-01 22:14:45 -06:00
/// # }
/// # fn convert_params(_: ParamType) -> usize { 42 }
/// use std::marker::PhantomData;
/// use std::mem;
///
/// struct ExternalResource<R> {
/// resource_handle: *mut (),
/// resource_type: PhantomData<R>,
/// }
///
/// impl<R: ResType> ExternalResource<R> {
/// fn new() -> Self {
2015-03-01 22:14:45 -06:00
/// let size_of_res = mem::size_of::<R>();
/// Self {
2015-03-01 22:14:45 -06:00
/// resource_handle: foreign_lib::new(size_of_res),
/// resource_type: PhantomData,
/// }
/// }
///
/// fn do_stuff(&self, param: ParamType) {
/// let foreign_params = convert_params(param);
/// foreign_lib::do_stuff(self.resource_handle, foreign_params);
/// }
/// }
/// ```
///
2016-09-11 17:09:05 -05:00
/// ## Ownership and the drop check
///
2016-09-11 17:09:05 -05:00
/// Adding a field of type `PhantomData<T>` indicates that your
/// type owns data of type `T`. This in turn implies that when your
/// type is dropped, it may drop one or more instances of the type
/// `T`. This has bearing on the Rust compiler's [drop check]
/// analysis.
///
/// If your struct does not in fact *own* the data of type `T`, it is
/// better to use a reference type, like `PhantomData<&'a T>`
/// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so
/// as not to indicate ownership.
2016-09-11 17:09:05 -05:00
///
/// [drop check]: ../../nomicon/dropck.html
#[lang = "phantom_data"]
#[stable(feature = "rust1", since = "1.0.0")]
2019-12-22 16:42:04 -06:00
pub struct PhantomData<T: ?Sized>;
impls! { PhantomData }
mod impls {
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: Sync + ?Sized> Send for &T {}
2015-11-16 10:54:28 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: Send + ?Sized> Send for &mut T {}
}
/// Compiler-internal trait used to indicate the type of enum discriminants.
///
/// This trait is automatically implemented for every type and does not add any
/// guarantees to [`mem::Discriminant`]. It is **undefined behavior** to transmute
/// between `DiscriminantKind::Discriminant` and `mem::Discriminant`.
///
2020-09-02 17:22:40 -05:00
/// [`mem::Discriminant`]: crate::mem::Discriminant
#[unstable(
feature = "discriminant_kind",
issue = "none",
reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead"
)]
2020-06-03 14:15:53 -05:00
#[lang = "discriminant_kind"]
pub trait DiscriminantKind {
2020-07-03 10:21:20 -05:00
/// The type of the discriminant, which must satisfy the trait
/// bounds required by `mem::Discriminant`.
2020-08-26 03:17:31 -05:00
#[lang = "discriminant_type"]
type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin;
}
/// Compiler-internal trait used to determine whether a type contains
/// any `UnsafeCell` internally, but not through an indirection.
/// This affects, for example, whether a `static` of that type is
/// placed in read-only static memory or writable static memory.
#[lang = "freeze"]
pub(crate) unsafe auto trait Freeze {}
impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
unsafe impl<T: ?Sized> Freeze for PhantomData<T> {}
unsafe impl<T: ?Sized> Freeze for *const T {}
unsafe impl<T: ?Sized> Freeze for *mut T {}
unsafe impl<T: ?Sized> Freeze for &T {}
unsafe impl<T: ?Sized> Freeze for &mut T {}
2018-03-14 17:57:25 -05:00
/// Types that can be safely moved after being pinned.
2018-03-14 17:57:25 -05:00
///
/// Rust itself has no notion of immovable types, and considers moves (e.g.,
/// through assignment or [`mem::replace`]) to always be safe.
2018-08-06 15:52:15 -05:00
///
/// The [`Pin`][Pin] type is used instead to prevent moves through the type
/// system. Pointers `P<T>` wrapped in the [`Pin<P<T>>`][Pin] wrapper can't be
2020-09-02 17:22:40 -05:00
/// moved out of. See the [`pin` module] documentation for more information on
/// pinning.
2018-03-14 17:57:25 -05:00
///
/// Implementing the `Unpin` trait for `T` lifts the restrictions of pinning off
/// the type, which then allows moving `T` out of [`Pin<P<T>>`][Pin] with
/// functions such as [`mem::replace`].
2019-02-19 06:08:46 -06:00
///
/// `Unpin` has no consequence at all for non-pinned data. In particular,
2019-02-19 13:50:16 -06:00
/// [`mem::replace`] happily moves `!Unpin` data (it works for any `&mut T`, not
/// just when `T: Unpin`). However, you cannot use [`mem::replace`] on data
/// wrapped inside a [`Pin<P<T>>`][Pin] because you cannot get the `&mut T` you
/// need for that, and *that* is what makes this system work.
2018-08-16 05:56:08 -05:00
///
/// So this, for example, can only be done on types implementing `Unpin`:
///
/// ```rust
2020-04-17 15:59:14 -05:00
/// # #![allow(unused_must_use)]
2019-02-19 14:27:48 -06:00
/// use std::mem;
2018-08-31 23:12:10 -05:00
/// use std::pin::Pin;
2018-08-16 05:56:08 -05:00
///
/// let mut string = "this".to_string();
2018-08-31 23:12:10 -05:00
/// let mut pinned_string = Pin::new(&mut string);
2018-08-17 14:28:05 -05:00
///
2019-02-19 14:27:48 -06:00
/// // We need a mutable reference to call `mem::replace`.
/// // We can obtain such a reference by (implicitly) invoking `Pin::deref_mut`,
/// // but that is only possible because `String` implements `Unpin`.
/// mem::replace(&mut *pinned_string, "other".to_string());
2018-08-16 05:56:08 -05:00
/// ```
2018-03-14 17:57:25 -05:00
///
/// This trait is automatically implemented for almost every type.
2018-04-29 12:15:40 -05:00
///
2020-09-02 17:22:40 -05:00
/// [`mem::replace`]: crate::mem::replace
/// [Pin]: crate::pin::Pin
2020-09-02 17:22:40 -05:00
/// [`pin` module]: crate::pin
2018-12-17 20:14:07 -06:00
#[stable(feature = "pin", since = "1.33.0")]
#[rustc_on_unimplemented(
note = "consider using `Box::pin`",
message = "`{Self}` cannot be unpinned"
)]
#[lang = "unpin"]
2018-05-22 19:09:49 -05:00
pub auto trait Unpin {}
Move some implementations of Clone and Copy to libcore Add implementations of `Clone` and `Copy` for some primitive types to libcore so that they show up in the documentation. The concerned types are the following: * All primitive signed and unsigned integer types (`usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`); * All primitive floating point types (`f32`, `f64`) * `bool` * `char` * `!` * Raw pointers (`*const T` and `*mut T`) * Shared references (`&'a T`) These types already implemented `Clone` and `Copy`, but the implementation was provided by the compiler. The compiler no longer provides these implementations and instead tries to look them up as normal trait implementations. The goal of this change is to make the implementations appear in the generated documentation. For `Copy` specifically, the compiler would reject an attempt to write an `impl` for the primitive types listed above with error `E0206`; this error no longer occurs for these types, but it will still occur for the other types that used to raise that error. The trait implementations are guarded with `#[cfg(not(stage0))]` because they are invalid according to the stage0 compiler. When the stage0 compiler is updated to a revision that includes this change, the attribute will have to be removed, otherwise the stage0 build will fail because the types mentioned above no longer implement `Clone` or `Copy`. For type variants that are variadic, such as tuples and function pointers, and for array types, the `Clone` and `Copy` implementations are still provided by the compiler, because the language is not expressive enough yet to be able to write the appropriate implementations in Rust. The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to make them apply only when generating documentation, without having to touch the compiler. However, rustdoc's usage of the compiler still rejected those `impl` blocks. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own implementations of `Clone` and `Copy` for the primitive types listed above. The easiest way to do that is to simply copy the implementations from `src/libcore/clone.rs` and `src/libcore/marker.rs`. Fixes #25893
2018-02-12 00:17:32 -06:00
/// A marker type which does not implement `Unpin`.
///
/// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default.
2018-12-17 20:14:07 -06:00
#[stable(feature = "pin", since = "1.33.0")]
2020-10-13 03:26:35 -05:00
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct PhantomPinned;
2018-12-17 20:14:07 -06:00
#[stable(feature = "pin", since = "1.33.0")]
impl !Unpin for PhantomPinned {}
2018-12-17 20:14:07 -06:00
#[stable(feature = "pin", since = "1.33.0")]
impl<'a, T: ?Sized + 'a> Unpin for &'a T {}
2018-12-17 20:14:07 -06:00
#[stable(feature = "pin", since = "1.33.0")]
impl<'a, T: ?Sized + 'a> Unpin for &'a mut T {}
#[stable(feature = "pin_raw", since = "1.38.0")]
impl<T: ?Sized> Unpin for *const T {}
#[stable(feature = "pin_raw", since = "1.38.0")]
impl<T: ?Sized> Unpin for *mut T {}
Move some implementations of Clone and Copy to libcore Add implementations of `Clone` and `Copy` for some primitive types to libcore so that they show up in the documentation. The concerned types are the following: * All primitive signed and unsigned integer types (`usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`); * All primitive floating point types (`f32`, `f64`) * `bool` * `char` * `!` * Raw pointers (`*const T` and `*mut T`) * Shared references (`&'a T`) These types already implemented `Clone` and `Copy`, but the implementation was provided by the compiler. The compiler no longer provides these implementations and instead tries to look them up as normal trait implementations. The goal of this change is to make the implementations appear in the generated documentation. For `Copy` specifically, the compiler would reject an attempt to write an `impl` for the primitive types listed above with error `E0206`; this error no longer occurs for these types, but it will still occur for the other types that used to raise that error. The trait implementations are guarded with `#[cfg(not(stage0))]` because they are invalid according to the stage0 compiler. When the stage0 compiler is updated to a revision that includes this change, the attribute will have to be removed, otherwise the stage0 build will fail because the types mentioned above no longer implement `Clone` or `Copy`. For type variants that are variadic, such as tuples and function pointers, and for array types, the `Clone` and `Copy` implementations are still provided by the compiler, because the language is not expressive enough yet to be able to write the appropriate implementations in Rust. The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to make them apply only when generating documentation, without having to touch the compiler. However, rustdoc's usage of the compiler still rejected those `impl` blocks. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own implementations of `Clone` and `Copy` for the primitive types listed above. The easiest way to do that is to simply copy the implementations from `src/libcore/clone.rs` and `src/libcore/marker.rs`. Fixes #25893
2018-02-12 00:17:32 -06:00
/// Implementations of `Copy` for primitive types.
///
/// Implementations that cannot be described in Rust
/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
/// in `rustc_trait_selection`.
Move some implementations of Clone and Copy to libcore Add implementations of `Clone` and `Copy` for some primitive types to libcore so that they show up in the documentation. The concerned types are the following: * All primitive signed and unsigned integer types (`usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`); * All primitive floating point types (`f32`, `f64`) * `bool` * `char` * `!` * Raw pointers (`*const T` and `*mut T`) * Shared references (`&'a T`) These types already implemented `Clone` and `Copy`, but the implementation was provided by the compiler. The compiler no longer provides these implementations and instead tries to look them up as normal trait implementations. The goal of this change is to make the implementations appear in the generated documentation. For `Copy` specifically, the compiler would reject an attempt to write an `impl` for the primitive types listed above with error `E0206`; this error no longer occurs for these types, but it will still occur for the other types that used to raise that error. The trait implementations are guarded with `#[cfg(not(stage0))]` because they are invalid according to the stage0 compiler. When the stage0 compiler is updated to a revision that includes this change, the attribute will have to be removed, otherwise the stage0 build will fail because the types mentioned above no longer implement `Clone` or `Copy`. For type variants that are variadic, such as tuples and function pointers, and for array types, the `Clone` and `Copy` implementations are still provided by the compiler, because the language is not expressive enough yet to be able to write the appropriate implementations in Rust. The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to make them apply only when generating documentation, without having to touch the compiler. However, rustdoc's usage of the compiler still rejected those `impl` blocks. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own implementations of `Clone` and `Copy` for the primitive types listed above. The easiest way to do that is to simply copy the implementations from `src/libcore/clone.rs` and `src/libcore/marker.rs`. Fixes #25893
2018-02-12 00:17:32 -06:00
mod copy_impls {
use super::Copy;
macro_rules! impl_copy {
($($t:ty)*) => {
$(
#[stable(feature = "rust1", since = "1.0.0")]
impl Copy for $t {}
)*
}
}
impl_copy! {
usize u8 u16 u32 u64 u128
isize i8 i16 i32 i64 i128
f32 f64
bool char
}
#[unstable(feature = "never_type", issue = "35121")]
Move some implementations of Clone and Copy to libcore Add implementations of `Clone` and `Copy` for some primitive types to libcore so that they show up in the documentation. The concerned types are the following: * All primitive signed and unsigned integer types (`usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`); * All primitive floating point types (`f32`, `f64`) * `bool` * `char` * `!` * Raw pointers (`*const T` and `*mut T`) * Shared references (`&'a T`) These types already implemented `Clone` and `Copy`, but the implementation was provided by the compiler. The compiler no longer provides these implementations and instead tries to look them up as normal trait implementations. The goal of this change is to make the implementations appear in the generated documentation. For `Copy` specifically, the compiler would reject an attempt to write an `impl` for the primitive types listed above with error `E0206`; this error no longer occurs for these types, but it will still occur for the other types that used to raise that error. The trait implementations are guarded with `#[cfg(not(stage0))]` because they are invalid according to the stage0 compiler. When the stage0 compiler is updated to a revision that includes this change, the attribute will have to be removed, otherwise the stage0 build will fail because the types mentioned above no longer implement `Clone` or `Copy`. For type variants that are variadic, such as tuples and function pointers, and for array types, the `Clone` and `Copy` implementations are still provided by the compiler, because the language is not expressive enough yet to be able to write the appropriate implementations in Rust. The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to make them apply only when generating documentation, without having to touch the compiler. However, rustdoc's usage of the compiler still rejected those `impl` blocks. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own implementations of `Clone` and `Copy` for the primitive types listed above. The easiest way to do that is to simply copy the implementations from `src/libcore/clone.rs` and `src/libcore/marker.rs`. Fixes #25893
2018-02-12 00:17:32 -06:00
impl Copy for ! {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Copy for *const T {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Copy for *mut T {}
2020-03-13 13:33:37 -05:00
/// Shared references can be copied, but mutable references *cannot*!
Move some implementations of Clone and Copy to libcore Add implementations of `Clone` and `Copy` for some primitive types to libcore so that they show up in the documentation. The concerned types are the following: * All primitive signed and unsigned integer types (`usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`); * All primitive floating point types (`f32`, `f64`) * `bool` * `char` * `!` * Raw pointers (`*const T` and `*mut T`) * Shared references (`&'a T`) These types already implemented `Clone` and `Copy`, but the implementation was provided by the compiler. The compiler no longer provides these implementations and instead tries to look them up as normal trait implementations. The goal of this change is to make the implementations appear in the generated documentation. For `Copy` specifically, the compiler would reject an attempt to write an `impl` for the primitive types listed above with error `E0206`; this error no longer occurs for these types, but it will still occur for the other types that used to raise that error. The trait implementations are guarded with `#[cfg(not(stage0))]` because they are invalid according to the stage0 compiler. When the stage0 compiler is updated to a revision that includes this change, the attribute will have to be removed, otherwise the stage0 build will fail because the types mentioned above no longer implement `Clone` or `Copy`. For type variants that are variadic, such as tuples and function pointers, and for array types, the `Clone` and `Copy` implementations are still provided by the compiler, because the language is not expressive enough yet to be able to write the appropriate implementations in Rust. The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to make them apply only when generating documentation, without having to touch the compiler. However, rustdoc's usage of the compiler still rejected those `impl` blocks. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own implementations of `Clone` and `Copy` for the primitive types listed above. The easiest way to do that is to simply copy the implementations from `src/libcore/clone.rs` and `src/libcore/marker.rs`. Fixes #25893
2018-02-12 00:17:32 -06:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Copy for &T {}
Move some implementations of Clone and Copy to libcore Add implementations of `Clone` and `Copy` for some primitive types to libcore so that they show up in the documentation. The concerned types are the following: * All primitive signed and unsigned integer types (`usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`); * All primitive floating point types (`f32`, `f64`) * `bool` * `char` * `!` * Raw pointers (`*const T` and `*mut T`) * Shared references (`&'a T`) These types already implemented `Clone` and `Copy`, but the implementation was provided by the compiler. The compiler no longer provides these implementations and instead tries to look them up as normal trait implementations. The goal of this change is to make the implementations appear in the generated documentation. For `Copy` specifically, the compiler would reject an attempt to write an `impl` for the primitive types listed above with error `E0206`; this error no longer occurs for these types, but it will still occur for the other types that used to raise that error. The trait implementations are guarded with `#[cfg(not(stage0))]` because they are invalid according to the stage0 compiler. When the stage0 compiler is updated to a revision that includes this change, the attribute will have to be removed, otherwise the stage0 build will fail because the types mentioned above no longer implement `Clone` or `Copy`. For type variants that are variadic, such as tuples and function pointers, and for array types, the `Clone` and `Copy` implementations are still provided by the compiler, because the language is not expressive enough yet to be able to write the appropriate implementations in Rust. The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to make them apply only when generating documentation, without having to touch the compiler. However, rustdoc's usage of the compiler still rejected those `impl` blocks. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own implementations of `Clone` and `Copy` for the primitive types listed above. The easiest way to do that is to simply copy the implementations from `src/libcore/clone.rs` and `src/libcore/marker.rs`. Fixes #25893
2018-02-12 00:17:32 -06:00
}