Skip to content

Commit 125e7fa

Browse files
committed
Create lang item array and add map fn
This creates the language item for arrays, and adds the map fn which is like map in options or iterators. It currently allocates an extra array, unfortunately. Added fixme for transmuting Fix typo Add drop guard
1 parent 814bc4f commit 125e7fa

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

library/core/src/array/mod.rs

+53
Original file line numberDiff line numberDiff line change
@@ -364,3 +364,56 @@ macro_rules! array_impl_default {
364364
}
365365

366366
array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}
367+
368+
#[cfg(not(bootstrap))]
369+
#[lang = "array"]
370+
impl<T, const N: usize> [T; N] {
371+
/// Returns an array of the same size as self, with `f` applied to each element.
372+
///
373+
/// # Examples
374+
/// ```
375+
/// let x = [1,2,3];
376+
/// let y = x.map(|v| v + 1);
377+
/// assert_eq!(y, [2,3,4]);
378+
/// ```
379+
#[unstable(feature = "array_map", issue = "77777")]
380+
fn map<F, S>(self, f: F) -> [S; N]
381+
where
382+
F: FnMut(T) -> S,
383+
{
384+
use crate::mem::MaybeUninit;
385+
struct Guard<T, const N: usize> {
386+
dst: *mut T,
387+
curr_init: usize,
388+
}
389+
390+
impl<T, const N: usize> Guard<T, N> {
391+
fn new(dst: &mut [MaybeUninit<T>; N]) -> Self {
392+
Guard { dst: dst as *mut _ as *mut T, curr_init: 0 }
393+
}
394+
}
395+
396+
impl<T, const N: usize> Drop for Guard<T, N> {
397+
fn drop(&mut self) {
398+
debug_assert!(self.curr_init <= N);
399+
400+
let initialized_part =
401+
crate::ptr::slice_from_raw_parts_mut(self.dst, self.curr_init);
402+
// SAFETY: this raw slice will contain only initialized objects
403+
// that's why, it is allowed to drop it.
404+
unsafe {
405+
crate::ptr::drop_in_place(initialized_part);
406+
}
407+
}
408+
}
409+
let dst = MaybeUninit::uninit_array::<N>();
410+
let mut guard = Guard::new(&mut dst);
411+
for (i, e) in self.into_iter().enumerate() {
412+
dst[i] = MaybeUninit::new(f(e));
413+
guard.curr_init += 1;
414+
}
415+
// FIXME convert to crate::mem::transmute when works with generics
416+
// unsafe { crate::mem::transmute::<[MaybeUninit<S>; N], [S; N]>(dst) }
417+
unsafe { (&mut dst as *mut _ as *mut [S; N]).read() }
418+
}
419+
}

src/librustc_hir/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ language_item_table! {
165165
BoolImplItem, sym::bool, bool_impl, Target::Impl;
166166
CharImplItem, sym::char, char_impl, Target::Impl;
167167
StrImplItem, sym::str, str_impl, Target::Impl;
168+
ArrayImplItem, sym::array, array_impl, Target::Impl;
168169
SliceImplItem, sym::slice, slice_impl, Target::Impl;
169170
SliceU8ImplItem, sym::slice_u8, slice_u8_impl, Target::Impl;
170171
StrAllocImplItem, sym::str_alloc, str_alloc_impl, Target::Impl;

0 commit comments

Comments
 (0)