Skip to content

while_let_loop fails to see that temporary value needs to be dropped #9206

@tijsvd

Description

@tijsvd

Summary

There may be important temporary values in the if/while expression, like a mutex lock guard. In case of an if-statement-with-break, these are dropped after the statement. In case of a while-let loop, these are retained for the whole loop body.

I would expect that the lint might recognise this kind of thing and not warn. Seems hard though. But blindly "fixing" can lead to bad errors.

Lint Name

while_let_loop

Reproducer

I tried this code:

use std::sync::{Arc, Mutex}; fn handle_items(q: Arc<Mutex<Vec<i32>>>) { loop { let item = match q.lock().unwrap().pop() { Some(item) => item, None => break, }; // lock guard dropped here println!("process: {}", item); if item > 10 { // deadlocks here if while-let q.lock().unwrap().insert(0, item - 1); } } } fn main() { let q = Arc::new(Mutex::new(vec![1, 2, 3, 12, 7])); handle_items(q); }

I saw this happen:

warning: this loop could be written as a `while let` loop --> src/main.rs:4:2 | 4 | / loop { 5 | | let item = match q.lock().unwrap().pop() { 6 | | Some(item) => item, 7 | | None => break, ... | 14 | | } 15 | | } | |_____^ help: try: `while let Some(item) = q.lock().unwrap().pop() { .. }` | = note: `#[warn(clippy::while_let_loop)]` on by default = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#while_let_loop 

I expected to see this happen:

Nothing. The suggested code will deadlock.

Version

rustc 1.62.0 (a8314ef7d 2022-06-27) binary: rustc commit-hash: a8314ef7d0ec7b75c336af2c9857bfaf43002bfc commit-date: 2022-06-27 host: x86_64-unknown-linux-gnu release: 1.62.0 LLVM version: 14.0.5 

Additional Labels

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions