diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-04-26 21:02:32 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-26 21:02:32 +0200 |
| commit | 398d3eeca1f6cb84f91275826d66548c75e8fac0 (patch) | |
| tree | 73b5d8aa93f4b3fc06ae7fd9b22b7fc02f3ac7d2 /src/liballoc | |
| parent | 7f3b3df9e2f2efe3434b4f6fc76462d2c8ad332f (diff) | |
| parent | 0228ca0c7d07f92d449209fa2eeda9eb72e68f63 (diff) | |
| download | rust-398d3eeca1f6cb84f91275826d66548c75e8fac0.tar.gz rust-398d3eeca1f6cb84f91275826d66548c75e8fac0.zip | |
Rollup merge of #71421 - elichai:2020-04-boxed-slice, r=sfackler
Add a function to turn Box<T> into Box<[T]>
Hi,
I think this is very useful, as currently it's not possible in safe rust to do this without re-allocating.
an alternative implementation of the same function can be:
```rust
pub fn into_boxed_slice<T>(boxed: Box<T>) -> Box<[T]> {
unsafe {
let slice = slice::from_raw_parts_mut(Box::into_raw(boxed), 1);
Box::from_raw(slice)
}
}
```
The only thing that makes me a little uncomfortable is this line :
> The alignment of array types is greater or equal to the alignment of its element type
from https://rust-lang.github.io/unsafe-code-guidelines/layout/arrays-and-slices.html
But then I see:
> The alignment of &T, &mut T, *const T and *mut T are the same, and are at least the word size.
> The alignment of &[T] is the word size.
from https://rust-lang.github.io/unsafe-code-guidelines/layout/pointers.html#representation
So I do believe this is valid(FWIW it also passes in miri https://play.rust-lang.org/?gist=c002b99364ee6b29862aeb3565a91c19)
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/boxed.rs | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 3d657396a9f..b3a771a721d 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -239,6 +239,16 @@ impl<T> Box<T> { pub fn pin(x: T) -> Pin<Box<T>> { (box x).into() } + + /// Converts a `Box<T>` into a `Box<[T]>` + /// + /// This conversion does not allocate on the heap and happens in place. + /// + #[unstable(feature = "box_into_boxed_slice", issue = "71582")] + pub fn into_boxed_slice(boxed: Box<T>) -> Box<[T]> { + // *mut T and *mut [T; 1] have the same size and alignment + unsafe { Box::from_raw(Box::into_raw(boxed) as *mut [T; 1] as *mut [T]) } + } } impl<T> Box<[T]> { |
