#lifetime #static #async #async-context #borrowck #no-std

no-std extend_mut

A library for extending exclusive references

1 unstable release

new 0.3.0 Jan 16, 2025
0.2.0 Jan 12, 2025
0.1.0 Jan 12, 2025

#564 in Asynchronous

Download history 222/week @ 2025-01-08

222 downloads per month

MIT/Apache

15KB
210 lines

extend_mut

docs.rs crates.io

extend_mut is a #![no_std] Rust crate that provides safe and unsafe utilities to extend the lifetime of an exclusive mutable reference (&mut). It includes both synchronous and asynchronous methods for achieving this, with a focus on correctness and safety guarantees around mutable reference lifetimes.

Features

  • extend_mut: A synchronous function that safely extends the lifetime of a mutable reference using a sync closure. Note that you can still use this in async context, if you will call it on every poll, instead of on future creation.
  • extend_mut_async: An asynchronous function that allows extending the lifetime of a mutable reference in an async context. This function comes with important safety considerations.

Why Use extend_mut?

Rust's borrow checker enforces strict lifetime rules to ensure memory safety. However, there are scenarios where you may need to work around lifetime limitations in a controlled way. extend_mut provides a way to extend the lifetime of mutable references safely and correctly, without introducing undefined behavior.

A commom use case is crating a temporary &'static mut reference to send somewhere, give execution control to other function that expects &'static mut, and then take back the control, take back &'static mut and recover original lifetime.

Crate Attributes

  • #![no_std] support: This crate is compatible with #![no_std] environments, making it suitable for embedded and constrained systems.

Usage

Add extend_mut to your Cargo.toml:

[dependencies]
extend_mut = "0.2"

Synchronous Example

use extend_mut::extend_mut;

fn main() {
    let mut x = 5;

    fn modify_static(x: &'static mut i32) -> &'static mut i32 {
        *x += 1;
        x
    }

    extend_mut(&mut x, |x| modify_static(x));
    assert_eq!(x, 6);

    extend_mut(&mut x, modify_static);
    assert_eq!(x, 7);

    let result = extend_mut(&mut x, |x| (modify_static(x), 42));

    assert_eq!(result, 42);
    assert_eq!(x, 8);
}

Safety Considerations

extend_mut is designed to be safe, while extend_mut_async is inherently unsafe due to the lack of linear types in Rust. When using extend_mut_async, ensure that the returned future is fully awaited before being dropped.

Dependencies

~47KB