Skip to content

Confusing error messages (a closure can't be cloned) #37736

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
gibfahn opened this issue Nov 12, 2016 · 4 comments
Closed

Confusing error messages (a closure can't be cloned) #37736

gibfahn opened this issue Nov 12, 2016 · 4 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@gibfahn
Copy link
Contributor

gibfahn commented Nov 12, 2016

Trying to filter and then clone an Iterator over the chars in &str, I'm getting an error message that was pretty opaque (at least to me).

Code

    let f = |c: &char| c.is_digit(10);
    let iter = "abc123".chars().filter(f);
    match iter.clone().take(3).count() {
        3 => println!("{}", iter.collect::<String>()), // Print whole string including first three digits
        _ => {},
    }

Error

error: no method named `clone` found for type `std::iter::Filter<std::str::Chars<'_>, [closure@test.rs:2:13: 2:38]>` in the current scope
 --> test.rs:4:16
  |
4 |     match iter.clone().take(3).count() {
  |                ^^^^^
  |
  = note: the method `clone` exists but the following trait bounds were not satisfied: `[closure@test.rs:2:13: 2:38] : std::clone::Clone`

error: aborting due to previous error

It'd be nice if this error gave more info about how to fix the problem (the fix seems to be to change L1 from let f = |c: &char| to let f = &|c: &char|).

Sorry if this is a duplicate, I couldn't find anything obvious.

EDIT: What I'm trying to do is to make sure there are at least three digits in my Iterator before I actually collect it, I suspect the right answer isn't changing the filter closure (I'm not sure why that fixes the compiler error tbh), but using something else instead of iter.clone().

@sanxiyn sanxiyn added the A-diagnostics Area: Messages for errors, warnings, and lints label Nov 15, 2016
@tirkarthi
Copy link

@gibfahn Asked the same at IRC. Its caused because closures inside the filter cannot be cloned. Passing & before the closure makes it a reference and references are always clone-able. Please find the chat log at https://botbot.me/mozilla/rust/2016-11-14/?msg=76433946&page=11 . Hope it helps

@gibfahn
Copy link
Contributor Author

gibfahn commented Nov 21, 2016

Thanks a lot @tirkarthi! Very helpful.

Now I understand the issue the error message seems obvious, but if it were possible to say something like Closures can't be cloned, try using a function instead it might be clearer.

Maybe even something including the suggestion from Quxxy2 about using fn f(c: &char) -> bool { c.is_digit(10) } "abc123".chars().filter(f as fn(_) -> _);.

@jonathandturner @nikomatsakis Would a more specific error message be feasible/desirable? If not I'll close.

@gibfahn gibfahn changed the title Confusing error messages Confusing error messages (a closure can't be cloned) Nov 21, 2016
@steveklabnik steveklabnik added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 9, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 26, 2017
@gibfahn
Copy link
Contributor Author

gibfahn commented Dec 21, 2017

Looks like this will be fixed by #44490.

@estebank
Copy link
Contributor

estebank commented Mar 8, 2019

The code now compiles without errors.

@estebank estebank closed this as completed Mar 8, 2019
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants