Auto merge of #28538 - alevy:make_fixedsizearray_unsafe, r=alexcrichton
[breaking-change] `FixedSizeArray` is meant to be implemented for arrays of fixed size only, but can be implemented for anything at the moment. Marking the trait unsafe would make it more reasonable to write unsafe code which operates on fixed size arrays of any size. For example, using `uninitialized` to create a fixed size array and immediately filling it with a fixed value is externally safe: ``` pub fn init_with_nones<T, A: FixedSizeArray<Option<T>>>() -> A { let mut res = unsafe { mem::uninitialized() }; for elm in res.as_mut_slice().iter_mut() { *elm = None; } res } ``` But the same code is not safe if `FixedSizeArray` is implemented for other types: ``` struct Foo { foo: usize } impl FixedSizeArray<Option<usize>> for Foo { fn as_slice(&self) -> &[usize] { &[] } fn as_mut_slice(&self) -> &mut [usize] { &mut [] } } ``` now `init_with_nones() : Foo` returns a `Foo` with an undefined value for the field `foo`.
This commit is contained in:
commit
6a2187414a
@ -35,14 +35,23 @@ use slice::{Iter, IterMut, SliceExt};
|
||||
///
|
||||
/// This trait can be used to implement other traits on fixed-size arrays
|
||||
/// without causing much metadata bloat.
|
||||
pub trait FixedSizeArray<T> {
|
||||
///
|
||||
/// The trait is marked unsafe in order to restrict implementors to fixed-size
|
||||
/// arrays. User of this trait can assume that implementors have the exact
|
||||
/// layout in memory of a fixed size array (for example, for unsafe
|
||||
/// initialization).
|
||||
///
|
||||
/// Note that the traits AsRef and AsMut provide similar methods for types that
|
||||
/// may not be fixed-size arrays. Implementors should prefer those traits
|
||||
/// instead.
|
||||
pub unsafe trait FixedSizeArray<T> {
|
||||
/// Converts the array to immutable slice
|
||||
fn as_slice(&self) -> &[T];
|
||||
/// Converts the array to mutable slice
|
||||
fn as_mut_slice(&mut self) -> &mut [T];
|
||||
}
|
||||
|
||||
impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
|
||||
unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
|
||||
#[inline]
|
||||
fn as_slice(&self) -> &[T] {
|
||||
self
|
||||
|
Loading…
Reference in New Issue
Block a user