diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-11-29 03:14:07 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-29 03:14:07 +0100 |
| commit | a2b4d97984bfe9df4b47da345aa01d79eb57a9f9 (patch) | |
| tree | 2cb54d1c60aa1cedf6aa94ec63f86277cbadf268 | |
| parent | 914d07ae5f90f01f138e66807873295fceaa9a26 (diff) | |
| parent | 7387f48e506456b8ca336d5036e380cd61e8c8c7 (diff) | |
| download | rust-a2b4d97984bfe9df4b47da345aa01d79eb57a9f9.tar.gz rust-a2b4d97984bfe9df4b47da345aa01d79eb57a9f9.zip | |
Rollup merge of #79327 - TimDiekmann:static-alloc-pin-in-box, r=Mark-Simulacrum
Require allocator to be static for boxed `Pin`-API Allocators has to retain their validity until the instance and all of its clones are dropped. When pinning a value, it must live forever, thus, the allocator requires a `'static` lifetime for pinning a value. [Example from reddit](https://www.reddit.com/r/rust/comments/jymzdw/the_story_continues_vec_now_supports_custom/gd7qak2?utm_source=share&utm_medium=web2x&context=3): ```rust let alloc = MyAlloc(/* ... */); let pinned = Box::pin_in(42, alloc); mem::forget(pinned); // Now `value` must live forever // Otherwise `Pin`'s invariants are violated, storage invalidated // before Drop was called. // borrow of `memory` can end here, there is no value keeping it. drop(alloc); // Oh, value doesn't live forever. ```
| -rw-r--r-- | library/alloc/src/boxed.rs | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index f56e3af4ff2..d814c525ceb 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -327,7 +327,10 @@ impl<T, A: AllocRef> Box<T, A> { /// `x` will be pinned in memory and unable to be moved. #[unstable(feature = "allocator_api", issue = "32838")] #[inline(always)] - pub fn pin_in(x: T, alloc: A) -> Pin<Self> { + pub fn pin_in(x: T, alloc: A) -> Pin<Self> + where + A: 'static, + { Self::new_in(x, alloc).into() } @@ -802,7 +805,10 @@ impl<T: ?Sized, A: AllocRef> Box<T, A> { /// /// This is also available via [`From`]. #[unstable(feature = "box_into_pin", issue = "62370")] - pub fn into_pin(boxed: Self) -> Pin<Self> { + pub fn into_pin(boxed: Self) -> Pin<Self> + where + A: 'static, + { // It's not possible to move or replace the insides of a `Pin<Box<T>>` // when `T: !Unpin`, so it's safe to pin it directly without any // additional requirements. @@ -1010,7 +1016,10 @@ impl<T> From<T> for Box<T> { } #[stable(feature = "pin", since = "1.33.0")] -impl<T: ?Sized, A: AllocRef> From<Box<T, A>> for Pin<Box<T, A>> { +impl<T: ?Sized, A: AllocRef> From<Box<T, A>> for Pin<Box<T, A>> +where + A: 'static, +{ /// Converts a `Box<T>` into a `Pin<Box<T>>` /// /// This conversion does not allocate on the heap and happens in place. @@ -1413,10 +1422,13 @@ impl<T: ?Sized, A: AllocRef> AsMut<T> for Box<T, A> { * could have a method to project a Pin<T> from it. */ #[stable(feature = "pin", since = "1.33.0")] -impl<T: ?Sized, A: AllocRef> Unpin for Box<T, A> {} +impl<T: ?Sized, A: AllocRef> Unpin for Box<T, A> where A: 'static {} #[unstable(feature = "generator_trait", issue = "43122")] -impl<G: ?Sized + Generator<R> + Unpin, R, A: AllocRef> Generator<R> for Box<G, A> { +impl<G: ?Sized + Generator<R> + Unpin, R, A: AllocRef> Generator<R> for Box<G, A> +where + A: 'static, +{ type Yield = G::Yield; type Return = G::Return; @@ -1426,7 +1438,10 @@ impl<G: ?Sized + Generator<R> + Unpin, R, A: AllocRef> Generator<R> for Box<G, A } #[unstable(feature = "generator_trait", issue = "43122")] -impl<G: ?Sized + Generator<R>, R, A: AllocRef> Generator<R> for Pin<Box<G, A>> { +impl<G: ?Sized + Generator<R>, R, A: AllocRef> Generator<R> for Pin<Box<G, A>> +where + A: 'static, +{ type Yield = G::Yield; type Return = G::Return; @@ -1436,7 +1451,10 @@ impl<G: ?Sized + Generator<R>, R, A: AllocRef> Generator<R> for Pin<Box<G, A>> { } #[stable(feature = "futures_api", since = "1.36.0")] -impl<F: ?Sized + Future + Unpin, A: AllocRef> Future for Box<F, A> { +impl<F: ?Sized + Future + Unpin, A: AllocRef> Future for Box<F, A> +where + A: 'static, +{ type Output = F::Output; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
