ExamplesBy LevelBy TopicLearning Paths
708 Fundamental

transmute safe patterns

Functional Programming

Tutorial Video

Text description (accessibility)

This video demonstrates the "transmute safe patterns" functional Rust example. Difficulty level: Fundamental. Key concepts covered: Functional Programming. This example covers a specific aspect of Rust's unsafe programming model: raw memory manipulation, FFI interop, allocator customization, or soundness principles. Key difference from OCaml: 1. **Safety model**: Rust requires explicit `unsafe` for these operations; OCaml achieves safety through the GC and type system without explicit unsafe regions.

Tutorial

The Problem

This example covers a specific aspect of Rust's unsafe programming model: raw memory manipulation, FFI interop, allocator customization, or soundness principles. These topics are essential for systems programming — writing OS components, device drivers, game engines, and any code that must interact with C libraries or control memory layout precisely. Rust's unsafe system is designed to confine unsafety to small, auditable regions while maintaining safety in the surrounding code.

🎯 Learning Outcomes

  • • The specific unsafe feature demonstrated: transmute safe patterns
  • • When this feature is necessary vs when safe alternatives exist
  • • How to use it correctly with appropriate SAFETY documentation
  • • The invariants that must be maintained for the operation to be sound
  • • Real-world contexts: embedded systems, OS kernels, C FFI, performance-critical code
  • Code Example

    #![allow(clippy::all)]
    //! # Transmute Safe Patterns
    
    use std::mem;
    
    /// Safe transmute for same-size types
    pub fn bytes_to_u32(bytes: [u8; 4]) -> u32 {
        u32::from_ne_bytes(bytes)
    }
    
    /// Transmute slice of bytes to slice of u32 (requires alignment)
    pub fn transmute_slice_safe(bytes: &[u8]) -> Option<&[u32]> {
        if bytes.len() % 4 != 0 {
            return None;
        }
        if bytes.as_ptr() as usize % mem::align_of::<u32>() != 0 {
            return None;
        }
        Some(unsafe { std::slice::from_raw_parts(bytes.as_ptr() as *const u32, bytes.len() / 4) })
    }
    
    /// Zero-copy view (when types have same layout)
    #[repr(C)]
    pub struct Point {
        pub x: f32,
        pub y: f32,
    }
    
    pub fn floats_to_point(arr: [f32; 2]) -> Point {
        Point {
            x: arr[0],
            y: arr[1],
        }
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
        #[test]
        fn test_bytes() {
            assert_eq!(
                bytes_to_u32([1, 0, 0, 0]),
                1u32.to_ne_bytes()
                    .iter()
                    .fold(0u32, |a, &b| a * 256 + b as u32)
                    .swap_bytes()
            );
        }
    }

    Key Differences

  • Safety model: Rust requires explicit unsafe for these operations; OCaml achieves safety through the GC and type system without explicit unsafe regions.
  • FFI approach: Rust uses raw C types directly with extern "C"; OCaml uses ctypes which wraps C types in OCaml values.
  • Memory control: Rust allows complete control over memory layout (#[repr(C)], custom allocators); OCaml's GC manages memory layout automatically.
  • Auditability: Rust unsafe regions are syntactically visible and toolable; OCaml unsafe operations (Obj.magic, direct C calls) are also explicit but less common.
  • OCaml Approach

    OCaml's GC and type system eliminate most of the need for these unsafe operations. The equivalent functionality typically uses:

  • • C FFI via the ctypes library for external function calls
  • Bigarray for controlled raw memory access
  • • The GC for memory management (no manual allocators needed)
  • Bytes.t for mutable byte sequences
  • OCaml programs rarely need operations equivalent to these Rust unsafe patterns.

    Full Source

    #![allow(clippy::all)]
    //! # Transmute Safe Patterns
    
    use std::mem;
    
    /// Safe transmute for same-size types
    pub fn bytes_to_u32(bytes: [u8; 4]) -> u32 {
        u32::from_ne_bytes(bytes)
    }
    
    /// Transmute slice of bytes to slice of u32 (requires alignment)
    pub fn transmute_slice_safe(bytes: &[u8]) -> Option<&[u32]> {
        if bytes.len() % 4 != 0 {
            return None;
        }
        if bytes.as_ptr() as usize % mem::align_of::<u32>() != 0 {
            return None;
        }
        Some(unsafe { std::slice::from_raw_parts(bytes.as_ptr() as *const u32, bytes.len() / 4) })
    }
    
    /// Zero-copy view (when types have same layout)
    #[repr(C)]
    pub struct Point {
        pub x: f32,
        pub y: f32,
    }
    
    pub fn floats_to_point(arr: [f32; 2]) -> Point {
        Point {
            x: arr[0],
            y: arr[1],
        }
    }
    
    #[cfg(test)]
    mod tests {
        use super::*;
        #[test]
        fn test_bytes() {
            assert_eq!(
                bytes_to_u32([1, 0, 0, 0]),
                1u32.to_ne_bytes()
                    .iter()
                    .fold(0u32, |a, &b| a * 256 + b as u32)
                    .swap_bytes()
            );
        }
    }
    ✓ Tests Rust test suite
    #[cfg(test)]
    mod tests {
        use super::*;
        #[test]
        fn test_bytes() {
            assert_eq!(
                bytes_to_u32([1, 0, 0, 0]),
                1u32.to_ne_bytes()
                    .iter()
                    .fold(0u32, |a, &b| a * 256 + b as u32)
                    .swap_bytes()
            );
        }
    }

    Deep Comparison

    Transmute Safe Patterns

    See example files for OCaml vs Rust comparison.

    Exercises

  • Minimize unsafe: Find the smallest possible unsafe region in the source and verify that all safe code is outside the unsafe block.
  • Safe alternative: Identify if a safe alternative exists for the demonstrated technique (e.g., bytemuck for transmute, CString for FFI strings) and implement it.
  • SAFETY documentation: Write a complete SAFETY comment for each unsafe block listing preconditions, invariants, and what would break if violated.
  • Open Source Repos