Skip to main content

Crate rust_spec

Crate rust_spec 

Source
Expand description

Compile-time classification of types according to the Rust specification.

§Classification Axes

RustSpec describes a type across the following axes:

  • layout: representation stability.
  • size: statically sized, metadata-sized, or extern-type-like shape.
  • trap: whether the value has trap representations.
  • niche: whether a type has a stable, unstable, or no niche value.
  • mutability: whether type can be mutated through shared access.
  • drop: whether dropping runs custom or compiler-generated code.
  • Opaque: whether the value representation may be inspected.

§Layout

Describes total reachable (through pointer indirection) representation stability:

  • Stable: compiler-guaranteed representation.
  • Unstable: representation is not guaranteed.

§Size

Describes compile-time size and pointer metadata shape:

§Trap

Describes total reachable (through pointer indirection) value-representation validity:

  • Robust: every bit pattern (through indirection) is valid.
  • NonRobust: some bit patterns are trap/invalid values.

This classification does not establish provenance, alignment, lifetimes, or aliasing requirements for pointers or references. For example, Option<&u8> is Robust, but a non-null representation must still be a valid reference before constructing the value.

§Niche

Describes whether and what kind of niche is available for the type:

Use #[rust_spec(custom_niche)] when deriving RustSpec to select WithNiche<Unstable>.

§Drop

Describes the type’s behavior when dropped:

Use #[rust_spec(custom_drop)] when deriving RustSpec for a type that implements Drop.

§Mutability

Describes whether a type has parts that can be mutated through shared access:

§Opacity

  • NonOpaque: the value representation is not opaque.
  • Opaque: the value must appear only behind an indirection.

Use #[rust_spec(opaque)] when deriving RustSpec to classify type as Opaque.

§How to Use

Derive RustSpec for your types, then use its associated marker families as bounds when implementing other traits:

use disjoint_impls::disjoint_impls;
use rust_spec::{RustSpec, Stable, Unstable, niche::{WithNiche, WithoutNiche}};

#[derive(RustSpec)]
struct Header {
    id: u32,
    flags: u16,
}

disjoint_impls! {
    trait NullableEncoding {
        const NEEDS_TAG: bool;
    }

    impl<T: RustSpec<Niche = WithoutNiche>> NullableEncoding for T {
        const NEEDS_TAG: bool = true;
    }

    impl<T: RustSpec<Niche = WithNiche<Stable>>> NullableEncoding for T {
        const NEEDS_TAG: bool = false;
    }

    impl<T: RustSpec<Niche = WithNiche<Unstable>>> NullableEncoding for T {
        const NEEDS_TAG: bool = false;
    }
}

const HEADER_OPTION_NEEDS_TAG: bool = Header::NEEDS_TAG;

Check out CO3 to see how this crate allows for building higher zero-cost abstractions.

Modules§

drop
Drop behavior classification.
layout
Representation stability and trap/robustness classification.
mutability
Mutability classification of Rust types.
niche
Logic related to the conversion of Option<T> to and from FFI-compatible representation
size

Structs§

Gt
Marker for a statically sized type greater than the given threshold.

Enums§

NonOpaque
The value representation is not opaque.
Opaque
The value is opaque and must be placed behind an indirection.
Stable
Marker for a compiler-guaranteed representation or niche.
Unstable
Marker for a representation or niche that is not compiler-guaranteed.
Zero
Marker for a zero-sized type.

Traits§

RustSpec
Joined Rust-spec classification of a type.

Derive Macros§

RustSpec
Derives RustSpec for a struct, enum, or union.