Core traits and types for type-level reification and reflection in Rust.
This is the foundation crate. It defines:
- [
Reflect]: a trait for types that carry a compile-time value, withreflect()extracting that value at runtime. - [
reify]: a function that takes any runtime value and lifts it into a scoped type-level context, where it is available through a [Reified] token branded with an invariant lifetime that cannot escape the callback. - [
RuntimeValue]: a small, structural enum used as the standard payload type for [Reflect] implementations across the workspace.
Everything is fully safe (#![deny(unsafe_code)]), with scoping
enforced by the borrow checker.
When should I use this crate?
- You're writing a library where types encode values (Peano numbers,
type-level flags, dimensional units, etc.) and want a uniform way to
surface those values at runtime: implement [
Reflect] for them. - You want a Haskell-
reflection-style scoping primitive in Rust: use [reify] to thread a runtime value into a callback as if it were a compile-time fact. - You're writing a downstream crate (such as
reflect-natorreflect-derive) that produces [Reflect] implementations: depend on this crate for the trait and the [RuntimeValue] vocabulary.
The reification / reflection pattern
This implements the pattern from Kiselyov & Shan's Functional Pearl:
Implicit Configurations, popularized by Kmett's Haskell reflection
library, adapted to Rust with branded lifetimes for scoping safety.
In Haskell:
In Rust, the forall s is modeled by an invariant lifetime 'brand
on [Reified]. The higher-rank bound for<'brand> on the callback
ensures the token cannot escape, just as Haskell's rank-2 type
prevents s from escaping.
Unlike Haskell's reflection library (which uses unsafeCoerce to
fabricate typeclass dictionaries from GHC internals), this
implementation is safe all the way down: no unsafe code, no
compiler-internal assumptions. Scoping is enforced mechanically by
the borrow checker.
Examples
Lift a runtime value into a scoped type-level context:
use reify;
let result = reify;
assert_eq!;
Implement [Reflect] for a type that carries a compile-time value:
use ;
;
assert_eq!;
See also: reflect-nat for ready-made
[Reflect] implementations on Peano naturals, booleans, and HLists,
and reflect-derive for
#[derive(Reflect)] on user types.