Closed
Description
In long method chains we might inadvertently call a method that is not meant to be chained. When this happens, the most likely error to occur is a type error involving ()
. We should instead look if the rhs expression is a method chain and look at all the chained call's type to find where ()
is introduced.
Given
let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i);
let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort();
error[[E0308]](https://doc.rust-lang.org/nightly/error-index.html#E0308): mismatched types
--> src/main.rs:2:23
|
2 | let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i);
| -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Vec`, found `()`
| |
| expected due to this
|
= note: expected struct `Vec<i32>`
found unit type `()`
error[[E0599]](https://doc.rust-lang.org/nightly/error-index.html#E0599): no method named `sort` found for unit type `()` in the current scope
--> src/main.rs:3:90
|
3 | let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort();
| ^^^^ method not found in `()`
Ideally the output would be closer to
error[E0308]: mismatched types
--> src/main.rs:2:23
|
2 | let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i);
| -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Vec`, found `()`
| |
| expected due to this
|
= note: expected struct `Vec<i32>`
found unit type `()`
help: `sort_by_key` takes `&mut self` and returns `()`, it isn't meant to be used in method chains
--> src/main.rs:2:23
|
2 | let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i);
| ^^^^^^^^^^^^^^^^^^ takes `&mut self` and returns `()`, it is not meant to be chained
|
help: introduce a binding and call `sort_by_key` on it
|
2 ~ let mut x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>();
3 + x.sort_by_key(|i| i);
|
error[E0599]: no method named `sort` found for unit type `()` in the current scope
--> src/main.rs:3:90
|
3 | let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort();
| ^^^^ method not found in `()`
help: an earlier method call is of type `Vec<i32>`, which has method `sort`
--> src/main.rs:3:90
|
3 | let x: Vec<i32> = vec![1, 2, 3].into_iter().collect::<Vec<i32>>().sort_by_key(|i| i).sort();
| ^^^^^^^^^^^^^^^^^^^^^^ ------------------ takes `&mut self` and returns `()`, it is not meant to be chained
| |
| `sort` can be called after this method call
Metadata
Metadata
Assignees
Labels
Area: Messages for errors, warnings, and lintsArea: Suggestions generated by the compiler applied by `cargo fix`Diagnostics: Confusing error or lint; hard to understand for new users.Diagnostics: An error or lint that needs small tweaks.Diagnostics: An error or lint that doesn't give enough information about the problem at hand.Relevant to the compiler team, which will review and decide on the PR/issue.