rust-lang / rust-lang/rust-clippy
New lint: suggest using `transpose` to deal with fallible iterable APIs
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
struct Foo(usize);
impl Foo {
fn next(&mut self) -> Option<Result<usize, usize>> {
self.0 += 1;
match self.0 {
i if i > 3 => None,
3 => Some(Err(3)),
i => Some(Ok(i)),
}
}
}
fn main() -> Result<(), usize> {
let mut foo = Foo(0);
while let Some(i) = foo.next() {
let i = i?;
println!("{}", i);
}
Ok(())
}
The loop in main could instead be written
while let Some(i) = foo.next().transpose()? {
println!("{}", i);
}
I don't know how easy this would be to detect, and because of for loops it is not that widely applicable, but IMO it does lead to an appreciable increase in code readability.
One upcoming usecase where this will come up a lot is working with async Streams, those will commonly be streams of results and can't be used with for loops, so the standard way to work with them should be
while let Some(item) = stream.next().await.transpose()? {
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the main example and compare the two while let forms, then examine the stream.next().await example as the async use case. The issue names no files or tests; done means defining a reliable lint scope for these patterns and validating the suggested transpose form without incorrectly covering unrelated loops.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100