Skip to content

Calling .cloned() on an Option<X> gives a misleading error message about iterators. #151147

@ssbr

Description

@ssbr

Code

pub fn example(x: Option<i32>) -> i32 {
    x.cloned().unwrap()
}

Current output

error[E0599]: no method named `cloned` found for enum `Option<i32>` in the current scope
 --> src/lib.rs:5:7
  |
5 |     x.cloned().unwrap()
  |       ^^^^^^ `Option<i32>` is not an iterator
  |
help: call `.into_iter()` first
  |
5 |     x.into_iter().cloned().unwrap()
  |       ++++++++++++

Desired output

error[E0599]: no method named `cloned` found for enum `Option<i32>` in the current scope
 --> src/lib.rs:5:7
  |
5 |     x.cloned().unwrap()
  |       ^^^^^^ this is already an `Option<i32>`
  |
help: delete the call to `cloned`
  |
5 |     x.unwrap()

Rationale and extra context

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b8c24e8e97ad348d3d803be38cf0c213

This happens to me a lot, embarrassingly. The problem is that I thought I had an Option<&X>, but in fact I have an Option<X>. For example, the following snippet of code:

let mut found = None;
for x in y {
  if ... {
    found = Some(x);
  }
}
x.cloned()

In this snippet, we never explicitly spell out the type of found. In one version of the code, it might be Option<&i32>, because y implements IntoIterator<Item=&i32>. For example, maybe y was a &[i32].

But if I later change y to be a Vec<i32>, or otherwise somehow end up with a non-reference when I wasn't really thinking about it, I get this confusing error message about iterators!

Other cases

Rust Version

I used the playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b8c24e8e97ad348d3d803be38cf0c213

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions