@@ -316,8 +316,49 @@ impl<A:?Sized,R:?Sized,T:?Sized> PhantomFn<A,R> for T { }
316
316
///
317
317
/// # Examples
318
318
///
319
- /// When handling external resources over a foreign function interface, `PhantomData<T>` can
320
- /// prevent mismatches by enforcing types in the method implementations:
319
+ /// ## Unused lifetime parameter
320
+ ///
321
+ /// Perhaps the most common time that `PhantomData` is required is
322
+ /// with a struct that has an unused lifetime parameter, typically as
323
+ /// part of some unsafe code. For example, here is a struct `Slice`
324
+ /// that has two pointers of type `*const T`, presumably pointing into
325
+ /// an array somewhere:
326
+ ///
327
+ /// ```ignore
328
+ /// struct Slice<'a, T> {
329
+ /// start: *const T,
330
+ /// end: *const T,
331
+ /// }
332
+ /// ```
333
+ ///
334
+ /// The intention is that the underlying data is only valid for the
335
+ /// lifetime `'a`, so `Slice` should not outlive `'a`. However, this
336
+ /// intent is not expressed in the code, since there are no uses of
337
+ /// the lifetime `'a` and hence it is not clear what data it applies
338
+ /// to. We can correct this by telling the compiler to act *as if* the
339
+ /// `Slice` struct contained a borrowed reference `&'a T`:
340
+ ///
341
+ /// ```
342
+ /// use std::marker::PhantomData;
343
+ ///
344
+ /// struct Slice<'a, T:'a> {
345
+ /// start: *const T,
346
+ /// end: *const T,
347
+ /// phantom: PhantomData<&'a T>
348
+ /// }
349
+ /// ```
350
+ ///
351
+ /// This also in turn requires that we annotate `T:'a`, indicating
352
+ /// that `T` is a type that can be borrowed for the lifetime `'a`.
353
+ ///
354
+ /// ## Unused type parameters
355
+ ///
356
+ /// It sometimes happens that there are unused type parameters that
357
+ /// indicate what type of data a struct is "tied" to, even though that
358
+ /// data is not actually found in the struct itself. Here is an
359
+ /// example where this arises when handling external resources over a
360
+ /// foreign function interface. `PhantomData<T>` can prevent
361
+ /// mismatches by enforcing types in the method implementations:
321
362
///
322
363
/// ```
323
364
/// # trait ResType { fn foo(&self); };
@@ -351,13 +392,21 @@ impl<A:?Sized,R:?Sized,T:?Sized> PhantomFn<A,R> for T { }
351
392
/// }
352
393
/// ```
353
394
///
354
- /// Another example: embedding a `PhantomData<T>` will inform the compiler
355
- /// that one or more instances of the type `T` could be dropped when
356
- /// instances of the type itself is dropped, though that may not be
357
- /// apparent from the other structure of the type itself. This is
358
- /// commonly necessary if the structure is using an unsafe pointer
359
- /// like `*mut T` whose referent may be dropped when the type is
360
- /// dropped, as a `*mut T` is otherwise not treated as owned.
395
+ /// ## Indicating ownership
396
+ ///
397
+ /// Adding a field of type `PhantomData<T>` also indicates that your
398
+ /// struct owns data of type `T`. This in turn implies that when your
399
+ /// struct is dropped, it may in turn drop one or more instances of
400
+ /// the type `T`, though that may not be apparent from the other
401
+ /// structure of the type itself. This is commonly necessary if the
402
+ /// structure is using an unsafe pointer like `*mut T` whose referent
403
+ /// may be dropped when the type is dropped, as a `*mut T` is
404
+ /// otherwise not treated as owned.
405
+ ///
406
+ /// If your struct does not in fact *own* the data of type `T`, it is
407
+ /// better to use a reference type, like `PhantomData<&'a T>`
408
+ /// (ideally) or `PhantomData<*const T>` (if no lifetime applies), so
409
+ /// as not to indicate ownership.
361
410
#[ lang="phantom_data" ]
362
411
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
363
412
pub struct PhantomData < T : ?Sized > ;
0 commit comments