Skip to main content

core/stdarch/crates/core_arch/src/
simd.rs

1//! Internal `#[repr(simd)]` types
2
3#![allow(non_camel_case_types)]
4
5#[inline(always)]
6#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
7pub(crate) const unsafe fn simd_imax<T: Copy>(a: T, b: T) -> T {
8    let mask: T = crate::intrinsics::simd::simd_gt(a, b);
9    crate::intrinsics::simd::simd_select(mask, a, b)
10}
11
12#[inline(always)]
13#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
14pub(crate) const unsafe fn simd_imin<T: Copy>(a: T, b: T) -> T {
15    let mask: T = crate::intrinsics::simd::simd_lt(a, b);
16    crate::intrinsics::simd::simd_select(mask, a, b)
17}
18
19/// SAFETY: All bits patterns must be valid
20pub(crate) unsafe trait SimdElement:
21    Copy + const PartialEq + crate::fmt::Debug
22{
23}
24
25unsafe impl SimdElement for u8 {}
26unsafe impl SimdElement for u16 {}
27unsafe impl SimdElement for u32 {}
28unsafe impl SimdElement for u64 {}
29
30unsafe impl SimdElement for i8 {}
31unsafe impl SimdElement for i16 {}
32unsafe impl SimdElement for i32 {}
33unsafe impl SimdElement for i64 {}
34
35unsafe impl SimdElement for f16 {}
36unsafe impl SimdElement for f32 {}
37unsafe impl SimdElement for f64 {}
38
39#[repr(simd)]
40#[derive(Copy)]
41pub(crate) struct Simd<T: SimdElement, const N: usize>([T; N]);
42
43impl<T: SimdElement, const N: usize> Simd<T, N> {
44    /// A value of this type where all elements are zeroed out.
45    // SAFETY: `T` implements `SimdElement`, so it is zeroable.
46    pub(crate) const ZERO: Self = unsafe { crate::mem::zeroed() };
47
48    #[inline(always)]
49    pub(crate) const fn from_array(elements: [T; N]) -> Self {
50        Self(elements)
51    }
52
53    #[inline]
54    #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
55    pub(crate) const fn splat(value: T) -> Self {
56        unsafe { crate::intrinsics::simd::simd_splat(value) }
57    }
58
59    /// Extract the element at position `index`. Note that `index` is not a constant so this
60    /// operation is not efficient on most platforms. Use for testing only.
61    #[inline]
62    #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
63    pub(crate) const fn extract_dyn(&self, index: usize) -> T {
64        assert!(index < N);
65        // SAFETY: self is a vector, T its element type.
66        unsafe { crate::intrinsics::simd::simd_extract_dyn(*self, index as u32) }
67    }
68
69    #[inline]
70    pub(crate) const fn as_array(&self) -> &[T; N] {
71        let simd_ptr: *const Self = self;
72        let array_ptr: *const [T; N] = simd_ptr.cast();
73        // SAFETY: We can always read the prefix of a simd type as an array.
74        // There might be more padding afterwards for some widths, but
75        // that's not a problem for reading less than that.
76        unsafe { &*array_ptr }
77    }
78}
79
80// `#[derive(Clone)]` causes ICE "Projecting into SIMD type core_arch::simd::Simd is banned by MCP#838"
81impl<T: SimdElement, const N: usize> Clone for Simd<T, N> {
82    #[inline]
83    fn clone(&self) -> Self {
84        *self
85    }
86}
87
88#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
89impl<T: SimdElement, const N: usize> const crate::cmp::PartialEq for Simd<T, N> {
90    #[inline]
91    fn eq(&self, other: &Self) -> bool {
92        self.as_array() == other.as_array()
93    }
94}
95
96impl<T: SimdElement, const N: usize> crate::fmt::Debug for Simd<T, N> {
97    #[inline]
98    fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
99        debug_simd_finish(f, "Simd", self.as_array())
100    }
101}
102
103impl<const N: usize> Simd<f16, N> {
104    #[inline]
105    pub(crate) const fn to_bits(self) -> Simd<u16, N> {
106        assert!(size_of::<Self>() == size_of::<Simd<u16, N>>());
107        unsafe { crate::mem::transmute_copy(&self) }
108    }
109
110    #[inline]
111    pub(crate) const fn from_bits(bits: Simd<u16, N>) -> Self {
112        assert!(size_of::<Self>() == size_of::<Simd<u16, N>>());
113        unsafe { crate::mem::transmute_copy(&bits) }
114    }
115}
116
117impl<const N: usize> Simd<f32, N> {
118    #[inline]
119    pub(crate) const fn to_bits(self) -> Simd<u32, N> {
120        assert!(size_of::<Self>() == size_of::<Simd<u32, N>>());
121        unsafe { crate::mem::transmute_copy(&self) }
122    }
123
124    #[inline]
125    pub(crate) const fn from_bits(bits: Simd<u32, N>) -> Self {
126        assert!(size_of::<Self>() == size_of::<Simd<u32, N>>());
127        unsafe { crate::mem::transmute_copy(&bits) }
128    }
129}
130
131impl<const N: usize> Simd<f64, N> {
132    #[inline]
133    pub(crate) const fn to_bits(self) -> Simd<u64, N> {
134        assert!(size_of::<Self>() == size_of::<Simd<u64, N>>());
135        unsafe { crate::mem::transmute_copy(&self) }
136    }
137
138    #[inline]
139    pub(crate) const fn from_bits(bits: Simd<u64, N>) -> Self {
140        assert!(size_of::<Self>() == size_of::<Simd<u64, N>>());
141        unsafe { crate::mem::transmute_copy(&bits) }
142    }
143}
144
145macro_rules! simd_ty {
146    ($id:ident [$elem_type:ty ; $len:literal]: $($param_name:ident),*) => {
147        pub(crate) type $id = Simd<$elem_type, $len>;
148
149        impl $id {
150            #[inline(always)]
151            pub(crate) const fn new($($param_name: $elem_type),*) -> Self {
152                Self([$($param_name),*])
153            }
154        }
155    }
156}
157
158#[repr(simd)]
159#[derive(Copy)]
160pub(crate) struct SimdM<T: SimdElement, const N: usize>([T; N]);
161
162impl<T: SimdElement, const N: usize> SimdM<T, N> {
163    #[inline(always)]
164    const fn bool_to_internal(x: bool) -> T {
165        // SAFETY: `T` implements `SimdElement`, so all bit patterns are valid.
166        let zeros = const { unsafe { crate::mem::zeroed::<T>() } };
167        let ones = const {
168            // Ideally, this would be `transmute([0xFFu8; size_of::<T>()])`, but
169            // `size_of::<T>()` is not allowed to use a generic parameter there.
170            let mut r = crate::mem::MaybeUninit::<T>::uninit();
171            let mut i = 0;
172            while i < crate::mem::size_of::<T>() {
173                r.as_bytes_mut()[i] = crate::mem::MaybeUninit::new(0xFF);
174                i += 1;
175            }
176            unsafe { r.assume_init() }
177        };
178        [zeros, ones][x as usize]
179    }
180
181    #[inline]
182    #[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
183    pub(crate) const fn splat(value: bool) -> Self {
184        unsafe { crate::intrinsics::simd::simd_splat(value) }
185    }
186
187    #[inline]
188    pub(crate) const fn as_array(&self) -> &[T; N] {
189        let simd_ptr: *const Self = self;
190        let array_ptr: *const [T; N] = simd_ptr.cast();
191        // SAFETY: We can always read the prefix of a simd type as an array.
192        // There might be more padding afterwards for some widths, but
193        // that's not a problem for reading less than that.
194        unsafe { &*array_ptr }
195    }
196}
197
198// `#[derive(Clone)]` causes ICE "Projecting into SIMD type core_arch::simd::SimdM is banned by MCP#838"
199impl<T: SimdElement, const N: usize> Clone for SimdM<T, N> {
200    #[inline]
201    fn clone(&self) -> Self {
202        *self
203    }
204}
205
206#[rustc_const_unstable(feature = "stdarch_const_helpers", issue = "none")]
207impl<T: SimdElement, const N: usize> const crate::cmp::PartialEq for SimdM<T, N> {
208    #[inline]
209    fn eq(&self, other: &Self) -> bool {
210        self.as_array() == other.as_array()
211    }
212}
213
214impl<T: SimdElement, const N: usize> crate::fmt::Debug for SimdM<T, N> {
215    #[inline]
216    fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
217        debug_simd_finish(f, "SimdM", self.as_array())
218    }
219}
220
221macro_rules! simd_m_ty {
222    ($id:ident [$elem_type:ident ; $len:literal]: $($param_name:ident),*) => {
223        pub(crate) type $id  = SimdM<$elem_type, $len>;
224
225        impl $id {
226            #[inline(always)]
227            pub(crate) const fn new($($param_name: bool),*) -> Self {
228                Self([$(Self::bool_to_internal($param_name)),*])
229            }
230        }
231    }
232}
233
234// 16-bit wide types:
235
236simd_ty!(u8x2[u8;2]: x0, x1);
237simd_ty!(i8x2[i8;2]: x0, x1);
238
239// 32-bit wide types:
240
241simd_ty!(u8x4[u8;4]: x0, x1, x2, x3);
242simd_ty!(u16x2[u16;2]: x0, x1);
243
244simd_ty!(i8x4[i8;4]: x0, x1, x2, x3);
245simd_ty!(i16x2[i16;2]: x0, x1);
246
247// 64-bit wide types:
248
249simd_ty!(
250    u8x8[u8;8]:
251    x0,
252    x1,
253    x2,
254    x3,
255    x4,
256    x5,
257    x6,
258    x7
259);
260simd_ty!(u16x4[u16;4]: x0, x1, x2, x3);
261simd_ty!(u32x2[u32;2]: x0, x1);
262simd_ty!(u64x1[u64;1]: x1);
263
264simd_ty!(
265    i8x8[i8;8]:
266    x0,
267    x1,
268    x2,
269    x3,
270    x4,
271    x5,
272    x6,
273    x7
274);
275simd_ty!(i16x4[i16;4]: x0, x1, x2, x3);
276simd_ty!(i32x2[i32;2]: x0, x1);
277simd_ty!(i64x1[i64;1]: x1);
278
279simd_ty!(f32x2[f32;2]: x0, x1);
280simd_ty!(f64x1[f64;1]: x1);
281
282// 128-bit wide types:
283
284simd_ty!(
285    u8x16[u8;16]:
286    x0,
287    x1,
288    x2,
289    x3,
290    x4,
291    x5,
292    x6,
293    x7,
294    x8,
295    x9,
296    x10,
297    x11,
298    x12,
299    x13,
300    x14,
301    x15
302);
303simd_ty!(
304    u16x8[u16;8]:
305    x0,
306    x1,
307    x2,
308    x3,
309    x4,
310    x5,
311    x6,
312    x7
313);
314simd_ty!(u32x4[u32;4]: x0, x1, x2, x3);
315simd_ty!(u64x2[u64;2]: x0, x1);
316
317simd_ty!(
318    i8x16[i8;16]:
319    x0,
320    x1,
321    x2,
322    x3,
323    x4,
324    x5,
325    x6,
326    x7,
327    x8,
328    x9,
329    x10,
330    x11,
331    x12,
332    x13,
333    x14,
334    x15
335);
336simd_ty!(
337    i16x8[i16;8]:
338    x0,
339    x1,
340    x2,
341    x3,
342    x4,
343    x5,
344    x6,
345    x7
346);
347simd_ty!(i32x4[i32;4]: x0, x1, x2, x3);
348simd_ty!(i64x2[i64;2]: x0, x1);
349
350simd_ty!(f16x4[f16;4]: x0, x1, x2, x3);
351
352simd_ty!(
353    f16x8[f16;8]:
354    x0,
355    x1,
356    x2,
357    x3,
358    x4,
359    x5,
360    x6,
361    x7
362);
363simd_ty!(f32x4[f32;4]: x0, x1, x2, x3);
364simd_ty!(f64x2[f64;2]: x0, x1);
365
366simd_m_ty!(
367    m8x16[i8;16]:
368    x0,
369    x1,
370    x2,
371    x3,
372    x4,
373    x5,
374    x6,
375    x7,
376    x8,
377    x9,
378    x10,
379    x11,
380    x12,
381    x13,
382    x14,
383    x15
384);
385simd_m_ty!(
386    m16x8[i16;8]:
387    x0,
388    x1,
389    x2,
390    x3,
391    x4,
392    x5,
393    x6,
394    x7
395);
396simd_m_ty!(m32x4[i32;4]: x0, x1, x2, x3);
397simd_m_ty!(m64x2[i64;2]: x0, x1);
398
399// 256-bit wide types:
400
401simd_ty!(
402    u8x32[u8;32]:
403    x0,
404    x1,
405    x2,
406    x3,
407    x4,
408    x5,
409    x6,
410    x7,
411    x8,
412    x9,
413    x10,
414    x11,
415    x12,
416    x13,
417    x14,
418    x15,
419    x16,
420    x17,
421    x18,
422    x19,
423    x20,
424    x21,
425    x22,
426    x23,
427    x24,
428    x25,
429    x26,
430    x27,
431    x28,
432    x29,
433    x30,
434    x31
435);
436simd_ty!(
437    u16x16[u16;16]:
438    x0,
439    x1,
440    x2,
441    x3,
442    x4,
443    x5,
444    x6,
445    x7,
446    x8,
447    x9,
448    x10,
449    x11,
450    x12,
451    x13,
452    x14,
453    x15
454);
455simd_ty!(
456    u32x8[u32;8]:
457    x0,
458    x1,
459    x2,
460    x3,
461    x4,
462    x5,
463    x6,
464    x7
465);
466simd_ty!(u64x4[u64;4]: x0, x1, x2, x3);
467
468simd_ty!(
469    i8x32[i8;32]:
470    x0,
471    x1,
472    x2,
473    x3,
474    x4,
475    x5,
476    x6,
477    x7,
478    x8,
479    x9,
480    x10,
481    x11,
482    x12,
483    x13,
484    x14,
485    x15,
486    x16,
487    x17,
488    x18,
489    x19,
490    x20,
491    x21,
492    x22,
493    x23,
494    x24,
495    x25,
496    x26,
497    x27,
498    x28,
499    x29,
500    x30,
501    x31
502);
503simd_ty!(
504    i16x16[i16;16]:
505    x0,
506    x1,
507    x2,
508    x3,
509    x4,
510    x5,
511    x6,
512    x7,
513    x8,
514    x9,
515    x10,
516    x11,
517    x12,
518    x13,
519    x14,
520    x15
521);
522simd_ty!(
523    i32x8[i32;8]:
524    x0,
525    x1,
526    x2,
527    x3,
528    x4,
529    x5,
530    x6,
531    x7
532);
533simd_ty!(i64x4[i64;4]: x0, x1, x2, x3);
534
535simd_ty!(
536    f16x16[f16;16]:
537    x0,
538    x1,
539    x2,
540    x3,
541    x4,
542    x5,
543    x6,
544    x7,
545    x8,
546    x9,
547    x10,
548    x11,
549    x12,
550    x13,
551    x14,
552    x15
553);
554simd_ty!(
555    f32x8[f32;8]:
556    x0,
557    x1,
558    x2,
559    x3,
560    x4,
561    x5,
562    x6,
563    x7
564);
565simd_ty!(f64x4[f64;4]: x0, x1, x2, x3);
566
567simd_m_ty!(
568    m8x32[i8;32]:
569    x0,
570    x1,
571    x2,
572    x3,
573    x4,
574    x5,
575    x6,
576    x7,
577    x8,
578    x9,
579    x10,
580    x11,
581    x12,
582    x13,
583    x14,
584    x15,
585    x16,
586    x17,
587    x18,
588    x19,
589    x20,
590    x21,
591    x22,
592    x23,
593    x24,
594    x25,
595    x26,
596    x27,
597    x28,
598    x29,
599    x30,
600    x31
601);
602simd_m_ty!(
603    m16x16[i16;16]:
604    x0,
605    x1,
606    x2,
607    x3,
608    x4,
609    x5,
610    x6,
611    x7,
612    x8,
613    x9,
614    x10,
615    x11,
616    x12,
617    x13,
618    x14,
619    x15
620);
621simd_m_ty!(
622    m32x8[i32;8]:
623    x0,
624    x1,
625    x2,
626    x3,
627    x4,
628    x5,
629    x6,
630    x7
631);
632
633// 512-bit wide types:
634
635simd_ty!(
636    i8x64[i8;64]:
637    x0,
638    x1,
639    x2,
640    x3,
641    x4,
642    x5,
643    x6,
644    x7,
645    x8,
646    x9,
647    x10,
648    x11,
649    x12,
650    x13,
651    x14,
652    x15,
653    x16,
654    x17,
655    x18,
656    x19,
657    x20,
658    x21,
659    x22,
660    x23,
661    x24,
662    x25,
663    x26,
664    x27,
665    x28,
666    x29,
667    x30,
668    x31,
669    x32,
670    x33,
671    x34,
672    x35,
673    x36,
674    x37,
675    x38,
676    x39,
677    x40,
678    x41,
679    x42,
680    x43,
681    x44,
682    x45,
683    x46,
684    x47,
685    x48,
686    x49,
687    x50,
688    x51,
689    x52,
690    x53,
691    x54,
692    x55,
693    x56,
694    x57,
695    x58,
696    x59,
697    x60,
698    x61,
699    x62,
700    x63
701);
702
703simd_ty!(
704    u8x64[u8;64]:
705    x0,
706    x1,
707    x2,
708    x3,
709    x4,
710    x5,
711    x6,
712    x7,
713    x8,
714    x9,
715    x10,
716    x11,
717    x12,
718    x13,
719    x14,
720    x15,
721    x16,
722    x17,
723    x18,
724    x19,
725    x20,
726    x21,
727    x22,
728    x23,
729    x24,
730    x25,
731    x26,
732    x27,
733    x28,
734    x29,
735    x30,
736    x31,
737    x32,
738    x33,
739    x34,
740    x35,
741    x36,
742    x37,
743    x38,
744    x39,
745    x40,
746    x41,
747    x42,
748    x43,
749    x44,
750    x45,
751    x46,
752    x47,
753    x48,
754    x49,
755    x50,
756    x51,
757    x52,
758    x53,
759    x54,
760    x55,
761    x56,
762    x57,
763    x58,
764    x59,
765    x60,
766    x61,
767    x62,
768    x63
769);
770
771simd_ty!(
772    i16x32[i16;32]:
773    x0,
774    x1,
775    x2,
776    x3,
777    x4,
778    x5,
779    x6,
780    x7,
781    x8,
782    x9,
783    x10,
784    x11,
785    x12,
786    x13,
787    x14,
788    x15,
789    x16,
790    x17,
791    x18,
792    x19,
793    x20,
794    x21,
795    x22,
796    x23,
797    x24,
798    x25,
799    x26,
800    x27,
801    x28,
802    x29,
803    x30,
804    x31
805);
806
807simd_ty!(
808    u16x32[u16;32]:
809    x0,
810    x1,
811    x2,
812    x3,
813    x4,
814    x5,
815    x6,
816    x7,
817    x8,
818    x9,
819    x10,
820    x11,
821    x12,
822    x13,
823    x14,
824    x15,
825    x16,
826    x17,
827    x18,
828    x19,
829    x20,
830    x21,
831    x22,
832    x23,
833    x24,
834    x25,
835    x26,
836    x27,
837    x28,
838    x29,
839    x30,
840    x31
841);
842
843simd_ty!(
844    i32x16[i32;16]:
845    x0,
846    x1,
847    x2,
848    x3,
849    x4,
850    x5,
851    x6,
852    x7,
853    x8,
854    x9,
855    x10,
856    x11,
857    x12,
858    x13,
859    x14,
860    x15
861);
862
863simd_ty!(
864    u32x16[u32;16]:
865    x0,
866    x1,
867    x2,
868    x3,
869    x4,
870    x5,
871    x6,
872    x7,
873    x8,
874    x9,
875    x10,
876    x11,
877    x12,
878    x13,
879    x14,
880    x15
881);
882
883simd_ty!(
884    f16x32[f16;32]:
885    x0,
886    x1,
887    x2,
888    x3,
889    x4,
890    x5,
891    x6,
892    x7,
893    x8,
894    x9,
895    x10,
896    x11,
897    x12,
898    x13,
899    x14,
900    x15,
901    x16,
902    x17,
903    x18,
904    x19,
905    x20,
906    x21,
907    x22,
908    x23,
909    x24,
910    x25,
911    x26,
912    x27,
913    x28,
914    x29,
915    x30,
916    x31
917);
918simd_ty!(
919    f32x16[f32;16]:
920    x0,
921    x1,
922    x2,
923    x3,
924    x4,
925    x5,
926    x6,
927    x7,
928    x8,
929    x9,
930    x10,
931    x11,
932    x12,
933    x13,
934    x14,
935    x15
936);
937
938simd_ty!(
939    i64x8[i64;8]:
940    x0,
941    x1,
942    x2,
943    x3,
944    x4,
945    x5,
946    x6,
947    x7
948);
949
950simd_ty!(
951    u64x8[u64;8]:
952    x0,
953    x1,
954    x2,
955    x3,
956    x4,
957    x5,
958    x6,
959    x7
960);
961
962simd_ty!(
963    f64x8[f64;8]:
964    x0,
965    x1,
966    x2,
967    x3,
968    x4,
969    x5,
970    x6,
971    x7
972);
973
974// 1024-bit wide types:
975simd_ty!(
976    u16x64[u16;64]:
977    x0,
978    x1,
979    x2,
980    x3,
981    x4,
982    x5,
983    x6,
984    x7,
985    x8,
986    x9,
987    x10,
988    x11,
989    x12,
990    x13,
991    x14,
992    x15,
993    x16,
994    x17,
995    x18,
996    x19,
997    x20,
998    x21,
999    x22,
1000    x23,
1001    x24,
1002    x25,
1003    x26,
1004    x27,
1005    x28,
1006    x29,
1007    x30,
1008    x31,
1009    x32,
1010    x33,
1011    x34,
1012    x35,
1013    x36,
1014    x37,
1015    x38,
1016    x39,
1017    x40,
1018    x41,
1019    x42,
1020    x43,
1021    x44,
1022    x45,
1023    x46,
1024    x47,
1025    x48,
1026    x49,
1027    x50,
1028    x51,
1029    x52,
1030    x53,
1031    x54,
1032    x55,
1033    x56,
1034    x57,
1035    x58,
1036    x59,
1037    x60,
1038    x61,
1039    x62,
1040    x63
1041);
1042simd_ty!(
1043    i32x32[i32;32]:
1044    x0,
1045    x1,
1046    x2,
1047    x3,
1048    x4,
1049    x5,
1050    x6,
1051    x7,
1052    x8,
1053    x9,
1054    x10,
1055    x11,
1056    x12,
1057    x13,
1058    x14,
1059    x15,
1060    x16,
1061    x17,
1062    x18,
1063    x19,
1064    x20,
1065    x21,
1066    x22,
1067    x23,
1068    x24,
1069    x25,
1070    x26,
1071    x27,
1072    x28,
1073    x29,
1074    x30,
1075    x31
1076);
1077simd_ty!(
1078    u32x32[u32;32]:
1079    x0,
1080    x1,
1081    x2,
1082    x3,
1083    x4,
1084    x5,
1085    x6,
1086    x7,
1087    x8,
1088    x9,
1089    x10,
1090    x11,
1091    x12,
1092    x13,
1093    x14,
1094    x15,
1095    x16,
1096    x17,
1097    x18,
1098    x19,
1099    x20,
1100    x21,
1101    x22,
1102    x23,
1103    x24,
1104    x25,
1105    x26,
1106    x27,
1107    x28,
1108    x29,
1109    x30,
1110    x31
1111);
1112
1113/// Used to continue `Debug`ging SIMD types as `MySimd(1, 2, 3, 4)`, as they
1114/// were before moving to array-based simd.
1115#[inline]
1116pub(crate) fn debug_simd_finish<T: crate::fmt::Debug, const N: usize>(
1117    formatter: &mut crate::fmt::Formatter<'_>,
1118    type_name: &str,
1119    array: &[T; N],
1120) -> crate::fmt::Result {
1121    crate::fmt::Formatter::debug_tuple_fields_finish(
1122        formatter,
1123        type_name,
1124        &crate::array::from_fn::<&dyn crate::fmt::Debug, N, _>(|i| &array[i]),
1125    )
1126}