-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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)
- Loading branch information
Showing
4 changed files
with
79 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// ignore-tidy-linelength | ||
#![feature(box_into_boxed_slice)] | ||
|
||
use std::boxed::Box; | ||
use std::fmt::Debug; | ||
fn main() { | ||
let boxed_slice = Box::new([1,2,3]) as Box<[u8]>; | ||
let _ = Box::into_boxed_slice(boxed_slice); | ||
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time | ||
//~^^ ERROR the size for values of type `[u8]` cannot be known at compilation time | ||
let boxed_trait: Box<dyn Debug> = Box::new(5u8); | ||
let _ = Box::into_boxed_slice(boxed_trait); | ||
//~^ ERROR the size for values of type `dyn std::fmt::Debug` cannot be known at compilation time | ||
//~^^ ERROR the size for values of type `dyn std::fmt::Debug` cannot be known at compilation time | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time | ||
--> $DIR/box-into-boxed-slice-fail.rs:8:35 | ||
| | ||
LL | let _ = Box::into_boxed_slice(boxed_slice); | ||
| ^^^^^^^^^^^ doesn't have a size known at compile-time | ||
| | ||
= help: the trait `std::marker::Sized` is not implemented for `[u8]` | ||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait> | ||
= note: required by `std::boxed::Box::<T>::into_boxed_slice` | ||
|
||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time | ||
--> $DIR/box-into-boxed-slice-fail.rs:8:13 | ||
| | ||
LL | let _ = Box::into_boxed_slice(boxed_slice); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ||
| | ||
= help: the trait `std::marker::Sized` is not implemented for `[u8]` | ||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait> | ||
= note: slice and array elements must have `Sized` type | ||
|
||
error[E0277]: the size for values of type `dyn std::fmt::Debug` cannot be known at compilation time | ||
--> $DIR/box-into-boxed-slice-fail.rs:12:35 | ||
| | ||
LL | let _ = Box::into_boxed_slice(boxed_trait); | ||
| ^^^^^^^^^^^ doesn't have a size known at compile-time | ||
| | ||
= help: the trait `std::marker::Sized` is not implemented for `dyn std::fmt::Debug` | ||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait> | ||
= note: required by `std::boxed::Box::<T>::into_boxed_slice` | ||
|
||
error[E0277]: the size for values of type `dyn std::fmt::Debug` cannot be known at compilation time | ||
--> $DIR/box-into-boxed-slice-fail.rs:12:13 | ||
| | ||
LL | let _ = Box::into_boxed_slice(boxed_trait); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | ||
| | ||
= help: the trait `std::marker::Sized` is not implemented for `dyn std::fmt::Debug` | ||
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait> | ||
= note: slice and array elements must have `Sized` type | ||
|
||
error: aborting due to 4 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0277`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// run-pass | ||
#![feature(box_into_boxed_slice)] | ||
|
||
use std::boxed::Box; | ||
fn main() { | ||
assert_eq!(Box::into_boxed_slice(Box::new(5u8)), Box::new([5u8]) as Box<[u8]>); | ||
assert_eq!(Box::into_boxed_slice(Box::new([25u8])), Box::new([[25u8]]) as Box<[[u8; 1]]>); | ||
let a: Box<[Box<[u8; 1]>]> = Box::into_boxed_slice(Box::new(Box::new([5u8]))); | ||
let b: Box<[Box<[u8; 1]>]> = Box::new([Box::new([5u8])]); | ||
assert_eq!(a, b); | ||
} |