Official docs about Phantom Type & Data

Example

#![allow(unused)]
 
use std::marker::PhantomData;
use std::fmt::{Display, Formatter, Result};
use std::any::type_name;
 
enum Sec {}
enum Min {}
 
struct Duration<Unit> {
    value: i32,
    unit: PhantomData<Unit>,
}
 
impl<U> Duration<U> {
    fn new(value: i32) -> Duration<U> {
        Duration {
            value: value,
            unit: PhantomData
        }
    }
}
 
impl<U> Display for Duration<U> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(
            f, 
            "{} {}",
            self.value, type_name::<U>(),
        )
    }
}
 
fn print_second(sec: Duration<Sec>) {
    println!("Printed: {}", sec);
}
 
fn main() {
    // ok, rust compiler will imply that
    // Duration::new(1) is with unit sec
    print_second(Duration::new(1));
    
    let duration_min = Duration::<Min>::new(10);
    // compile time error! type mismatch
    // print_second(duration_min);
}