1#![doc = include_str!("../README.md")]
2
3use core::mem;
4use std::{hint::unreachable_unchecked, process};
5
6#[inline(always)]
13pub unsafe fn extend_ref<'a, T: 'a>(target: &T) -> &'a T {
14 mem::transmute::<&T, &'a T>(target)
15}
16
17#[inline(always)]
25pub unsafe fn extend_mut<'a, T: 'a>(target: &mut T) -> &'a mut T {
26 mem::transmute::<&mut T, &'a mut T>(target)
27}
28
29#[doc(hidden)]
30#[inline(always)]
31pub fn run_abort_guarded<F: FnOnce()>(func: F) -> ! {
32 struct AbortGuard;
33
34 impl Drop for AbortGuard {
35 fn drop(&mut self) {
36 process::abort();
37 }
38 }
39
40 {
41 let _guard = AbortGuard;
42
43 func();
44 }
45
46 unsafe { unreachable_unchecked() }
48}
49
50#[macro_export]
59macro_rules! ref_extended {
60 (|$(& $($var: ident)+ ),*| $body: expr) => {
61 ::ref_extended::run_abort_guarded(move || {
62 $(let ::ref_extended::extract_ref_name!($($var)*) = unsafe { ::ref_extended::extend_lifetime!($($var)*) };)*
63
64 {
65 $body
66 }
67 })
68 };
69}
70
71#[doc(hidden)]
72#[macro_export]
73macro_rules! extract_ref_name {
74 ($name: ident) => {
75 $name
76 };
77
78 (mut $name: ident) => {
79 $name
80 };
81}
82
83#[doc(hidden)]
84#[macro_export]
85macro_rules! extend_lifetime {
86 ($name: ident) => {
87 ::ref_extended::extend_ref(&$name)
88 };
89
90 (mut $name: ident) => {
91 ::ref_extended::extend_mut(&mut $name)
92 };
93}