@@ -282,11 +282,65 @@ macro_rules! impls{
282282pub trait MarkerTrait : PhantomFn < Self > { }
283283impl < T : ?Sized > MarkerTrait for T { }
284284
285- /// `PhantomFn` is a marker trait for use with traits that do not
286- /// include any methods.
285+ /// `PhantomFn` is a marker trait for use with traits that contain
286+ /// type or lifetime parameters that do not appear in any of their
287+ /// methods. In that case, you can either remove those parameters, or
288+ /// add a `PhantomFn` supertrait that reflects the signature of
289+ /// methods that compiler should "pretend" exists. This most commonly
290+ /// occurs for traits with no methods: in that particular case, you
291+ /// can extend `MarkerTrait`, which is equivalent to
292+ /// `PhantomFn<Self>`.
293+ ///
294+ /// # Example
295+ ///
296+ /// As an example, consider a trait with no methods like `Even`, meant
297+ /// to represent types that are "even":
298+ ///
299+ /// ```rust
300+ /// trait Even { }
301+ /// ```
287302///
288- /// FIXME. Better documentation needed here!
303+ /// In this case, because the implicit parameter `Self` is unused, the
304+ /// compiler will issue an error. The only purpose of this trait is to
305+ /// categorize types (and hence instances of those types) as "even" or
306+ /// not, so if we *were* going to have a method, it might look like:
307+ ///
308+ /// ```rust
309+ /// trait Even {
310+ /// fn is_even(self) -> bool { true }
311+ /// }
312+ /// ```
313+ ///
314+ /// Therefore, we can model a method like this as follows:
315+ ///
316+ /// ```rust
317+ /// use std::marker::PhantomFn
318+ /// trait Even : PhantomFn<Self> { }
319+ /// ```
320+ ///
321+ /// Another equivalent, but clearer, option would be to use
322+ /// `MarkerTrait`:
323+ ///
324+ /// ```rust
325+ /// use std::marker::MarkerTrait;
326+ /// trait Even : MarkerTrait { }
327+ /// ```
328+ ///
329+ /// # Parameters
330+ ///
331+ /// - `A` represents the type of the method's argument. You can use a
332+ /// tuple to represent "multiple" arguments. Any types appearing here
333+ /// will be considered "contravariant".
334+ /// - `R`, if supplied, represents the method's return type. This defaults
335+ /// to `()` as it is rarely needed.
336+ ///
337+ /// # Additional reading
338+ ///
339+ /// More details and background can be found in [RFC 738][738].
340+ ///
341+ /// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md
289342#[ lang="phantom_fn" ]
343+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
290344pub trait PhantomFn < A : ?Sized , R : ?Sized =( ) > { }
291345
292346#[ 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 { }
298352pub struct PhantomData < T : ?Sized > ;
299353
300354/// `PhantomData` is a way to tell the compiler about fake fields.
355+ /// Phantom data is required whenever type parameters are not used.
301356/// The idea is that if the compiler encounters a `PhantomData<T>`
302357/// instance, it will behave *as if* an instance of the type `T` were
303358/// present for the purpose of various automatic analyses.
304359///
305- /// FIXME. Better documentation needed here!
360+ /// For example, embedding a `PhantomData<T>` will inform the compiler
361+ /// that one or more instances of the type `T` could be dropped when
362+ /// instances of the type itself is dropped, though that may not be
363+ /// apparent from the other structure of the type itself. This is
364+ /// commonly necessary if the structure is using an unsafe pointer
365+ /// like `*mut T` whose referent may be dropped when the type is
366+ /// dropped, as a `*mut T` is otherwise not treated as owned.
367+ ///
368+ /// FIXME. Better documentation and examples of common patterns needed
369+ /// here! For now, please see [RFC 738][738] for more information.
370+ ///
371+ /// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md
306372#[ cfg( not( stage0) ) ]
307373#[ lang="phantom_data" ]
374+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
308375pub struct PhantomData < T : ?Sized > ;
309376
310377impls ! { PhantomData }
311378
312-
313379#[ cfg( not( stage0) ) ]
314380mod impls {
315381 use super :: { Send , Sync , Sized } ;
0 commit comments