@@ -282,11 +282,65 @@ macro_rules! impls{
282
282
pub trait MarkerTrait : PhantomFn < Self > { }
283
283
impl < T : ?Sized > MarkerTrait for T { }
284
284
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
+ /// ```
287
302
///
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
289
342
#[ lang="phantom_fn" ]
343
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
290
344
pub trait PhantomFn < A : ?Sized , R : ?Sized =( ) > { }
291
345
292
346
#[ 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 { }
298
352
pub struct PhantomData < T : ?Sized > ;
299
353
300
354
/// `PhantomData` is a way to tell the compiler about fake fields.
355
+ /// Phantom data is required whenever type parameters are not used.
301
356
/// The idea is that if the compiler encounters a `PhantomData<T>`
302
357
/// instance, it will behave *as if* an instance of the type `T` were
303
358
/// present for the purpose of various automatic analyses.
304
359
///
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
306
372
#[ cfg( not( stage0) ) ]
307
373
#[ lang="phantom_data" ]
374
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
308
375
pub struct PhantomData < T : ?Sized > ;
309
376
310
377
impls ! { PhantomData }
311
378
312
-
313
379
#[ cfg( not( stage0) ) ]
314
380
mod impls {
315
381
use super :: { Send , Sync , Sized } ;
0 commit comments