Using if let Err(_) on a Thread::JoinHandle::result

I have a JoinHandle from:

let handle: thread::JoinHandle<_> = thread::spawn(move || {
    blah blah blah
}

When I try to join it:

        let join_result = handle.join();
        if let Err(err) = join_result {
            eprintln!("Error {err:?}");
        }

I get a clippy error:

warning: irrefutable `if let` pattern
  --> src/read_midi_virtual.rs:70:12
   |
70 |         if let Err(err) = join_result {
   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this pattern will always match, so the `if let` is useless
   = help: consider replacing the `if let` with a `let`
   = note: `#[warn(irrefutable_let_patterns)]` on by default

Yet:

        let join_result = handle.join();
        match join_result {
            Ok(_) => (),

            Err(err) => eprintln!("Error read_midi_virtual run: Join error: {err:?}"),
        }

has no warnings.

I do not understand.

I am using edition 2024 if it matters

The irrefutable_let_patterns warning is specific to if let. There just doesn't happen to be a similar warning for a useless match arm in this case. The problem is the same — your thread is not expected to ever return successfully (presumably it contains a loop {}) so if you get anything from join() at all, it will always be a panic.

As Clippy says, you can replace the if let with a let. Demo program:

use std::thread;
fn main() {
    let handle: thread::JoinHandle<_> = thread::spawn(move || loop {
        // ...
    });
    let Err(err) = handle.join();
    eprintln!("Error read_midi_virtual run: thread panicked: {err:?}");
}
7 Likes

Bingo.

I put a break in the loop and the warning goes away.

This old person is discombobulated by compilers having so many smarts

2 Likes

TBF the lint should point out that some uninhabited type is what made the pattern irrefutable.

4 Likes

To be clear, you should not add a break to “fix” the warning. Only add a break if there is an actual reason the thread should stop.

  • If the thread is intended to run forever, use let Err(err) = join();.
  • If the thread is not intended to run forever, make sure it does have a break, and use if let or match on the result of join().
5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.