• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::{array, assert_eq};
2 use core::convert::TryFrom;
3 use core::num::NonZeroUsize;
4 use core::sync::atomic::{AtomicUsize, Ordering};
5 
6 #[test]
array_from_ref()7 fn array_from_ref() {
8     let value: String = "Hello World!".into();
9     let arr: &[String; 1] = array::from_ref(&value);
10     assert_eq!(&[value.clone()], arr);
11 
12     const VALUE: &&str = &"Hello World!";
13     const ARR: &[&str; 1] = array::from_ref(VALUE);
14     assert_eq!(&[*VALUE], ARR);
15     assert!(core::ptr::eq(VALUE, &ARR[0]));
16 }
17 
18 #[test]
array_from_mut()19 fn array_from_mut() {
20     let mut value: String = "Hello World".into();
21     let arr: &mut [String; 1] = array::from_mut(&mut value);
22     arr[0].push_str("!");
23     assert_eq!(&value, "Hello World!");
24 }
25 
26 #[test]
array_try_from()27 fn array_try_from() {
28     macro_rules! test {
29         ($($N:expr)+) => {
30             $({
31                 type Array = [u8; $N];
32                 let mut array: Array = [0; $N];
33                 let slice: &[u8] = &array[..];
34 
35                 let result = <&Array>::try_from(slice);
36                 assert_eq!(&array, result.unwrap());
37 
38                 let result = <Array>::try_from(slice);
39                 assert_eq!(&array, &result.unwrap());
40 
41                 let mut_slice: &mut [u8] = &mut array[..];
42                 let result = <&mut Array>::try_from(mut_slice);
43                 assert_eq!(&[0; $N], result.unwrap());
44 
45                 let mut_slice: &mut [u8] = &mut array[..];
46                 let result = <Array>::try_from(mut_slice);
47                 assert_eq!(&array, &result.unwrap());
48             })+
49         }
50     }
51     test! {
52          0  1  2  3  4  5  6  7  8  9
53         10 11 12 13 14 15 16 17 18 19
54         20 21 22 23 24 25 26 27 28 29
55         30 31 32
56     }
57 }
58 
59 #[test]
iterator_collect()60 fn iterator_collect() {
61     let arr = [0, 1, 2, 5, 9];
62     let v: Vec<_> = IntoIterator::into_iter(arr.clone()).collect();
63     assert_eq!(&arr[..], &v[..]);
64 }
65 
66 #[test]
iterator_rev_collect()67 fn iterator_rev_collect() {
68     let arr = [0, 1, 2, 5, 9];
69     let v: Vec<_> = IntoIterator::into_iter(arr.clone()).rev().collect();
70     assert_eq!(&v[..], &[9, 5, 2, 1, 0]);
71 }
72 
73 #[test]
iterator_nth()74 fn iterator_nth() {
75     let v = [0, 1, 2, 3, 4];
76     for i in 0..v.len() {
77         assert_eq!(IntoIterator::into_iter(v.clone()).nth(i).unwrap(), v[i]);
78     }
79     assert_eq!(IntoIterator::into_iter(v.clone()).nth(v.len()), None);
80 
81     let mut iter = IntoIterator::into_iter(v);
82     assert_eq!(iter.nth(2).unwrap(), v[2]);
83     assert_eq!(iter.nth(1).unwrap(), v[4]);
84 }
85 
86 #[test]
iterator_last()87 fn iterator_last() {
88     let v = [0, 1, 2, 3, 4];
89     assert_eq!(IntoIterator::into_iter(v).last().unwrap(), 4);
90     assert_eq!(IntoIterator::into_iter([0]).last().unwrap(), 0);
91 
92     let mut it = IntoIterator::into_iter([0, 9, 2, 4]);
93     assert_eq!(it.next_back(), Some(4));
94     assert_eq!(it.last(), Some(2));
95 }
96 
97 #[test]
iterator_clone()98 fn iterator_clone() {
99     let mut it = IntoIterator::into_iter([0, 2, 4, 6, 8]);
100     assert_eq!(it.next(), Some(0));
101     assert_eq!(it.next_back(), Some(8));
102     let mut clone = it.clone();
103     assert_eq!(it.next_back(), Some(6));
104     assert_eq!(clone.next_back(), Some(6));
105     assert_eq!(it.next_back(), Some(4));
106     assert_eq!(clone.next_back(), Some(4));
107     assert_eq!(it.next(), Some(2));
108     assert_eq!(clone.next(), Some(2));
109 }
110 
111 #[test]
iterator_fused()112 fn iterator_fused() {
113     let mut it = IntoIterator::into_iter([0, 9, 2]);
114     assert_eq!(it.next(), Some(0));
115     assert_eq!(it.next(), Some(9));
116     assert_eq!(it.next(), Some(2));
117     assert_eq!(it.next(), None);
118     assert_eq!(it.next(), None);
119     assert_eq!(it.next(), None);
120     assert_eq!(it.next(), None);
121     assert_eq!(it.next(), None);
122 }
123 
124 #[test]
iterator_len()125 fn iterator_len() {
126     let mut it = IntoIterator::into_iter([0, 1, 2, 5, 9]);
127     assert_eq!(it.size_hint(), (5, Some(5)));
128     assert_eq!(it.len(), 5);
129     assert_eq!(it.is_empty(), false);
130 
131     assert_eq!(it.next(), Some(0));
132     assert_eq!(it.size_hint(), (4, Some(4)));
133     assert_eq!(it.len(), 4);
134     assert_eq!(it.is_empty(), false);
135 
136     assert_eq!(it.next_back(), Some(9));
137     assert_eq!(it.size_hint(), (3, Some(3)));
138     assert_eq!(it.len(), 3);
139     assert_eq!(it.is_empty(), false);
140 
141     // Empty
142     let it = IntoIterator::into_iter([] as [String; 0]);
143     assert_eq!(it.size_hint(), (0, Some(0)));
144     assert_eq!(it.len(), 0);
145     assert_eq!(it.is_empty(), true);
146 }
147 
148 #[test]
iterator_count()149 fn iterator_count() {
150     let v = [0, 1, 2, 3, 4];
151     assert_eq!(IntoIterator::into_iter(v.clone()).count(), 5);
152 
153     let mut iter2 = IntoIterator::into_iter(v);
154     iter2.next();
155     iter2.next();
156     assert_eq!(iter2.count(), 3);
157 }
158 
159 #[test]
iterator_flat_map()160 fn iterator_flat_map() {
161     assert!((0..5).flat_map(|i| IntoIterator::into_iter([2 * i, 2 * i + 1])).eq(0..10));
162 }
163 
164 #[test]
iterator_debug()165 fn iterator_debug() {
166     let arr = [0, 1, 2, 5, 9];
167     assert_eq!(format!("{:?}", IntoIterator::into_iter(arr)), "IntoIter([0, 1, 2, 5, 9])",);
168 }
169 
170 #[test]
iterator_drops()171 fn iterator_drops() {
172     use core::cell::Cell;
173 
174     // This test makes sure the correct number of elements are dropped. The `R`
175     // type is just a reference to a `Cell` that is incremented when an `R` is
176     // dropped.
177 
178     #[derive(Clone)]
179     struct Foo<'a>(&'a Cell<usize>);
180 
181     impl Drop for Foo<'_> {
182         fn drop(&mut self) {
183             self.0.set(self.0.get() + 1);
184         }
185     }
186 
187     fn five(i: &Cell<usize>) -> [Foo<'_>; 5] {
188         // This is somewhat verbose because `Foo` does not implement `Copy`
189         // since it implements `Drop`. Consequently, we cannot write
190         // `[Foo(i); 5]`.
191         [Foo(i), Foo(i), Foo(i), Foo(i), Foo(i)]
192     }
193 
194     // Simple: drop new iterator.
195     let i = Cell::new(0);
196     {
197         IntoIterator::into_iter(five(&i));
198     }
199     assert_eq!(i.get(), 5);
200 
201     // Call `next()` once.
202     let i = Cell::new(0);
203     {
204         let mut iter = IntoIterator::into_iter(five(&i));
205         let _x = iter.next();
206         assert_eq!(i.get(), 0);
207         assert_eq!(iter.count(), 4);
208         assert_eq!(i.get(), 4);
209     }
210     assert_eq!(i.get(), 5);
211 
212     // Check `clone` and calling `next`/`next_back`.
213     let i = Cell::new(0);
214     {
215         let mut iter = IntoIterator::into_iter(five(&i));
216         iter.next();
217         assert_eq!(i.get(), 1);
218         iter.next_back();
219         assert_eq!(i.get(), 2);
220 
221         let mut clone = iter.clone();
222         assert_eq!(i.get(), 2);
223 
224         iter.next();
225         assert_eq!(i.get(), 3);
226 
227         clone.next();
228         assert_eq!(i.get(), 4);
229 
230         assert_eq!(clone.count(), 2);
231         assert_eq!(i.get(), 6);
232     }
233     assert_eq!(i.get(), 8);
234 
235     // Check via `nth`.
236     let i = Cell::new(0);
237     {
238         let mut iter = IntoIterator::into_iter(five(&i));
239         let _x = iter.nth(2);
240         assert_eq!(i.get(), 2);
241         let _y = iter.last();
242         assert_eq!(i.get(), 3);
243     }
244     assert_eq!(i.get(), 5);
245 
246     // Check every element.
247     let i = Cell::new(0);
248     for (index, _x) in IntoIterator::into_iter(five(&i)).enumerate() {
249         assert_eq!(i.get(), index);
250     }
251     assert_eq!(i.get(), 5);
252 
253     let i = Cell::new(0);
254     for (index, _x) in IntoIterator::into_iter(five(&i)).rev().enumerate() {
255         assert_eq!(i.get(), index);
256     }
257     assert_eq!(i.get(), 5);
258 }
259 
260 #[test]
261 #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
array_default_impl_avoids_leaks_on_panic()262 fn array_default_impl_avoids_leaks_on_panic() {
263     use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
264     static COUNTER: AtomicUsize = AtomicUsize::new(0);
265     #[derive(Debug)]
266     struct Bomb(usize);
267 
268     impl Default for Bomb {
269         fn default() -> Bomb {
270             if COUNTER.load(Relaxed) == 3 {
271                 panic!("bomb limit exceeded");
272             }
273 
274             COUNTER.fetch_add(1, Relaxed);
275             Bomb(COUNTER.load(Relaxed))
276         }
277     }
278 
279     impl Drop for Bomb {
280         fn drop(&mut self) {
281             COUNTER.fetch_sub(1, Relaxed);
282         }
283     }
284 
285     let res = std::panic::catch_unwind(|| <[Bomb; 5]>::default());
286     let panic_msg = match res {
287         Ok(_) => unreachable!(),
288         Err(p) => p.downcast::<&'static str>().unwrap(),
289     };
290     assert_eq!(*panic_msg, "bomb limit exceeded");
291     // check that all bombs are successfully dropped
292     assert_eq!(COUNTER.load(Relaxed), 0);
293 }
294 
295 #[test]
empty_array_is_always_default()296 fn empty_array_is_always_default() {
297     struct DoesNotImplDefault;
298 
299     let _arr = <[DoesNotImplDefault; 0]>::default();
300 }
301 
302 #[test]
array_map()303 fn array_map() {
304     let a = [1, 2, 3];
305     let b = a.map(|v| v + 1);
306     assert_eq!(b, [2, 3, 4]);
307 
308     let a = [1u8, 2, 3];
309     let b = a.map(|v| v as u64);
310     assert_eq!(b, [1, 2, 3]);
311 }
312 
313 #[test]
314 #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
array_map_drop_safety()315 fn array_map_drop_safety() {
316     static DROPPED: AtomicUsize = AtomicUsize::new(0);
317     struct DropCounter;
318     impl Drop for DropCounter {
319         fn drop(&mut self) {
320             DROPPED.fetch_add(1, Ordering::SeqCst);
321         }
322     }
323 
324     let num_to_create = 5;
325     let success = std::panic::catch_unwind(|| {
326         let items = [0; 10];
327         let mut nth = 0;
328         items.map(|_| {
329             assert!(nth < num_to_create);
330             nth += 1;
331             DropCounter
332         });
333     });
334     assert!(success.is_err());
335     assert_eq!(DROPPED.load(Ordering::SeqCst), num_to_create);
336 }
337 
338 #[test]
cell_allows_array_cycle()339 fn cell_allows_array_cycle() {
340     use core::cell::Cell;
341 
342     #[derive(Debug)]
343     struct B<'a> {
344         a: [Cell<Option<&'a B<'a>>>; 2],
345     }
346 
347     impl<'a> B<'a> {
348         fn new() -> B<'a> {
349             B { a: [Cell::new(None), Cell::new(None)] }
350         }
351     }
352 
353     let b1 = B::new();
354     let b2 = B::new();
355     let b3 = B::new();
356 
357     b1.a[0].set(Some(&b2));
358     b1.a[1].set(Some(&b3));
359 
360     b2.a[0].set(Some(&b2));
361     b2.a[1].set(Some(&b3));
362 
363     b3.a[0].set(Some(&b1));
364     b3.a[1].set(Some(&b2));
365 }
366 
367 #[test]
array_from_fn()368 fn array_from_fn() {
369     let array = core::array::from_fn(|idx| idx);
370     assert_eq!(array, [0, 1, 2, 3, 4]);
371 }
372 
373 #[test]
array_try_from_fn()374 fn array_try_from_fn() {
375     #[derive(Debug, PartialEq)]
376     enum SomeError {
377         Foo,
378     }
379 
380     let array = core::array::try_from_fn(|i| Ok::<_, SomeError>(i));
381     assert_eq!(array, Ok([0, 1, 2, 3, 4]));
382 
383     let another_array = core::array::try_from_fn::<Result<(), _>, 2, _>(|_| Err(SomeError::Foo));
384     assert_eq!(another_array, Err(SomeError::Foo));
385 }
386 
387 #[cfg(not(panic = "abort"))]
388 #[test]
array_try_from_fn_drops_inserted_elements_on_err()389 fn array_try_from_fn_drops_inserted_elements_on_err() {
390     static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
391 
392     struct CountDrop;
393     impl Drop for CountDrop {
394         fn drop(&mut self) {
395             DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
396         }
397     }
398 
399     let _ = catch_unwind_silent(move || {
400         let _: Result<[CountDrop; 4], ()> = core::array::try_from_fn(|idx| {
401             if idx == 2 {
402                 return Err(());
403             }
404             Ok(CountDrop)
405         });
406     });
407 
408     assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
409 }
410 
411 #[cfg(not(panic = "abort"))]
412 #[test]
array_try_from_fn_drops_inserted_elements_on_panic()413 fn array_try_from_fn_drops_inserted_elements_on_panic() {
414     static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
415 
416     struct CountDrop;
417     impl Drop for CountDrop {
418         fn drop(&mut self) {
419             DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
420         }
421     }
422 
423     let _ = catch_unwind_silent(move || {
424         let _: Result<[CountDrop; 4], ()> = core::array::try_from_fn(|idx| {
425             if idx == 2 {
426                 panic!("peek a boo");
427             }
428             Ok(CountDrop)
429         });
430     });
431 
432     assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
433 }
434 
435 #[cfg(not(panic = "abort"))]
436 // https://stackoverflow.com/a/59211505
catch_unwind_silent<F, R>(f: F) -> std::thread::Result<R> where F: FnOnce() -> R + core::panic::UnwindSafe,437 fn catch_unwind_silent<F, R>(f: F) -> std::thread::Result<R>
438 where
439     F: FnOnce() -> R + core::panic::UnwindSafe,
440 {
441     let prev_hook = std::panic::take_hook();
442     std::panic::set_hook(Box::new(|_| {}));
443     let result = std::panic::catch_unwind(f);
444     std::panic::set_hook(prev_hook);
445     result
446 }
447 
448 #[test]
array_split_array_mut()449 fn array_split_array_mut() {
450     let mut v = [1, 2, 3, 4, 5, 6];
451 
452     {
453         let (left, right) = v.split_array_mut::<0>();
454         assert_eq!(left, &mut []);
455         assert_eq!(right, &mut [1, 2, 3, 4, 5, 6]);
456     }
457 
458     {
459         let (left, right) = v.split_array_mut::<6>();
460         assert_eq!(left, &mut [1, 2, 3, 4, 5, 6]);
461         assert_eq!(right, &mut []);
462     }
463 }
464 
465 #[test]
array_rsplit_array_mut()466 fn array_rsplit_array_mut() {
467     let mut v = [1, 2, 3, 4, 5, 6];
468 
469     {
470         let (left, right) = v.rsplit_array_mut::<0>();
471         assert_eq!(left, &mut [1, 2, 3, 4, 5, 6]);
472         assert_eq!(right, &mut []);
473     }
474 
475     {
476         let (left, right) = v.rsplit_array_mut::<6>();
477         assert_eq!(left, &mut []);
478         assert_eq!(right, &mut [1, 2, 3, 4, 5, 6]);
479     }
480 }
481 
482 #[should_panic]
483 #[test]
array_split_array_ref_out_of_bounds()484 fn array_split_array_ref_out_of_bounds() {
485     let v = [1, 2, 3, 4, 5, 6];
486 
487     v.split_array_ref::<7>();
488 }
489 
490 #[should_panic]
491 #[test]
array_split_array_mut_out_of_bounds()492 fn array_split_array_mut_out_of_bounds() {
493     let mut v = [1, 2, 3, 4, 5, 6];
494 
495     v.split_array_mut::<7>();
496 }
497 
498 #[should_panic]
499 #[test]
array_rsplit_array_ref_out_of_bounds()500 fn array_rsplit_array_ref_out_of_bounds() {
501     let v = [1, 2, 3, 4, 5, 6];
502 
503     v.rsplit_array_ref::<7>();
504 }
505 
506 #[should_panic]
507 #[test]
array_rsplit_array_mut_out_of_bounds()508 fn array_rsplit_array_mut_out_of_bounds() {
509     let mut v = [1, 2, 3, 4, 5, 6];
510 
511     v.rsplit_array_mut::<7>();
512 }
513 
514 #[test]
array_intoiter_advance_by()515 fn array_intoiter_advance_by() {
516     use std::cell::Cell;
517     struct DropCounter<'a>(usize, &'a Cell<usize>);
518     impl Drop for DropCounter<'_> {
519         fn drop(&mut self) {
520             let x = self.1.get();
521             self.1.set(x + 1);
522         }
523     }
524 
525     let counter = Cell::new(0);
526     let a: [_; 100] = std::array::from_fn(|i| DropCounter(i, &counter));
527     let mut it = IntoIterator::into_iter(a);
528 
529     let r = it.advance_by(1);
530     assert_eq!(r, Ok(()));
531     assert_eq!(it.len(), 99);
532     assert_eq!(counter.get(), 1);
533 
534     let r = it.advance_by(0);
535     assert_eq!(r, Ok(()));
536     assert_eq!(it.len(), 99);
537     assert_eq!(counter.get(), 1);
538 
539     let r = it.advance_by(11);
540     assert_eq!(r, Ok(()));
541     assert_eq!(it.len(), 88);
542     assert_eq!(counter.get(), 12);
543 
544     let x = it.next();
545     assert_eq!(x.as_ref().map(|x| x.0), Some(12));
546     assert_eq!(it.len(), 87);
547     assert_eq!(counter.get(), 12);
548     drop(x);
549     assert_eq!(counter.get(), 13);
550 
551     let r = it.advance_by(123456);
552     assert_eq!(r, Err(NonZeroUsize::new(123456 - 87).unwrap()));
553     assert_eq!(it.len(), 0);
554     assert_eq!(counter.get(), 100);
555 
556     let r = it.advance_by(0);
557     assert_eq!(r, Ok(()));
558     assert_eq!(it.len(), 0);
559     assert_eq!(counter.get(), 100);
560 
561     let r = it.advance_by(10);
562     assert_eq!(r, Err(NonZeroUsize::new(10).unwrap()));
563     assert_eq!(it.len(), 0);
564     assert_eq!(counter.get(), 100);
565 }
566 
567 #[test]
array_intoiter_advance_back_by()568 fn array_intoiter_advance_back_by() {
569     use std::cell::Cell;
570     struct DropCounter<'a>(usize, &'a Cell<usize>);
571     impl Drop for DropCounter<'_> {
572         fn drop(&mut self) {
573             let x = self.1.get();
574             self.1.set(x + 1);
575         }
576     }
577 
578     let counter = Cell::new(0);
579     let a: [_; 100] = std::array::from_fn(|i| DropCounter(i, &counter));
580     let mut it = IntoIterator::into_iter(a);
581 
582     let r = it.advance_back_by(1);
583     assert_eq!(r, Ok(()));
584     assert_eq!(it.len(), 99);
585     assert_eq!(counter.get(), 1);
586 
587     let r = it.advance_back_by(0);
588     assert_eq!(r, Ok(()));
589     assert_eq!(it.len(), 99);
590     assert_eq!(counter.get(), 1);
591 
592     let r = it.advance_back_by(11);
593     assert_eq!(r, Ok(()));
594     assert_eq!(it.len(), 88);
595     assert_eq!(counter.get(), 12);
596 
597     let x = it.next_back();
598     assert_eq!(x.as_ref().map(|x| x.0), Some(87));
599     assert_eq!(it.len(), 87);
600     assert_eq!(counter.get(), 12);
601     drop(x);
602     assert_eq!(counter.get(), 13);
603 
604     let r = it.advance_back_by(123456);
605     assert_eq!(r, Err(NonZeroUsize::new(123456 - 87).unwrap()));
606     assert_eq!(it.len(), 0);
607     assert_eq!(counter.get(), 100);
608 
609     let r = it.advance_back_by(0);
610     assert_eq!(r, Ok(()));
611     assert_eq!(it.len(), 0);
612     assert_eq!(counter.get(), 100);
613 
614     let r = it.advance_back_by(10);
615     assert_eq!(r, Err(NonZeroUsize::new(10).unwrap()));
616     assert_eq!(it.len(), 0);
617     assert_eq!(counter.get(), 100);
618 }
619 
620 #[test]
array_mixed_equality_integers()621 fn array_mixed_equality_integers() {
622     let array3: [i32; 3] = [1, 2, 3];
623     let array3b: [i32; 3] = [3, 2, 1];
624     let array4: [i32; 4] = [1, 2, 3, 4];
625 
626     let slice3: &[i32] = &{ array3 };
627     let slice3b: &[i32] = &{ array3b };
628     let slice4: &[i32] = &{ array4 };
629     assert!(array3 == slice3);
630     assert!(array3 != slice3b);
631     assert!(array3 != slice4);
632     assert!(slice3 == array3);
633     assert!(slice3b != array3);
634     assert!(slice4 != array3);
635 
636     let mut3: &mut [i32] = &mut { array3 };
637     let mut3b: &mut [i32] = &mut { array3b };
638     let mut4: &mut [i32] = &mut { array4 };
639     assert!(array3 == mut3);
640     assert!(array3 != mut3b);
641     assert!(array3 != mut4);
642     assert!(mut3 == array3);
643     assert!(mut3b != array3);
644     assert!(mut4 != array3);
645 }
646 
647 #[test]
array_mixed_equality_nans()648 fn array_mixed_equality_nans() {
649     let array3: [f32; 3] = [1.0, std::f32::NAN, 3.0];
650 
651     let slice3: &[f32] = &{ array3 };
652     assert!(!(array3 == slice3));
653     assert!(array3 != slice3);
654     assert!(!(slice3 == array3));
655     assert!(slice3 != array3);
656 
657     let mut3: &mut [f32] = &mut { array3 };
658     assert!(!(array3 == mut3));
659     assert!(array3 != mut3);
660     assert!(!(mut3 == array3));
661     assert!(mut3 != array3);
662 }
663 
664 #[test]
array_into_iter_fold()665 fn array_into_iter_fold() {
666     // Strings to help MIRI catch if we double-free or something
667     let a = ["Aa".to_string(), "Bb".to_string(), "Cc".to_string()];
668     let mut s = "s".to_string();
669     a.into_iter().for_each(|b| s += &b);
670     assert_eq!(s, "sAaBbCc");
671 
672     let a = [1, 2, 3, 4, 5, 6];
673     let mut it = a.into_iter();
674     assert_eq!(it.advance_by(1), Ok(()));
675     assert_eq!(it.advance_back_by(2), Ok(()));
676     let s = it.fold(10, |a, b| 10 * a + b);
677     assert_eq!(s, 10234);
678 }
679 
680 #[test]
array_into_iter_rfold()681 fn array_into_iter_rfold() {
682     // Strings to help MIRI catch if we double-free or something
683     let a = ["Aa".to_string(), "Bb".to_string(), "Cc".to_string()];
684     let mut s = "s".to_string();
685     a.into_iter().rev().for_each(|b| s += &b);
686     assert_eq!(s, "sCcBbAa");
687 
688     let a = [1, 2, 3, 4, 5, 6];
689     let mut it = a.into_iter();
690     assert_eq!(it.advance_by(1), Ok(()));
691     assert_eq!(it.advance_back_by(2), Ok(()));
692     let s = it.rfold(10, |a, b| 10 * a + b);
693     assert_eq!(s, 10432);
694 }
695 
696 #[cfg(not(panic = "abort"))]
697 #[test]
array_map_drops_unmapped_elements_on_panic()698 fn array_map_drops_unmapped_elements_on_panic() {
699     struct DropCounter<'a>(usize, &'a AtomicUsize);
700     impl Drop for DropCounter<'_> {
701         fn drop(&mut self) {
702             self.1.fetch_add(1, Ordering::SeqCst);
703         }
704     }
705 
706     const MAX: usize = 11;
707     for panic_after in 0..MAX {
708         let counter = AtomicUsize::new(0);
709         let a = array::from_fn::<_, 11, _>(|i| DropCounter(i, &counter));
710         let success = std::panic::catch_unwind(|| {
711             let _ = a.map(|x| {
712                 assert!(x.0 < panic_after);
713                 assert_eq!(counter.load(Ordering::SeqCst), x.0);
714             });
715         });
716         assert!(success.is_err());
717         assert_eq!(counter.load(Ordering::SeqCst), MAX);
718     }
719 }
720