Skip to content

Commit 196146b

Browse files
committed
Auto merge of #46934 - varkor:slice-contains-generic, r=<try>
Generalise slice::contains over PartialEq This allows `contains` to be used on slices to search for elements that satisfy a partial equality with the slice item type, rather than an identity. This closes #42671. Note that string literals need to be referenced in this implementation due to `str` not implementing `Sized`. It’s likely this will have to go through a Crater run to test for breakage (see #43020).
2 parents 3fd27b2 + 6ea22ad commit 196146b

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

src/liballoc/slice.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -980,8 +980,8 @@ impl<T> [T] {
980980
/// assert!(!v.contains(&50));
981981
/// ```
982982
#[stable(feature = "rust1", since = "1.0.0")]
983-
pub fn contains(&self, x: &T) -> bool
984-
where T: PartialEq
983+
pub fn contains<U>(&self, x: &U) -> bool
984+
where U: ?Sized, T: PartialEq<U>
985985
{
986986
core_slice::SliceExt::contains(self, x)
987987
}

src/liballoc/tests/slice.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,20 @@ fn test_shrink_to_fit() {
10511051
assert_eq!(xs, (0..100).collect::<Vec<_>>());
10521052
}
10531053

1054+
#[test]
1055+
fn test_contains() {
1056+
let numbers = [1, 2, 3];
1057+
assert!(numbers.contains(&2));
1058+
assert!(!numbers.contains(&4));
1059+
1060+
let strings = vec![String::from("AB"), String::from("CD")];
1061+
assert!(strings.contains(&String::from("AB")));
1062+
assert!(!strings.contains(&String::from("A")));
1063+
assert!(strings.contains(&"AB"));
1064+
assert!(!strings.contains(&"BC"));
1065+
assert!(strings.contains("AB"));
1066+
}
1067+
10541068
#[test]
10551069
fn test_starts_with() {
10561070
assert!(b"foobar".starts_with(b"foo"));

src/libcore/slice/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ pub trait SliceExt {
192192
fn as_mut_ptr(&mut self) -> *mut Self::Item;
193193

194194
#[stable(feature = "core", since = "1.6.0")]
195-
fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
195+
fn contains<U>(&self, x: &U) -> bool where U: ?Sized, Self::Item: PartialEq<U>;
196196

197197
#[stable(feature = "core", since = "1.6.0")]
198198
fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
@@ -618,8 +618,8 @@ impl<T> SliceExt for [T] {
618618
}
619619

620620
#[inline]
621-
fn contains(&self, x: &T) -> bool where T: PartialEq {
622-
self.iter().any(|elt| *x == *elt)
621+
fn contains<U>(&self, x: &U) -> bool where U: ?Sized, T: PartialEq<U> {
622+
self.iter().any(|e| e == x)
623623
}
624624

625625
#[inline]

src/libcore/str/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,22 @@ mod traits {
16081608
fn ne(&self, other: &str) -> bool { !(*self).eq(other) }
16091609
}
16101610

1611+
#[unstable(feature = "str_str_ref_partialeq", issue = "46934")]
1612+
impl<'a> PartialEq<&'a str> for str {
1613+
#[inline]
1614+
fn eq(&self, other: &&'a str) -> bool { self == *other }
1615+
#[inline]
1616+
fn ne(&self, other: &&'a str) -> bool { self != *other }
1617+
}
1618+
1619+
#[unstable(feature = "str_str_ref_partialeq", issue = "46934")]
1620+
impl<'a> PartialEq<str> for &'a str {
1621+
#[inline]
1622+
fn eq(&self, other: &str) -> bool { *self == other }
1623+
#[inline]
1624+
fn ne(&self, other: &str) -> bool { *self != other }
1625+
}
1626+
16111627
#[stable(feature = "rust1", since = "1.0.0")]
16121628
impl Eq for str {}
16131629

0 commit comments

Comments
 (0)