Skip to main content

rs_matter/utils/
cell.rs

1/*
2 *
3 *    Copyright (c) 2024-2026 Project CHIP Authors
4 *
5 *    Licensed under the Apache License, Version 2.0 (the "License");
6 *    you may not use this file except in compliance with the License.
7 *    You may obtain a copy of the License at
8 *
9 *        http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *    Unless required by applicable law or agreed to in writing, software
12 *    distributed under the License is distributed on an "AS IS" BASIS,
13 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *    See the License for the specific language governing permissions and
15 *    limitations under the License.
16 */
17
18//! A modification of the Rust `RefCell` type which provides in-place initialization
19//! via `RefCell::init`.
20//!
21//! NOTE: TEMPORARY and subject to removal once all Matter state is hidden behind
22//! a `blmutex::Mutex` in future.
23
24#![allow(unexpected_cfgs)]
25#![allow(clippy::should_implement_trait)]
26
27use core::cell::{Cell, UnsafeCell};
28use core::cmp::Ordering;
29use core::fmt::{self, Debug, Display};
30use core::marker::PhantomData;
31use core::mem;
32use core::ops::{Deref, DerefMut};
33use core::ptr::NonNull;
34
35use super::init::{init, Init, UnsafeCellInit};
36
37/// A mutable memory location with dynamically checked borrow rules
38///
39/// See the [module-level documentation](self) for more.
40pub struct RefCell<T: ?Sized> {
41    borrow: Cell<BorrowFlag>,
42    // Stores the location of the earliest currently active borrow.
43    // This gets updated whenever we go from having zero borrows
44    // to having a single borrow. When a borrow occurs, this gets included
45    // in the generated `BorrowError`/`BorrowMutError`
46    #[cfg(feature = "debug_refcell")]
47    borrowed_at: Cell<Option<&'static crate::panic::Location<'static>>>,
48    _not_sync: PhantomData<*const ()>,
49    value: UnsafeCell<T>,
50}
51
52/// An error returned by [`RefCell::try_borrow`].
53#[non_exhaustive]
54pub struct BorrowError {
55    #[cfg(feature = "debug_refcell")]
56    location: &'static crate::panic::Location<'static>,
57}
58
59impl Debug for BorrowError {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        let mut builder = f.debug_struct("BorrowError");
62
63        #[cfg(feature = "debug_refcell")]
64        builder.field("location", self.location);
65
66        builder.finish()
67    }
68}
69
70impl Display for BorrowError {
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        Display::fmt("already mutably borrowed", f)
73    }
74}
75
76#[cfg(feature = "defmt")]
77impl defmt::Format for BorrowError {
78    fn format(&self, f: defmt::Formatter<'_>) {
79        defmt::write!(f, "already mutably borrowed")
80    }
81}
82
83/// An error returned by [`RefCell::try_borrow_mut`].
84#[non_exhaustive]
85pub struct BorrowMutError {
86    #[cfg(feature = "debug_refcell")]
87    location: &'static crate::panic::Location<'static>,
88}
89
90impl Debug for BorrowMutError {
91    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92        let mut builder = f.debug_struct("BorrowMutError");
93
94        #[cfg(feature = "debug_refcell")]
95        builder.field("location", self.location);
96
97        builder.finish()
98    }
99}
100
101impl Display for BorrowMutError {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        Display::fmt("already borrowed", f)
104    }
105}
106
107#[cfg(feature = "defmt")]
108impl defmt::Format for BorrowMutError {
109    fn format(&self, f: defmt::Formatter<'_>) {
110        defmt::write!(f, "already borrowed")
111    }
112}
113
114// This ensures the panicking code is outlined from `borrow_mut` for `RefCell`.
115#[inline(never)]
116#[track_caller]
117#[cold]
118fn panic_already_borrowed(err: BorrowMutError) -> ! {
119    panic!("already borrowed: {:?}", err)
120}
121
122// This ensures the panicking code is outlined from `borrow` for `RefCell`.
123#[inline(never)]
124#[track_caller]
125#[cold]
126fn panic_already_mutably_borrowed(err: BorrowError) -> ! {
127    panic!("already mutably borrowed: {:?}", err)
128}
129
130// Positive values represent the number of `Ref` active. Negative values
131// represent the number of `RefMut` active. Multiple `RefMut`s can only be
132// active at a time if they refer to distinct, nonoverlapping components of a
133// `RefCell` (e.g., different ranges of a slice).
134//
135// `Ref` and `RefMut` are both two words in size, and so there will likely never
136// be enough `Ref`s or `RefMut`s in existence to overflow half of the `usize`
137// range. Thus, a `BorrowFlag` will probably never overflow or underflow.
138// However, this is not a guarantee, as a pathological program could repeatedly
139// create and then mem::forget `Ref`s or `RefMut`s. Thus, all code must
140// explicitly check for overflow and underflow in order to avoid unsafety, or at
141// least behave correctly in the event that overflow or underflow happens (e.g.,
142// see BorrowRef::new).
143type BorrowFlag = isize;
144const UNUSED: BorrowFlag = 0;
145
146#[inline(always)]
147fn is_writing(x: BorrowFlag) -> bool {
148    x < UNUSED
149}
150
151#[inline(always)]
152fn is_reading(x: BorrowFlag) -> bool {
153    x > UNUSED
154}
155
156impl<T> RefCell<T> {
157    /// Creates a new `RefCell` containing `value`.
158    ///
159    /// # Examples
160    ///
161    /// ```
162    /// use std::cell::RefCell;
163    ///
164    /// let c = RefCell::new(5);
165    /// ```
166    #[inline]
167    pub const fn new(value: T) -> RefCell<T> {
168        RefCell {
169            value: UnsafeCell::new(value),
170            borrow: Cell::new(UNUSED),
171            #[cfg(feature = "debug_refcell")]
172            borrowed_at: Cell::new(None),
173            _not_sync: PhantomData,
174        }
175    }
176
177    /// Creates a new `RefCell` in-place initializer
178    /// by using the given value initializer.
179    pub fn init<I: Init<T>>(value: I) -> impl Init<Self> {
180        init!(Self {
181            value <- UnsafeCell::init(value),
182            borrow: Cell::new(UNUSED),
183            // #[cfg(feature = "debug_refcell")]
184            // borrowed_at: Cell::new(None),
185            _not_sync: PhantomData,
186        })
187    }
188
189    /// Consumes the `RefCell`, returning the wrapped value.
190    ///
191    /// # Examples
192    ///
193    /// ```
194    /// use std::cell::RefCell;
195    ///
196    /// let c = RefCell::new(5);
197    ///
198    /// let five = c.into_inner();
199    /// ```
200    #[inline]
201    pub fn into_inner(self) -> T {
202        // Since this function takes `self` (the `RefCell`) by value, the
203        // compiler statically verifies that it is not currently borrowed.
204        self.value.into_inner()
205    }
206
207    /// Replaces the wrapped value with a new one, returning the old value,
208    /// without deinitializing either one.
209    ///
210    /// This function corresponds to [`std::mem::replace`](../mem/fn.replace.html).
211    ///
212    /// # Panics
213    ///
214    /// Panics if the value is currently borrowed.
215    ///
216    /// # Examples
217    ///
218    /// ```
219    /// use std::cell::RefCell;
220    /// let cell = RefCell::new(5);
221    /// let old_value = cell.replace(6);
222    /// assert_eq!(old_value, 5);
223    /// assert_eq!(cell, RefCell::new(6));
224    /// ```
225    #[inline]
226    #[track_caller]
227    pub fn replace(&self, t: T) -> T {
228        mem::replace(&mut *self.borrow_mut(), t)
229    }
230
231    /// Replaces the wrapped value with a new one computed from `f`, returning
232    /// the old value, without deinitializing either one.
233    ///
234    /// # Panics
235    ///
236    /// Panics if the value is currently borrowed.
237    ///
238    /// # Examples
239    ///
240    /// ```
241    /// use std::cell::RefCell;
242    /// let cell = RefCell::new(5);
243    /// let old_value = cell.replace_with(|&mut old| old + 1);
244    /// assert_eq!(old_value, 5);
245    /// assert_eq!(cell, RefCell::new(6));
246    /// ```
247    #[inline]
248    #[track_caller]
249    pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T {
250        let mut_borrow = &mut *self.borrow_mut();
251        let replacement = f(mut_borrow);
252        mem::replace(mut_borrow, replacement)
253    }
254
255    /// Swaps the wrapped value of `self` with the wrapped value of `other`,
256    /// without deinitializing either one.
257    ///
258    /// This function corresponds to [`std::mem::swap`](../mem/fn.swap.html).
259    ///
260    /// # Panics
261    ///
262    /// Panics if the value in either `RefCell` is currently borrowed, or
263    /// if `self` and `other` point to the same `RefCell`.
264    ///
265    /// # Examples
266    ///
267    /// ```
268    /// use std::cell::RefCell;
269    /// let c = RefCell::new(5);
270    /// let d = RefCell::new(6);
271    /// c.swap(&d);
272    /// assert_eq!(c, RefCell::new(6));
273    /// assert_eq!(d, RefCell::new(5));
274    /// ```
275    #[inline]
276    pub fn swap(&self, other: &Self) {
277        mem::swap(&mut *self.borrow_mut(), &mut *other.borrow_mut())
278    }
279}
280
281impl<T: ?Sized> RefCell<T> {
282    /// Immutably borrows the wrapped value.
283    ///
284    /// The borrow lasts until the returned `Ref` exits scope. Multiple
285    /// immutable borrows can be taken out at the same time.
286    ///
287    /// # Panics
288    ///
289    /// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
290    /// [`try_borrow`](#method.try_borrow).
291    ///
292    /// # Examples
293    ///
294    /// ```
295    /// use std::cell::RefCell;
296    ///
297    /// let c = RefCell::new(5);
298    ///
299    /// let borrowed_five = c.borrow();
300    /// let borrowed_five2 = c.borrow();
301    /// ```
302    ///
303    /// An example of panic:
304    ///
305    /// ```should_panic
306    /// use std::cell::RefCell;
307    ///
308    /// let c = RefCell::new(5);
309    ///
310    /// let m = c.borrow_mut();
311    /// let b = c.borrow(); // this causes a panic
312    /// ```
313    #[inline]
314    #[track_caller]
315    pub fn borrow(&self) -> Ref<'_, T> {
316        match self.try_borrow() {
317            Ok(b) => b,
318            Err(err) => panic_already_mutably_borrowed(err),
319        }
320    }
321
322    /// Immutably borrows the wrapped value, returning an error if the value is currently mutably
323    /// borrowed.
324    ///
325    /// The borrow lasts until the returned `Ref` exits scope. Multiple immutable borrows can be
326    /// taken out at the same time.
327    ///
328    /// This is the non-panicking variant of [`borrow`](#method.borrow).
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// use std::cell::RefCell;
334    ///
335    /// let c = RefCell::new(5);
336    ///
337    /// {
338    ///     let m = c.borrow_mut();
339    ///     assert!(c.try_borrow().is_err());
340    /// }
341    ///
342    /// {
343    ///     let m = c.borrow();
344    ///     assert!(c.try_borrow().is_ok());
345    /// }
346    /// ```
347    #[inline]
348    pub fn try_borrow(&self) -> Result<Ref<'_, T>, BorrowError> {
349        match BorrowRef::new(&self.borrow) {
350            Some(b) => {
351                #[cfg(feature = "debug_refcell")]
352                {
353                    // `borrowed_at` is always the *first* active borrow
354                    if b.borrow.get() == 1 {
355                        self.borrowed_at.set(Some(crate::panic::Location::caller()));
356                    }
357                }
358
359                // SAFETY: `BorrowRef` ensures that there is only immutable access
360                // to the value while borrowed.
361                let value = unsafe { NonNull::new_unchecked(self.value.get()) };
362                Ok(Ref { value, borrow: b })
363            }
364            None => Err(BorrowError {
365                // If a borrow occurred, then we must already have an outstanding borrow,
366                // so `borrowed_at` will be `Some`
367                #[cfg(feature = "debug_refcell")]
368                location: unwrap!(self.borrowed_at.get()),
369            }),
370        }
371    }
372
373    /// Mutably borrows the wrapped value.
374    ///
375    /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived
376    /// from it exit scope. The value cannot be borrowed while this borrow is
377    /// active.
378    ///
379    /// # Panics
380    ///
381    /// Panics if the value is currently borrowed. For a non-panicking variant, use
382    /// [`try_borrow_mut`](#method.try_borrow_mut).
383    ///
384    /// # Examples
385    ///
386    /// ```
387    /// use std::cell::RefCell;
388    ///
389    /// let c = RefCell::new("hello".to_owned());
390    ///
391    /// *c.borrow_mut() = "bonjour".to_owned();
392    ///
393    /// assert_eq!(&*c.borrow(), "bonjour");
394    /// ```
395    ///
396    /// An example of panic:
397    ///
398    /// ```should_panic
399    /// use std::cell::RefCell;
400    ///
401    /// let c = RefCell::new(5);
402    /// let m = c.borrow();
403    ///
404    /// let b = c.borrow_mut(); // this causes a panic
405    /// ```
406    #[inline]
407    #[track_caller]
408    pub fn borrow_mut(&self) -> RefMut<'_, T> {
409        match self.try_borrow_mut() {
410            Ok(b) => b,
411            Err(err) => panic_already_borrowed(err),
412        }
413    }
414
415    /// Mutably borrows the wrapped value, returning an error if the value is currently borrowed.
416    ///
417    /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived
418    /// from it exit scope. The value cannot be borrowed while this borrow is
419    /// active.
420    ///
421    /// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
422    ///
423    /// # Examples
424    ///
425    /// ```
426    /// use std::cell::RefCell;
427    ///
428    /// let c = RefCell::new(5);
429    ///
430    /// {
431    ///     let m = c.borrow();
432    ///     assert!(c.try_borrow_mut().is_err());
433    /// }
434    ///
435    /// assert!(c.try_borrow_mut().is_ok());
436    /// ```
437    #[inline]
438    pub fn try_borrow_mut(&self) -> Result<RefMut<'_, T>, BorrowMutError> {
439        match BorrowRefMut::new(&self.borrow) {
440            Some(b) => {
441                #[cfg(feature = "debug_refcell")]
442                {
443                    self.borrowed_at.set(Some(crate::panic::Location::caller()));
444                }
445
446                // SAFETY: `BorrowRefMut` guarantees unique access.
447                let value = unsafe { NonNull::new_unchecked(self.value.get()) };
448                Ok(RefMut {
449                    value,
450                    borrow: b,
451                    marker: PhantomData,
452                })
453            }
454            None => Err(BorrowMutError {
455                // If a borrow occurred, then we must already have an outstanding borrow,
456                // so `borrowed_at` will be `Some`
457                #[cfg(feature = "debug_refcell")]
458                location: unwrap!(self.borrowed_at.get()),
459            }),
460        }
461    }
462
463    /// Returns a raw pointer to the underlying data in this cell.
464    ///
465    /// # Examples
466    ///
467    /// ```
468    /// use std::cell::RefCell;
469    ///
470    /// let c = RefCell::new(5);
471    ///
472    /// let ptr = c.as_ptr();
473    /// ```
474    #[inline]
475    //#[rustc_never_returns_null_ptr]
476    pub fn as_ptr(&self) -> *mut T {
477        self.value.get()
478    }
479
480    /// Returns a mutable reference to the underlying data.
481    ///
482    /// Since this method borrows `RefCell` mutably, it is statically guaranteed
483    /// that no borrows to the underlying data exist. The dynamic checks inherent
484    /// in [`borrow_mut`] and most other methods of `RefCell` are therefore
485    /// unnecessary.
486    ///
487    /// This method can only be called if `RefCell` can be mutably borrowed,
488    /// which in general is only the case directly after the `RefCell` has
489    /// been created. In these situations, skipping the aforementioned dynamic
490    /// borrowing checks may yield better ergonomics and runtime-performance.
491    ///
492    /// In most situations where `RefCell` is used, it can't be borrowed mutably.
493    /// Use [`borrow_mut`] to get mutable access to the underlying data then.
494    ///
495    /// [`borrow_mut`]: RefCell::borrow_mut()
496    ///
497    /// # Examples
498    ///
499    /// ```
500    /// use std::cell::RefCell;
501    ///
502    /// let mut c = RefCell::new(5);
503    /// *c.get_mut() += 1;
504    ///
505    /// assert_eq!(c, RefCell::new(6));
506    /// ```
507    #[inline]
508    pub fn get_mut(&mut self) -> &mut T {
509        self.value.get_mut()
510    }
511
512    /// Immutably borrows the wrapped value, returning an error if the value is
513    /// currently mutably borrowed.
514    ///
515    /// # Safety
516    ///
517    /// Unlike `RefCell::borrow`, this method is unsafe because it does not
518    /// return a `Ref`, thus leaving the borrow flag untouched. Mutably
519    /// borrowing the `RefCell` while the reference returned by this method
520    /// is alive is undefined behaviour.
521    ///
522    /// # Examples
523    ///
524    /// ```
525    /// use std::cell::RefCell;
526    ///
527    /// let c = RefCell::new(5);
528    ///
529    /// {
530    ///     let m = c.borrow_mut();
531    ///     assert!(unsafe { c.try_borrow_unguarded() }.is_err());
532    /// }
533    ///
534    /// {
535    ///     let m = c.borrow();
536    ///     assert!(unsafe { c.try_borrow_unguarded() }.is_ok());
537    /// }
538    /// ```
539    #[inline]
540    pub unsafe fn try_borrow_unguarded(&self) -> Result<&T, BorrowError> {
541        if !is_writing(self.borrow.get()) {
542            // SAFETY: We check that nobody is actively writing now, but it is
543            // the caller's responsibility to ensure that nobody writes until
544            // the returned reference is no longer in use.
545            // Also, `self.value.get()` refers to the value owned by `self`
546            // and is thus guaranteed to be valid for the lifetime of `self`.
547            Ok(unsafe { &*self.value.get() })
548        } else {
549            Err(BorrowError {
550                // If a borrow occurred, then we must already have an outstanding borrow,
551                // so `borrowed_at` will be `Some`
552                #[cfg(feature = "debug_refcell")]
553                location: unwrap!(self.borrowed_at.get()),
554            })
555        }
556    }
557}
558
559impl<T: Default> RefCell<T> {
560    /// Takes the wrapped value, leaving `Default::default()` in its place.
561    ///
562    /// # Panics
563    ///
564    /// Panics if the value is currently borrowed.
565    ///
566    /// # Examples
567    ///
568    /// ```
569    /// use std::cell::RefCell;
570    ///
571    /// let c = RefCell::new(5);
572    /// let five = c.take();
573    ///
574    /// assert_eq!(five, 5);
575    /// assert_eq!(c.into_inner(), 0);
576    /// ```
577    pub fn take(&self) -> T {
578        self.replace(Default::default())
579    }
580}
581
582unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}
583
584impl<T: Clone> Clone for RefCell<T> {
585    /// # Panics
586    ///
587    /// Panics if the value is currently mutably borrowed.
588    #[inline]
589    #[track_caller]
590    fn clone(&self) -> RefCell<T> {
591        RefCell::new(self.borrow().clone())
592    }
593
594    /// # Panics
595    ///
596    /// Panics if `other` is currently mutably borrowed.
597    #[inline]
598    #[track_caller]
599    fn clone_from(&mut self, other: &Self) {
600        self.get_mut().clone_from(&other.borrow())
601    }
602}
603
604impl<T: Default> Default for RefCell<T> {
605    /// Creates a `RefCell<T>`, with the `Default` value for T.
606    #[inline]
607    fn default() -> RefCell<T> {
608        RefCell::new(Default::default())
609    }
610}
611
612impl<T: ?Sized + PartialEq> PartialEq for RefCell<T> {
613    /// # Panics
614    ///
615    /// Panics if the value in either `RefCell` is currently mutably borrowed.
616    #[inline]
617    fn eq(&self, other: &RefCell<T>) -> bool {
618        *self.borrow() == *other.borrow()
619    }
620}
621
622impl<T: ?Sized + Eq> Eq for RefCell<T> {}
623
624impl<T: ?Sized + PartialOrd> PartialOrd for RefCell<T> {
625    /// # Panics
626    ///
627    /// Panics if the value in either `RefCell` is currently mutably borrowed.
628    #[inline]
629    fn partial_cmp(&self, other: &RefCell<T>) -> Option<Ordering> {
630        self.borrow().partial_cmp(&*other.borrow())
631    }
632
633    /// # Panics
634    ///
635    /// Panics if the value in either `RefCell` is currently mutably borrowed.
636    #[inline]
637    fn lt(&self, other: &RefCell<T>) -> bool {
638        *self.borrow() < *other.borrow()
639    }
640
641    /// # Panics
642    ///
643    /// Panics if the value in either `RefCell` is currently mutably borrowed.
644    #[inline]
645    fn le(&self, other: &RefCell<T>) -> bool {
646        *self.borrow() <= *other.borrow()
647    }
648
649    /// # Panics
650    ///
651    /// Panics if the value in either `RefCell` is currently mutably borrowed.
652    #[inline]
653    fn gt(&self, other: &RefCell<T>) -> bool {
654        *self.borrow() > *other.borrow()
655    }
656
657    /// # Panics
658    ///
659    /// Panics if the value in either `RefCell` is currently mutably borrowed.
660    #[inline]
661    fn ge(&self, other: &RefCell<T>) -> bool {
662        *self.borrow() >= *other.borrow()
663    }
664}
665
666impl<T: ?Sized + Ord> Ord for RefCell<T> {
667    /// # Panics
668    ///
669    /// Panics if the value in either `RefCell` is currently mutably borrowed.
670    #[inline]
671    fn cmp(&self, other: &RefCell<T>) -> Ordering {
672        self.borrow().cmp(&*other.borrow())
673    }
674}
675
676// NOTE: `core::cell::RefCell` defines `impl<T> From<T> for RefCell<T>`, but we
677// deliberately do NOT mirror it here. Because this `RefCell` is a crate-local
678// type (a copy of `core`'s, plus our `init` support), such a blanket `From<T>`
679// impl is subject to coherence checks against every *visible* impl in our
680// dependency graph - and `time` >= 0.3.48 has an
681// `impl From<HourBase> for <HourBase as ModifierValue>::Type` whose
682// associated-type projection the compiler cannot prove disjoint from
683// `RefCell<_>`, yielding a spurious `E0119`. `core`'s own impl is immune (the
684// orphan rule seals it and `time` is not in `core`'s graph). The impl is unused
685// anyway, so we simply omit it. See the `time` 0.3.48 coherence regression.
686
687struct BorrowRef<'b> {
688    borrow: &'b Cell<BorrowFlag>,
689}
690
691impl<'b> BorrowRef<'b> {
692    #[inline]
693    fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
694        let b = borrow.get().wrapping_add(1);
695        if !is_reading(b) {
696            // Incrementing borrow can result in a non-reading value (<= 0) in these cases:
697            // 1. It was < 0, i.e. there are writing borrows, so we can't allow a read borrow
698            //    due to Rust's reference aliasing rules
699            // 2. It was isize::MAX (the max amount of reading borrows) and it overflowed
700            //    into isize::MIN (the max amount of writing borrows) so we can't allow
701            //    an additional read borrow because isize can't represent so many read borrows
702            //    (this can only happen if you mem::forget more than a small constant amount of
703            //    `Ref`s, which is not good practice)
704            None
705        } else {
706            // Incrementing borrow can result in a reading value (> 0) in these cases:
707            // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow
708            // 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize
709            //    is large enough to represent having one more read borrow
710            borrow.set(b);
711            Some(BorrowRef { borrow })
712        }
713    }
714}
715
716impl Drop for BorrowRef<'_> {
717    #[inline]
718    fn drop(&mut self) {
719        let borrow = self.borrow.get();
720        debug_assert!(is_reading(borrow));
721        self.borrow.set(borrow - 1);
722    }
723}
724
725impl Clone for BorrowRef<'_> {
726    #[inline]
727    fn clone(&self) -> Self {
728        // Since this Ref exists, we know the borrow flag
729        // is a reading borrow.
730        let borrow = self.borrow.get();
731        debug_assert!(is_reading(borrow));
732        // Prevent the borrow counter from overflowing into
733        // a writing borrow.
734        assert!(borrow != BorrowFlag::MAX);
735        self.borrow.set(borrow + 1);
736        BorrowRef {
737            borrow: self.borrow,
738        }
739    }
740}
741
742/// Wraps a borrowed reference to a value in a `RefCell` box.
743/// A wrapper type for an immutably borrowed value from a `RefCell<T>`.
744///
745/// See the [module-level documentation](self) for more.
746// #[must_not_suspend = "holding a Ref across suspend points can cause BorrowErrors"]
747// #[rustc_diagnostic_item = "RefCellRef"]
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    borrow: BorrowRef<'b>,
754}
755
756impl<T: ?Sized> Deref for Ref<'_, T> {
757    type Target = T;
758
759    #[inline]
760    fn deref(&self) -> &T {
761        // SAFETY: the value is accessible as long as we hold our borrow.
762        unsafe { self.value.as_ref() }
763    }
764}
765
766impl<'b, T: ?Sized> Ref<'b, T> {
767    /// Copies a `Ref`.
768    ///
769    /// The `RefCell` is already immutably borrowed, so this cannot fail.
770    ///
771    /// This is an associated function that needs to be used as
772    /// `Ref::clone(...)`. A `Clone` implementation or a method would interfere
773    /// with the widespread use of `r.borrow().clone()` to clone the contents of
774    /// a `RefCell`.
775    #[must_use]
776    #[inline]
777    pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> {
778        Ref {
779            value: orig.value,
780            borrow: orig.borrow.clone(),
781        }
782    }
783
784    /// Makes a new `Ref` for a component of the borrowed data.
785    ///
786    /// The `RefCell` is already immutably borrowed, so this cannot fail.
787    ///
788    /// This is an associated function that needs to be used as `Ref::map(...)`.
789    /// A method would interfere with methods of the same name on the contents
790    /// of a `RefCell` used through `Deref`.
791    ///
792    /// # Examples
793    ///
794    /// ```
795    /// use std::cell::{RefCell, Ref};
796    ///
797    /// let c = RefCell::new((5, 'b'));
798    /// let b1: Ref<'_, (u32, char)> = c.borrow();
799    /// let b2: Ref<'_, u32> = Ref::map(b1, |t| &t.0);
800    /// assert_eq!(*b2, 5)
801    /// ```
802    #[inline]
803    pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
804    where
805        F: FnOnce(&T) -> &U,
806    {
807        Ref {
808            value: NonNull::from(f(&*orig)),
809            borrow: orig.borrow,
810        }
811    }
812
813    /// Makes a new `Ref` for an optional component of the borrowed data. The
814    /// original guard is returned as an `Err(..)` if the closure returns
815    /// `None`.
816    ///
817    /// The `RefCell` is already immutably borrowed, so this cannot fail.
818    ///
819    /// This is an associated function that needs to be used as
820    /// `Ref::filter_map(...)`. A method would interfere with methods of the same
821    /// name on the contents of a `RefCell` used through `Deref`.
822    ///
823    /// # Examples
824    ///
825    /// ```
826    /// use std::cell::{RefCell, Ref};
827    ///
828    /// let c = RefCell::new(vec![1, 2, 3]);
829    /// let b1: Ref<'_, Vec<u32>> = c.borrow();
830    /// let b2: Result<Ref<'_, u32>, _> = Ref::filter_map(b1, |v| v.get(1));
831    /// assert_eq!(*b2.unwrap(), 2);
832    /// ```
833    #[inline]
834    pub fn filter_map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Result<Ref<'b, U>, Self>
835    where
836        F: FnOnce(&T) -> Option<&U>,
837    {
838        match f(&*orig) {
839            Some(value) => Ok(Ref {
840                value: NonNull::from(value),
841                borrow: orig.borrow,
842            }),
843            None => Err(orig),
844        }
845    }
846
847    /// Splits a `Ref` into multiple `Ref`s for different components of the
848    /// borrowed data.
849    ///
850    /// The `RefCell` is already immutably borrowed, so this cannot fail.
851    ///
852    /// This is an associated function that needs to be used as
853    /// `Ref::map_split(...)`. A method would interfere with methods of the same
854    /// name on the contents of a `RefCell` used through `Deref`.
855    ///
856    /// # Examples
857    ///
858    /// ```
859    /// use std::cell::{Ref, RefCell};
860    ///
861    /// let cell = RefCell::new([1, 2, 3, 4]);
862    /// let borrow = cell.borrow();
863    /// let (begin, end) = Ref::map_split(borrow, |slice| slice.split_at(2));
864    /// assert_eq!(*begin, [1, 2]);
865    /// assert_eq!(*end, [3, 4]);
866    /// ```
867    #[inline]
868    pub fn map_split<U: ?Sized, V: ?Sized, F>(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>)
869    where
870        F: FnOnce(&T) -> (&U, &V),
871    {
872        let (a, b) = f(&*orig);
873        let borrow = orig.borrow.clone();
874        (
875            Ref {
876                value: NonNull::from(a),
877                borrow,
878            },
879            Ref {
880                value: NonNull::from(b),
881                borrow: orig.borrow,
882            },
883        )
884    }
885}
886
887impl<T: ?Sized + fmt::Display> fmt::Display for Ref<'_, T> {
888    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
889        (**self).fmt(f)
890    }
891}
892
893impl<'b, T: ?Sized> RefMut<'b, T> {
894    /// Makes a new `RefMut` for a component of the borrowed data, e.g., an enum
895    /// variant.
896    ///
897    /// The `RefCell` is already mutably borrowed, so this cannot fail.
898    ///
899    /// This is an associated function that needs to be used as
900    /// `RefMut::map(...)`. A method would interfere with methods of the same
901    /// name on the contents of a `RefCell` used through `Deref`.
902    ///
903    /// # Examples
904    ///
905    /// ```
906    /// use std::cell::{RefCell, RefMut};
907    ///
908    /// let c = RefCell::new((5, 'b'));
909    /// {
910    ///     let b1: RefMut<'_, (u32, char)> = c.borrow_mut();
911    ///     let mut b2: RefMut<'_, u32> = RefMut::map(b1, |t| &mut t.0);
912    ///     assert_eq!(*b2, 5);
913    ///     *b2 = 42;
914    /// }
915    /// assert_eq!(*c.borrow(), (42, 'b'));
916    /// ```
917    #[inline]
918    pub fn map<U: ?Sized, F>(mut orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
919    where
920        F: FnOnce(&mut T) -> &mut U,
921    {
922        let value = NonNull::from(f(&mut *orig));
923        RefMut {
924            value,
925            borrow: orig.borrow,
926            marker: PhantomData,
927        }
928    }
929
930    /// Makes a new `RefMut` for an optional component of the borrowed data. The
931    /// original guard is returned as an `Err(..)` if the closure returns
932    /// `None`.
933    ///
934    /// The `RefCell` is already mutably borrowed, so this cannot fail.
935    ///
936    /// This is an associated function that needs to be used as
937    /// `RefMut::filter_map(...)`. A method would interfere with methods of the
938    /// same name on the contents of a `RefCell` used through `Deref`.
939    ///
940    /// # Examples
941    ///
942    /// ```
943    /// use std::cell::{RefCell, RefMut};
944    ///
945    /// let c = RefCell::new(vec![1, 2, 3]);
946    ///
947    /// {
948    ///     let b1: RefMut<'_, Vec<u32>> = c.borrow_mut();
949    ///     let mut b2: Result<RefMut<'_, u32>, _> = RefMut::filter_map(b1, |v| v.get_mut(1));
950    ///
951    ///     if let Ok(mut b2) = b2 {
952    ///         *b2 += 2;
953    ///     }
954    /// }
955    ///
956    /// assert_eq!(*c.borrow(), vec![1, 4, 3]);
957    /// ```
958    #[inline]
959    pub fn filter_map<U: ?Sized, F>(mut orig: RefMut<'b, T>, f: F) -> Result<RefMut<'b, U>, Self>
960    where
961        F: FnOnce(&mut T) -> Option<&mut U>,
962    {
963        // SAFETY: function holds onto an exclusive reference for the duration
964        // of its call through `orig`, and the pointer is only de-referenced
965        // inside of the function call never allowing the exclusive reference to
966        // escape.
967        match f(&mut *orig) {
968            Some(value) => Ok(RefMut {
969                value: NonNull::from(value),
970                borrow: orig.borrow,
971                marker: PhantomData,
972            }),
973            None => Err(orig),
974        }
975    }
976
977    /// Splits a `RefMut` into multiple `RefMut`s for different components of the
978    /// borrowed data.
979    ///
980    /// The underlying `RefCell` will remain mutably borrowed until both
981    /// returned `RefMut`s go out of scope.
982    ///
983    /// The `RefCell` is already mutably borrowed, so this cannot fail.
984    ///
985    /// This is an associated function that needs to be used as
986    /// `RefMut::map_split(...)`. A method would interfere with methods of the
987    /// same name on the contents of a `RefCell` used through `Deref`.
988    ///
989    /// # Examples
990    ///
991    /// ```
992    /// use std::cell::{RefCell, RefMut};
993    ///
994    /// let cell = RefCell::new([1, 2, 3, 4]);
995    /// let borrow = cell.borrow_mut();
996    /// let (mut begin, mut end) = RefMut::map_split(borrow, |slice| slice.split_at_mut(2));
997    /// assert_eq!(*begin, [1, 2]);
998    /// assert_eq!(*end, [3, 4]);
999    /// begin.copy_from_slice(&[4, 3]);
1000    /// end.copy_from_slice(&[2, 1]);
1001    /// ```
1002    #[inline]
1003    pub fn map_split<U: ?Sized, V: ?Sized, F>(
1004        mut orig: RefMut<'b, T>,
1005        f: F,
1006    ) -> (RefMut<'b, U>, RefMut<'b, V>)
1007    where
1008        F: FnOnce(&mut T) -> (&mut U, &mut V),
1009    {
1010        let borrow = orig.borrow.clone();
1011        let (a, b) = f(&mut *orig);
1012        (
1013            RefMut {
1014                value: NonNull::from(a),
1015                borrow,
1016                marker: PhantomData,
1017            },
1018            RefMut {
1019                value: NonNull::from(b),
1020                borrow: orig.borrow,
1021                marker: PhantomData,
1022            },
1023        )
1024    }
1025}
1026
1027struct BorrowRefMut<'b> {
1028    borrow: &'b Cell<BorrowFlag>,
1029}
1030
1031impl Drop for BorrowRefMut<'_> {
1032    #[inline]
1033    fn drop(&mut self) {
1034        let borrow = self.borrow.get();
1035        debug_assert!(is_writing(borrow));
1036        self.borrow.set(borrow + 1);
1037    }
1038}
1039
1040impl<'b> BorrowRefMut<'b> {
1041    #[inline]
1042    fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
1043        // NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
1044        // mutable reference, and so there must currently be no existing
1045        // references. Thus, while clone increments the mutable refcount, here
1046        // we explicitly only allow going from UNUSED to UNUSED - 1.
1047        match borrow.get() {
1048            UNUSED => {
1049                borrow.set(UNUSED - 1);
1050                Some(BorrowRefMut { borrow })
1051            }
1052            _ => None,
1053        }
1054    }
1055
1056    // Clones a `BorrowRefMut`.
1057    //
1058    // This is only valid if each `BorrowRefMut` is used to track a mutable
1059    // reference to a distinct, nonoverlapping range of the original object.
1060    // This isn't in a Clone impl so that code doesn't call this implicitly.
1061    #[inline]
1062    fn clone(&self) -> BorrowRefMut<'b> {
1063        let borrow = self.borrow.get();
1064        debug_assert!(is_writing(borrow));
1065        // Prevent the borrow counter from underflowing.
1066        assert!(borrow != BorrowFlag::MIN);
1067        self.borrow.set(borrow - 1);
1068        BorrowRefMut {
1069            borrow: self.borrow,
1070        }
1071    }
1072}
1073
1074/// A wrapper type for a mutably borrowed value from a `RefCell<T>`.
1075///
1076/// See the [module-level documentation](self) for more.
1077// #[must_not_suspend = "holding a RefMut across suspend points can cause BorrowErrors"]
1078// #[rustc_diagnostic_item = "RefCellRefMut"]
1079pub struct RefMut<'b, T: ?Sized + 'b> {
1080    // NB: we use a pointer instead of `&'b mut T` to avoid `noalias` violations, because a
1081    // `RefMut` argument doesn't hold exclusivity for its whole scope, only until it drops.
1082    value: NonNull<T>,
1083    borrow: BorrowRefMut<'b>,
1084    // `NonNull` is covariant over `T`, so we need to reintroduce invariance.
1085    marker: PhantomData<&'b mut T>,
1086}
1087
1088impl<T: ?Sized> Deref for RefMut<'_, T> {
1089    type Target = T;
1090
1091    #[inline]
1092    fn deref(&self) -> &T {
1093        // SAFETY: the value is accessible as long as we hold our borrow.
1094        unsafe { self.value.as_ref() }
1095    }
1096}
1097
1098impl<T: ?Sized> DerefMut for RefMut<'_, T> {
1099    #[inline]
1100    fn deref_mut(&mut self) -> &mut T {
1101        // SAFETY: the value is accessible as long as we hold our borrow.
1102        unsafe { self.value.as_mut() }
1103    }
1104}
1105
1106impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
1107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1108        (**self).fmt(f)
1109    }
1110}