Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Jul 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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?
Centril marked this conversation as resolved.
Show resolved Hide resolved
//__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`.