Skip to content

Commit a2393e6

Browse files
committed
WIP -- improve documentation on the phantom traits
1 parent e8cb11c commit a2393e6

File tree

1 file changed

+71
-5
lines changed

1 file changed

+71
-5
lines changed

src/libcore/marker.rs

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,65 @@ macro_rules! impls{
282282
pub trait MarkerTrait : PhantomFn<Self> { }
283283
impl<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")]
290344
pub 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 { }
298352
pub 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")]
308375
pub struct PhantomData<T:?Sized>;
309376

310377
impls! { PhantomData }
311378

312-
313379
#[cfg(not(stage0))]
314380
mod impls {
315381
use super::{Send, Sync, Sized};

0 commit comments

Comments
 (0)