summaryrefslogtreecommitdiffstats
path: root/third_party/rust/fluent-fallback/src/pin_cell
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/fluent-fallback/src/pin_cell
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/fluent-fallback/src/pin_cell')
-rw-r--r--third_party/rust/fluent-fallback/src/pin_cell/README.md2
-rw-r--r--third_party/rust/fluent-fallback/src/pin_cell/mod.rs97
-rw-r--r--third_party/rust/fluent-fallback/src/pin_cell/pin_mut.rs50
-rw-r--r--third_party/rust/fluent-fallback/src/pin_cell/pin_ref.rs47
4 files changed, 196 insertions, 0 deletions
diff --git a/third_party/rust/fluent-fallback/src/pin_cell/README.md b/third_party/rust/fluent-fallback/src/pin_cell/README.md
new file mode 100644
index 0000000000..b1c475f51b
--- /dev/null
+++ b/third_party/rust/fluent-fallback/src/pin_cell/README.md
@@ -0,0 +1,2 @@
+This is a temporary fork of https://github.com/withoutboats/pin-cell until
+https://github.com/withoutboats/pin-cell/issues/6 gets resolved.
diff --git a/third_party/rust/fluent-fallback/src/pin_cell/mod.rs b/third_party/rust/fluent-fallback/src/pin_cell/mod.rs
new file mode 100644
index 0000000000..175f9677e0
--- /dev/null
+++ b/third_party/rust/fluent-fallback/src/pin_cell/mod.rs
@@ -0,0 +1,97 @@
+#![deny(missing_docs, missing_debug_implementations)]
+//! This library defines the `PinCell` type, a pinning variant of the standard
+//! library's `RefCell`.
+//!
+//! It is not safe to "pin project" through a `RefCell` - getting a pinned
+//! reference to something inside the `RefCell` when you have a pinned
+//! refernece to the `RefCell` - because `RefCell` is too powerful.
+//!
+//! A `PinCell` is slightly less powerful than `RefCell`: unlike a `RefCell`,
+//! one cannot get a mutable reference into a `PinCell`, only a pinned mutable
+//! reference (`Pin<&mut T>`). This makes pin projection safe, allowing you
+//! to use interior mutability with the knowledge that `T` will never actually
+//! be moved out of the `RefCell` that wraps it.
+
+mod pin_mut;
+mod pin_ref;
+
+use core::cell::{BorrowMutError, RefCell, RefMut};
+use core::pin::Pin;
+
+pub use pin_mut::PinMut;
+pub use pin_ref::PinRef;
+
+/// A mutable memory location with dynamically checked borrow rules
+///
+/// Unlike `RefCell`, this type only allows *pinned* mutable access to the
+/// inner value, enabling a "pin-safe" version of interior mutability.
+///
+/// See the standard library documentation for more information.
+#[derive(Default, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
+pub struct PinCell<T: ?Sized> {
+ inner: RefCell<T>,
+}
+
+impl<T> PinCell<T> {
+ /// Creates a new `PinCell` containing `value`.
+ pub const fn new(value: T) -> PinCell<T> {
+ PinCell {
+ inner: RefCell::new(value),
+ }
+ }
+}
+
+impl<T: ?Sized> PinCell<T> {
+ /// Mutably borrows the wrapped value, preserving its pinnedness.
+ ///
+ /// The borrow lasts until the returned `PinMut` or all `PinMut`s derived
+ /// from it exit scope. The value cannot be borrowed while this borrow is
+ /// active.
+ pub fn borrow_mut(self: Pin<&Self>) -> PinMut<'_, T> {
+ self.try_borrow_mut().expect("already borrowed")
+ }
+
+ /// Mutably borrows the wrapped value, preserving its pinnedness,
+ /// returning an error if the value is currently borrowed.
+ ///
+ /// The borrow lasts until the returned `PinMut` or all `PinMut`s derived
+ /// from it exit scope. The value cannot be borrowed while this borrow is
+ /// active.
+ ///
+ /// This is the non-panicking variant of `borrow_mut`.
+ pub fn try_borrow_mut<'a>(self: Pin<&'a Self>) -> Result<PinMut<'a, T>, BorrowMutError> {
+ let ref_mut: RefMut<'a, T> = Pin::get_ref(self).inner.try_borrow_mut()?;
+
+ // this is a pin projection from Pin<&PinCell<T>> to Pin<RefMut<T>>
+ // projecting is safe because:
+ //
+ // - for<T: ?Sized> (PinCell<T>: Unpin) imples (RefMut<T>: Unpin)
+ // holds true
+ // - PinCell does not implement Drop
+ //
+ // see discussion on tracking issue #49150 about pin projection
+ // invariants
+ let pin_ref_mut: Pin<RefMut<'a, T>> = unsafe { Pin::new_unchecked(ref_mut) };
+
+ Ok(PinMut { inner: pin_ref_mut })
+ }
+}
+
+impl<T> From<T> for PinCell<T> {
+ fn from(value: T) -> PinCell<T> {
+ PinCell::new(value)
+ }
+}
+
+impl<T> From<RefCell<T>> for PinCell<T> {
+ fn from(cell: RefCell<T>) -> PinCell<T> {
+ PinCell { inner: cell }
+ }
+}
+
+impl<T> From<PinCell<T>> for RefCell<T> {
+ fn from(input: PinCell<T>) -> Self {
+ input.inner
+ }
+}
+// TODO CoerceUnsized
diff --git a/third_party/rust/fluent-fallback/src/pin_cell/pin_mut.rs b/third_party/rust/fluent-fallback/src/pin_cell/pin_mut.rs
new file mode 100644
index 0000000000..09a4d4a6fb
--- /dev/null
+++ b/third_party/rust/fluent-fallback/src/pin_cell/pin_mut.rs
@@ -0,0 +1,50 @@
+use core::cell::RefMut;
+use core::fmt;
+use core::ops::Deref;
+use core::pin::Pin;
+
+#[derive(Debug)]
+/// A wrapper type for a mutably borrowed value from a `PinCell<T>`.
+pub struct PinMut<'a, T: ?Sized> {
+ pub(crate) inner: Pin<RefMut<'a, T>>,
+}
+
+impl<'a, T: ?Sized> Deref for PinMut<'a, T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &*self.inner
+ }
+}
+
+impl<'a, T: ?Sized> PinMut<'a, T> {
+ /// Get a pinned mutable reference to the value inside this wrapper.
+ pub fn as_mut<'b>(orig: &'b mut PinMut<'a, T>) -> Pin<&'b mut T> {
+ orig.inner.as_mut()
+ }
+}
+
+/* TODO implement these APIs
+
+impl<'a, T: ?Sized> PinMut<'a, T> {
+ pub fn map<U, F>(orig: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
+ F: FnOnce(Pin<&mut T>) -> Pin<&mut U>,
+ {
+ panic!()
+ }
+
+ pub fn map_split<U, V, F>(orig: PinMut<'a, T>, f: F) -> (PinMut<'a, U>, PinMut<'a, V>) where
+ F: FnOnce(Pin<&mut T>) -> (Pin<&mut U>, Pin<&mut V>)
+ {
+ panic!()
+ }
+}
+*/
+
+impl<'a, T: fmt::Display + ?Sized> fmt::Display for PinMut<'a, T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ <T as fmt::Display>::fmt(&**self, f)
+ }
+}
+
+// TODO CoerceUnsized
diff --git a/third_party/rust/fluent-fallback/src/pin_cell/pin_ref.rs b/third_party/rust/fluent-fallback/src/pin_cell/pin_ref.rs
new file mode 100644
index 0000000000..46f9cfdabb
--- /dev/null
+++ b/third_party/rust/fluent-fallback/src/pin_cell/pin_ref.rs
@@ -0,0 +1,47 @@
+use core::cell::Ref;
+use core::fmt;
+use core::ops::Deref;
+use core::pin::Pin;
+
+#[derive(Debug)]
+/// A wrapper type for a immutably borrowed value from a `PinCell<T>`.
+pub struct PinRef<'a, T: ?Sized> {
+ pub(crate) inner: Pin<Ref<'a, T>>,
+}
+
+impl<'a, T: ?Sized> Deref for PinRef<'a, T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &*self.inner
+ }
+}
+
+/* TODO implement these APIs
+
+impl<'a, T: ?Sized> PinRef<'a, T> {
+ pub fn clone(orig: &PinRef<'a, T>) -> PinRef<'a, T> {
+ panic!()
+ }
+
+ pub fn map<U, F>(orig: PinRef<'a, T>, f: F) -> PinRef<'a, U> where
+ F: FnOnce(Pin<&T>) -> Pin<&U>,
+ {
+ panic!()
+ }
+
+ pub fn map_split<U, V, F>(orig: PinRef<'a, T>, f: F) -> (PinRef<'a, U>, PinRef<'a, V>) where
+ F: FnOnce(Pin<&T>) -> (Pin<&U>, Pin<&V>)
+ {
+ panic!()
+ }
+}
+*/
+
+impl<'a, T: fmt::Display + ?Sized> fmt::Display for PinRef<'a, T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ <T as fmt::Display>::fmt(&**self, f)
+ }
+}
+
+// TODO CoerceUnsized