Crate unused[][src]

Expand description

About Unused

The unused crate allows types to have unused generic parameters that do not act like they are owned.


If you experience any issues or have any feedback, please feel free to open an issue on the GitHub repository.

no_std Support

unused supports no_std.


Imagine we have a struct LazyFromStr, which contains a &’static str and can lazily create a T using its FromStr impl.

To have T be a generic parameter of LazyFromStr, we can use a PhantomData. Otherwise, we get a compilation error that the parameter T is never used.

use std::marker::PhantomData;
use std::str::FromStr;

struct LazyFromStr<T> {
    str: &'static str,
    phantom: PhantomData<T>,

impl<T: FromStr> LazyFromStr<T> {
    fn create(&self) -> T {
        match T::from_str(self.str) {
            Ok(t) => t,
            Err(_) => panic!(),

The issue with using PhantomData is that LazyFromStr<T> is only Send and Sync if T also is, even though our LazyFromStr<T> does not own a T.

This is where unused comes in.

// We need to import `Unused`.
use unused::Unused;

struct LazyFromStr<T> {
    str: &'static str,
    // Use the `Unused` macro instead of `PhantomData`.
    unused: Unused!(T),

use std::convert::Infallible;
use std::rc::Rc;

// `RcString` is not `Send` or `Sync`.
struct RcString(Rc<String>);

impl FromStr for RcString {
    type Err = Infallible;

    fn from_str(str: &str) -> Result<Self, Self::Err> {

let lazy: LazyFromStr<RcString> = LazyFromStr {
    str: "a",
    // Use `Unused` as a value.
    unused: Unused,

use std::thread;

// `lazy` is `Send` (even though `RcString` is not), so we can send it between threads.
thread::spawn(move ||{
    let _ = lazy.create();

By default, Unused makes generics invariant.

See the Unused! macro for more examples.


A macro that allows for the creation of Unused type containers.

Type Definitions

A container for unused generic types.