rust-lang / rust-lang/rust-clippy

let_and_return FP on ugly async Send workaround

Open
#8,598 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-false-positive I-suggestion-causes-error
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Summary

let_and_return trips up on an awful construction I invented to avoid a future-not-Send problem.

The workaround code I have here is terrible, but I'm not aware of a better way to write it. (NB that in this example I use mpc::channel::Receiver as a thing that is Send but not Sync; the example program doesn't make much sense semantically.)

I bet the underlying cause is the same as #8114.

Lint Name

let_and_return

Reproducer

I tried this code:

use std::sync::mpsc;
use std::future::Future;
use std::pin::Pin;

async fn awaitpoint(_: ()) { }

async fn failure() {
    let (_, rx) = mpsc::channel::<()>();

    while let Ok(event) = { let k= &rx; k.recv()} {
        awaitpoint(event).await;
    }
}

fn main() {
    let _: Pin<Box<dyn Future<Output=()> + Send>> = Box::pin(
        async {
            failure().await;
        }
    );
}

I saw this happen:

    Checking foo v0.1.0 (/volatile/rustcargo/Rustup/Arti/experiments)
warning: returning the result of a `let` binding from a block
  --> src/main.rs:10:59
   |
10 |     while let Ok(event) = { let k= &rx; let y = k.recv(); y } {
   |                                         ----------------- ^
   |                                         |
   |                                         unnecessary `let` binding
   |
   = note: `#[warn(clippy::let_and_return)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
help: return the expression directly
   |
10 -     while let Ok(event) = { let k= &rx; let y = k.recv(); y } {
10 +     while let Ok(event) = { let k= &rx;  k.recv() } {
   | 

warning: `foo` (bin "foo") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.21s

I expected to see this happen:

Well, ideally, Rust would have accepted

    while let Ok(event) = rx.recv() {

but failing that, it wouldl be nice if clippy didn't suggest changes that cause compiler errors.

Version
rustc 1.61.0-nightly (1bfe40d11 2022-03-18)
binary: rustc
commit-hash: 1bfe40d11c3630254504fb73eeccfca28d50df52
commit-date: 2022-03-18
host: x86_64-unknown-linux-gnu
release: 1.61.0-nightly
LLVM version: 14.0.0
Additional Labels

@rustbot label +I-suggestion-causes-error

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the supplied async Send workaround and its let_and_return warning with the shown Rust code. Trace the let_and_return lint logic and verify that its suggested simplification does not produce a compiler error for this pattern; the issue is resolved when this case is handled without an invalid suggestion.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.