rust-lang / rust-clippy

A bunch of lints to catch common mistakes and improve your Rust code. Book: https://doc.rust-lang.org/clippy/
https://rust-lang.github.io/rust-clippy/
Other
11.4k stars 1.54k forks source link

Clippy can't fix warnings because compiler false error #10648

Open asensio-project opened 1 year ago

asensio-project commented 1 year ago

Summary

Hello everyone,

I was trying to automatically fix all the warnings of Clippy, but I got this error:

warning: failed to automatically apply fixes suggested by rustc to crate `trivial_packager`

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

  * src/register_handler.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/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[E0425]: cannot find value `user` in this scope
  --> src/register_handler.rs:32:32
   |
32 |     Ok(HttpResponse::Ok().json(user))
   |                                ^^^^ not found in this scope

error: aborting due to previous error

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

But the code works fine when executing cargo run.

The full project can be found at github

Reproducer

I tried this code:

pub async fn register_user(
    user_data: web::Json<UserData>,
    pool: web::Data<Pool>,
) -> Result<HttpResponse, actix_web::Error> {
    let user_data = user_data.into_inner();

    if !(user_data.gender == String::from("B") || user_data.gender == String::from("G")) {
        return Err(actix_web::error::ErrorBadRequest("Missing gender"));
    } else if !(user_data.role == String::from("A") || user_data.role == String::from("T")) {
        return Err(actix_web::error::ErrorBadRequest("Missing role"));
    }

    let user = web::block(move || query(user_data, pool)).await??;

    Ok(HttpResponse::Ok().json(&user))
}

I expected to see this happen: Successful. All warnings fixed

Instead, this happened: (see above)

Version

rustc 1.68.2 (9eb3afe9e 2023-03-27)
binary: rustc
commit-hash: 9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0
commit-date: 2023-03-27
host: x86_64-unknown-linux-gnu
release: 1.68.2
LLVM version: 15.0.6

Additional Labels

No response

lukaslueg commented 1 year ago

This is due to the unfortunate interaction of two different lints:

The line

let user = web::block(move || query(user_data, pool)).await??;

triggers let_unit_value, as user will be of type (). The lint recommends removing the (useless) binding of () to users.

The line

Ok(HttpResponse::Ok().json(&user))

triggers the needless_borrow lint, as it should read .json(user) instead of .json(&user). But the binding to user has already been removed by the other lint, triggering this error. You'll have to manually fix this, as the lints can't coordinate their actions with respect to one another.

Having only looked at the code for 15 seconds, my guess is that user being of type () is an unforeseen error in the code's structure in itself.

asensio-project commented 1 year ago

Thanks, that solved my issue. But should we do something for this not to happen in clippy?

Adimac93 commented 1 year ago

Hi! In my case this error was caused by unit "()" value in res variable.

The following errors were reported:
error[E0425]: cannot find value `res` in this scope
  --> src/routes/groups.rs:42:8
   |
42 |     Ok(res)
   |        ^^^ not found in this scope
async fn post_create_group(
    claims: Claims,
    State(pool): State<PgPool>,
    group: Json<NewGroup>,
) -> Result<(), AppError> {
    tracing::trace!("JWT: {:#?}", claims);
    let res = create_group(&pool, group.name.trim(), claims.user_id).await?;

    debug!("Group {} created successfully", group.name);

    Ok(res)
}

create_group fn signature

pub async fn create_group(pool: &PgPool, name: &str, user_id: Uuid) -> Result<(), AppError>