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
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! Convenient ways to shoot yourself in the foot.
#![feature(alloc_layout_extra, maybe_uninit)]

/// Given any pointer, even an immutable one with a short lifetime, returns a
/// mutable pointer of unbounded `'static` lifetime to the same underlying
/// address.
///
/// # Safety
///
/// "Abandon all hope, ye who enter here."
///
/// # Example
///
/// Interwoven use of two aliased mutable references:
///
/// ```
/// let mut original = vec![1, 2, 3, 4, 5];
/// let handle = unsafe { fuckit::grapple(&original) };
/// original[4] = 1;
/// handle[0] = 5;
/// original[3] = 2;
/// handle[1] = 4;
/// assert_eq!(original, vec![5, 4, 3, 2, 1]);
/// assert_eq!(original, *handle);
/// ```
pub unsafe fn grapple<T>(pointer: &T) -> &'static mut T {
    #[allow(
        mutable_transmutes,
        clippy::transmute_ptr_to_ptr,
        clippy::clone_double_ref
    )]
    std::mem::transmute(pointer.clone())
}

/// Given a statically-sized value, allocates new memory for it which will
/// never be freed and moves (or copies) the value to that memory, where it
/// will have an unbounded  `'static` lifetime, and returns a mutable
/// reference. This leaks memory.
///
/// # Example
///
/// Returning a reference to a locally-created value without manually making
/// it owned by some longer-lived value.
///
/// ```
/// fn inner_function() -> &'static mut Vec<usize> {
///     let on_stack = vec![1, 2, 3];
///     let on_heap = fuckit::immortalize(on_stack);
///     on_heap
/// }
///
/// let v = inner_function();
///
/// assert_eq!(*v, vec![1, 2, 3]);
/// ```
pub fn immortalize<T>(value: T) -> &'static mut T {
    let reference = unsafe { summon() };
    *reference = value;
    reference
}

/// Allocates space for a slice of `len` clones/copies of `value`, which will
/// never be freed, so they can have unbounded `'static` lifetimes. This
/// leaks memory.
///
/// # Example
///
/// Returning a reference to a locally-created slice of clones without
/// manually making it owned by some longer-lived value.
///
/// ```
/// fn inner_function() -> &'static mut [Vec<usize>] {
///     let on_stack = vec![1, 2, 3];
///     let on_heap = fuckit::summon_clones(&on_stack, 32);
///     on_heap
/// }
///
/// let vs = inner_function();
///
/// // Ensure the value was actually cloned:
/// for v in vs.iter() {
///     assert_eq!(*v, vec![1, 2, 3]);
/// }
///
/// // Ensure the value wasn't just aliased: modifying one vec shouldn't
/// // affect the others:
/// vs[0][0] = 99;
/// vs[1].clear();
/// assert_eq!(1, vs[2][0]);
/// assert_eq!(1, vs[31][0]);
///
pub fn summon_clones<T: Clone>(value: &T, len: usize) -> &'static mut [T] {
    let slice = unsafe { summon_many(len) };
    for clone in slice.iter_mut() {
        *clone = value.clone();
    }
    slice
}

/// Allocates (but does not initialize) space for a value of type `T` which
/// will never be freed, so it can have a unbounded `'static` lifetime. This
/// leaks memory.
///
/// # Safety
///
/// The value must be initialized before it is used.
pub unsafe fn summon<T>() -> &'static mut T {
    &mut summon_many(1)[0]
}

/// Allocates (but does not initialize) space for a slice of `len` values of
/// type `T` which will never be freed, so they can have unbounded `'static`
/// lifetimes. This leaks memory.
///
/// # Safety
///
/// Each value must be initialized before it is used.
pub unsafe fn summon_many<T>(len: usize) -> &'static mut [T] {
    let layout = std::alloc::Layout::array::<T>(len).unwrap();
    // Ask your allocator for the memory.
    let pointer: *mut u8 = std::alloc::alloc(layout);
    // As in C, we get a pointer to raw bytes, so we cast it.
    let typed_pointer = pointer as *mut T;
    // Then we return a slice pointing to the allocation.
    // A slcie is just a typed pointer with a length for bounds-checking.
    std::slice::from_raw_parts_mut(typed_pointer, len)
}