Skip to content

E0308 suggestion can lead to unnecessary clones #114050

Description

Code

fn main() {
    let string = String::from("foo");
    let a = Some(string.clone());
    let b = Some(&string);
    if a == b {
        println!("do stuff");
    }
}

Current output

error[E0308]: mismatched types
 --> src/main.rs:5:13
  |
5 |     if a == b {
  |             ^ expected `Option<String>`, found `Option<&String>`
  |
  = note: expected enum `Option<String>`
             found enum `Option<&String>`
help: use `Option::cloned` to clone the value inside the `Option`
  |
5 |     if a == b.cloned() {
  |              +++++++++

Desired output

error[E0308]: mismatched types
 --> src/main.rs:5:13
  |
5 |     if a == b {
  |             ^ expected `Option<String>`, found `Option<&String>`
  |
  = note: expected enum `Option<String>`
             found enum `Option<&String>`
help: try using `.as_ref()` to convert `Option<String>` to `Option<&String>`
  |
5 |     if a.as_ref() == b {
  |         +++++++++

Rationale and extra context

This works as expected when a and b are swapped, but with this ordering, cloned is suggested, which leads to an allocation/copy which will be immediately freed and is entirely avoidable.

Other cases

a and b swapped leads to the correct output.

Anything else?

Tested on nightly 2023-07-24 31395ec38250b60b380f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions