diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-02-18 16:38:39 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-02-18 16:38:39 -0500 |
| commit | a2393e665d484b088773dea58e9f4fa92e8871a7 (patch) | |
| tree | 9aeea9d1d7e6101f116b69c8472c67b4baff373c | |
| parent | e8cb11c7e39d896a6d361e86470cf3dcae8856a9 (diff) | |
| download | rust-a2393e665d484b088773dea58e9f4fa92e8871a7.tar.gz rust-a2393e665d484b088773dea58e9f4fa92e8871a7.zip | |
WIP -- improve documentation on the phantom traits
| -rw-r--r-- | src/libcore/marker.rs | 76 |
1 files changed, 71 insertions, 5 deletions
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 5c7ec423e7c..0e217f6d574 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -282,11 +282,65 @@ macro_rules! impls{ pub trait MarkerTrait : PhantomFn<Self> { } impl<T:?Sized> MarkerTrait for T { } -/// `PhantomFn` is a marker trait for use with traits that do not -/// include any methods. +/// `PhantomFn` is a marker trait for use with traits that contain +/// type or lifetime parameters that do not appear in any of their +/// methods. In that case, you can either remove those parameters, or +/// add a `PhantomFn` supertrait that reflects the signature of +/// methods that compiler should "pretend" exists. This most commonly +/// occurs for traits with no methods: in that particular case, you +/// can extend `MarkerTrait`, which is equivalent to +/// `PhantomFn<Self>`. +/// +/// # Example +/// +/// As an example, consider a trait with no methods like `Even`, meant +/// to represent types that are "even": +/// +/// ```rust +/// trait Even { } +/// ``` /// -/// FIXME. Better documentation needed here! +/// In this case, because the implicit parameter `Self` is unused, the +/// compiler will issue an error. The only purpose of this trait is to +/// categorize types (and hence instances of those types) as "even" or +/// not, so if we *were* going to have a method, it might look like: +/// +/// ```rust +/// trait Even { +/// fn is_even(self) -> bool { true } +/// } +/// ``` +/// +/// Therefore, we can model a method like this as follows: +/// +/// ```rust +/// use std::marker::PhantomFn +/// trait Even : PhantomFn<Self> { } +/// ``` +/// +/// Another equivalent, but clearer, option would be to use +/// `MarkerTrait`: +/// +/// ```rust +/// use std::marker::MarkerTrait; +/// trait Even : MarkerTrait { } +/// ``` +/// +/// # Parameters +/// +/// - `A` represents the type of the method's argument. You can use a +/// tuple to represent "multiple" arguments. Any types appearing here +/// will be considered "contravariant". +/// - `R`, if supplied, represents the method's return type. This defaults +/// to `()` as it is rarely needed. +/// +/// # Additional reading +/// +/// More details and background can be found in [RFC 738][738]. +/// +/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md #[lang="phantom_fn"] +#[stable(feature = "rust1", since = "1.0.0")] pub trait PhantomFn<A:?Sized,R:?Sized=()> { } #[cfg(stage0)] // built into the trait matching system after stage0 @@ -298,18 +352,30 @@ impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { } pub struct PhantomData<T:?Sized>; /// `PhantomData` is a way to tell the compiler about fake fields. +/// Phantom data is required whenever type parameters are not used. /// The idea is that if the compiler encounters a `PhantomData<T>` /// instance, it will behave *as if* an instance of the type `T` were /// present for the purpose of various automatic analyses. /// -/// FIXME. Better documentation needed here! +/// For example, embedding a `PhantomData<T>` will inform the compiler +/// that one or more instances of the type `T` could be dropped when +/// instances of the type itself is dropped, though that may not be +/// apparent from the other structure of the type itself. This is +/// commonly necessary if the structure is using an unsafe pointer +/// like `*mut T` whose referent may be dropped when the type is +/// dropped, as a `*mut T` is otherwise not treated as owned. +/// +/// FIXME. Better documentation and examples of common patterns needed +/// here! For now, please see [RFC 738][738] for more information. +/// +/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md #[cfg(not(stage0))] #[lang="phantom_data"] +#[stable(feature = "rust1", since = "1.0.0")] pub struct PhantomData<T:?Sized>; impls! { PhantomData } - #[cfg(not(stage0))] mod impls { use super::{Send, Sync, Sized}; |
