MCPcopy Index your code
hub / github.com/dtolnay/typeid

github.com/dtolnay/typeid @1.0.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release 1.0.3 ↗ · + Follow
17 symbols 23 edges 3 files 0 documented · 0%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Const TypeId and non-'static TypeId

github crates.io docs.rs build status

Const TypeId

This crate provides [ConstTypeId], which is like [core::any::TypeId] but is constructible in const in stable Rust. (The standard library's TypeId's is nightly-only to construct in const; the tracking issue for this is rust#77125.)

Being able to construct ConstTypeId in const makes it suitable for use cases that rely on static promotion:

use std::fmt::{self, Debug, Display};
use std::ptr;
use typeid::ConstTypeId;

pub struct ObjectVTable {
    type_id: ConstTypeId,
    drop_in_place: unsafe fn(*mut ()),
    display: unsafe fn(*const (), &mut fmt::Formatter) -> fmt::Result,
    debug: unsafe fn(*const (), &mut fmt::Formatter) -> fmt::Result,
}

impl ObjectVTable {
    pub const fn new<T: Display + Debug>() -> &'static Self {
        &ObjectVTable {
            type_id: const { ConstTypeId::of::<T>() },
            drop_in_place: |ptr| unsafe { ptr::drop_in_place(ptr.cast::<T>()) },
            display: |ptr, f| unsafe { Display::fmt(&*ptr.cast::<T>(), f) },
            debug: |ptr, f| unsafe { Debug::fmt(&*ptr.cast::<T>(), f) },
        }
    }
}

and in associated constants:

use typeid::ConstTypeId;

pub trait GetTypeId {
    const TYPEID: ConstTypeId;
}

impl<T: 'static> GetTypeId for T {
    const TYPEID: ConstTypeId = ConstTypeId::of::<Self>();
}

Non-'static TypeId

This crate provides [typeid::of], which takes an arbitrary non-'static type T and produces the TypeId for the type obtained by replacing all lifetimes in T by 'static, other than higher-rank lifetimes found in trait objects.

For example if T is &'b dyn for<'a> Trait<'a, 'c>, then typeid::of::<T>() produces the TypeId of &'static dyn for<'a> Trait<'a, 'static>.

It should be obvious that unlike with the standard library's TypeId, typeid::of::<A>() == typeid::of::<B>() does not mean that A and B are the same type. However, there is a common special case where this behavior is exactly what is needed. If:

  • A is an arbitrary non-'static type parameter, and
  • B is 'static, and
  • all types with the same id as B are also 'static

then typeid::of::<A>() == typeid::of::<B>() guarantees that A and B are the same type.

use core::any::TypeId;
use core::slice;

pub fn example<T>(slice: &[T]) {
    // T is arbitrary and non-'static.

    if typeid::of::<T>() == TypeId::of::<u8>() {
        // T is definitely u8
        let bytes = unsafe { slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) };
        process_bytes(bytes);
    } else {
        for t in slice {
            process(t);
        }
    }
}

fn process<T>(_: &T) {/* ... */}
fn process_bytes(_: &[u8]) {/* ... */}

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Extension points exported contracts — how you extend this code

NonStaticAny (Interface)
(no doc) [1 implementers]
src/lib.rs
Trait (Interface)
(no doc)
tests/test.rs

Core symbols most depended-on inside this repo

get
called by 7
src/lib.rs
rustc_minor_version
called by 1
build.rs
main
called by 0
build.rs
of
called by 0
src/lib.rs
fmt
called by 0
src/lib.rs
eq
called by 0
src/lib.rs
partial_cmp
called by 0
src/lib.rs
cmp
called by 0
src/lib.rs

Shape

Method 8
Function 4
Class 3
Interface 2

Languages

Rust100%

Modules by API surface

src/lib.rs11 symbols
tests/test.rs4 symbols
build.rs2 symbols

For agents

$ claude mcp add typeid \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact