Skip to content

Clippy wrong detects E0597 #13962

Open
Open
@devmaxde

Description

@devmaxde

Summary

Clippy gives me a lifetime warning, but the compiler doesn't care. Somewhere is a bug

Reproducer

I tried this code:

main.rs

use std::path::Path;
use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::info;

/// # Example
/// ```
/// use crate::monitor_process;
///
/// monitor_process!("MainTask", {
///         for i in 0..5 {
///             println!("Doing work... Step {}", i + 1);
///             tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
///         }
///     }, 10);
/// ```
#[macro_export]
macro_rules! monitor_process {
    ($task_name:expr, $task:block, $interval_seconds:expr) => {{
        // Create a channel for graceful shutdown
        let (shutdown_tx, mut shutdown_rx) = tokio::sync::watch::channel(());
        let start_time = tokio::time::Instant::now(); // Record the start time

        let task_handle = tokio::spawn(async move {
            // Run the main task
            $task

            // After the task is done, signal the reporter to shut down
            let _ = shutdown_tx.send(());
        });

        let report_handle = tokio::spawn(async move {
            let mut interval = tokio::time::interval(tokio::time::Duration::from_secs($interval_seconds));
            interval.tick().await; // Skip the first tick to avoid reporting "0 seconds"

            loop {
                tokio::select! {
                    _ = interval.tick() => {
                        // Calculate elapsed time in seconds
                        let elapsed = start_time.elapsed().as_secs();
                        info!("Process {} has been running for {} seconds...", $task_name, elapsed);
                    }
                    _ = shutdown_rx.changed() => {
                        // Exit when the main task signals shutdown
                        let elapsed = start_time.elapsed().as_secs();
                        info!("Process {} completed after {} seconds.", $task_name, elapsed);
                        break;
                    }
                }
            }
        });

        // Wait for the main task to complete
        let _ = task_handle.await;
        // Optionally, wait for the reporter task to finish
        let _ = report_handle.await;
    }};
}

pub async fn extreme_long_calculation(path: String) -> String {
    let folder_hash = Arc::new(Mutex::new(String::new()));
    let folder_hash_clone = Arc::clone(&folder_hash);
    let path_clone = path.clone();
    monitor_process!(
        "Calculate Hash",
        {
            let _path = Path::new(&path_clone);
            let result = "Long Calculated TESTSTRING".to_string();

            let mut folder_hash_guard = folder_hash_clone.lock().await;
            *folder_hash_guard = result;
        },
        5
    );

    let x = folder_hash.lock().await.clone();
    x
}

#[tokio::main]
async fn main() {
    let result = extreme_long_calculation("test".to_string()).await;
}

Cargo.toml

[package]
name = "bug_testing"
version = "0.1.0"
edition = "2021"

[dependencies]
tokio = {version = "1.42.0", features = ["full"]}
tracing = "0.1.41"

Command

cargo clippy --fix --allow-staged --allow-dirty

Version

rustc 1.83.0 (90b35a623 2024-11-26)
binary: rustc
commit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf
commit-date: 2024-11-26
host: aarch64-apple-darwin
release: 1.83.0
LLVM version: 19.1.1

Additional Labels

No response

clippy output:

    Checking testig v0.1.0 (/Users/privat/Documents/GitHub/flexi-servers/testig)
warning: failed to automatically apply fixes suggested by rustc to crate `testig`

after fixes were automatically applied the compiler reported errors within these files:

  * src/main.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0597]: `folder_hash` does not live long enough
  --> src/main.rs:77:5
   |
61 |     let folder_hash = Arc::new(Mutex::new(String::new()));
   |         ----------- binding `folder_hash` declared here
...
77 |     folder_hash.lock().await.clone()
   |     ^^^^^^^^^^^-------------
   |     |
   |     borrowed value does not live long enough
   |     a temporary with access to the borrow is created here ...
78 | }
   | -
   | |
   | `folder_hash` dropped here while still borrowed
   | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `tokio::sync::MutexGuard`
   |
   = note: the temporary is part of an expression at the end of a block;
           consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
   |
77 |     let x = folder_hash.lock().await.clone(); x
   |     +++++++                                 +++

warning: unused variable: `result`
  --> src/main.rs:82:9
   |
82 |     let result = extreme_long_calculation("test".to_string()).await;
   |         ^^^^^^ help: if this is intentional, prefix it with an underscore: `_result`
   |
   = note: `#[warn(unused_variables)]` on by default

error: aborting due to 1 previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0597`.
Original diagnostics will follow.

warning: unused variable: `result`
  --> src/main.rs:82:9
   |
82 |     let result = extreme_long_calculation("test".to_string()).await;
   |         ^^^^^^ help: if this is intentional, prefix it with an underscore: `_result`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: returning the result of a `let` binding from a block
  --> src/main.rs:77:5
   |
76 |     let x = folder_hash.lock().await.clone();
   |     ----------------------------------------- unnecessary `let` binding
77 |     x
   |     ^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
   = note: `#[warn(clippy::let_and_return)]` on by default
help: return the expression directly
   |
76 ~     
77 ~     folder_hash.lock().await.clone()
   |

warning: `testig` (bin "testig" test) generated 2 warnings (run `cargo clippy --fix --bin "testig" --tests` to apply 1 suggestion)
warning: failed to automatically apply fixes suggested by rustc to crate `testig`

after fixes were automatically applied the compiler reported errors within these files:

  * src/main.rs

This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error[E0597]: `folder_hash` does not live long enough
  --> src/main.rs:77:5
   |
61 |     let folder_hash = Arc::new(Mutex::new(String::new()));
   |         ----------- binding `folder_hash` declared here
...
77 |     folder_hash.lock().await.clone()
   |     ^^^^^^^^^^^-------------
   |     |
   |     borrowed value does not live long enough
   |     a temporary with access to the borrow is created here ...
78 | }
   | -
   | |
   | `folder_hash` dropped here while still borrowed
   | ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `tokio::sync::MutexGuard`
   |
   = note: the temporary is part of an expression at the end of a block;
           consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
   |
77 |     let x = folder_hash.lock().await.clone(); x
   |     +++++++                                 +++

warning: unused variable: `result`
  --> src/main.rs:82:9
   |
82 |     let result = extreme_long_calculation("test".to_string()).await;
   |         ^^^^^^ help: if this is intentional, prefix it with an underscore: `_result`
   |
   = note: `#[warn(unused_variables)]` on by default

error: aborting due to 1 previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0597`.
Original diagnostics will follow.

warning: `testig` (bin "testig") generated 2 warnings (2 duplicates)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.83s

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