@@ -356,8 +356,48 @@ pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
356
356
///
357
357
/// # Examples
358
358
///
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:
361
401
///
362
402
/// ```
363
403
/// # trait ResType { fn foo(&self); };
@@ -391,13 +431,21 @@ pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
391
431
/// }
392
432
/// ```
393
433
///
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.
401
449
#[ lang="phantom_data" ]
402
450
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
403
451
pub struct PhantomData < T : ?Sized > ;
0 commit comments