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`