|
| 1 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 2 | +impl<A, B, const N: usize> PartialEq<[B; N]> for [A; N] |
| 3 | +where |
| 4 | + A: PartialEq<B>, |
| 5 | +{ |
| 6 | + #[inline] |
| 7 | + fn eq(&self, other: &[B; N]) -> bool { |
| 8 | + SpecArrayEq::spec_eq(self, other) |
| 9 | + } |
| 10 | + #[inline] |
| 11 | + fn ne(&self, other: &[B; N]) -> bool { |
| 12 | + SpecArrayEq::spec_ne(self, other) |
| 13 | + } |
| 14 | +} |
| 15 | + |
| 16 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 17 | +impl<A, B, const N: usize> PartialEq<[B]> for [A; N] |
| 18 | +where |
| 19 | + A: PartialEq<B>, |
| 20 | +{ |
| 21 | + #[inline] |
| 22 | + fn eq(&self, other: &[B]) -> bool { |
| 23 | + self[..] == other[..] |
| 24 | + } |
| 25 | + #[inline] |
| 26 | + fn ne(&self, other: &[B]) -> bool { |
| 27 | + self[..] != other[..] |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 32 | +impl<A, B, const N: usize> PartialEq<[A; N]> for [B] |
| 33 | +where |
| 34 | + B: PartialEq<A>, |
| 35 | +{ |
| 36 | + #[inline] |
| 37 | + fn eq(&self, other: &[A; N]) -> bool { |
| 38 | + self[..] == other[..] |
| 39 | + } |
| 40 | + #[inline] |
| 41 | + fn ne(&self, other: &[A; N]) -> bool { |
| 42 | + self[..] != other[..] |
| 43 | + } |
| 44 | +} |
| 45 | + |
| 46 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 47 | +impl<A, B, const N: usize> PartialEq<&[B]> for [A; N] |
| 48 | +where |
| 49 | + A: PartialEq<B>, |
| 50 | +{ |
| 51 | + #[inline] |
| 52 | + fn eq(&self, other: &&[B]) -> bool { |
| 53 | + self[..] == other[..] |
| 54 | + } |
| 55 | + #[inline] |
| 56 | + fn ne(&self, other: &&[B]) -> bool { |
| 57 | + self[..] != other[..] |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 62 | +impl<A, B, const N: usize> PartialEq<[A; N]> for &[B] |
| 63 | +where |
| 64 | + B: PartialEq<A>, |
| 65 | +{ |
| 66 | + #[inline] |
| 67 | + fn eq(&self, other: &[A; N]) -> bool { |
| 68 | + self[..] == other[..] |
| 69 | + } |
| 70 | + #[inline] |
| 71 | + fn ne(&self, other: &[A; N]) -> bool { |
| 72 | + self[..] != other[..] |
| 73 | + } |
| 74 | +} |
| 75 | + |
| 76 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 77 | +impl<A, B, const N: usize> PartialEq<&mut [B]> for [A; N] |
| 78 | +where |
| 79 | + A: PartialEq<B>, |
| 80 | +{ |
| 81 | + #[inline] |
| 82 | + fn eq(&self, other: &&mut [B]) -> bool { |
| 83 | + self[..] == other[..] |
| 84 | + } |
| 85 | + #[inline] |
| 86 | + fn ne(&self, other: &&mut [B]) -> bool { |
| 87 | + self[..] != other[..] |
| 88 | + } |
| 89 | +} |
| 90 | + |
| 91 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 92 | +impl<A, B, const N: usize> PartialEq<[A; N]> for &mut [B] |
| 93 | +where |
| 94 | + B: PartialEq<A>, |
| 95 | +{ |
| 96 | + #[inline] |
| 97 | + fn eq(&self, other: &[A; N]) -> bool { |
| 98 | + self[..] == other[..] |
| 99 | + } |
| 100 | + #[inline] |
| 101 | + fn ne(&self, other: &[A; N]) -> bool { |
| 102 | + self[..] != other[..] |
| 103 | + } |
| 104 | +} |
| 105 | + |
| 106 | +// NOTE: some less important impls are omitted to reduce code bloat |
| 107 | +// __impl_slice_eq2! { [A; $N], &'b [B; $N] } |
| 108 | +// __impl_slice_eq2! { [A; $N], &'b mut [B; $N] } |
| 109 | + |
| 110 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 111 | +impl<T: Eq, const N: usize> Eq for [T; N] {} |
| 112 | + |
| 113 | +trait SpecArrayEq<Other, const N: usize>: Sized { |
| 114 | + fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool; |
| 115 | + fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool; |
| 116 | +} |
| 117 | + |
| 118 | +impl<T: PartialEq<Other>, Other, const N: usize> SpecArrayEq<Other, N> for T { |
| 119 | + default fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool { |
| 120 | + a[..] == b[..] |
| 121 | + } |
| 122 | + default fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool { |
| 123 | + a[..] != b[..] |
| 124 | + } |
| 125 | +} |
| 126 | + |
| 127 | +impl<T: PartialEq<U> + IsRawEqComparable<U>, U, const N: usize> SpecArrayEq<U, N> for T { |
| 128 | + #[cfg(bootstrap)] |
| 129 | + fn spec_eq(a: &[T; N], b: &[U; N]) -> bool { |
| 130 | + a[..] == b[..] |
| 131 | + } |
| 132 | + #[cfg(not(bootstrap))] |
| 133 | + fn spec_eq(a: &[T; N], b: &[U; N]) -> bool { |
| 134 | + // SAFETY: This is why `IsRawEqComparable` is an `unsafe trait`. |
| 135 | + unsafe { |
| 136 | + let b = &*b.as_ptr().cast::<[T; N]>(); |
| 137 | + crate::intrinsics::raw_eq(a, b) |
| 138 | + } |
| 139 | + } |
| 140 | + fn spec_ne(a: &[T; N], b: &[U; N]) -> bool { |
| 141 | + !Self::spec_eq(a, b) |
| 142 | + } |
| 143 | +} |
| 144 | + |
| 145 | +/// `U` exists on here mostly because `min_specialization` didn't let me |
| 146 | +/// repeat the `T` type parameter in the above specialization, so instead |
| 147 | +/// the `T == U` constraint comes from the impls on this. |
| 148 | +/// # Safety |
| 149 | +/// - Neither `Self` nor `U` has any padding. |
| 150 | +/// - `Self` and `U` have the same layout. |
| 151 | +/// - `Self: PartialEq<U>` is byte-wise (this means no floats, among other things) |
| 152 | +#[rustc_specialization_trait] |
| 153 | +unsafe trait IsRawEqComparable<U> {} |
| 154 | + |
| 155 | +macro_rules! is_raw_comparable { |
| 156 | + ($($t:ty),+) => {$( |
| 157 | + unsafe impl IsRawEqComparable<$t> for $t {} |
| 158 | + )+}; |
| 159 | +} |
| 160 | +is_raw_comparable!(bool, char, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize); |
0 commit comments