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