unchecked_refcell/
lib.rs

1use core::fmt;
2use core::{
3    cell::{Cell, UnsafeCell},
4    cmp::Ordering,
5    fmt::Display,
6    marker::PhantomData,
7    mem,
8    ops::{Deref, DerefMut},
9    ptr::NonNull,
10};
11
12/// A mutable memory location with dynamically checked borrow rules.
13///
14/// `UncheckedRefCell` behaves exactly like `std::cell::RefCell` when `debug_assertions` is enabled or `checked` feature
15/// flag is enabled (for non-release-like builds). For release-like builds, `UncheckedRefCell` does not
16/// perform any borrow checking. Thus it is faster than `RefCell` (see benchmarks), but may lead to 
17/// undefined behavior instead of panicking like `RefCell`. Use this over `RefCell` for performance
18/// critical code where it is known a `RefCell` would never panic.
19pub struct UncheckedRefCell<T: ?Sized> {
20    #[cfg(any(feature = "checked", debug_assertions))]
21    borrow: Cell<BorrowCounter>,
22    // Stores the location of the earliest currently active borrow.
23    // This gets updated whenever we go from having zero borrows
24    // to having a single borrow. When a borrow occurs, this gets included
25    // in the generated `BorrowError`/`BorrowMutError`
26    #[cfg(feature = "debug_refcell")]
27    borrowed_at: Cell<Option<&'static core::panic::Location<'static>>>,
28    // to make not sync since `impl<T: ?Sized> !Sync for RefCell<T> {}` is not possible on stable outside of core
29    marker: PhantomData<*mut T>,
30    value: UnsafeCell<T>,
31}
32
33/// An error returned by [`RefCell::try_borrow`].
34#[non_exhaustive]
35#[derive(Debug)]
36pub struct BorrowError {
37    #[cfg(feature = "debug_refcell")]
38    location: &'static core::panic::Location<'static>,
39}
40
41impl Display for BorrowError {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        #[cfg(feature = "debug_refcell")]
44        let res = write!(
45            f,
46            "RefCell already mutably borrowed; a previous borrow was at {}",
47            self.location
48        );
49
50        #[cfg(not(feature = "debug_refcell"))]
51        let res = Display::fmt("RefCell already mutably borrowed", f);
52
53        res
54    }
55}
56
57/// An error returned by [`RefCell::try_borrow_mut`].
58#[non_exhaustive]
59#[derive(Debug)]
60pub struct BorrowMutError {
61    #[cfg(feature = "debug_refcell")]
62    location: &'static core::panic::Location<'static>,
63}
64
65impl Display for BorrowMutError {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        #[cfg(feature = "debug_refcell")]
68        let res = write!(
69            f,
70            "RefCell already borrowed; a previous borrow was at {}",
71            self.location
72        );
73
74        #[cfg(not(feature = "debug_refcell"))]
75        let res = Display::fmt("RefCell already borrowed", f);
76
77        res
78    }
79}
80
81// This ensures the panicking code is outlined from `borrow_mut` for `RefCell`.
82#[track_caller]
83#[cold]
84fn panic_already_borrowed(err: BorrowError) -> ! {
85    panic!("RefCell already borrowed: {err}")
86}
87
88// This ensures the panicking code is outlined from `borrow` for `RefCell`.
89#[track_caller]
90#[cold]
91fn panic_already_mutably_borrowed(err: BorrowMutError) -> ! {
92    panic!("RefCell already mutably borrowed: {err}")
93}
94
95// Positive values represent the number of `Ref` active. Negative values
96// represent the number of `RefMut` active. Multiple `RefMut`s can only be
97// active at a time if they refer to distinct, nonoverlapping components of a
98// `RefCell` (e.g., different ranges of a slice).
99//
100// `Ref` and `RefMut` are both two words in size, and so there will likely never
101// be enough `Ref`s or `RefMut`s in existence to overflow half of the `usize`
102// range. Thus, a `BorrowCounter` will probably never overflow or underflow.
103// However, this is not a guarantee, as a pathological program could repeatedly
104// create and then mem::forget `Ref`s or `RefMut`s. Thus, all code must
105// explicitly check for overflow and underflow in order to avoid unsafety, or at
106// least behave correctly in the event that overflow or underflow happens (e.g.,
107// see BorrowRef::new).
108type BorrowCounter = isize;
109const UNUSED: BorrowCounter = 0;
110
111#[inline(always)]
112const fn is_writing(x: BorrowCounter) -> bool {
113    x < UNUSED
114}
115
116#[inline(always)]
117const fn is_reading(x: BorrowCounter) -> bool {
118    x > UNUSED
119}
120
121impl<T> UncheckedRefCell<T> {
122    /// Creates a new `RefCell` containing `value`.
123    ///
124    /// # Examples
125    ///
126    /// ```
127    /// use std::cell::RefCell;
128    ///
129    /// let c = RefCell::new(5);
130    /// ```
131    #[inline]
132    pub const fn new(value: T) -> UncheckedRefCell<T> {
133        UncheckedRefCell {
134            value: UnsafeCell::new(value),
135            #[cfg(any(feature = "checked", debug_assertions))]
136            borrow: Cell::new(UNUSED),
137            marker: PhantomData,
138            #[cfg(feature = "debug_refcell")]
139            borrowed_at: Cell::new(None),
140        }
141    }
142
143    /// Consumes the `RefCell`, returning the wrapped value.
144    ///
145    /// # Examples
146    ///
147    /// ```
148    /// use std::cell::RefCell;
149    ///
150    /// let c = RefCell::new(5);
151    ///
152    /// let five = c.into_inner();
153    /// ```
154    #[inline]
155    pub fn into_inner(self) -> T {
156        // Since this function takes `self` (the `RefCell`) by value, the
157        // compiler statically verifies that it is not currently borrowed.
158        self.value.into_inner()
159    }
160
161    /// Replaces the wrapped value with a new one, returning the old value,
162    /// without deinitializing either one.
163    ///
164    /// This function corresponds to [`std::mem::replace`](../mem/fn.replace.html).
165    ///
166    /// # Panics
167    ///
168    /// Panics if the value is currently borrowed.
169    ///
170    /// # Examples
171    ///
172    /// ```
173    /// use std::cell::RefCell;
174    /// let cell = RefCell::new(5);
175    /// let old_value = cell.replace(6);
176    /// assert_eq!(old_value, 5);
177    /// assert_eq!(cell, RefCell::new(6));
178    /// ```
179    #[track_caller]
180    pub fn replace(&self, t: T) -> T {
181        mem::replace(&mut self.borrow_mut(), t)
182    }
183
184    /// Replaces the wrapped value with a new one computed from `f`, returning
185    /// the old value, without deinitializing either one.
186    ///
187    /// # Panics
188    ///
189    /// Panics if the value is currently borrowed.
190    ///
191    /// # Examples
192    ///
193    /// ```
194    /// use std::cell::RefCell;
195    /// let cell = RefCell::new(5);
196    /// let old_value = cell.replace_with(|&mut old| old + 1);
197    /// assert_eq!(old_value, 5);
198    /// assert_eq!(cell, RefCell::new(6));
199    /// ```
200    #[inline]
201    #[track_caller]
202    pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T {
203        let mut_borrow = &mut *self.borrow_mut();
204        let replacement = f(mut_borrow);
205        mem::replace(mut_borrow, replacement)
206    }
207
208    /// Swaps the wrapped value of `self` with the wrapped value of `other`,
209    /// without deinitializing either one.
210    ///
211    /// This function corresponds to [`std::mem::swap`](../mem/fn.swap.html).
212    ///
213    /// # Panics
214    ///
215    /// Panics if the value in either `RefCell` is currently borrowed, or
216    /// if `self` and `other` point to the same `RefCell`.
217    ///
218    /// # Examples
219    ///
220    /// ```
221    /// use std::cell::RefCell;
222    /// let c = RefCell::new(5);
223    /// let d = RefCell::new(6);
224    /// c.swap(&d);
225    /// assert_eq!(c, RefCell::new(6));
226    /// assert_eq!(d, RefCell::new(5));
227    /// ```
228    #[inline]
229    pub fn swap(&self, other: &Self) {
230        mem::swap(&mut *self.borrow_mut(), &mut *other.borrow_mut())
231    }
232}
233
234impl<T: ?Sized> UncheckedRefCell<T> {
235    /// Immutably borrows the wrapped value.
236    ///
237    /// The borrow lasts until the returned `Ref` exits scope. Multiple
238    /// immutable borrows can be taken out at the same time.
239    ///
240    /// # Panics
241    ///
242    /// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
243    /// [`try_borrow`](#method.try_borrow).
244    ///
245    /// # Examples
246    ///
247    /// ```
248    /// use std::cell::RefCell;
249    ///
250    /// let c = RefCell::new(5);
251    ///
252    /// let borrowed_five = c.borrow();
253    /// let borrowed_five2 = c.borrow();
254    /// ```
255    ///
256    /// An example of panic:
257    ///
258    /// ```should_panic
259    /// use std::cell::RefCell;
260    ///
261    /// let c = RefCell::new(5);
262    ///
263    /// let m = c.borrow_mut();
264    /// let b = c.borrow(); // this causes a panic
265    /// ```
266    #[inline]
267    #[track_caller]
268    pub fn borrow(&self) -> Ref<'_, T> {
269        match self.try_borrow() {
270            Ok(b) => b,
271            Err(err) => panic_already_borrowed(err),
272        }
273    }
274
275    /// Immutably borrows the wrapped value, returning an error if the value is currently mutably
276    /// borrowed.
277    ///
278    /// The borrow lasts until the returned `Ref` exits scope. Multiple immutable borrows can be
279    /// taken out at the same time.
280    ///
281    /// This is the non-panicking variant of [`borrow`](#method.borrow).
282    ///
283    /// # Examples
284    ///
285    /// ```
286    /// use std::cell::RefCell;
287    ///
288    /// let c = RefCell::new(5);
289    ///
290    /// {
291    ///     let m = c.borrow_mut();
292    ///     assert!(c.try_borrow().is_err());
293    /// }
294    ///
295    /// {
296    ///     let m = c.borrow();
297    ///     assert!(c.try_borrow().is_ok());
298    /// }
299    /// ```
300    #[inline]
301    pub fn try_borrow(&self) -> Result<Ref<'_, T>, BorrowError> {
302        #[cfg(any(feature = "checked", debug_assertions))]
303        match BorrowRef::new(&self.borrow) {
304            Some(b) => {
305                // SAFETY: `BorrowRef` ensures that there is only immutable access
306                // to the value while borrowed.
307                let value = unsafe { NonNull::new_unchecked(self.value.get()) };
308                Ok(Ref { value, borrow: b })
309            }
310            None => Err(BorrowError {
311                // If a borrow occurred, then we must already have an outstanding borrow,
312                // so `borrowed_at` will be `Some`
313                #[cfg(feature = "debug_refcell")]
314                location: self.borrowed_at.get().unwrap(),
315            }),
316        }
317        #[cfg(not(any(feature = "checked", debug_assertions)))]
318        {
319            // SAFETY: `BorrowRef` ensures that there is only immutable access
320            // to the value while borrowed.
321            let value = unsafe { NonNull::new_unchecked(self.value.get()) };
322            Ok(Ref {
323                value,
324                marker: PhantomData,
325            })
326        }
327    }
328
329    /// Mutably borrows the wrapped value.
330    ///
331    /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived
332    /// from it exit scope. The value cannot be borrowed while this borrow is
333    /// active.
334    ///
335    /// # Panics
336    ///
337    /// Panics if the value is currently borrowed. For a non-panicking variant, use
338    /// [`try_borrow_mut`](#method.try_borrow_mut).
339    ///
340    /// # Examples
341    ///
342    /// ```
343    /// use std::cell::RefCell;
344    ///
345    /// let c = RefCell::new("hello".to_owned());
346    ///
347    /// *c.borrow_mut() = "bonjour".to_owned();
348    ///
349    /// assert_eq!(&*c.borrow(), "bonjour");
350    /// ```
351    ///
352    /// An example of panic:
353    ///
354    /// ```should_panic
355    /// use std::cell::RefCell;
356    ///
357    /// let c = RefCell::new(5);
358    /// let m = c.borrow();
359    ///
360    /// let b = c.borrow_mut(); // this causes a panic
361    /// ```
362    #[inline]
363    #[track_caller]
364    pub fn borrow_mut(&self) -> RefMut<'_, T> {
365        match self.try_borrow_mut() {
366            Ok(b) => b,
367            Err(err) => panic_already_mutably_borrowed(err),
368        }
369    }
370
371    /// Mutably borrows the wrapped value, returning an error if the value is currently borrowed.
372    ///
373    /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived
374    /// from it exit scope. The value cannot be borrowed while this borrow is
375    /// active.
376    ///
377    /// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
378    ///
379    /// # Examples
380    ///
381    /// ```
382    /// use std::cell::RefCell;
383    ///
384    /// let c = RefCell::new(5);
385    ///
386    /// {
387    ///     let m = c.borrow();
388    ///     assert!(c.try_borrow_mut().is_err());
389    /// }
390    ///
391    /// assert!(c.try_borrow_mut().is_ok());
392    /// ```
393    #[inline]
394    #[cfg_attr(feature = "debug_refcell", track_caller)]
395    pub fn try_borrow_mut(&self) -> Result<RefMut<'_, T>, BorrowMutError> {
396        #[cfg(any(feature = "checked", debug_assertions))]
397        {
398            match BorrowRefMut::new(&self.borrow) {
399                Some(b) => {
400                    #[cfg(feature = "debug_refcell")]
401                    {
402                        self.borrowed_at
403                            .replace(Some(core::panic::Location::caller()));
404                    }
405
406                    // SAFETY: `BorrowRefMut` guarantees unique access.
407                    let value = unsafe { NonNull::new_unchecked(self.value.get()) };
408                    Ok(RefMut {
409                        value,
410                        borrow: b,
411                        marker: PhantomData,
412                    })
413                }
414                None => Err(BorrowMutError {
415                    // If a borrow occurred, then we must already have an outstanding borrow,
416                    // so `borrowed_at` will be `Some`
417                    #[cfg(feature = "debug_refcell")]
418                    location: self.borrowed_at.get().unwrap(),
419                }),
420            }
421        }
422        #[cfg(not(any(feature = "checked", debug_assertions)))]
423        {
424            let value = unsafe { NonNull::new_unchecked(self.value.get()) };
425            Ok(RefMut {
426                value,
427                marker: PhantomData,
428            })
429        }
430    }
431
432    /// Returns a raw pointer to the underlying data in this cell.
433    ///
434    /// # Examples
435    ///
436    /// ```
437    /// use std::cell::RefCell;
438    ///
439    /// let c = RefCell::new(5);
440    ///
441    /// let ptr = c.as_ptr();
442    /// ```
443    #[inline]
444    pub const fn as_ptr(&self) -> *mut T {
445        self.value.get()
446    }
447
448    /// Returns a mutable reference to the underlying data.
449    ///
450    /// Since this method borrows `RefCell` mutably, it is statically guaranteed
451    /// that no borrows to the underlying data exist. The dynamic checks inherent
452    /// in [`borrow_mut`] and most other methods of `RefCell` are therefore
453    /// unnecessary. Note that this method does not reset the borrowing state if borrows were previously leaked
454    /// (e.g., via [`forget()`] on a [`Ref`] or [`RefMut`]). For that purpose,
455    /// consider using the unstable [`undo_leak`] method.
456    ///
457    /// This method can only be called if `RefCell` can be mutably borrowed,
458    /// which in general is only the case directly after the `RefCell` has
459    /// been created. In these situations, skipping the aforementioned dynamic
460    /// borrowing checks may yield better ergonomics and runtime-performance.
461    ///
462    /// In most situations where `RefCell` is used, it can't be borrowed mutably.
463    /// Use [`borrow_mut`] to get mutable access to the underlying data then.
464    ///
465    /// [`borrow_mut`]: RefCell::borrow_mut()
466    /// [`forget()`]: mem::forget
467    /// [`undo_leak`]: RefCell::undo_leak()
468    ///
469    /// # Examples
470    ///
471    /// ```
472    /// use std::cell::RefCell;
473    ///
474    /// let mut c = RefCell::new(5);
475    /// *c.get_mut() += 1;
476    ///
477    /// assert_eq!(c, RefCell::new(6));
478    /// ```
479    #[inline]
480    pub const fn get_mut(&mut self) -> &mut T {
481        self.value.get_mut()
482    }
483
484    /// Undo the effect of leaked guards on the borrow state of the `RefCell`.
485    ///
486    /// This call is similar to [`get_mut`] but more specialized. It borrows `RefCell` mutably to
487    /// ensure no borrows exist and then resets the state tracking shared borrows. This is relevant
488    /// if some `Ref` or `RefMut` borrows have been leaked.
489    ///
490    /// [`get_mut`]: RefCell::get_mut()
491    ///
492    /// # Examples
493    ///
494    /// ```
495    /// #![feature(cell_leak)]
496    /// use std::cell::RefCell;
497    ///
498    /// let mut c = RefCell::new(0);
499    /// std::mem::forget(c.borrow_mut());
500    ///
501    /// assert!(c.try_borrow().is_err());
502    /// c.undo_leak();
503    /// assert!(c.try_borrow().is_ok());
504    /// ```
505    pub const fn undo_leak(&mut self) -> &mut T {
506        #[cfg(any(feature = "checked", debug_assertions))]
507        {
508            *self.borrow.get_mut() = UNUSED;
509        }
510        self.get_mut()
511    }
512
513    /// Immutably borrows the wrapped value, returning an error if the value is
514    /// currently mutably borrowed.
515    ///
516    /// # Safety
517    ///
518    /// Unlike `RefCell::borrow`, this method is unsafe because it does not
519    /// return a `Ref`, thus leaving the borrow flag untouched. Mutably
520    /// borrowing the `RefCell` while the reference returned by this method
521    /// is alive is undefined behavior.
522    ///
523    /// # Examples
524    ///
525    /// ```
526    /// use std::cell::RefCell;
527    ///
528    /// let c = RefCell::new(5);
529    ///
530    /// {
531    ///     let m = c.borrow_mut();
532    ///     assert!(unsafe { c.try_borrow_unguarded() }.is_err());
533    /// }
534    ///
535    /// {
536    ///     let m = c.borrow();
537    ///     assert!(unsafe { c.try_borrow_unguarded() }.is_ok());
538    /// }
539    /// ```
540    #[inline]
541    pub const unsafe fn try_borrow_unguarded(&self) -> Result<&T, BorrowError> {
542        #[cfg(any(feature = "checked", debug_assertions))]
543        {
544            if !is_writing(self.borrow.get()) {
545                // SAFETY: We check that nobody is actively writing now, but it is
546                // the caller's responsibility to ensure that nobody writes until
547                // the returned reference is no longer in use.
548                // Also, `self.value.get()` refers to the value owned by `self`
549                // and is thus guaranteed to be valid for the lifetime of `self`.
550                Ok(unsafe { &*self.value.get() })
551            } else {
552                Err(BorrowError {
553                    // If a borrow occurred, then we must already have an outstanding borrow,
554                    // so `borrowed_at` will be `Some`
555                    #[cfg(feature = "debug_refcell")]
556                    location: self.borrowed_at.get().unwrap(),
557                })
558            }
559        }
560        #[cfg(not(any(feature = "checked", debug_assertions)))]
561        Ok(unsafe { &*self.value.get() })
562    }
563}
564
565impl<T: Default> UncheckedRefCell<T> {
566    /// Takes the wrapped value, leaving `Default::default()` in its place.
567    ///
568    /// # Panics
569    ///
570    /// Panics if the value is currently borrowed.
571    ///
572    /// # Examples
573    ///
574    /// ```
575    /// use std::cell::RefCell;
576    ///
577    /// let c = RefCell::new(5);
578    /// let five = c.take();
579    ///
580    /// assert_eq!(five, 5);
581    /// assert_eq!(c.into_inner(), 0);
582    /// ```
583    pub fn take(&self) -> T {
584        self.replace(Default::default())
585    }
586}
587
588unsafe impl<T: ?Sized> Send for UncheckedRefCell<T> where T: Send {}
589
590impl<T: Clone> Clone for UncheckedRefCell<T> {
591    /// # Panics
592    ///
593    /// Panics if the value is currently mutably borrowed.
594    #[inline]
595    #[track_caller]
596    fn clone(&self) -> UncheckedRefCell<T> {
597        UncheckedRefCell::new(self.borrow().clone())
598    }
599
600    /// # Panics
601    ///
602    /// Panics if `source` is currently mutably borrowed.
603    #[inline]
604    #[track_caller]
605    fn clone_from(&mut self, source: &Self) {
606        self.get_mut().clone_from(&source.borrow())
607    }
608}
609
610impl<T: Default> Default for UncheckedRefCell<T> {
611    /// Creates a `RefCell<T>`, with the `Default` value for T.
612    #[inline]
613    fn default() -> UncheckedRefCell<T> {
614        UncheckedRefCell::new(Default::default())
615    }
616}
617
618impl<T: ?Sized + PartialEq> PartialEq for UncheckedRefCell<T> {
619    /// # Panics
620    ///
621    /// Panics if the value in either `RefCell` is currently mutably borrowed.
622    #[inline]
623    fn eq(&self, other: &UncheckedRefCell<T>) -> bool {
624        *self.borrow() == *other.borrow()
625    }
626}
627
628impl<T: ?Sized + Eq> Eq for UncheckedRefCell<T> {}
629
630impl<T: ?Sized + PartialOrd> PartialOrd for UncheckedRefCell<T> {
631    /// # Panics
632    ///
633    /// Panics if the value in either `RefCell` is currently mutably borrowed.
634    #[inline]
635    fn partial_cmp(&self, other: &UncheckedRefCell<T>) -> Option<Ordering> {
636        self.borrow().partial_cmp(&*other.borrow())
637    }
638
639    /// # Panics
640    ///
641    /// Panics if the value in either `RefCell` is currently mutably borrowed.
642    #[inline]
643    fn lt(&self, other: &UncheckedRefCell<T>) -> bool {
644        *self.borrow() < *other.borrow()
645    }
646
647    /// # Panics
648    ///
649    /// Panics if the value in either `RefCell` is currently mutably borrowed.
650    #[inline]
651    fn le(&self, other: &UncheckedRefCell<T>) -> bool {
652        *self.borrow() <= *other.borrow()
653    }
654
655    /// # Panics
656    ///
657    /// Panics if the value in either `RefCell` is currently mutably borrowed.
658    #[inline]
659    fn gt(&self, other: &UncheckedRefCell<T>) -> bool {
660        *self.borrow() > *other.borrow()
661    }
662
663    /// # Panics
664    ///
665    /// Panics if the value in either `RefCell` is currently mutably borrowed.
666    #[inline]
667    fn ge(&self, other: &UncheckedRefCell<T>) -> bool {
668        *self.borrow() >= *other.borrow()
669    }
670}
671
672impl<T: ?Sized + Ord> Ord for UncheckedRefCell<T> {
673    /// # Panics
674    ///
675    /// Panics if the value in either `RefCell` is currently mutably borrowed.
676    #[inline]
677    fn cmp(&self, other: &UncheckedRefCell<T>) -> Ordering {
678        self.borrow().cmp(&*other.borrow())
679    }
680}
681
682impl<T> From<T> for UncheckedRefCell<T> {
683    /// Creates a new `RefCell<T>` containing the given value.
684    fn from(t: T) -> UncheckedRefCell<T> {
685        UncheckedRefCell::new(t)
686    }
687}
688
689struct BorrowRef<'b> {
690    borrow: &'b Cell<BorrowCounter>,
691}
692
693impl<'b> BorrowRef<'b> {
694    #[inline]
695    const fn new(borrow: &'b Cell<BorrowCounter>) -> Option<BorrowRef<'b>> {
696        let b = borrow.get().wrapping_add(1);
697        if !is_reading(b) {
698            // Incrementing borrow can result in a non-reading value (<= 0) in these cases:
699            // 1. It was < 0, i.e. there are writing borrows, so we can't allow a read borrow
700            //    due to Rust's reference aliasing rules
701            // 2. It was isize::MAX (the max amount of reading borrows) and it overflowed
702            //    into isize::MIN (the max amount of writing borrows) so we can't allow
703            //    an additional read borrow because isize can't represent so many read borrows
704            //    (this can only happen if you mem::forget more than a small constant amount of
705            //    `Ref`s, which is not good practice)
706            None
707        } else {
708            // Incrementing borrow can result in a reading value (> 0) in these cases:
709            // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow
710            // 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize
711            //    is large enough to represent having one more read borrow
712            borrow.replace(b);
713            Some(BorrowRef { borrow })
714        }
715    }
716}
717
718impl Drop for BorrowRef<'_> {
719    #[inline]
720    fn drop(&mut self) {
721        let borrow = self.borrow.get();
722        debug_assert!(is_reading(borrow));
723        self.borrow.replace(borrow - 1);
724    }
725}
726
727impl Clone for BorrowRef<'_> {
728    #[inline]
729    fn clone(&self) -> Self {
730        // Since this Ref exists, we know the borrow flag
731        // is a reading borrow.
732        let borrow = self.borrow.get();
733        debug_assert!(is_reading(borrow));
734        // Prevent the borrow counter from overflowing into
735        // a writing borrow.
736        assert!(borrow != BorrowCounter::MAX);
737        self.borrow.replace(borrow + 1);
738        BorrowRef {
739            borrow: self.borrow,
740        }
741    }
742}
743
744/// Wraps a borrowed reference to a value in a `RefCell` box.
745/// A wrapper type for an immutably borrowed value from a `RefCell<T>`.
746///
747/// See the [module-level documentation](self) for more.
748pub struct Ref<'b, T: ?Sized + 'b> {
749    // NB: we use a pointer instead of `&'b T` to avoid `noalias` violations, because a
750    // `Ref` argument doesn't hold immutability for its whole scope, only until it drops.
751    // `NonNull` is also covariant over `T`, just like we would have with `&T`.
752    value: NonNull<T>,
753    #[cfg(any(feature = "checked", debug_assertions))]
754    borrow: BorrowRef<'b>,
755    #[cfg(not(any(feature = "checked", debug_assertions)))]
756    marker: PhantomData<&'b ()>,
757}
758
759impl<T: ?Sized> Deref for Ref<'_, T> {
760    type Target = T;
761
762    #[inline]
763    fn deref(&self) -> &T {
764        // SAFETY: the value is accessible as long as we hold our borrow.
765        unsafe { self.value.as_ref() }
766    }
767}
768
769impl<'b, T: ?Sized> Ref<'b, T> {
770    /// Copies a `Ref`.
771    ///
772    /// The `RefCell` is already immutably borrowed, so this cannot fail.
773    ///
774    /// This is an associated function that needs to be used as
775    /// `Ref::clone(...)`. A `Clone` implementation or a method would interfere
776    /// with the widespread use of `r.borrow().clone()` to clone the contents of
777    /// a `RefCell`.
778    #[must_use]
779    #[inline]
780    pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> {
781        Ref {
782            value: orig.value,
783            #[cfg(any(feature = "checked", debug_assertions))]
784            borrow: orig.borrow.clone(),
785            #[cfg(not(any(feature = "checked", debug_assertions)))]
786            marker: PhantomData,
787        }
788    }
789
790    /// Makes a new `Ref` for a component of the borrowed data.
791    ///
792    /// The `RefCell` is already immutably borrowed, so this cannot fail.
793    ///
794    /// This is an associated function that needs to be used as `Ref::map(...)`.
795    /// A method would interfere with methods of the same name on the contents
796    /// of a `RefCell` used through `Deref`.
797    ///
798    /// # Examples
799    ///
800    /// ```
801    /// use std::cell::{RefCell, Ref};
802    ///
803    /// let c = RefCell::new((5, 'b'));
804    /// let b1: Ref<'_, (u32, char)> = c.borrow();
805    /// let b2: Ref<'_, u32> = Ref::map(b1, |t| &t.0);
806    /// assert_eq!(*b2, 5)
807    /// ```
808    #[inline]
809    pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
810    where
811        F: FnOnce(&T) -> &U,
812    {
813        Ref {
814            value: NonNull::from(f(&*orig)),
815            #[cfg(any(feature = "checked", debug_assertions))]
816            borrow: orig.borrow,
817            #[cfg(not(any(feature = "checked", debug_assertions)))]
818            marker: PhantomData,
819        }
820    }
821
822    /// Makes a new `Ref` for an optional component of the borrowed data. The
823    /// original guard is returned as an `Err(..)` if the closure returns
824    /// `None`.
825    ///
826    /// The `RefCell` is already immutably borrowed, so this cannot fail.
827    ///
828    /// This is an associated function that needs to be used as
829    /// `Ref::filter_map(...)`. A method would interfere with methods of the same
830    /// name on the contents of a `RefCell` used through `Deref`.
831    ///
832    /// # Examples
833    ///
834    /// ```
835    /// use std::cell::{RefCell, Ref};
836    ///
837    /// let c = RefCell::new(vec![1, 2, 3]);
838    /// let b1: Ref<'_, Vec<u32>> = c.borrow();
839    /// let b2: Result<Ref<'_, u32>, _> = Ref::filter_map(b1, |v| v.get(1));
840    /// assert_eq!(*b2.unwrap(), 2);
841    /// ```
842    #[inline]
843    pub fn filter_map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Result<Ref<'b, U>, Self>
844    where
845        F: FnOnce(&T) -> Option<&U>,
846    {
847        match f(&*orig) {
848            Some(value) => Ok(Ref {
849                value: NonNull::from(value),
850                #[cfg(any(feature = "checked", debug_assertions))]
851                borrow: orig.borrow,
852                #[cfg(not(any(feature = "checked", debug_assertions)))]
853                marker: PhantomData,
854            }),
855            None => Err(orig),
856        }
857    }
858
859    /// Tries to makes a new `Ref` for a component of the borrowed data.
860    /// On failure, the original guard is returned alongside with the error
861    /// returned by the closure.
862    ///
863    /// The `RefCell` is already immutably borrowed, so this cannot fail.
864    ///
865    /// This is an associated function that needs to be used as
866    /// `Ref::try_map(...)`. A method would interfere with methods of the same
867    /// name on the contents of a `RefCell` used through `Deref`.
868    ///
869    /// # Examples
870    ///
871    /// ```
872    /// #![feature(refcell_try_map)]
873    /// use std::cell::{RefCell, Ref};
874    /// use std::str::{from_utf8, Utf8Error};
875    ///
876    /// let c = RefCell::new(vec![0xF0, 0x9F, 0xA6 ,0x80]);
877    /// let b1: Ref<'_, Vec<u8>> = c.borrow();
878    /// let b2: Result<Ref<'_, str>, _> = Ref::try_map(b1, |v| from_utf8(v));
879    /// assert_eq!(&*b2.unwrap(), "🦀");
880    ///
881    /// let c = RefCell::new(vec![0xF0, 0x9F, 0xA6]);
882    /// let b1: Ref<'_, Vec<u8>> = c.borrow();
883    /// let b2: Result<_, (Ref<'_, Vec<u8>>, Utf8Error)> = Ref::try_map(b1, |v| from_utf8(v));
884    /// let (b3, e) = b2.unwrap_err();
885    /// assert_eq!(*b3, vec![0xF0, 0x9F, 0xA6]);
886    /// assert_eq!(e.valid_up_to(), 0);
887    /// ```
888    #[inline]
889    pub fn try_map<U: ?Sized, E>(
890        orig: Ref<'b, T>,
891        f: impl FnOnce(&T) -> Result<&U, E>,
892    ) -> Result<Ref<'b, U>, (Self, E)> {
893        match f(&*orig) {
894            Ok(value) => Ok(Ref {
895                value: NonNull::from(value),
896                #[cfg(any(feature = "checked", debug_assertions))]
897                borrow: orig.borrow,
898                #[cfg(not(any(feature = "checked", debug_assertions)))]
899                marker: PhantomData,
900            }),
901            Err(e) => Err((orig, e)),
902        }
903    }
904
905    /// Splits a `Ref` into multiple `Ref`s for different components of the
906    /// borrowed data.
907    ///
908    /// The `RefCell` is already immutably borrowed, so this cannot fail.
909    ///
910    /// This is an associated function that needs to be used as
911    /// `Ref::map_split(...)`. A method would interfere with methods of the same
912    /// name on the contents of a `RefCell` used through `Deref`.
913    ///
914    /// # Examples
915    ///
916    /// ```
917    /// use std::cell::{Ref, RefCell};
918    ///
919    /// let cell = RefCell::new([1, 2, 3, 4]);
920    /// let borrow = cell.borrow();
921    /// let (begin, end) = Ref::map_split(borrow, |slice| slice.split_at(2));
922    /// assert_eq!(*begin, [1, 2]);
923    /// assert_eq!(*end, [3, 4]);
924    /// ```+>
925    #[inline]
926    pub fn map_split<U: ?Sized, V: ?Sized, F>(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>)
927    where
928        F: FnOnce(&T) -> (&U, &V),
929    {
930        let (a, b) = f(&*orig);
931        #[cfg(any(feature = "checked", debug_assertions))]
932        let borrow = orig.borrow.clone();
933        (
934            Ref {
935                value: NonNull::from(a),
936                #[cfg(any(feature = "checked", debug_assertions))]
937                borrow,
938                #[cfg(not(any(feature = "checked", debug_assertions)))]
939                marker: PhantomData,
940            },
941            Ref {
942                value: NonNull::from(b),
943                #[cfg(any(feature = "checked", debug_assertions))]
944                borrow: orig.borrow,
945                #[cfg(not(any(feature = "checked", debug_assertions)))]
946                marker: PhantomData,
947            },
948        )
949    }
950
951    /// Converts into a reference to the underlying data.
952    ///
953    /// The underlying `RefCell` can never be mutably borrowed from again and will always appear
954    /// already immutably borrowed. It is not a good idea to leak more than a constant number of
955    /// references. The `RefCell` can be immutably borrowed again if only a smaller number of leaks
956    /// have occurred in total.
957    ///
958    /// This is an associated function that needs to be used as
959    /// `Ref::leak(...)`. A method would interfere with methods of the
960    /// same name on the contents of a `RefCell` used through `Deref`.
961    ///
962    /// # Examples
963    ///
964    /// ```
965    /// #![feature(cell_leak)]
966    /// use std::cell::{RefCell, Ref};
967    /// let cell = RefCell::new(0);
968    ///
969    /// let value = Ref::leak(cell.borrow());
970    /// assert_eq!(*value, 0);
971    ///
972    /// assert!(cell.try_borrow().is_ok());
973    /// assert!(cell.try_borrow_mut().is_err());
974    /// ```
975    pub fn leak(orig: Ref<'b, T>) -> &'b T {
976        // By forgetting this Ref we ensure that the borrow counter in the RefCell can't go back to
977        // UNUSED within the lifetime `'b`. Resetting the reference tracking state would require a
978        // unique reference to the borrowed RefCell. No further mutable references can be created
979        // from the original cell.
980        #[cfg(any(feature = "checked", debug_assertions))]
981        mem::forget(orig.borrow);
982        // SAFETY: after forgetting, we can form a reference for the rest of lifetime `'b`.
983        unsafe { orig.value.as_ref() }
984    }
985}
986
987impl<T: ?Sized + fmt::Display> fmt::Display for Ref<'_, T> {
988    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
989        (**self).fmt(f)
990    }
991}
992
993impl<'b, T: ?Sized> RefMut<'b, T> {
994    /// Makes a new `RefMut` for a component of the borrowed data, e.g., an enum
995    /// variant.
996    ///
997    /// The `RefCell` is already mutably borrowed, so this cannot fail.
998    ///
999    /// This is an associated function that needs to be used as
1000    /// `RefMut::map(...)`. A method would interfere with methods of the same
1001    /// name on the contents of a `RefCell` used through `Deref`.
1002    ///
1003    /// # Examples
1004    ///
1005    /// ```
1006    /// use std::cell::{RefCell, RefMut};
1007    ///
1008    /// let c = RefCell::new((5, 'b'));
1009    /// {
1010    ///     let b1: RefMut<'_, (u32, char)> = c.borrow_mut();
1011    ///     let mut b2: RefMut<'_, u32> = RefMut::map(b1, |t| &mut t.0);
1012    ///     assert_eq!(*b2, 5);
1013    ///     *b2 = 42;
1014    /// }
1015    /// assert_eq!(*c.borrow(), (42, 'b'));
1016    /// ```
1017    #[inline]
1018    pub fn map<U: ?Sized, F>(mut orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
1019    where
1020        F: FnOnce(&mut T) -> &mut U,
1021    {
1022        let value = NonNull::from(f(&mut *orig));
1023        RefMut {
1024            value,
1025            #[cfg(any(feature = "checked", debug_assertions))]
1026            borrow: orig.borrow,
1027            marker: PhantomData,
1028        }
1029    }
1030
1031    /// Makes a new `RefMut` for an optional component of the borrowed data. The
1032    /// original guard is returned as an `Err(..)` if the closure returns
1033    /// `None`.
1034    ///
1035    /// The `RefCell` is already mutably borrowed, so this cannot fail.
1036    ///
1037    /// This is an associated function that needs to be used as
1038    /// `RefMut::filter_map(...)`. A method would interfere with methods of the
1039    /// same name on the contents of a `RefCell` used through `Deref`.
1040    ///
1041    /// # Examples
1042    ///
1043    /// ```
1044    /// use std::cell::{RefCell, RefMut};
1045    ///
1046    /// let c = RefCell::new(vec![1, 2, 3]);
1047    ///
1048    /// {
1049    ///     let b1: RefMut<'_, Vec<u32>> = c.borrow_mut();
1050    ///     let mut b2: Result<RefMut<'_, u32>, _> = RefMut::filter_map(b1, |v| v.get_mut(1));
1051    ///
1052    ///     if let Ok(mut b2) = b2 {
1053    ///         *b2 += 2;
1054    ///     }
1055    /// }
1056    ///
1057    /// assert_eq!(*c.borrow(), vec![1, 4, 3]);
1058    /// ```
1059    #[inline]
1060    pub fn filter_map<U: ?Sized, F>(mut orig: RefMut<'b, T>, f: F) -> Result<RefMut<'b, U>, Self>
1061    where
1062        F: FnOnce(&mut T) -> Option<&mut U>,
1063    {
1064        // SAFETY: function holds onto an exclusive reference for the duration
1065        // of its call through `orig`, and the pointer is only de-referenced
1066        // inside of the function call never allowing the exclusive reference to
1067        // escape.
1068        match f(&mut *orig) {
1069            Some(value) => Ok(RefMut {
1070                value: NonNull::from(value),
1071                #[cfg(any(feature = "checked", debug_assertions))]
1072                borrow: orig.borrow,
1073                marker: PhantomData,
1074            }),
1075            None => Err(orig),
1076        }
1077    }
1078
1079    /// Tries to makes a new `RefMut` for a component of the borrowed data.
1080    /// On failure, the original guard is returned alongside with the error
1081    /// returned by the closure.
1082    ///
1083    /// The `RefCell` is already mutably borrowed, so this cannot fail.
1084    ///
1085    /// This is an associated function that needs to be used as
1086    /// `RefMut::try_map(...)`. A method would interfere with methods of the same
1087    /// name on the contents of a `RefCell` used through `Deref`.
1088    ///
1089    /// # Examples
1090    ///
1091    /// ```
1092    /// #![feature(refcell_try_map)]
1093    /// use std::cell::{RefCell, RefMut};
1094    /// use std::str::{from_utf8_mut, Utf8Error};
1095    ///
1096    /// let c = RefCell::new(vec![0x68, 0x65, 0x6C, 0x6C, 0x6F]);
1097    /// {
1098    ///     let b1: RefMut<'_, Vec<u8>> = c.borrow_mut();
1099    ///     let b2: Result<RefMut<'_, str>, _> = RefMut::try_map(b1, |v| from_utf8_mut(v));
1100    ///     let mut b2 = b2.unwrap();
1101    ///     assert_eq!(&*b2, "hello");
1102    ///     b2.make_ascii_uppercase();
1103    /// }
1104    /// assert_eq!(*c.borrow(), "HELLO".as_bytes());
1105    ///
1106    /// let c = RefCell::new(vec![0xFF]);
1107    /// let b1: RefMut<'_, Vec<u8>> = c.borrow_mut();
1108    /// let b2: Result<_, (RefMut<'_, Vec<u8>>, Utf8Error)> = RefMut::try_map(b1, |v| from_utf8_mut(v));
1109    /// let (b3, e) = b2.unwrap_err();
1110    /// assert_eq!(*b3, vec![0xFF]);
1111    /// assert_eq!(e.valid_up_to(), 0);
1112    /// ```
1113    #[inline]
1114    pub fn try_map<U: ?Sized, E>(
1115        mut orig: RefMut<'b, T>,
1116        f: impl FnOnce(&mut T) -> Result<&mut U, E>,
1117    ) -> Result<RefMut<'b, U>, (Self, E)> {
1118        // SAFETY: function holds onto an exclusive reference for the duration
1119        // of its call through `orig`, and the pointer is only de-referenced
1120        // inside of the function call never allowing the exclusive reference to
1121        // escape.
1122        match f(&mut *orig) {
1123            Ok(value) => Ok(RefMut {
1124                value: NonNull::from(value),
1125                #[cfg(any(feature = "checked", debug_assertions))]
1126                borrow: orig.borrow,
1127                marker: PhantomData,
1128            }),
1129            Err(e) => Err((orig, e)),
1130        }
1131    }
1132
1133    /// Splits a `RefMut` into multiple `RefMut`s for different components of the
1134    /// borrowed data.
1135    ///
1136    /// The underlying `RefCell` will remain mutably borrowed until both
1137    /// returned `RefMut`s go out of scope.
1138    ///
1139    /// The `RefCell` is already mutably borrowed, so this cannot fail.
1140    ///
1141    /// This is an associated function that needs to be used as
1142    /// `RefMut::map_split(...)`. A method would interfere with methods of the
1143    /// same name on the contents of a `RefCell` used through `Deref`.
1144    ///
1145    /// # Examples
1146    ///
1147    /// ```
1148    /// use std::cell::{RefCell, RefMut};
1149    ///
1150    /// let cell = RefCell::new([1, 2, 3, 4]);
1151    /// let borrow = cell.borrow_mut();
1152    /// let (mut begin, mut end) = RefMut::map_split(borrow, |slice| slice.split_at_mut(2));
1153    /// assert_eq!(*begin, [1, 2]);
1154    /// assert_eq!(*end, [3, 4]);
1155    /// begin.copy_from_slice(&[4, 3]);
1156    /// end.copy_from_slice(&[2, 1]);
1157    /// ```
1158    #[inline]
1159    pub fn map_split<U: ?Sized, V: ?Sized, F>(
1160        mut orig: RefMut<'b, T>,
1161        f: F,
1162    ) -> (RefMut<'b, U>, RefMut<'b, V>)
1163    where
1164        F: FnOnce(&mut T) -> (&mut U, &mut V),
1165    {
1166        #[cfg(any(feature = "checked", debug_assertions))]
1167        let borrow = orig.borrow.clone();
1168        let (a, b) = f(&mut *orig);
1169        (
1170            RefMut {
1171                value: NonNull::from(a),
1172                #[cfg(any(feature = "checked", debug_assertions))]
1173                borrow,
1174                marker: PhantomData,
1175            },
1176            RefMut {
1177                value: NonNull::from(b),
1178                #[cfg(any(feature = "checked", debug_assertions))]
1179                borrow: orig.borrow,
1180                marker: PhantomData,
1181            },
1182        )
1183    }
1184
1185    /// Converts into a mutable reference to the underlying data.
1186    ///
1187    /// The underlying `RefCell` can not be borrowed from again and will always appear already
1188    /// mutably borrowed, making the returned reference the only to the interior.
1189    ///
1190    /// This is an associated function that needs to be used as
1191    /// `RefMut::leak(...)`. A method would interfere with methods of the
1192    /// same name on the contents of a `RefCell` used through `Deref`.
1193    ///
1194    /// # Examples
1195    ///
1196    /// ```
1197    /// #![feature(cell_leak)]
1198    /// use std::cell::{RefCell, RefMut};
1199    /// let cell = RefCell::new(0);
1200    ///
1201    /// let value = RefMut::leak(cell.borrow_mut());
1202    /// assert_eq!(*value, 0);
1203    /// *value = 1;
1204    ///
1205    /// assert!(cell.try_borrow_mut().is_err());
1206    /// ```
1207    pub fn leak(mut orig: RefMut<'b, T>) -> &'b mut T {
1208        // By forgetting this BorrowRefMut we ensure that the borrow counter in the RefCell can't
1209        // go back to UNUSED within the lifetime `'b`. Resetting the reference tracking state would
1210        // require a unique reference to the borrowed RefCell. No further references can be created
1211        // from the original cell within that lifetime, making the current borrow the only
1212        // reference for the remaining lifetime.
1213        #[cfg(any(feature = "checked", debug_assertions))]
1214        mem::forget(orig.borrow);
1215        // SAFETY: after forgetting, we can form a reference for the rest of lifetime `'b`.
1216        unsafe { orig.value.as_mut() }
1217    }
1218}
1219
1220struct BorrowRefMut<'b> {
1221    borrow: &'b Cell<BorrowCounter>,
1222}
1223
1224impl Drop for BorrowRefMut<'_> {
1225    #[inline]
1226    fn drop(&mut self) {
1227        let borrow = self.borrow.get();
1228        debug_assert!(is_writing(borrow));
1229        self.borrow.replace(borrow + 1);
1230    }
1231}
1232
1233impl<'b> BorrowRefMut<'b> {
1234    #[inline]
1235    const fn new(borrow: &'b Cell<BorrowCounter>) -> Option<BorrowRefMut<'b>> {
1236        // NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
1237        // mutable reference, and so there must currently be no existing
1238        // references. Thus, while clone increments the mutable refcount, here
1239        // we explicitly only allow going from UNUSED to UNUSED - 1.
1240        match borrow.get() {
1241            UNUSED => {
1242                borrow.replace(UNUSED - 1);
1243                Some(BorrowRefMut { borrow })
1244            }
1245            _ => None,
1246        }
1247    }
1248
1249    // Clones a `BorrowRefMut`.
1250    //
1251    // This is only valid if each `BorrowRefMut` is used to track a mutable
1252    // reference to a distinct, nonoverlapping range of the original object.
1253    // This isn't in a Clone impl so that code doesn't call this implicitly.
1254    #[inline]
1255    fn clone(&self) -> BorrowRefMut<'b> {
1256        let borrow = self.borrow.get();
1257        debug_assert!(is_writing(borrow));
1258        // Prevent the borrow counter from underflowing.
1259        assert!(borrow != BorrowCounter::MIN);
1260        self.borrow.set(borrow - 1);
1261        BorrowRefMut {
1262            borrow: self.borrow,
1263        }
1264    }
1265}
1266
1267/// A wrapper type for a mutably borrowed value from a `RefCell<T>`.
1268///
1269/// See the [module-level documentation](self) for more.
1270pub struct RefMut<'b, T: ?Sized + 'b> {
1271    // NB: we use a pointer instead of `&'b mut T` to avoid `noalias` violations, because a
1272    // `RefMut` argument doesn't hold exclusivity for its whole scope, only until it drops.
1273    value: NonNull<T>,
1274    #[cfg(any(feature = "checked", debug_assertions))]
1275    borrow: BorrowRefMut<'b>,
1276    // `NonNull` is covariant over `T`, so we need to reintroduce invariance.
1277    marker: PhantomData<&'b mut T>,
1278}
1279
1280impl<T: ?Sized> Deref for RefMut<'_, T> {
1281    type Target = T;
1282
1283    #[inline]
1284    fn deref(&self) -> &T {
1285        // SAFETY: the value is accessible as long as we hold our borrow.
1286        unsafe { self.value.as_ref() }
1287    }
1288}
1289
1290impl<T: ?Sized> DerefMut for RefMut<'_, T> {
1291    #[inline]
1292    fn deref_mut(&mut self) -> &mut T {
1293        // SAFETY: the value is accessible as long as we hold our borrow.
1294        unsafe { self.value.as_mut() }
1295    }
1296}
1297
1298impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
1299    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1300        (**self).fmt(f)
1301    }
1302}