Trait konst_kernel::type_eq::MakeTypeWitness

source ·
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.

§Example

(this example requires Rust 1.61.0)

use typewit::{TypeWitnessTypeArg, MakeTypeWitness, TypeEq};
 
const fn default<'a, T, const L: usize>() -> T 
where
    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)
#[non_exhaustive]
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:

typewit::simple_type_witness!{
    // Declares `enum Defaultable<'a, const L: usize, __Wit>`
    // The `__Wit` type parameter is implicit and always the last generic parameter.
    #[non_exhaustive]
    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§

source

const MAKE: Self

A constant with the type witness

Object Safety§

This trait is not object safe.

Implementors§

source§

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

source§

const MAKE: MetaBaseTypeWit<L, R, TypeCmp<L, R>> = _

source§

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

source§

const MAKE: MetaBaseTypeWit<L, R, TypeNe<L, R>> = _

source§

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

source§

const MAKE: MetaBaseTypeWit<L, R, TypeEq<L, R>> = _

source§

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

source§

const MAKE: TypeEq<T, T> = Self::NEW

source§

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

source§

const MAKE: BoolWit<B> = _