@@ -356,8 +356,48 @@ pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
356356///
357357/// # Examples
358358///
359- /// When handling external resources over a foreign function interface, `PhantomData<T>` can
360- /// prevent mismatches by enforcing types in the method implementations:
359+ /// ## Unused lifetime parameter
360+ ///
361+ /// Perhaps the most common time that `PhantomData` is required is
362+ /// with a struct that has an unused lifetime parameter, typically as
363+ /// part of some unsafe code. For example, here is a struct `Slice`
364+ /// that has two pointers of type `*mut T`, presumably pointing into
365+ /// an array somewhere:
366+ ///
367+ /// ```
368+ /// struct Slice<'a, T> {
369+ /// start: *mut T,
370+ /// end: *mut T,
371+ /// }
372+ /// ```
373+ ///
374+ /// The intention is that the underlying data is only valid for the
375+ /// lifetime `'a`, so `Slice` should not outlive `'a`. However, this
376+ /// intent is not expressed in the code, since there are no uses of
377+ /// the lifetime `'a` and hence it is not clear what data it applies
378+ /// to. We can correct this by telling the compiler to act *as if* the
379+ /// `Slice` struct contained a borrowed reference `&'a T`:
380+ ///
381+ /// ```
382+ /// # use std::marker::PhantomData;
383+ /// struct Slice<'a, T:'a> {
384+ /// start: *mut T,
385+ /// end: *mut T,
386+ /// phantom: PhantomData<&'a T>
387+ /// }
388+ /// ```
389+ ///
390+ /// This also in turn requires that we annotate `T:'a`, indicating
391+ /// that `T` is a type that can be borrowed for the lifetime `'a`.
392+ ///
393+ /// ## Unused type parameters
394+ ///
395+ /// It sometimes happens that there are unused type parameters that
396+ /// indicate what type of data a struct is "tied" to, even though that
397+ /// data is not actually found in the struct itself. Here is an
398+ /// example where this arises when handling external resources over a
399+ /// foreign function interface. `PhantomData<T>` can prevent
400+ /// mismatches by enforcing types in the method implementations:
361401///
362402/// ```
363403/// # trait ResType { fn foo(&self); };
@@ -391,13 +431,21 @@ pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
391431/// }
392432/// ```
393433///
394- /// Another example: embedding a `PhantomData<T>` will inform the compiler
395- /// that one or more instances of the type `T` could be dropped when
396- /// instances of the type itself is dropped, though that may not be
397- /// apparent from the other structure of the type itself. This is
398- /// commonly necessary if the structure is using an unsafe pointer
399- /// like `*mut T` whose referent may be dropped when the type is
400- /// dropped, as a `*mut T` is otherwise not treated as owned.
434+ /// ## Indicating ownership
435+ ///
436+ /// Adding a field of type `PhantomData<T>` also indicates that your
437+ /// struct owns data of type `T` and hence may drop one or more
438+ /// instances of the type `T` could be dropped when instances of the
439+ /// type itself is dropped, though that may not be apparent from the
440+ /// other structure of the type itself. This is commonly necessary if
441+ /// the structure is using an unsafe pointer like `*mut T` whose
442+ /// referent may be dropped when the type is dropped, as a `*mut T` is
443+ /// otherwise not treated as owned.
444+ ///
445+ /// If your struct does not in fact *own* the data of type `T`, it is
446+ /// better to use a reference type, like `PhantomData<&'a T>`
447+ /// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so
448+ /// as not to indicate ownership.
401449#[ lang="phantom_data" ]
402450#[ stable( feature = "rust1" , since = "1.0.0" ) ]
403451pub struct PhantomData < T : ?Sized > ;
0 commit comments