Rollup merge of #51730 - MajorBreakfast:pin-get-mut-unchecked, r=withoutboats
New safe associated functions for PinMut - Add safe `get_mut` and `map` - Rename unsafe equivalents to `get_mut_unchecked` and `map_unchecked` The discussion about this starts [in this comment](https://github.com/rust-lang/rust/issues/49150#issuecomment-399604573) on the tracking issue.
This commit is contained in:
commit
b71f6df5dd
@ -1119,6 +1119,12 @@ impl<'a, T: ?Sized + Unpin> PinMut<'a, T> {
|
||||
pub fn new(reference: &'a mut T) -> PinMut<'a, T> {
|
||||
PinMut { inner: reference }
|
||||
}
|
||||
|
||||
/// Get a mutable reference to the data inside of this `PinMut`.
|
||||
#[unstable(feature = "pin", issue = "49150")]
|
||||
pub fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
|
||||
this.inner
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1150,21 +1156,21 @@ impl<'a, T: ?Sized> PinMut<'a, T> {
|
||||
/// the data out of the mutable reference you receive when you call this
|
||||
/// function.
|
||||
#[unstable(feature = "pin", issue = "49150")]
|
||||
pub unsafe fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
|
||||
pub unsafe fn get_mut_unchecked(this: PinMut<'a, T>) -> &'a mut T {
|
||||
this.inner
|
||||
}
|
||||
|
||||
/// Construct a new pin by mapping the interior value.
|
||||
///
|
||||
/// For example, if you wanted to get a `PinMut` of a field of something, you
|
||||
/// could use this to get access to that field in one line of code.
|
||||
/// For example, if you wanted to get a `PinMut` of a field of something,
|
||||
/// you could use this to get access to that field in one line of code.
|
||||
///
|
||||
/// This function is unsafe. You must guarantee that the data you return
|
||||
/// will not move so long as the argument value does not move (for example,
|
||||
/// because it is one of the fields of that value), and also that you do
|
||||
/// not move out of the argument you receive to the interior function.
|
||||
#[unstable(feature = "pin", issue = "49150")]
|
||||
pub unsafe fn map<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
|
||||
pub unsafe fn map_unchecked<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
|
||||
F: FnOnce(&mut T) -> &mut U
|
||||
{
|
||||
PinMut { inner: f(this.inner) }
|
||||
|
@ -275,7 +275,7 @@ impl<T> Option<T> {
|
||||
#[unstable(feature = "pin", issue = "49150")]
|
||||
pub fn as_pin_mut<'a>(self: PinMut<'a, Self>) -> Option<PinMut<'a, T>> {
|
||||
unsafe {
|
||||
PinMut::get_mut(self).as_mut().map(|x| PinMut::new_unchecked(x))
|
||||
PinMut::get_mut_unchecked(self).as_mut().map(|x| PinMut::new_unchecked(x))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {}
|
||||
impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
|
||||
type Output = T::Return;
|
||||
fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
|
||||
set_task_cx(cx, || match unsafe { PinMut::get_mut(self).0.resume() } {
|
||||
set_task_cx(cx, || match unsafe { PinMut::get_mut_unchecked(self).0.resume() } {
|
||||
GeneratorState::Yielded(()) => Poll::Pending,
|
||||
GeneratorState::Complete(x) => Poll::Ready(x),
|
||||
})
|
||||
|
@ -327,14 +327,9 @@ impl<T: fmt::Debug> fmt::Debug for AssertUnwindSafe<T> {
|
||||
impl<'a, F: Future> Future for AssertUnwindSafe<F> {
|
||||
type Output = F::Output;
|
||||
|
||||
fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
|
||||
unsafe {
|
||||
let pinned_field = PinMut::new_unchecked(
|
||||
&mut PinMut::get_mut(self.reborrow()).0
|
||||
);
|
||||
|
||||
pinned_field.poll(cx)
|
||||
}
|
||||
fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
|
||||
let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
|
||||
pinned_field.poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user