Add Vec::contains_ref which is worse for inference but less restrictive than Vec::contains

f3a0025
Opened by Istvan Ruzman at 2024-09-14 16:26:27

Using Vec::contains currently only works if the contains parameter is of the same &Type as the Vector elements. This means the parameter must be converted to the vec-item-type even though it is comparable with the type in the first place.

e.g. following code does not work, even though impl<'a, 'b> PartialEq<str> for String exists:

fn main() {
    let mut v: Vec<String> = Vec::new();
    v.contains("mystring");
}

The Error:

error[E0308]: mismatched types
 --> <anon>:3:16
  |
3 |     v.contains("mystring");
  |                ^^^^^^^^^^ expected struct `std::string::String`, found str
  |
  = note: expected type `&std::string::String`
             found type `&'static str`

I'd be better if Vec::contains had definition like: fn contains<U>(&self, value: &U) where T: PartialEq<U>, U: ?Sized

  1. You could use v.iter().any(|x| x == "mystring") as a workaround, you don't need to convert the &str to String.

    kennytm at 2017-06-15 12:15:36

  2. I'm aware of this workaround, but isn't that what "contains" should be in the first place?

    Istvan Ruzman at 2017-06-15 12:26:05

  3. There was an attempt to fix this in #43020 but it has caused some major inference failure.

    kennytm at 2017-07-27 23:37:07

  4. Is the alternative mentioned in https://github.com/rust-lang/rust/pull/43020#issuecomment-314650930 any better with respect to the inference failure?

    Brian Smith at 2017-07-28 01:52:33

  5. Tagging C-feature-accepted to follow up on the approach in https://github.com/rust-lang/rust/pull/43020#issuecomment-314650930. Please submit a PR with an implementation and tests. We will need to confirm that this causes less breakage than the original Borrow-based approach.

    David Tolnay at 2017-11-15 02:32:20

  6. This was attempted using the other approach in https://github.com/rust-lang/rust/pull/46934. Unfortunately, it too causes too much breakage in downstream crates. Even though this API change would be significantly nicer, it doesn't seem plausible unless this breakage is acceptable (maybe for a later epoch).

    varkor at 2018-01-18 00:30:36

  7. Note that the problems mentioned here are the same as those in https://github.com/rust-lang/rust/issues/20063.

    varkor at 2018-01-30 23:24:58

  8. Shouldn't this issue and a workaround be mentioned in Vec::contains documentation?

    sigod at 2019-06-06 09:55:11

  9. Relabeling as a documentation issue. contains is probably not fixable as it stands today but documenting the workaround would be good.

    Mark Rousskov at 2019-08-06 13:20:45

  10. I'm not sure when it was added, but the docs do mention the workaround. Perhaps this issue should be closed?

    leo60228 at 2019-12-06 12:53:57

  11. How about adding a new method alongside contains?

    Something like fn contains_ref<U>(&self, x: &U) -> bool where T: PartialEq<U>

    Raniz Daniel Raneland at 2020-01-23 09:02:43

  12. I am willing to do the work about contains_ref but would it be accepted ? Creating it means ensuring it works forever, but if someone from the relevant team can confirm it is ok for contains_ref to be added, I will tackle it.

    Poliorcetics at 2020-05-30 23:29:38

  13. Can someone review this?

    Dmytro Polunin at 2020-08-12 13:55:57

  14. We just stumbled upon this problem in our project, which is kind of frustrating and makes the code ugly and less readable. Could the Rust edition mechanism (or similar) be used for doing some cleanup in the standard library? I understand that fully supporting programs using two different stdlib editions might requires having two versions of the standard library in memory sharing data together, but in cases of enhancements like this there might be a way for third-party packages to be tested against new versions and declare compatibility with these versions (a program could then be compiled with a newer version only if all its dependencies declare compatibility with that version), progressively allowing the ecosystem to use the better interfaces.

    Stéphane Magnenat at 2022-10-20 19:23:40

  15. Any update ?

    tk at 2024-09-14 11:59:51

  16. If someone wants a Vec::contains_ref method in std consider filing an ACP to the libs-team.

    kennytm at 2024-09-14 16:26:27