Skip to content

Ergonomics: &String does not implement PartialEq<str> #44695

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
djc opened this issue Sep 19, 2017 · 2 comments · Fixed by #118431
Closed

Ergonomics: &String does not implement PartialEq<str> #44695

djc opened this issue Sep 19, 2017 · 2 comments · Fixed by #118431
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-trait-system Area: Trait system C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@djc
Copy link
Contributor

djc commented Sep 19, 2017

Start with this:

fn cmp_prefix() -> bool {
    let owned = "foo".to_owned();
    let string_ref = &owned;
    let partial = "foobar";
    string_ref == partial[..3]
}

It doesn't compile: "the trait bound &String: PartialEq<str> is not satisfied".

Let's Google this, first hit is StackOverflow, first/accepted answer talks about .as_ref(), try that. string_ref.as_ref() == &partial[..3] results in "the trait bound &_: PartialEq<str> is not satisfied" [oh, how I hate these underscores in errors].

At this point I try adding * to the LHS or & to the RHS. The latter results in "type annotations required: cannot resolve String: AsRef<_>" [huh?].

Here's actually everything I tried (from my actual code instead of simple example):

meta_subj == db_subj[..998]
&meta_subj == &db_subj[..998]
meta_subj.as_ref() == &db_subj[..998] // I think this was before Googling, even
meta_subj.as_ref() == db_subj[..998]
meta_subj.as_ref::<&str>() == &db_subj[..998] // WTF is this thing with not resolving String: AsRef?
&meta_subj.as_ref() == db_subj[..998]
*meta_subj.as_ref() == db_subj[..998]

At this point I'm pretty much out of ideas other than brute-forcing with some to_string(). I don't really consider myself a beginner at this point, having successfully written a few thousand lines of code over the past 15 months, so here's where I have some empathy for those saying Rust's learning curve is just too steep.

I went and read some more on SO and found this, which actually seems to work (meta_subj as &str) == &db_subj[..998]. The reason I would not have come up with this is that generally the compiler seems to be able to coerce &T where T: String to &str, so I find it hard to come up with a reason it cannot do so in this case.

@kennytm
Copy link
Member

kennytm commented Sep 19, 2017

FYI this also works.

    *string_ref == partial[..3]

I think #44619 (auto-ref with operators) will fix this.

But even without #44619, the error message could take some idea for the suggestion, rather than telling the user about something they are not able to do anyway (you can't impl PartialEq<str> for &String without hacking the standard library).

@aidanhs aidanhs added C-enhancement Category: An issue proposing an enhancement or a PR with one. C-feature-request Category: A feature request, i.e: not implemented / a PR. and removed C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Sep 19, 2017
@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-trait-system Area: Trait system T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jan 17, 2020
@estebank
Copy link
Contributor

Output with #90006:

error[E0369]: can't compare `&String` with `str`
 --> f16.rs:5:30
  |
5 |     let x: bool = string_ref == partial[..3];
  |                   ---------- ^^ ------------ str
  |                   |
  |                   &String
  |
help: `==` can be applied on `&str`
  |
5 |     let x: bool = string_ref == &partial[..3];
  |                                 +

error[E0369]: can't compare `&_` with `str`
 --> f16.rs:9:28
  |
9 |     let _ = owned.as_ref() == partial[..998];
  |             -------------- ^^ -------------- str
  |             |
  |             &_
  |
help: `==` can be applied on `&str`
  |
9 |     let _ = owned.as_ref() == &partial[..998];
  |                               +

error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
   --> f16.rs:10:19
    |
10  |     let _ = owned.as_ref::<&str>() == &partial[..998]; // WTF is this thing with not resolving String: AsRef?
    |                   ^^^^^^-------- help: remove these generics
    |                   |
    |                   expected 0 generic arguments
    |
note: associated function defined here, with 0 generic parameters
   --> /local/home/ekuber/workspace/rust/library/core/src/convert/mod.rs:159:8
    |
159 |     fn as_ref(&self) -> &T;
    |        ^^^^^^

error[E0369]: can't compare `&&_` with `str`
  --> f16.rs:11:29
   |
11 |     let _ = &owned.as_ref() == partial[..998];
   |             --------------- ^^ -------------- str
   |             |
   |             &&_

@Dylan-DPC Dylan-DPC added C-bug Category: This is a bug. and removed C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Nov 30, 2023
@bors bors closed this as completed in 2df6406 Dec 26, 2023
@fmease fmease added A-trait-system Area: Trait system and removed A-trait-system Area: Trait system labels Dec 21, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-trait-system Area: Trait system C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
6 participants