1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//! A system for getting static type information.
//!
//! This effectively gives (some) of the power of reflection
//! without any of the runtime cost!
//!
//! The original use case was type-checking generated code in a JIT compiler (with zero runtime cost).
//! However, other use cases are certainly possible :)
//!
//! Contributions are welcome!
//! I'd be happy to add more features as long as they align with the general philosophy
//! of compile-time reflection.
#![deny(missing_docs)]
#![feature(
    const_fn, // We rely on const eval :(
    const_panic, const_option, // We use Option::unwrap
    const_fn_fn_ptr_basics, // We use PhantomData<fn() -> T>
    // Used for field_offset macro
    const_raw_ptr_deref,
    const_raw_ptr_to_usize_cast,
)]
/*
 * This is required on recent nightly
 *
 * However it breaks on the version that docs.rs is using (as of this writing).
 * Therefore, we have to turn it off there.
 */
#![cfg_attr(not(feature="docs-rs"), feature(const_fn_trait_bound))]
#![cfg_attr(feature = "never", feature(never_type))]

mod macros;
#[cfg(feature = "builtins")]
pub mod builtins;
pub mod types;
pub mod funcs;

mod core;

pub use crate::types::TypeInfo;

/// The trait for types whose information can be accessed via static reflection.
///
/// In order to proper access any fields,
/// the representation must be C-compatible.
/// Otherwise, transmutes and pointer-arithmetic are
/// pointless because they are already undefined behavior.
///
/// ## Safety
/// Incorrect implementation of this trait is considered
/// undefined behavior. All the static type information must
/// be correct at runtime.
/// 
/// For example, if this type gives field information via [FieldReflect],
/// then the field information **must** match the representation
/// at runtime.
/// 
/// The advantage of this is that other crates can rely
/// on the representation being stable (for example, JIT compilers can use it).
/// 
/// The type must be `#[repr(C)]` or have some other
/// form of FFI safety.
pub unsafe trait StaticReflect {
    /// The static information about the type's representation
    const TYPE_INFO: TypeInfo<'static>;
}

/// A type that supports accessing its fields via reflection.
/// 
/// All fields are assumed to be defined in a way that is compatible
/// with the the C ABI. In other words, the type must be `#[repr(C)]`
///
/// ## Safety
/// Implementing this type incorrectly is undefined behavior.
pub unsafe trait FieldReflect: StaticReflect {
    /// A magic structure that can be used to access
    /// field info by name
    type NamedFieldInfo;
    /// Static information on this structure's fields,
    /// where each field's information is given by name
    const NAMED_FIELD_INFO: Self::NamedFieldInfo;
}