about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2020-10-21 13:59:29 +0900
committerGitHub <noreply@github.com>2020-10-21 13:59:29 +0900
commitff3c8cb5182ae5ffee4cd47dbabbe981f859c40f (patch)
treecf78d624aa0e1e6e1d2c8e91bb6c5f0a000d563a
parentf965120ad3dbe7d4d6b90a16cc7028eb6363b983 (diff)
parentdf95dcebf5f98cefdc60c9b9d818fb285ac07d5b (diff)
downloadrust-ff3c8cb5182ae5ffee4cd47dbabbe981f859c40f.tar.gz
rust-ff3c8cb5182ae5ffee4cd47dbabbe981f859c40f.zip
Rollup merge of #77726 - fusion-engineering-forks:static-pin, r=dtolnay
Add Pin::static_ref, static_mut.

This adds `Pin::static_ref` and `Pin::static_mut`, which convert a static reference to a pinned static reference.

Static references are effectively already pinned, as what they refer to has to live forever and can never be moved.

---

Context: I want to update the `sys` and `sys_common` mutexes/rwlocks/condvars to use `Pin<&self>` in their functions, instead of only warning in the unsafety comments that they may not be moved. That should make them a little bit less dangerous to use. Putting such an object in a `static` (e.g. through `sys_common::StaticMutex`) fulfills the requirements about never moving it, but right now there's no safe way to get a `Pin<&T>` to a `static`. This solves that.
-rw-r--r--library/core/src/pin.rs28
1 files changed, 28 insertions, 0 deletions
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 9f0284d5d95..b73cd046e5a 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -781,6 +781,34 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     }
 }
 
+impl<T: ?Sized> Pin<&'static T> {
+    /// Get a pinned reference from a static reference.
+    ///
+    /// This is safe, because `T` is borrowed for the `'static` lifetime, which
+    /// never ends.
+    #[unstable(feature = "pin_static_ref", issue = "none")]
+    #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+    pub const fn static_ref(r: &'static T) -> Pin<&'static T> {
+        // SAFETY: The 'static borrow guarantees the data will not be
+        // moved/invalidated until it gets dropped (which is never).
+        unsafe { Pin::new_unchecked(r) }
+    }
+}
+
+impl<T: ?Sized> Pin<&'static mut T> {
+    /// Get a pinned mutable reference from a static mutable reference.
+    ///
+    /// This is safe, because `T` is borrowed for the `'static` lifetime, which
+    /// never ends.
+    #[unstable(feature = "pin_static_ref", issue = "none")]
+    #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
+    pub const fn static_mut(r: &'static mut T) -> Pin<&'static mut T> {
+        // SAFETY: The 'static borrow guarantees the data will not be
+        // moved/invalidated until it gets dropped (which is never).
+        unsafe { Pin::new_unchecked(r) }
+    }
+}
+
 #[stable(feature = "pin", since = "1.33.0")]
 impl<P: Deref> Deref for Pin<P> {
     type Target = P::Target;