Skip to content

Standard library documentation for alternatives to [T]::contains suggests Borrow is needed when it is not #84877

Closed
@jimblandy

Description

@jimblandy

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`

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions