pub trait MakeTypeWitness: TypeWitnessTypeArg {
    const MAKE: Self;
Expand description

Constructs this type witness.

A type witness is an enum whose variants only have TypeEq fields. Each variant requires the enum’s type parameter to be a specific type.

This trait can be automatically implemented for simple type witnesses by declaring the type witness with the simple_type_witness macro.


(this example requires Rust 1.61.0)

use typewit::{TypeWitnessTypeArg, MakeTypeWitness, TypeEq};
const fn default<'a, T, const L: usize>() -> T 
    Defaultable<'a, L, T>: MakeTypeWitness
    match MakeTypeWitness::MAKE {
        // `te` is a `TypeEq<T, i32>`, which allows coercing between `T` and `i32`.
        // `te.to_left(...)` goes from `i32` to `T`.
        Defaultable::I32(te) => te.to_left(3),

        // `te` is a `TypeEq<T, bool>`
        Defaultable::Bool(te) => te.to_left(true),

        // `te` is a `TypeEq<T, &'a str>`
        Defaultable::Str(te) => te.to_left("empty"),

        // `te` is a `TypeEq<T, [u32; L]>`
        Defaultable::Array(te) => te.to_left([5; L]),
let number: i32 = default();
assert_eq!(number, 3);
let boolean: bool = default();
assert_eq!(boolean, true);
let string: &str = default();
assert_eq!(string, "empty");

let array: [u32; 3] = default();
assert_eq!(array, [5, 5, 5]);
// This enum is a type witness (documented in the root module)
enum Defaultable<'a, const L: usize, T> {
    // This variant requires `T == i32`
    I32(TypeEq<T, i32>),

    // This variant requires `T == bool`
    Bool(TypeEq<T, bool>),

    // This variant requires `T == &'a str`
    Str(TypeEq<T, &'a str>),

    // This variant requires `T == [u32; L]`
    Array(TypeEq<T, [u32; L]>),
impl<T, const L: usize> TypeWitnessTypeArg for Defaultable<'_, L, T> {
    // this aids type inference for what type parameter is witnessed 
    type Arg = T;
// Specifying dummy values for the generics that the `I32` variant doesn't use,
// so that they don't have to be specified when this impl is used.
impl MakeTypeWitness for Defaultable<'_, 0, i32> {
    // The `TypeEq<T, i32>` field can be constructed because `T == i32` here.
    const MAKE: Self = Self::I32(TypeEq::NEW);
impl MakeTypeWitness for Defaultable<'_, 0, bool> {
    const MAKE: Self = Self::Bool(TypeEq::NEW);
impl<'a> MakeTypeWitness for Defaultable<'a, 0, &'a str> {
    const MAKE: Self = Self::Str(TypeEq::NEW);
impl<const L: usize> MakeTypeWitness for Defaultable<'_, L, [u32; L]> {
    const MAKE: Self = Self::Array(TypeEq::NEW);

The Defaultable type definition and its impls can also be written using the simple_type_witness macro:

    // Declares `enum Defaultable<'a, const L: usize, __Wit>`
    // The `__Wit` type parameter is implicit and always the last generic parameter.
    enum Defaultable<'a, const L: usize> {
        // `<'a, 0>` is necessary to have 
        // `impl MakeTypeWitness for Defaultable<'_, 0, i32>` instead of 
        // `impl<'a, const L: u32> MakeTypeWitness for Defaultable<'a, L, i32>`,
        // which allows the generic arguments to be inferred.
        I32<'a, 0> = i32,

        Bool<'a, 0> = bool,

        Str<'a, 0> = &'a str,

        Array = [u32; L],

note that simple_type_witness can’t replace enums whose witnessed type parameter is not the last, or have variants with anything but one TypeEq field each.

Required Associated Constants§


const MAKE: Self

A constant with the type witness

Object Safety§

This trait is not object safe.



impl<L: ?Sized, R: ?Sized> MakeTypeWitness for MetaBaseTypeWit<L, R, TypeCmp<L, R>>


const MAKE: Self = _


impl<L: ?Sized, R: ?Sized> MakeTypeWitness for MetaBaseTypeWit<L, R, TypeEq<L, R>>


const MAKE: Self = _


impl<L: ?Sized, R: ?Sized> MakeTypeWitness for MetaBaseTypeWit<L, R, TypeNe<L, R>>


const MAKE: Self = _


impl<T: ?Sized> MakeTypeWitness for TypeEq<T, T>


const MAKE: Self = Self::NEW


impl<const B: bool> MakeTypeWitness for BoolWit<B>


const MAKE: Self = _