Skip to content

Commit fe8d917

Browse files
committed
remove FromIterator impl
1 parent 6c6b51c commit fe8d917

File tree

2 files changed

+38
-76
lines changed

2 files changed

+38
-76
lines changed

library/core/src/array/mod.rs

+13-51
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use crate::cmp::Ordering;
1111
use crate::convert::{Infallible, TryFrom};
1212
use crate::fmt;
1313
use crate::hash::{self, Hash};
14-
use crate::iter::FromIterator;
1514
use crate::marker::Unsize;
1615
use crate::mem::MaybeUninit;
1716
use crate::slice::{Iter, IterMut};
@@ -176,7 +175,10 @@ impl<T: fmt::Debug, const N: usize> fmt::Debug for [T; N] {
176175
}
177176
}
178177

179-
/// Return Error of the FromIterator impl for array
178+
/// The error returned by the `FromIterator` implementation of
179+
/// arrays once these are implemented.
180+
///
181+
/// Until then `FillError::new().fill(iter)` can be used instead.
180182
#[unstable(feature = "array_from_iter_impl", issue = "none")]
181183
pub struct FillError<T, const N: usize> {
182184
array: [MaybeUninit<T>; N],
@@ -194,27 +196,26 @@ impl<T, const N: usize> fmt::Display for FillError<T, N> {
194196
}
195197

196198
#[unstable(feature = "array_from_iter_impl", issue = "none")]
197-
impl<T: fmt::Debug, const N: usize> fmt::Debug for FillError<T, N> {
199+
impl<T, const N: usize> fmt::Debug for FillError<T, N> {
198200
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199-
f.debug_struct("FillError")
200-
.field("array", &self.as_slice())
201-
.field("len", &self.len())
202-
.finish()
201+
fmt::Display::fmt(self, f)
203202
}
204203
}
205204

206205
#[unstable(feature = "array_from_iter_impl", issue = "none")]
207206
impl<T, const N: usize> Drop for FillError<T, N> {
208207
fn drop(&mut self) {
209208
// SAFETY: This is safe: `as_mut_slice` returns exactly the sub-slice
210-
// of elements that have been initialized and need to be droped
209+
// of elements that have been initialized and need to be dropped.
211210
unsafe { crate::ptr::drop_in_place(self.as_mut_slice()) }
212211
}
213212
}
214213

215214
#[unstable(feature = "array_from_iter_impl", issue = "none")]
216215
impl<T, const N: usize> FillError<T, N> {
217-
fn new() -> Self {
216+
/// Creates a new empty `FillError` which can be used
217+
/// to build `[T; N]` from an iterator.
218+
pub fn new() -> Self {
218219
Self { array: MaybeUninit::uninit_array(), len: 0 }
219220
}
220221

@@ -242,8 +243,8 @@ impl<T, const N: usize> FillError<T, N> {
242243
for i in self.len..N {
243244
if let Some(value) = iter.next() {
244245
self.array[i].write(value);
246+
self.len = i + 1;
245247
} else {
246-
self.len = i;
247248
return Err(self);
248249
}
249250
}
@@ -265,14 +266,6 @@ impl<T, const N: usize> FillError<T, N> {
265266
}
266267
}
267268

268-
#[unstable(feature = "array_from_iter_impl", issue = "none")]
269-
impl<T, const N: usize> FromIterator<T> for Result<[T; N], FillError<T, N>> {
270-
#[inline]
271-
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
272-
FillError::<T, N>::new().fill(iter)
273-
}
274-
}
275-
276269
#[stable(feature = "rust1", since = "1.0.0")]
277270
impl<'a, T, const N: usize> IntoIterator for &'a [T; N] {
278271
type Item = &'a T;
@@ -484,42 +477,11 @@ impl<T, const N: usize> [T; N] {
484477
/// assert_eq!(y, [6, 9, 3, 3]);
485478
/// ```
486479
#[unstable(feature = "array_map", issue = "75243")]
487-
pub fn map<F, U>(self, mut f: F) -> [U; N]
480+
pub fn map<F, U>(self, f: F) -> [U; N]
488481
where
489482
F: FnMut(T) -> U,
490483
{
491-
use crate::mem::MaybeUninit;
492-
struct Guard<T, const N: usize> {
493-
dst: *mut T,
494-
initialized: usize,
495-
}
496-
497-
impl<T, const N: usize> Drop for Guard<T, N> {
498-
fn drop(&mut self) {
499-
debug_assert!(self.initialized <= N);
500-
501-
let initialized_part =
502-
crate::ptr::slice_from_raw_parts_mut(self.dst, self.initialized);
503-
// SAFETY: this raw slice will contain only initialized objects
504-
// that's why, it is allowed to drop it.
505-
unsafe {
506-
crate::ptr::drop_in_place(initialized_part);
507-
}
508-
}
509-
}
510-
let mut dst = MaybeUninit::uninit_array::<N>();
511-
let mut guard: Guard<U, N> =
512-
Guard { dst: MaybeUninit::slice_as_mut_ptr(&mut dst), initialized: 0 };
513-
for (src, dst) in IntoIter::new(self).zip(&mut dst) {
514-
dst.write(f(src));
515-
guard.initialized += 1;
516-
}
517-
// FIXME: Convert to crate::mem::transmute once it works with generics.
518-
// unsafe { crate::mem::transmute::<[MaybeUninit<U>; N], [U; N]>(dst) }
519-
crate::mem::forget(guard);
520-
// SAFETY: At this point we've properly initialized the whole array
521-
// and we just need to cast it to the correct type.
522-
unsafe { crate::mem::transmute_copy::<_, [U; N]>(&dst) }
484+
FillError::new().fill(IntoIter::new(self).map(f)).unwrap()
523485
}
524486

525487
/// Returns a slice containing the entire array. Equivalent to `&s[..]`.

library/core/tests/array.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use core::array::{FixedSizeArray, IntoIter};
1+
use core::array::{FillError, FixedSizeArray, IntoIter};
22
use core::convert::TryFrom;
33

44
#[test]
@@ -334,37 +334,37 @@ fn array_map_drop_safety() {
334334
#[test]
335335
fn array_collects() {
336336
let v = vec![1, 2, 3, 4, 5];
337-
let a: [i32; 5] = v
338-
.clone()
339-
.into_iter()
340-
.collect::<Result<[i32; 5], core::array::FillError<i32, 5>>>()
341-
.unwrap();
337+
let a: [i32; 5] = FillError::new().fill(v.clone()).unwrap();
342338

343339
assert_eq!(v[..], a[..]);
344340
}
345341

346342
#[test]
347-
fn array_collect_drop_on_panic() {
348-
use std::sync::atomic::{AtomicUsize, Ordering};
349-
use std::sync::Arc;
350-
351-
#[derive(Clone)]
352-
struct Foo(Arc<AtomicUsize>);
353-
354-
// count the number of eleemts that got dropped
355-
impl Drop for Foo {
343+
#[should_panic(expected = "test succeeded")]
344+
fn array_collect_drop_safety() {
345+
use core::sync::atomic::AtomicUsize;
346+
use core::sync::atomic::Ordering;
347+
static DROPPED: AtomicUsize = AtomicUsize::new(0);
348+
struct DropCounter;
349+
impl Drop for DropCounter {
356350
fn drop(&mut self) {
357-
self.0.fetch_add(1, Ordering::SeqCst);
351+
DROPPED.fetch_add(1, Ordering::SeqCst);
358352
}
359353
}
360354

361-
let i = Arc::new(AtomicUsize::new(0));
362-
let foo = Foo(i.clone());
363-
364-
std::panic::catch_unwind(move || {
365-
let _a: [Foo; 5] = from_iter(vec![foo.clone(), foo.clone(), foo.clone(), foo]);
366-
})
367-
.unwrap_err();
368-
369-
assert_eq!(i.load(Ordering::SeqCst), 4);
355+
let num_to_create = 5;
356+
let success = std::panic::catch_unwind(|| {
357+
let items = [0; 10];
358+
let mut nth = 0;
359+
FillError::<DropCounter, 10>::new()
360+
.fill(items.iter().map(|_| {
361+
assert!(nth < num_to_create);
362+
nth += 1;
363+
DropCounter
364+
}))
365+
.unwrap()
366+
});
367+
assert!(success.is_err());
368+
assert_eq!(DROPPED.load(Ordering::SeqCst), num_to_create);
369+
panic!("test succeeded")
370370
}

0 commit comments

Comments
 (0)