Add Array Impl Lang Item in various places

Add basic test

And also run fmt which is where the other changes are from

Fix mut issues

These only appear when running tests, so resolved by adding mut

Swap order of forget

Add pub and rm guard impl

Add explicit type to guard

Add safety note

Change guard type from T to S

It should never have been T, as it guards over [MaybeUninit<S>; N]
Also add feature to test
This commit is contained in:
kadmin 2020-08-06 22:08:56 +00:00
parent d8718183b2
commit f6411e4c66
7 changed files with 31 additions and 11 deletions

View file

@ -377,7 +377,7 @@ impl<T, const N: usize> [T; N] {
/// assert_eq!(y, [2,3,4]);
/// ```
#[unstable(feature = "array_map", issue = "77777")]
fn map<F, S>(self, f: F) -> [S; N]
pub fn map<F, S>(self, mut f: F) -> [S; N]
where
F: FnMut(T) -> S,
{
@ -387,12 +387,6 @@ impl<T, const N: usize> [T; N] {
curr_init: usize,
}
impl<T, const N: usize> Guard<T, N> {
fn new(dst: &mut [MaybeUninit<T>; N]) -> Self {
Guard { dst: dst as *mut _ as *mut T, curr_init: 0 }
}
}
impl<T, const N: usize> Drop for Guard<T, N> {
fn drop(&mut self) {
debug_assert!(self.curr_init <= N);
@ -406,14 +400,17 @@ impl<T, const N: usize> [T; N] {
}
}
}
let dst = MaybeUninit::uninit_array::<N>();
let mut guard = Guard::new(&mut dst);
for (i, e) in self.into_iter().enumerate() {
let mut dst = MaybeUninit::uninit_array::<N>();
let mut guard: Guard<S, N> = Guard { dst: &mut dst as *mut _ as *mut S, curr_init: 0 };
for (i, e) in IntoIter::new(self).enumerate() {
dst[i] = MaybeUninit::new(f(e));
guard.curr_init += 1;
}
// FIXME convert to crate::mem::transmute when works with generics
// unsafe { crate::mem::transmute::<[MaybeUninit<S>; N], [S; N]>(dst) }
crate::mem::forget(guard);
// SAFETY: At this point we've properly initialized the whole array
// and we just need to cast it to the correct type
unsafe { (&mut dst as *mut _ as *mut [S; N]).read() }
}
}

View file

@ -290,3 +290,10 @@ fn empty_array_is_always_default() {
let _arr = <[DoesNotImplDefault; 0]>::default();
}
#[test]
fn array_map() {
let a = [1, 2, 3];
let b = a.map(|v| v + 1);
assert_eq!(b, [2, 3, 4]);
}

View file

@ -1,5 +1,6 @@
#![feature(alloc_layout_extra)]
#![feature(array_chunks)]
#![feature(array_map)]
#![feature(bool_to_option)]
#![feature(bound_cloned)]
#![feature(box_syntax)]

View file

@ -649,6 +649,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.assemble_inherent_impl_for_primitive(lang_def_id);
}
}
ty::Array(_, _) => {
let lang_def_id = lang_items.array_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
}
ty::RawPtr(ty::TypeAndMut { ty: _, mutbl }) => {
let (lang_def_id1, lang_def_id2) = match mutbl {
hir::Mutability::Not => {

View file

@ -112,6 +112,16 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
item.span,
);
}
ty::Array(_, _) => {
self.check_primitive_impl(
def_id,
lang_items.array_impl(),
None,
"array",
"[T; N]",
item.span,
);
}
ty::RawPtr(ty::TypeAndMut { ty: inner, mutbl: hir::Mutability::Not })
if matches!(inner.kind, ty::Slice(_)) =>
{

View file

@ -388,7 +388,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V
Bool => tcx.lang_items().bool_impl(),
Str => tcx.lang_items().str_impl(),
Slice => tcx.lang_items().slice_impl(),
Array => tcx.lang_items().slice_impl(),
Array => tcx.lang_items().array_impl(),
Tuple => None,
Unit => None,
RawPointer => tcx.lang_items().const_ptr_impl(),

View file

@ -55,6 +55,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
lang_items.bool_impl(),
lang_items.char_impl(),
lang_items.str_impl(),
lang_items.array_impl(),
lang_items.slice_impl(),
lang_items.slice_u8_impl(),
lang_items.str_alloc_impl(),