Skip to content

Commit f6411e4

Browse files
committed
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
1 parent d871818 commit f6411e4

File tree

7 files changed

+31
-11
lines changed

7 files changed

+31
-11
lines changed

library/core/src/array/mod.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ impl<T, const N: usize> [T; N] {
377377
/// assert_eq!(y, [2,3,4]);
378378
/// ```
379379
#[unstable(feature = "array_map", issue = "77777")]
380-
fn map<F, S>(self, f: F) -> [S; N]
380+
pub fn map<F, S>(self, mut f: F) -> [S; N]
381381
where
382382
F: FnMut(T) -> S,
383383
{
@@ -387,12 +387,6 @@ impl<T, const N: usize> [T; N] {
387387
curr_init: usize,
388388
}
389389

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-
396390
impl<T, const N: usize> Drop for Guard<T, N> {
397391
fn drop(&mut self) {
398392
debug_assert!(self.curr_init <= N);
@@ -406,14 +400,17 @@ impl<T, const N: usize> [T; N] {
406400
}
407401
}
408402
}
409-
let dst = MaybeUninit::uninit_array::<N>();
410-
let mut guard = Guard::new(&mut dst);
411-
for (i, e) in self.into_iter().enumerate() {
403+
let mut dst = MaybeUninit::uninit_array::<N>();
404+
let mut guard: Guard<S, N> = Guard { dst: &mut dst as *mut _ as *mut S, curr_init: 0 };
405+
for (i, e) in IntoIter::new(self).enumerate() {
412406
dst[i] = MaybeUninit::new(f(e));
413407
guard.curr_init += 1;
414408
}
415409
// FIXME convert to crate::mem::transmute when works with generics
416410
// unsafe { crate::mem::transmute::<[MaybeUninit<S>; N], [S; N]>(dst) }
411+
crate::mem::forget(guard);
412+
// SAFETY: At this point we've properly initialized the whole array
413+
// and we just need to cast it to the correct type
417414
unsafe { (&mut dst as *mut _ as *mut [S; N]).read() }
418415
}
419416
}

library/core/tests/array.rs

+7
Original file line numberDiff line numberDiff line change
@@ -290,3 +290,10 @@ fn empty_array_is_always_default() {
290290

291291
let _arr = <[DoesNotImplDefault; 0]>::default();
292292
}
293+
294+
#[test]
295+
fn array_map() {
296+
let a = [1, 2, 3];
297+
let b = a.map(|v| v + 1);
298+
assert_eq!(b, [2, 3, 4]);
299+
}

library/core/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![feature(alloc_layout_extra)]
22
#![feature(array_chunks)]
3+
#![feature(array_map)]
34
#![feature(bool_to_option)]
45
#![feature(bound_cloned)]
56
#![feature(box_syntax)]

src/librustc_typeck/check/method/probe.rs

+4
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
649649
self.assemble_inherent_impl_for_primitive(lang_def_id);
650650
}
651651
}
652+
ty::Array(_, _) => {
653+
let lang_def_id = lang_items.array_impl();
654+
self.assemble_inherent_impl_for_primitive(lang_def_id);
655+
}
652656
ty::RawPtr(ty::TypeAndMut { ty: _, mutbl }) => {
653657
let (lang_def_id1, lang_def_id2) = match mutbl {
654658
hir::Mutability::Not => {

src/librustc_typeck/coherence/inherent_impls.rs

+10
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,16 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
112112
item.span,
113113
);
114114
}
115+
ty::Array(_, _) => {
116+
self.check_primitive_impl(
117+
def_id,
118+
lang_items.array_impl(),
119+
None,
120+
"array",
121+
"[T; N]",
122+
item.span,
123+
);
124+
}
115125
ty::RawPtr(ty::TypeAndMut { ty: inner, mutbl: hir::Mutability::Not })
116126
if matches!(inner.kind, ty::Slice(_)) =>
117127
{

src/librustdoc/clean/utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V
388388
Bool => tcx.lang_items().bool_impl(),
389389
Str => tcx.lang_items().str_impl(),
390390
Slice => tcx.lang_items().slice_impl(),
391-
Array => tcx.lang_items().slice_impl(),
391+
Array => tcx.lang_items().array_impl(),
392392
Tuple => None,
393393
Unit => None,
394394
RawPointer => tcx.lang_items().const_ptr_impl(),

src/librustdoc/passes/collect_trait_impls.rs

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
5555
lang_items.bool_impl(),
5656
lang_items.char_impl(),
5757
lang_items.str_impl(),
58+
lang_items.array_impl(),
5859
lang_items.slice_impl(),
5960
lang_items.slice_u8_impl(),
6061
lang_items.str_alloc_impl(),

0 commit comments

Comments
 (0)