Skip to main content

core/array/
equality.rs

1use crate::cmp::BytewiseEq;
2
3#[stable(feature = "rust1", since = "1.0.0")]
4#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
5impl<T, U, const N: usize> const PartialEq<[U; N]> for [T; N]
6where
7    T: [const] PartialEq<U>,
8{
9    #[inline]
10    #[ferrocene::prevalidated]
11    fn eq(&self, other: &[U; N]) -> bool {
12        SpecArrayEq::spec_eq(self, other)
13    }
14    #[inline]
15    #[ferrocene::prevalidated]
16    fn ne(&self, other: &[U; N]) -> bool {
17        SpecArrayEq::spec_ne(self, other)
18    }
19}
20
21#[stable(feature = "rust1", since = "1.0.0")]
22#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
23impl<T, U, const N: usize> const PartialEq<[U]> for [T; N]
24where
25    T: [const] PartialEq<U>,
26{
27    #[inline]
28    #[ferrocene::prevalidated]
29    fn eq(&self, other: &[U]) -> bool {
30        match other.as_array::<N>() {
31            Some(b) => *self == *b,
32            None => false,
33        }
34    }
35    #[inline]
36    #[ferrocene::prevalidated]
37    fn ne(&self, other: &[U]) -> bool {
38        match other.as_array::<N>() {
39            Some(b) => *self != *b,
40            None => true,
41        }
42    }
43}
44
45#[stable(feature = "rust1", since = "1.0.0")]
46#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
47impl<T, U, const N: usize> const PartialEq<[U; N]> for [T]
48where
49    T: [const] PartialEq<U>,
50{
51    #[inline]
52    #[ferrocene::prevalidated]
53    fn eq(&self, other: &[U; N]) -> bool {
54        match self.as_array::<N>() {
55            Some(b) => *b == *other,
56            None => false,
57        }
58    }
59    #[inline]
60    #[ferrocene::prevalidated]
61    fn ne(&self, other: &[U; N]) -> bool {
62        match self.as_array::<N>() {
63            Some(b) => *b != *other,
64            None => true,
65        }
66    }
67}
68
69#[stable(feature = "rust1", since = "1.0.0")]
70#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
71impl<T, U, const N: usize> const PartialEq<&[U]> for [T; N]
72where
73    T: [const] PartialEq<U>,
74{
75    #[inline]
76    #[ferrocene::prevalidated]
77    fn eq(&self, other: &&[U]) -> bool {
78        *self == **other
79    }
80    #[inline]
81    #[ferrocene::prevalidated]
82    fn ne(&self, other: &&[U]) -> bool {
83        *self != **other
84    }
85}
86
87#[stable(feature = "rust1", since = "1.0.0")]
88#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
89impl<T, U, const N: usize> const PartialEq<[U; N]> for &[T]
90where
91    T: [const] PartialEq<U>,
92{
93    #[inline]
94    #[ferrocene::prevalidated]
95    fn eq(&self, other: &[U; N]) -> bool {
96        **self == *other
97    }
98    #[inline]
99    #[ferrocene::prevalidated]
100    fn ne(&self, other: &[U; N]) -> bool {
101        **self != *other
102    }
103}
104
105#[stable(feature = "rust1", since = "1.0.0")]
106#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
107impl<T, U, const N: usize> const PartialEq<&mut [U]> for [T; N]
108where
109    T: [const] PartialEq<U>,
110{
111    #[inline]
112    #[ferrocene::prevalidated]
113    fn eq(&self, other: &&mut [U]) -> bool {
114        *self == **other
115    }
116    #[inline]
117    #[ferrocene::prevalidated]
118    fn ne(&self, other: &&mut [U]) -> bool {
119        *self != **other
120    }
121}
122
123#[stable(feature = "rust1", since = "1.0.0")]
124#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
125impl<T, U, const N: usize> const PartialEq<[U; N]> for &mut [T]
126where
127    T: [const] PartialEq<U>,
128{
129    #[inline]
130    #[ferrocene::prevalidated]
131    fn eq(&self, other: &[U; N]) -> bool {
132        **self == *other
133    }
134    #[inline]
135    #[ferrocene::prevalidated]
136    fn ne(&self, other: &[U; N]) -> bool {
137        **self != *other
138    }
139}
140
141// NOTE: some less important impls are omitted to reduce code bloat
142// __impl_slice_eq2! { [A; $N], &'b [B; $N] }
143// __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
144
145#[stable(feature = "rust1", since = "1.0.0")]
146#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
147impl<T: [const] Eq, const N: usize> const Eq for [T; N] {}
148
149#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
150const trait SpecArrayEq<Other, const N: usize>: Sized {
151    fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool;
152    fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool;
153}
154
155#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
156impl<T: [const] PartialEq<Other>, Other, const N: usize> const SpecArrayEq<Other, N> for T {
157    #[ferrocene::prevalidated]
158    default fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool {
159        a[..] == b[..]
160    }
161    #[ferrocene::prevalidated]
162    default fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool {
163        a[..] != b[..]
164    }
165}
166
167#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
168impl<T: [const] BytewiseEq<U>, U, const N: usize> const SpecArrayEq<U, N> for T {
169    fn spec_eq(a: &[T; N], b: &[U; N]) -> bool {
170        // SAFETY: Arrays are compared element-wise, and don't add any padding
171        // between elements, so when the elements are `BytewiseEq`, we can
172        // compare the entire array at once.
173        unsafe { crate::intrinsics::raw_eq(a, crate::mem::transmute(b)) }
174    }
175    fn spec_ne(a: &[T; N], b: &[U; N]) -> bool {
176        !Self::spec_eq(a, b)
177    }
178}