From 90d7338c33340f06ce1eaadbe945406de64ffcb4 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 22 Dec 2017 01:34:34 +0000 Subject: [PATCH 1/4] Generalise slice::contains over PartialEq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 https://github.com/rust-lang/rust/pull/43020). --- src/liballoc/slice.rs | 4 ++-- src/liballoc/tests/slice.rs | 13 +++++++++++++ src/libcore/slice/mod.rs | 6 +++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 18bb13d847a87..d24d292a1ec9a 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -980,8 +980,8 @@ impl [T] { /// assert!(!v.contains(&50)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn contains(&self, x: &T) -> bool - where T: PartialEq + pub fn contains(&self, x: &U) -> bool + where T: PartialEq { core_slice::SliceExt::contains(self, x) } diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 85d5ce304b88d..6afff7ef9182a 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1051,6 +1051,19 @@ fn test_shrink_to_fit() { assert_eq!(xs, (0..100).collect::>()); } +#[test] +fn test_contains() { + let numbers = [1, 2, 3]; + assert!(numbers.contains(&2)); + assert!(!numbers.contains(&4)); + + let strings = vec![String::from("AB"), String::from("CD")]; + assert!(strings.contains(&String::from("AB"))); + assert!(!strings.contains(&String::from("A"))); + assert!(strings.contains(&"AB")); + assert!(!strings.contains(&"BC")); +} + #[test] fn test_starts_with() { assert!(b"foobar".starts_with(b"foo")); diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index ca5cf04b1d437..e2a4e37252481 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -192,7 +192,7 @@ pub trait SliceExt { fn as_mut_ptr(&mut self) -> *mut Self::Item; #[stable(feature = "core", since = "1.6.0")] - fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq; + fn contains(&self, x: &U) -> bool where Self::Item: PartialEq; #[stable(feature = "core", since = "1.6.0")] fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; @@ -618,8 +618,8 @@ impl SliceExt for [T] { } #[inline] - fn contains(&self, x: &T) -> bool where T: PartialEq { - self.iter().any(|elt| *x == *elt) + fn contains(&self, x: &U) -> bool where T: PartialEq { + self.iter().any(|e| e == x) } #[inline] From 7e4c0a08276e9c027f7dc12820528ae92915b00f Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 23 Dec 2017 01:10:00 +0000 Subject: [PATCH 2/4] Add `str` and `&str` partial equality --- src/libcore/str/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 1ca995cae6d97..f72d227b42320 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1608,6 +1608,22 @@ mod traits { fn ne(&self, other: &str) -> bool { !(*self).eq(other) } } + #[stable(feature = "rust1", since = "1.24.0")] + impl<'a> PartialEq<&'a str> for str { + #[inline] + fn eq(&self, other: &&'a str) -> bool { self == *other } + #[inline] + fn ne(&self, other: &&'a str) -> bool { self != *other } + } + + #[stable(feature = "rust1", since = "1.24.0")] + impl<'a> PartialEq for &'a str { + #[inline] + fn eq(&self, other: &str) -> bool { *self == other } + #[inline] + fn ne(&self, other: &str) -> bool { *self != other } + } + #[stable(feature = "rust1", since = "1.0.0")] impl Eq for str {} From 413850101cbd966db6f69695668fbd703db9139b Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 23 Dec 2017 01:26:02 +0000 Subject: [PATCH 3/4] Make str-&str partial equality unstable --- src/libcore/str/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index f72d227b42320..42eb1cb10bdcc 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1608,7 +1608,7 @@ mod traits { fn ne(&self, other: &str) -> bool { !(*self).eq(other) } } - #[stable(feature = "rust1", since = "1.24.0")] + #[unstable(feature = "str_str_ref_partialeq", issue = "46934")] impl<'a> PartialEq<&'a str> for str { #[inline] fn eq(&self, other: &&'a str) -> bool { self == *other } @@ -1616,7 +1616,7 @@ mod traits { fn ne(&self, other: &&'a str) -> bool { self != *other } } - #[stable(feature = "rust1", since = "1.24.0")] + #[unstable(feature = "str_str_ref_partialeq", issue = "46934")] impl<'a> PartialEq for &'a str { #[inline] fn eq(&self, other: &str) -> bool { *self == other } From 6ea22ad9e7658bda372276740cf82dd75ac4144f Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 23 Dec 2017 10:56:30 +0000 Subject: [PATCH 4/4] Add ?Sized --- src/liballoc/slice.rs | 2 +- src/liballoc/tests/slice.rs | 1 + src/libcore/slice/mod.rs | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index d24d292a1ec9a..da6254092382d 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -981,7 +981,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn contains(&self, x: &U) -> bool - where T: PartialEq + where U: ?Sized, T: PartialEq { core_slice::SliceExt::contains(self, x) } diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 6afff7ef9182a..d1642b1cdc75f 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1062,6 +1062,7 @@ fn test_contains() { assert!(!strings.contains(&String::from("A"))); assert!(strings.contains(&"AB")); assert!(!strings.contains(&"BC")); + assert!(strings.contains("AB")); } #[test] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index e2a4e37252481..963923dbeddf9 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -192,7 +192,7 @@ pub trait SliceExt { fn as_mut_ptr(&mut self) -> *mut Self::Item; #[stable(feature = "core", since = "1.6.0")] - fn contains(&self, x: &U) -> bool where Self::Item: PartialEq; + fn contains(&self, x: &U) -> bool where U: ?Sized, Self::Item: PartialEq; #[stable(feature = "core", since = "1.6.0")] fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq; @@ -618,7 +618,7 @@ impl SliceExt for [T] { } #[inline] - fn contains(&self, x: &U) -> bool where T: PartialEq { + fn contains(&self, x: &U) -> bool where U: ?Sized, T: PartialEq { self.iter().any(|e| e == x) }