From 8b57f689d54ff70d13e500e4d6e40c67b21e149e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 28 Jul 2019 05:06:20 +0200 Subject: [PATCH 1/3] Use const generics for some Vec/CCow impls. --- src/liballoc/lib.rs | 2 ++ src/liballoc/vec.rs | 56 +++++++++++++++++++-------------------------- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index dbc1f3b47c80d..e42d643472546 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 c076584cc3863..dac04e4e62403 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 { } 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 { + impl PartialEq<$rhs> for $lhs + where + A: PartialEq, + $($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, Vec } -__impl_slice_eq1! { Vec, &'b [B] } -__impl_slice_eq1! { Vec, &'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, Clone } +__impl_slice_eq1! { [] Vec, Vec, } +__impl_slice_eq1! { [] Vec, &[B], } +__impl_slice_eq1! { [] Vec, &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, A: Clone } +__impl_slice_eq1! { [const N: usize] Vec, [B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [const N: usize] Vec, &[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, [B; $N] } - __impl_slice_eq1! { Vec, &'b [B; $N] } - // __impl_slice_eq1! { Vec, &'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, &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")] From 744ec8809dbdbee03422e2456f8caf549c69656d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 28 Jul 2019 05:12:16 +0200 Subject: [PATCH 2/3] Use const generics for some VecDeque impls. --- src/liballoc/collections/vec_deque.rs | 40 ++++++++++----------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index d149f742b0134..495165f7786e0 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 PartialEq for VecDeque { impl Eq for VecDeque {} 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 PartialEq<$Rhs> for $Lhs where A: PartialEq { - fn eq(&self, other: &$Rhs) -> bool { + impl PartialEq<$rhs> for $lhs + where + A: PartialEq, + $($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, Vec } -__impl_slice_eq1! { VecDeque, &[B] } -__impl_slice_eq1! { VecDeque, &mut [B] } - -macro_rules! array_impls { - ($($N: expr)+) => { - $( - __impl_slice_eq1! { VecDeque, [B; $N] } - __impl_slice_eq1! { VecDeque, &[B; $N] } - __impl_slice_eq1! { VecDeque, &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, Vec, } +__impl_slice_eq1! { [] VecDeque, &[B], } +__impl_slice_eq1! { [] VecDeque, &mut [B], } +__impl_slice_eq1! { [const N: usize] VecDeque, [B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [const N: usize] VecDeque, &[B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [const N: usize] VecDeque, &mut [B; N], [B; N]: LengthAtMost32 } #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for VecDeque { From bfdfa85e73186ef96f082980113f7ace8561efd2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 28 Jul 2019 06:46:41 +0200 Subject: [PATCH 3/3] Add tests for Vec(Deque) array PartialEq impls. --- .../alloc-traits-impls-length-32.rs | 40 ++++++++++++++++ .../alloc-traits-no-impls-length-33.rs | 43 +++++++++++++++++ .../alloc-traits-no-impls-length-33.stderr | 48 +++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs create mode 100644 src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs create mode 100644 src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr 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 0000000000000..db941a440e104 --- /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() -> impl PartialEq<[B; 32]> +where + A: PartialEq, +{ + Vec::::new() +} + +pub fn yes_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]> +where + A: PartialEq, +{ + Vec::::new() +} + +use std::collections::VecDeque; + +pub fn yes_vecdeque_partial_eq_array() -> impl PartialEq<[B; 32]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn yes_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn yes_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 32]> +where + A: PartialEq, +{ + VecDeque::::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 0000000000000..19107e6bf16d5 --- /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() -> impl PartialEq<[B; 33]> +//~^ ERROR arrays only have std trait implementations for lengths 0..=32 +where + A: PartialEq, +{ + Vec::::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, +{ + Vec::::new() +} + +use std::collections::VecDeque; + +pub fn no_vecdeque_partial_eq_array() -> impl PartialEq<[B; 33]> +//~^ ERROR arrays only have std trait implementations for lengths 0..=32 +where + A: PartialEq, +{ + VecDeque::::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, +{ + VecDeque::::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, +{ + VecDeque::::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 0000000000000..5c37468130c64 --- /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() -> 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` + = 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` + = 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() -> 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` + = 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` + = 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` + = 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`.