Unsafe

Macro Unsafe 

Source
macro_rules! Unsafe {
    (
        <$lt:lifetime> $($T:tt)+
    ) => { ... };
    (
        $DropMarker:ty,
        <$lt:lifetime> $($T:tt)+
    ) => { ... };
    (
        $DropMarker:ty,
        $($T:tt)+
    ) => { ... };
    (
        $($T:tt)+
    ) => { ... };
}
Expand description

Convenience macro to name/express an unsafe<'lt> … type:

Unsafe![<'lt> = …] // morally, `unsafe<'lt> …`
// e.g.
Unsafe![<'lt> = &'lt str] // morally, `unsafe<'lt> &'lt str`.

§Syntax

Unsafe![
    $($DropMarker:ty, )? // if elided, it is left to be `_`-inferred.

    // then, either:
    <$lt:lifetime> = $T:ty $(,)?

    // or (lifetime-elision shorthand syntax):
    $T:ty // <- every `'_` or unnamed `&`-lifetime is deemed parametric.
]
  • §Lifetime-elision shorthand syntax

    Similar to lifetime-elision in fn signatures (to be more precise, the elision of the return type of an fn pointer, item, or Fn… trait), the Unsafe! macro also allows for “inferring” which lifetime parameters are parametric simply by virtue of eliding them, be it explicitly (via '_), or implicitly (unnamed-&[mut]).

    Do note that this macro is not able to see through elided_lifetimes_in_paths.

§Example

use ::unsafe_binders::{DropMarker, Unsafe};

pub struct SelfReferential {
    full_name: String,
    first_name: Unsafe![DropMarker::NoDropGlue, <'this> &'this str],
                                               // using lifetime-elision shorthand syntax:
    last_name: Unsafe![DropMarker::NoDropGlue, &str],
}

impl SelfReferential {
    pub fn new(full_name: String) -> Option<Self> {
        let (first_name, last_name) = full_name.split_once(" ")?;
        // erase the `&'full_name` lifetime:
        let first_name: Unsafe![_, &str] = Unsafe::wrap_binder_copy(first_name);
                               // shorthand syntax
        let last_name: Unsafe![&str] = Unsafe::wrap_binder_copy(last_name);
        Some(Self {
            full_name,
            first_name,
            last_name,
        })
    }

    pub fn first_name<'r>(&'r self) -> &'r str {
        unsafe {
            self.first_name.unwrap_binder_ref::<'_, 'r>()
        }
    }

    pub fn last_name<'r>(&'r self) -> &'r str {
        unsafe {
            self.last_name.unwrap_binder_ref::<'_, 'r>()
        }
    }
}