Skip to content

Commit

Permalink
Rollup merge of rust-lang#63061 - Centril:constantly-improving, r=sco…
Browse files Browse the repository at this point in the history
…ttmcm

In which we constantly improve the Vec(Deque) array PartialEq impls

Use the same approach as in rust-lang#62435 as sanctioned by rust-lang#61415 (comment).

r? @scottmcm
  • Loading branch information
Centril authored Jul 28, 2019
2 parents a55b8e8 + bfdfa85 commit c0cab5e
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 59 deletions.
40 changes: 14 additions & 26 deletions src/liballoc/collections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
}
Expand All @@ -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> {
Expand Down
2 changes: 2 additions & 0 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
56 changes: 23 additions & 33 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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")]
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit c0cab5e

Please sign in to comment.