Skip to content

Commit 918ef67

Browse files
author
boats
committed
Pin and Unpin in libcore.
1 parent c933440 commit 918ef67

File tree

2 files changed

+119
-2
lines changed

2 files changed

+119
-2
lines changed

src/libcore/marker.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,3 +565,13 @@ unsafe impl<T: ?Sized> Freeze for *const T {}
565565
unsafe impl<T: ?Sized> Freeze for *mut T {}
566566
unsafe impl<'a, T: ?Sized> Freeze for &'a T {}
567567
unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
568+
569+
/// Types which can be moved out of a `Pin`.
570+
///
571+
/// The `Unpin` trait is used to control the behavior of the [`Pin`] type. If a
572+
/// type implements `Unpin`, it is safe to move a value of that type out of the
573+
/// `Pin` pointer.
574+
///
575+
/// This trait is automatically implemented for almost every type.
576+
#[unstable(feature = "pin", issue = "0")]
577+
pub unsafe auto trait Unpin {}

src/libcore/mem.rs

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ use cmp;
2020
use fmt;
2121
use hash;
2222
use intrinsics;
23-
use marker::{Copy, PhantomData, Sized};
23+
use marker::{Copy, PhantomData, Sized, Unpin, Unsize};
2424
use ptr;
25-
use ops::{Deref, DerefMut};
25+
use ops::{Deref, DerefMut, CoerceUnsized};
2626

2727
#[stable(feature = "rust1", since = "1.0.0")]
2828
pub use intrinsics::transmute;
@@ -1105,3 +1105,110 @@ impl<T: ::hash::Hash> ::hash::Hash for ManuallyDrop<T> {
11051105
pub unsafe fn unreachable() -> ! {
11061106
intrinsics::unreachable()
11071107
}
1108+
1109+
/// A pinned reference.
1110+
///
1111+
/// A pinned reference is a lot like a mutable reference, except that it is not
1112+
/// safe to move a value out of a pinned reference unless the type of that
1113+
/// value implements the `Unpin` trait.
1114+
#[unstable(feature = "pin", issue = "0")]
1115+
pub struct Pin<'a, T: ?Sized + 'a> {
1116+
inner: &'a mut T,
1117+
}
1118+
1119+
#[unstable(feature = "pin", issue = "0")]
1120+
impl<'a, T: ?Sized + Unpin> Pin<'a, T> {
1121+
/// Construct a new `Pin` around a reference to some data of a type that
1122+
/// implements `Unpin`.
1123+
#[unstable(feature = "pin", issue = "0")]
1124+
pub fn new(reference: &'a mut T) -> Pin<'a, T> {
1125+
Pin { inner: reference }
1126+
}
1127+
}
1128+
1129+
1130+
#[unstable(feature = "pin", issue = "0")]
1131+
impl<'a, T: ?Sized> Pin<'a, T> {
1132+
/// Construct a new `Pin` around a reference to some data of a type that
1133+
/// may or may not implement `Unpin`.
1134+
///
1135+
/// This constructor is unsafe because we do not know what will happen with
1136+
/// that data after the reference ends. If you cannot guarantee that the
1137+
/// data will never move again, calling this constructor is invalid.
1138+
#[unstable(feature = "pin", issue = "0")]
1139+
pub unsafe fn new_unchecked(reference: &'a mut T) -> Pin<'a, T> {
1140+
Pin { inner: reference }
1141+
}
1142+
1143+
/// Borrow a Pin for a shorter lifetime than it already has.
1144+
#[unstable(feature = "pin", issue = "0")]
1145+
pub fn borrow<'b>(this: &'b mut Pin<'a, T>) -> Pin<'b, T> {
1146+
Pin { inner: this.inner }
1147+
}
1148+
1149+
/// Get a mutable reference to the data inside of this `Pin`.
1150+
///
1151+
/// This function is unsafe. You must guarantee that you will never move
1152+
/// the data out of the mutable reference you receive when you call this
1153+
/// function.
1154+
#[unstable(feature = "pin", issue = "0")]
1155+
pub unsafe fn get_mut<'b>(this: &'b mut Pin<'a, T>) -> &'b mut T {
1156+
this.inner
1157+
}
1158+
1159+
/// Construct a new pin by mapping the interior value.
1160+
///
1161+
/// For example, if you wanted to get a `Pin` of a field of something, you
1162+
/// could use this to get access to that field in one line of code.
1163+
///
1164+
/// This function is unsafe. You must guarantee that the data you return
1165+
/// will not move so long as the argument value does not move (for example,
1166+
/// because it is one of the fields of that value), and also that you do
1167+
/// not move out of the argument you receive to the interior function.
1168+
#[unstable(feature = "pin", issue = "0")]
1169+
pub unsafe fn map<'b, U, F>(this: &'b mut Pin<'a, T>, f: F) -> Pin<'b, U> where
1170+
F: FnOnce(&mut T) -> &mut U
1171+
{
1172+
Pin { inner: f(this.inner) }
1173+
}
1174+
}
1175+
1176+
#[unstable(feature = "pin", issue = "0")]
1177+
impl<'a, T: ?Sized> Deref for Pin<'a, T> {
1178+
type Target = T;
1179+
1180+
fn deref(&self) -> &T {
1181+
&*self.inner
1182+
}
1183+
}
1184+
1185+
#[unstable(feature = "pin", issue = "0")]
1186+
impl<'a, T: ?Sized + Unpin> DerefMut for Pin<'a, T> {
1187+
fn deref_mut(&mut self) -> &mut T {
1188+
self.inner
1189+
}
1190+
}
1191+
1192+
#[unstable(feature = "pin", issue = "0")]
1193+
impl<'a, T: fmt::Debug + ?Sized> fmt::Debug for Pin<'a, T> {
1194+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1195+
fmt::Debug::fmt(&**self, f)
1196+
}
1197+
}
1198+
1199+
#[unstable(feature = "pin", issue = "0")]
1200+
impl<'a, T: fmt::Display + ?Sized> fmt::Display for Pin<'a, T> {
1201+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1202+
fmt::Display::fmt(&**self, f)
1203+
}
1204+
}
1205+
1206+
#[unstable(feature = "pin", issue = "0")]
1207+
impl<'a, T: ?Sized> fmt::Pointer for Pin<'a, T> {
1208+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1209+
fmt::Pointer::fmt(&(&*self.inner as *const T), f)
1210+
}
1211+
}
1212+
1213+
#[unstable(feature = "pin", issue = "0")]
1214+
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Pin<'a, U>> for Pin<'a, T> {}

0 commit comments

Comments
 (0)