extend_lifetime/
lib.rs

1use std::cell::{Ref, RefMut};
2use std::mem::transmute;
3
4// TODO: Parameterize output lifetime instead of making it always 'static. This would require GAT
5
6pub unsafe fn extend_lifetime<T: ExtendableLife>(r: T) -> T::Out {
7    r.extend_lifetime()
8}
9
10
11pub unsafe trait ExtendableLife {
12    type Out;
13
14    unsafe fn extend_lifetime(self) -> Self::Out;
15}
16
17unsafe impl<'a, T: ?Sized + 'static> ExtendableLife for &'a T {
18    type Out = &'static T;
19    unsafe fn extend_lifetime(self) -> Self::Out {
20        transmute(self)
21    }
22}
23
24unsafe impl<'a, T: ?Sized + 'static> ExtendableLife for &'a mut T {
25    type Out = &'static mut T;
26    unsafe fn extend_lifetime(self) -> Self::Out {
27        transmute(self)
28    }
29}
30
31unsafe impl<'a, T: ExtendableLife + Sized> ExtendableLife for Option<T> {
32    type Out = Option<T::Out>;
33    unsafe fn extend_lifetime(self) -> Self::Out {
34        match self {
35            None => None,
36            Some(inner) => Some(inner.extend_lifetime()),
37        }
38    }
39}
40
41unsafe impl<'a, T: 'static> ExtendableLife for Ref<'a, T> {
42    type Out = Ref<'static, T>;
43    unsafe fn extend_lifetime(self) -> Self::Out {
44        transmute(self)
45    }
46}
47
48unsafe impl<'a, T: 'static> ExtendableLife for RefMut<'a, T> {
49    type Out = RefMut<'static, T>;
50    unsafe fn extend_lifetime(self) -> Self::Out {
51        transmute(self)
52    }
53}