Struct std::marker::PhantomData [] [src]

pub struct PhantomData<T> where T: ?Sized;

PhantomData<T>`PhantomDataallows you to describe that a type acts as if it stores a value of type` allows you to describe that a type acts as if it stores a value of type T`T`, even though it does not. This allows you to inform the compiler about certain safety properties of your code.

Though they both have scary names, PhantomData<T>`PhantomData` and "phantom types" are unrelated. 👻👻👻

Examples

Unused lifetime parameter

Perhaps the most common time that PhantomData`PhantomDatais required is with a struct that has an unused lifetime parameter, typically as part of some unsafe code. For example, here is a struct` is required is with a struct that has an unused lifetime parameter, typically as part of some unsafe code. For example, here is a struct Slice`Slicethat has two pointers of type` that has two pointers of type *const T`*const T`, presumably pointing into an array somewhere:

fn main() { struct Slice<'a, T> { start: *const T, end: *const T, } }
struct Slice<'a, T> {
    start: *const T,
    end: *const T,
}

The intention is that the underlying data is only valid for the lifetime 'a`'a, so`, so Slice`Sliceshould not outlive` should not outlive 'a`'a. However, this intent is not expressed in the code, since there are no uses of the lifetime`. However, this intent is not expressed in the code, since there are no uses of the lifetime 'a`'aand hence it is not clear what data it applies to. We can correct this by telling the compiler to act *as if* the` and hence it is not clear what data it applies to. We can correct this by telling the compiler to act as if the Slice`Slicestruct contained a borrowed reference` struct contained a borrowed reference &'a T`&'a T`:

fn main() { use std::marker::PhantomData; struct Slice<'a, T:'a> { start: *const T, end: *const T, phantom: PhantomData<&'a T> } }
use std::marker::PhantomData;

struct Slice<'a, T:'a> {
    start: *const T,
    end: *const T,
    phantom: PhantomData<&'a T>
}

This also in turn requires that we annotate T:'a`T:'a, indicating that`, indicating that T`Tis a type that can be borrowed for the lifetime` is a type that can be borrowed for the lifetime 'a`'a`.

Unused type parameters

It sometimes happens that there are unused type parameters that indicate what type of data a struct is "tied" to, even though that data is not actually found in the struct itself. Here is an example where this arises when handling external resources over a foreign function interface. PhantomData<T>`PhantomData` can prevent mismatches by enforcing types in the method implementations:

fn main() { trait ResType { fn foo(&self); } struct ParamType; mod foreign_lib { pub fn new(_: usize) -> *mut () { 42 as *mut () } pub fn do_stuff(_: *mut (), _: usize) {} } fn convert_params(_: ParamType) -> usize { 42 } use std::marker::PhantomData; use std::mem; struct ExternalResource<R> { resource_handle: *mut (), resource_type: PhantomData<R>, } impl<R: ResType> ExternalResource<R> { fn new() -> ExternalResource<R> { let size_of_res = mem::size_of::<R>(); ExternalResource { resource_handle: foreign_lib::new(size_of_res), resource_type: PhantomData, } } fn do_stuff(&self, param: ParamType) { let foreign_params = convert_params(param); foreign_lib::do_stuff(self.resource_handle, foreign_params); } } }
use std::marker::PhantomData;
use std::mem;

struct ExternalResource<R> {
   resource_handle: *mut (),
   resource_type: PhantomData<R>,
}

impl<R: ResType> ExternalResource<R> {
    fn new() -> ExternalResource<R> {
        let size_of_res = mem::size_of::<R>();
        ExternalResource {
            resource_handle: foreign_lib::new(size_of_res),
            resource_type: PhantomData,
        }
    }

    fn do_stuff(&self, param: ParamType) {
        let foreign_params = convert_params(param);
        foreign_lib::do_stuff(self.resource_handle, foreign_params);
    }
}

Indicating ownership

Adding a field of type PhantomData<T>`PhantomDataalso indicates that your struct owns data of type` also indicates that your struct owns data of type T`T. This in turn implies that when your struct is dropped, it may in turn drop one or more instances of the type`. This in turn implies that when your struct is dropped, it may in turn drop one or more instances of the type T`T, though that may not be apparent from the other structure of the type itself. This is commonly necessary if the structure is using an unsafe pointer like`, though that may not be apparent from the other structure of the type itself. This is commonly necessary if the structure is using an unsafe pointer like *mut T`*mut Twhose referent may be dropped when the type is dropped, as a` whose referent may be dropped when the type is dropped, as a *mut T`*mut T` is otherwise not treated as owned.

If your struct does not in fact own the data of type T`T, it is better to use a reference type, like`, it is better to use a reference type, like PhantomData<&'a T>`PhantomData<&'a T>(ideally) or` (ideally) or PhantomData<*const T>`PhantomData<*const T>` (if no lifetime applies), so as not to indicate ownership.

Trait Implementations

impl<T> Hash for PhantomData<T> where T: ?Sized

fn hash<H>(&self, &mut H) where H: Hasher

fn hash_slice<H>(data: &[Self], state: &mut H) where H: Hasher

impl<T> PartialEq<PhantomData<T>> for PhantomData<T> where T: ?Sized

fn eq(&self, _other: &PhantomData<T>) -> bool

fn ne(&self, other: &Rhs) -> bool

impl<T> Eq for PhantomData<T> where T: ?Sized

impl<T> PartialOrd<PhantomData<T>> for PhantomData<T> where T: ?Sized

fn partial_cmp(&self, _other: &PhantomData<T>) -> Option<Ordering>

fn lt(&self, other: &Rhs) -> bool

fn le(&self, other: &Rhs) -> bool

fn gt(&self, other: &Rhs) -> bool

fn ge(&self, other: &Rhs) -> bool

impl<T> Ord for PhantomData<T> where T: ?Sized

fn cmp(&self, _other: &PhantomData<T>) -> Ordering

impl<T> Copy for PhantomData<T> where T: ?Sized

impl<T> Clone for PhantomData<T> where T: ?Sized

fn clone(&self) -> PhantomData<T>

fn clone_from(&mut self, source: &Self)

impl<T> Debug for PhantomData<T>

fn fmt(&self, f: &mut Formatter) -> Result<(), Error>