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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
//! This module provides the wrapper type [`Lease`] that allows extending the
//! lifetime of references using Rust's type system, effectively preventing
//! further access to the original value once a specific borrow pattern is used.
//!
//! This mechanism is crucial for scenarios like intrusive reference counting
//! (`Irc`), where exclusive access rights need to be guaranteed for a pinned,
//! non-movable value without relying on standard ownership transfer.
//!
//! Credit goes to **Lukas Markeffsky** for the idea and proof-of-concept using
//! the underlying mechanism of using an inner lifetime to have the
//! borrow-checker enforce pinning and ownership semantics for mutable borrows.
use ;
/// A wrapper type that leverages Rust's lifetime and variance rules to prevent
/// further access to the wrapped value once a borrow using a specific pattern
/// is taken and consumed.
///
/// `Lease<'p, T>` wraps a value `T` and associates it with an invariant
/// lifetime `'p`. When a borrow like `&'p mut Lease<'p, T>` is passed to a
/// function, the borrow checker prevents the original `Lease` variable from
/// being accessed again for the duration of `'p`. This mimics the exclusivity
/// aspect of ownership transfer without moving the value, which is essential
/// for managing pinned or non-movable data safely.
///
/// ## Examples
/// The primary purpose is to prevent re-borrowing after consumption:
///
/// ```compile_fail,E0499
/// # use odem_rs_core::ptr::{Lease, LeasedMut};
/// // Function consumes the LeasedMut borrow
/// fn consume_lease<T>(_: LeasedMut<'_, T>) {}
///
/// struct S;
/// let mut value = Lease::new(S);
/// // 'p is inferred here, covering the remaining scope of value
/// consume_lease(&mut value); // Consumes the lease for lifetime 'p
///
/// // value is now considered borrowed for its entire remaining lifetime 'p.
/// // Attempting to borrow it again fails:
/// consume_lease(&mut value); // error: value is mutably borrowed
/// ```
///
/// It also prevents moving the `Lease` after a shared borrow (`LeasedRef`)
/// has been taken:
///
/// ```compile_fail,E0505
/// # use odem_rs_core::ptr::{Lease, LeasedRef};
/// fn use_shared_lease<T>(_: LeasedRef<'_, T>) {}
///
/// struct S;
/// let value = Lease::new(S);
/// use_shared_lease(&value); // Borrows value for its remaining lifetime 'p
/// use_shared_lease(&value); // OK: Multiple shared borrows allowed
///
/// // Cannot move value while it's borrowed:
/// let value = value; // error: value is still borrowed
/// std::mem::forget(value); // error: value is still borrowed
/// ```
///
/// ## Relationship with `Pin`
///
/// `Lease` controls borrow lifetimes but does *not* guarantee that `Drop` will
/// run. If this guarantee is needed (e.g., for `Irc`), `Lease` must be used in
/// conjunction with [`Pin`]. `Pin` provides the [drop guarantee], while `Lease`
/// ensures the borrow checker correctly manages exclusive access rights.
///
/// ```
/// # use {core::pin::{Pin, pin}, odem_rs_core::ptr::{Lease, LeasedMut}};
/// // Function requires a Pinned LeasedMut
/// fn consume_pinned_lease<T>(value: Pin<LeasedMut<'_, T>>) {}
///
/// struct S;
/// impl Drop for S { fn drop(&mut self) { println!("drop runs"); } }
///
/// let mut value = pin!(Lease::new(S)); // Pin the Lease
/// consume_pinned_lease(value.as_mut());
///
/// // Drop is guaranteed to run due to Pin
/// ```
///
/// Without `Pin`, `Drop` could be bypassed using `ManuallyDrop`, potentially
/// breaking safety invariants that rely on destructors running (like `IrcBox`'s
/// drop check).
///
/// To clarify, this code without `Pin` also compiles but doesn't run `Drop`:
/// ```
/// # use {core::mem::ManuallyDrop, odem_rs_core::ptr::{Lease, LeasedMut}};
/// // Function just requires a LeasedMut
/// fn consume_lease<T>(value: LeasedMut<'_, T>) {}
///
/// struct S;
/// impl Drop for S { fn drop(&mut self) { println!("drop runs"); } }
///
/// let mut value = ManuallyDrop::new(Lease::new(S)); // Don't pin the Lease
/// consume_lease(&mut value);
///
/// // Drop does not run (but the address is stable)
/// ```
///
/// # How it works
///
/// `Lease` achieves its borrow-control effect through the interaction of two
/// consequences stemming from its `PhantomData<&'p mut Self>` field:
///
/// 1. **Inner Lifetime:** `PhantomData<&'p mut Self>` signals to the borrow
/// checker that `Lease<'p, T>` should be treated *as if* it contains a
/// mutable reference tied to the lifetime `'p`. This implies `'p` must be
/// valid for at least the entire duration that the `Lease<'p, T>` instance
/// itself exists, otherwise the phantom inner reference would dangle.
///
/// 2. **Lifetime Invariance:** This specific `PhantomData` marker makes the
/// lifetime parameter `'p` **invariant** over `Lease<'p, T>`. Variance is
/// explained in the [Rustonomicon]. Invariance prevents the borrow checker
/// from shortening the lifetime `'p` via subtyping coercion when matching
/// types.
///
/// These two constraints work together within the intended usage pattern, such
/// as `LeasedMut<'p, T>` (which is `&'p mut Lease<'p, T>`). When the borrow
/// checker analyzes a borrow like `&'s mut Lease<'p, T>` in this pattern:
///
/// * It knows `'p` must be valid for at least the duration of `Lease`'s
/// existence (from constraint 1).
/// * It knows the `Lease` instance must exist for at least the duration of the
/// borrow `'s` (otherwise `&'s mut` would dangle).
/// * It knows that due to invariance (constraint 2), the inner lifetime `'p`
/// cannot be shortened to match `'s`. Therefore, for the types to be
/// compatible, the borrow lifetime `'s` must be *at least* as long as the
/// required inner lifetime `'p`.
/// * Combining these constraints (`'p` must cover `Lease`, `Lease` must cover
/// `'s`, and `'s` must cover `'p`), the only possibility is that the borrow
/// lifetime `'s` must be exactly equal to the required inner lifetime `'p`.
///
/// This forces the borrow (`&'s mut` which becomes `&'p mut`) to cover the
/// necessary lifetime `'p`. Consequently, once a `LeasedMut<'p, T>` reference
/// is created and passed to a function, the original `Lease` variable binding
/// cannot be accessed again for its remaining lifetime `'p`. This effectively
/// transfers the exclusive access rights away from the original binding for
/// that duration, mimicking ownership transfer without actually moving the
/// value.
///
/// Credit goes to **Lukas Markeffsky** for the idea and proof-of-concept.
///
/// [drop guarantee]: core::pin
/// [Rustonomicon]: https://doc.rust-lang.org/nomicon/subtyping.html#variance
/// A type alias representing a shared reference to a [`Lease`] using the
/// pattern `&'p Lease<'p, T>`.
///
/// # Overview
///
/// This pattern ensures that after it is passed, the original `Lease` value
/// cannot be moved or forgotten because it remains borrowed for its lifetime.
///
/// # Example
///
/// ```compile_fail,E0505
/// # use odem_rs_core::ptr::{Lease, LeasedRef};
/// fn ref_it<T>(val: LeasedRef<'_, T>) { /* Borrows val for its lifetime */ }
///
/// struct S;
/// let x = Lease::new(S);
/// ref_it(&x); // 'p inferred, x is borrowed for 'p
/// ref_it(&x); // OK: Multiple shared borrows allowed
/// std::mem::forget(x); // error: value is still borrowed
/// ```
pub type LeasedRef<'p, T> = &'p ;
/// A type alias representing a mutable reference to a [`Lease`] using the
/// pattern `&'p mut Lease<'p, T>`.
///
/// # Overview
///
/// This pattern ensures that after it is passed, the original `Lease` value
/// cannot be accessed again (mutably or immutably) for its remaining lifetime,
/// as if ownership had been transferred.
///
/// # Example
///
/// ```compile_fail,E0499
/// # use odem_rs_core::ptr::{Lease, LeasedMut};
/// fn ref_it<T>(val: LeasedMut<'_, T>) { /* Consumes the mutable borrow for its lifetime */ }
///
/// struct S;
/// let mut x = Lease::new(S);
/// ref_it(&mut x); // 'p inferred, consumes borrow for 'p
/// ref_it(&mut x); // Error: value is still mutably borrowed
/// let read = &x; // Error: value is still mutably borrowed
/// std::mem::forget(x); // Error: value is still mutably borrowed
/// ```
pub type LeasedMut<'p, T> = &'p mut ;