about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-07-28 11:11:14 +0200
committerGitHub <noreply@github.com>2019-07-28 11:11:14 +0200
commit4b3a017b352df52da17300be7c7ac16cc472fcf5 (patch)
tree3d9b4bcfc56e7d3342d69df5a23e8c3d348ee505
parenta558668cf2bd01cf47613694b786c08b6a91a607 (diff)
parentbfdfa85e73186ef96f082980113f7ace8561efd2 (diff)
downloadrust-4b3a017b352df52da17300be7c7ac16cc472fcf5.tar.gz
rust-4b3a017b352df52da17300be7c7ac16cc472fcf5.zip
Rollup merge of #63061 - Centril:constantly-improving, r=scottmcm
In which we constantly improve the Vec(Deque) array PartialEq impls

Use the same approach as in https://github.com/rust-lang/rust/pull/62435 as sanctioned by https://github.com/rust-lang/rust/issues/61415#issuecomment-504155110.

r? @scottmcm
-rw-r--r--src/liballoc/collections/vec_deque.rs40
-rw-r--r--src/liballoc/lib.rs2
-rw-r--r--src/liballoc/vec.rs56
-rw-r--r--src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs40
-rw-r--r--src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs43
-rw-r--r--src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr48
6 files changed, 170 insertions, 59 deletions
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index d149f742b01..495165f7786 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -9,6 +9,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use core::array::LengthAtMost32;
 use core::cmp::{self, Ordering};
 use core::fmt;
 use core::iter::{repeat_with, FromIterator, FusedIterator};
@@ -2571,13 +2572,14 @@ impl<A: PartialEq> PartialEq for VecDeque<A> {
 impl<A: Eq> Eq for VecDeque<A> {}
 
 macro_rules! __impl_slice_eq1 {
-    ($Lhs: ty, $Rhs: ty) => {
-        __impl_slice_eq1! { $Lhs, $Rhs, Sized }
-    };
-    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
+    ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => {
         #[stable(feature = "vec_deque_partial_eq_slice", since = "1.17.0")]
-        impl<A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
-            fn eq(&self, other: &$Rhs) -> bool {
+        impl<A, B, $($vars)*> PartialEq<$rhs> for $lhs
+        where
+            A: PartialEq<B>,
+            $($constraints)*
+        {
+            fn eq(&self, other: &$rhs) -> bool {
                 if self.len() != other.len() {
                     return false;
                 }
@@ -2589,26 +2591,12 @@ macro_rules! __impl_slice_eq1 {
     }
 }
 
-__impl_slice_eq1! { VecDeque<A>, Vec<B> }
-__impl_slice_eq1! { VecDeque<A>, &[B] }
-__impl_slice_eq1! { VecDeque<A>, &mut [B] }
-
-macro_rules! array_impls {
-    ($($N: expr)+) => {
-        $(
-            __impl_slice_eq1! { VecDeque<A>, [B; $N] }
-            __impl_slice_eq1! { VecDeque<A>, &[B; $N] }
-            __impl_slice_eq1! { VecDeque<A>, &mut [B; $N] }
-        )+
-    }
-}
-
-array_impls! {
-     0  1  2  3  4  5  6  7  8  9
-    10 11 12 13 14 15 16 17 18 19
-    20 21 22 23 24 25 26 27 28 29
-    30 31 32
-}
+__impl_slice_eq1! { [] VecDeque<A>, Vec<B>, }
+__impl_slice_eq1! { [] VecDeque<A>, &[B], }
+__impl_slice_eq1! { [] VecDeque<A>, &mut [B], }
+__impl_slice_eq1! { [const N: usize] VecDeque<A>, [B; N], [B; N]: LengthAtMost32 }
+__impl_slice_eq1! { [const N: usize] VecDeque<A>, &[B; N], [B; N]: LengthAtMost32 }
+__impl_slice_eq1! { [const N: usize] VecDeque<A>, &mut [B; N], [B; N]: LengthAtMost32 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A: PartialOrd> PartialOrd for VecDeque<A> {
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index dbc1f3b47c8..e42d6434725 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -78,6 +78,8 @@
 #![feature(cfg_target_has_atomic)]
 #![feature(coerce_unsized)]
 #![cfg_attr(not(bootstrap), feature(const_in_array_repeat_expressions))]
+#![feature(const_generic_impls_guard)]
+#![feature(const_generics)]
 #![feature(dispatch_from_dyn)]
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index c076584cc38..dac04e4e624 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -56,6 +56,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use core::array::LengthAtMost32;
 use core::cmp::{self, Ordering};
 use core::fmt;
 use core::hash::{self, Hash};
@@ -2171,47 +2172,36 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for Vec<T> {
 }
 
 macro_rules! __impl_slice_eq1 {
-    ($Lhs: ty, $Rhs: ty) => {
-        __impl_slice_eq1! { $Lhs, $Rhs, Sized }
-    };
-    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
+    ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => {
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
+        impl<A, B, $($vars)*> PartialEq<$rhs> for $lhs
+        where
+            A: PartialEq<B>,
+            $($constraints)*
+        {
             #[inline]
-            fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] }
+            fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] }
             #[inline]
-            fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] }
+            fn ne(&self, other: &$rhs) -> bool { self[..] != other[..] }
         }
     }
 }
 
-__impl_slice_eq1! { Vec<A>, Vec<B> }
-__impl_slice_eq1! { Vec<A>, &'b [B] }
-__impl_slice_eq1! { Vec<A>, &'b mut [B] }
-__impl_slice_eq1! { Cow<'a, [A]>, &'b [B], Clone }
-__impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B], Clone }
-__impl_slice_eq1! { Cow<'a, [A]>, Vec<B>, Clone }
+__impl_slice_eq1! { [] Vec<A>, Vec<B>, }
+__impl_slice_eq1! { [] Vec<A>, &[B], }
+__impl_slice_eq1! { [] Vec<A>, &mut [B], }
+__impl_slice_eq1! { [] Cow<'_, [A]>, &[B], A: Clone }
+__impl_slice_eq1! { [] Cow<'_, [A]>, &mut [B], A: Clone }
+__impl_slice_eq1! { [] Cow<'_, [A]>, Vec<B>, A: Clone }
+__impl_slice_eq1! { [const N: usize] Vec<A>, [B; N], [B; N]: LengthAtMost32 }
+__impl_slice_eq1! { [const N: usize] Vec<A>, &[B; N], [B; N]: LengthAtMost32 }
 
-macro_rules! array_impls {
-    ($($N: expr)+) => {
-        $(
-            // NOTE: some less important impls are omitted to reduce code bloat
-            __impl_slice_eq1! { Vec<A>, [B; $N] }
-            __impl_slice_eq1! { Vec<A>, &'b [B; $N] }
-            // __impl_slice_eq1! { Vec<A>, &'b mut [B; $N] }
-            // __impl_slice_eq1! { Cow<'a, [A]>, [B; $N], Clone }
-            // __impl_slice_eq1! { Cow<'a, [A]>, &'b [B; $N], Clone }
-            // __impl_slice_eq1! { Cow<'a, [A]>, &'b mut [B; $N], Clone }
-        )+
-    }
-}
-
-array_impls! {
-     0  1  2  3  4  5  6  7  8  9
-    10 11 12 13 14 15 16 17 18 19
-    20 21 22 23 24 25 26 27 28 29
-    30 31 32
-}
+// NOTE: some less important impls are omitted to reduce code bloat
+// FIXME(Centril): Reconsider this?
+//__impl_slice_eq1! { [const N: usize] Vec<A>, &mut [B; N], [B; N]: LengthAtMost32 }
+//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, [B; N], [B; N]: LengthAtMost32 }
+//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &[B; N], [B; N]: LengthAtMost32 }
+//__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &mut [B; N], [B; N]: LengthAtMost32 }
 
 /// Implements comparison of vectors, lexicographically.
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs
new file mode 100644
index 00000000000..db941a440e1
--- /dev/null
+++ b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs
@@ -0,0 +1,40 @@
+// check-pass
+
+pub fn yes_vec_partial_eq_array<A, B>() -> impl PartialEq<[B; 32]>
+where
+    A: PartialEq<B>,
+{
+    Vec::<A>::new()
+}
+
+pub fn yes_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]>
+where
+    A: PartialEq<B>,
+{
+    Vec::<A>::new()
+}
+
+use std::collections::VecDeque;
+
+pub fn yes_vecdeque_partial_eq_array<A, B>() -> impl PartialEq<[B; 32]>
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+pub fn yes_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]>
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+pub fn yes_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 32]>
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs
new file mode 100644
index 00000000000..19107e6bf16
--- /dev/null
+++ b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs
@@ -0,0 +1,43 @@
+pub fn no_vec_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    Vec::<A>::new()
+}
+
+pub fn no_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    Vec::<A>::new()
+}
+
+use std::collections::VecDeque;
+
+pub fn no_vecdeque_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+pub fn no_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+pub fn no_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr
new file mode 100644
index 00000000000..5c37468130c
--- /dev/null
+++ b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr
@@ -0,0 +1,48 @@
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:1:43
+   |
+LL | pub fn no_vec_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::vec::Vec<A>`
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:9:51
+   |
+LL | pub fn no_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
+   |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::vec::Vec<A>`
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:19:48
+   |
+LL | pub fn no_vecdeque_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
+   |                                                ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::collections::VecDeque<A>`
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:27:56
+   |
+LL | pub fn no_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
+   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::collections::VecDeque<A>`
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:35:60
+   |
+LL | pub fn no_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]>
+   |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a mut [B; 33]>` for `std::collections::VecDeque<A>`
+   = note: the return type of a function must have a statically known size
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.