Skip to content

Commit 6a21874

Browse files
committed
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`.
2 parents e980129 + b30d896 commit 6a21874

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

src/libcore/array.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,23 @@ use slice::{Iter, IterMut, SliceExt};
3535
///
3636
/// This trait can be used to implement other traits on fixed-size arrays
3737
/// without causing much metadata bloat.
38-
pub trait FixedSizeArray<T> {
38+
///
39+
/// The trait is marked unsafe in order to restrict implementors to fixed-size
40+
/// arrays. User of this trait can assume that implementors have the exact
41+
/// layout in memory of a fixed size array (for example, for unsafe
42+
/// initialization).
43+
///
44+
/// Note that the traits AsRef and AsMut provide similar methods for types that
45+
/// may not be fixed-size arrays. Implementors should prefer those traits
46+
/// instead.
47+
pub unsafe trait FixedSizeArray<T> {
3948
/// Converts the array to immutable slice
4049
fn as_slice(&self) -> &[T];
4150
/// Converts the array to mutable slice
4251
fn as_mut_slice(&mut self) -> &mut [T];
4352
}
4453

45-
impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
54+
unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
4655
#[inline]
4756
fn as_slice(&self) -> &[T] {
4857
self

0 commit comments

Comments
 (0)