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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//! 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."
///
/// ## Safe Alternative
///
/// Declare an
/// <code>[Rc](std::rc::Rc)<[RefCell](std::cell::RefCell)&lt;T>></code>
/// in your main or somewhere else near the bottom of your stack, and pass
/// that around.
///
/// # 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.
///
/// ## Safe Alternative
///
/// Use [`immortalize`] to move an existing value into such an allocation, so
/// you can't forget to initialize it.
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.
///
/// ## Safe Alternative
///
/// Use [`summon_clones`] to automatically initialize the values to
/// clones/copies of a provided value.
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)
}