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