rust-lang / rust-lang/rust-clippy
clippy::option-if-let-else generates invalid Rust code when the if-let-else block allows for better type coercion
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
Summary
The lint is triggered, but the provided code doesn't compile. I'm not particularly familiar with compilers, so this may actually be a shortcoming of the rust compiler in the case of Option::map_or_else, but I figured it was better to start here.
Lint Name
clippy::option-if-let-else
Reproducer
I tried this code:
use std::io::Error;
use std::pin::Pin;
use futures::Stream;
fn main() {
let result = Ok::<_, Error>(tokio_stream::once(Ok(())));
let stream: Pin<Box<dyn Stream<Item = Result<(), Error>>>> = if let Ok(stream) = result {
Box::pin(stream)
} else {
Box::pin(tokio_stream::pending())
};
}
I saw this happen:
This code compiles, as expected, but clippy provides the following alternative:
I tried this code:
use std::io::Error;
use std::pin::Pin;
use futures::Stream;
fn main() {
let result = Ok::<_, Error>(tokio_stream::once(Ok(())));
let stream: Pin<Box<dyn Stream<Item = Result<(), Error>>>> = result.map_or_else(
|_| Box::pin(tokio_stream::pending::<Result<(), Error>>()),
|stream| Box::pin(stream),
);
}
I saw this happen:
error[E0308]: mismatched types
--> src/main.rs:11:27
|
11 | |stream| Box::pin(stream),
| -------- ^^^^^^ expected `Pending<Result<(), Error>>`, found `Once<Result<(), _>>`
| |
| arguments to this function are incorrect
|
= note: expected struct `tokio_stream::Pending<Result<(), std::io::Error>>`
found struct `tokio_stream::Once<Result<(), _>>`
note: associated function defined here
--> /home/jeremy/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:326:12
|
326 | pub fn pin(x: T) -> Pin<Box<T>> {
| ^^^
For more information about this error, try `rustc --explain E0308`.
error: could not compile `temp` (bin "temp") due to 1 previous error
I expected to see this happen:
MaybeIncorrect clippy lints should generate valid Rust code.
Version
rustc 1.81.0-nightly (cc8da78a0 2024-07-04)
binary: rustc
commit-hash: cc8da78a036dc3c15c35a97651b02af9a6d30c1e
commit-date: 2024-07-04
host: x86_64-unknown-linux-gnu
release: 1.81.0-nightly
LLVM version: 18.1.7
Additional Labels
@rustbot label +I-suggestion-causes-error
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 by reproducing the supplied Rust example with clippy::option-if-let-else and inspect the lint implementation that generates the map_or_else suggestion. Compare the suggested code with the original coercion behavior; done means the lint no longer emits code that fails to compile, with a regression test covering this case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100