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
fnsignatures (to be more precise, the elision of the return type of anfnpointer, item, orFn…trait), theUnsafe!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>()
}
}
}