-
Couldn't load subscription status.
- Fork 13.9k
Description
The documentation for [T]::contains where T: PartialEq<T> suggests that, if this method is not applicable because the type you need to compare with is not exactly T, you should use .iter().any(). This is good advice, but it goes on to suggest that somehow a Borrow implementation is a necessary part of the solution, when it is not.
The documentation should suggest the use of iter().any without mentioning Borrow.
Specifically, the documentation says:
If you do not have an &T, but just an &U such that T: Borrow (e.g. String: Borrow), you can use iter().any:
let v = [String::from("hello"), String::from("world")]; // slice of `String`
assert!(v.iter().any(|e| e == "hello")); // search with `&str`
assert!(!v.iter().any(|e| e == "hi"));
This code works because String has an explicit implementation of PartialEq<str> (note, no &), not because it implements Borrow<str>. As far as I know, Borrow is never invoked implicitly (it's not a lang item), and it doesn't help one use == in this way. For example:
#![allow(unused)]
use std::borrow::Borrow;
#[derive(PartialEq)]
struct S(i32);
#[derive(PartialEq)]
struct T(S);
impl Borrow<S> for T {
fn borrow(&self) -> &S {
&self.0
}
}
fn main() {
let v = [T(S(10)), T(S(20))];
assert!(v.iter().any(|e| e == &S(10)));
assert!(!v.iter().any(|e| e == &S(15)));
}
This fails:
error[E0277]: can't compare `T` with `S`
--> src/main.rs:18:32
|
18 | assert!(v.iter().any(|e| e == &S(10)));
| ^^ no implementation for `T == S`
|
= help: the trait `PartialEq<S>` is not implemented for `T`
= note: required because of the requirements on the impl of `PartialEq<&S>` for `&T`
error[E0277]: can't compare `T` with `S`
--> src/main.rs:19:33
|
19 | assert!(!v.iter().any(|e| e == &S(15)));
| ^^ no implementation for `T == S`
|
= help: the trait `PartialEq<S>` is not implemented for `T`
= note: required because of the requirements on the impl of `PartialEq<&S>` for `&T`