Skip to content

Incorrect error when polling non-pinned future from future wrapper #125661

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
Urhengulas opened this issue May 28, 2024 · 0 comments · Fixed by #125684
Closed

Incorrect error when polling non-pinned future from future wrapper #125661

Urhengulas opened this issue May 28, 2024 · 0 comments · Fixed by #125684
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Urhengulas
Copy link
Contributor

Urhengulas commented May 28, 2024

Code

When polling future from a wrapping future, the error message when forgetting to pin the wrapped future is wrong. Take this as an example (playground):

use std::{
    future::Future,
    pin::Pin,
    task::{Context, Poll},
};

struct FutureWrapper<F> {
    fut: F,
}

impl<F> Future for FutureWrapper<F>
where
    F: Future,
{
    type Output = F::Output;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let res = self.fut.poll(cx);
        res
    }
}

Current output

The error is wrong because of the double let: let res = let mut pinned = std::pin::pin!(self.fut);.

error[E0599]: no method named `poll` found for type parameter `F` in the current scope
  --> src/lib.rs:18:28
   |
11 | impl<F> Future for FutureWrapper<F>
   |      - method `poll` not found for this type parameter
...
18 |         let res = self.fut.poll(cx);
   |                            ^^^^ method not found in `F`
   |
help: consider pinning the expression
   |
18 ~         let res = let mut pinned = std::pin::pin!(self.fut);
19 ~         pinned.as_mut().poll(cx);
   |

For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground` (lib) due to 1 previous error

Desired output

error[E0599]: no method named `poll` found for type parameter `F` in the current scope
  --> src/lib.rs:18:28
   |
11 | impl<F> Future for FutureWrapper<F>
   |      - method `poll` not found for this type parameter
...
18 |         let res = self.fut.poll(cx);
   |                            ^^^^ method not found in `F`
   |
help: consider pinning the expression
   |
18 ~         let mut pinned = std::pin::pin!(self.fut);
19 ~         let res = pinned.as_mut().poll(cx);
   |

For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground` (lib) due to 1 previous error

Rationale and extra context

No response

Other cases

No response

Rust Version

rustc 1.78.0 (9b00956e5 2024-04-29)
binary: rustc
commit-hash: 9b00956e56009bab2aa15d7bff10916599e3d6d6
commit-date: 2024-04-29
host: x86_64-unknown-linux-gnu
release: 1.78.0
LLVM version: 18.1.2

Anything else?

Credit to @skade for discovering the bug.

@Urhengulas Urhengulas added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 28, 2024
@Urhengulas Urhengulas changed the title Incorrect error for future wrappers Incorrect error when polling non-pinned future from future wrapper May 28, 2024
@estebank estebank added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. labels May 28, 2024
@estebank estebank self-assigned this May 28, 2024
jieyouxu added a commit to jieyouxu/rust that referenced this issue Jun 11, 2024
…, r=pnkfelix

Account for existing bindings when suggesting `pin!()`

When we encounter a situation where we'd suggest `pin!()`, we now account for that expression existing as part of an assignment and provide an appropriate suggestion:

```
error[E0599]: no method named `poll` found for type parameter `F` in the current scope
  --> $DIR/pin-needed-to-poll-3.rs:19:28
   |
LL | impl<F> Future for FutureWrapper<F>
   |      - method `poll` not found for this type parameter
...
LL |         let res = self.fut.poll(cx);
   |                            ^^^^ method not found in `F`
   |
help: consider pinning the expression
   |
LL ~         let mut pinned = std::pin::pin!(self.fut);
LL ~         let res = pinned.as_mut().poll(cx);
   |
```

Fix rust-lang#125661.
jieyouxu added a commit to jieyouxu/rust that referenced this issue Jun 11, 2024
…, r=pnkfelix

Account for existing bindings when suggesting `pin!()`

When we encounter a situation where we'd suggest `pin!()`, we now account for that expression existing as part of an assignment and provide an appropriate suggestion:

```
error[E0599]: no method named `poll` found for type parameter `F` in the current scope
  --> $DIR/pin-needed-to-poll-3.rs:19:28
   |
LL | impl<F> Future for FutureWrapper<F>
   |      - method `poll` not found for this type parameter
...
LL |         let res = self.fut.poll(cx);
   |                            ^^^^ method not found in `F`
   |
help: consider pinning the expression
   |
LL ~         let mut pinned = std::pin::pin!(self.fut);
LL ~         let res = pinned.as_mut().poll(cx);
   |
```

Fix rust-lang#125661.
jieyouxu added a commit to jieyouxu/rust that referenced this issue Jun 11, 2024
…, r=pnkfelix

Account for existing bindings when suggesting `pin!()`

When we encounter a situation where we'd suggest `pin!()`, we now account for that expression existing as part of an assignment and provide an appropriate suggestion:

```
error[E0599]: no method named `poll` found for type parameter `F` in the current scope
  --> $DIR/pin-needed-to-poll-3.rs:19:28
   |
LL | impl<F> Future for FutureWrapper<F>
   |      - method `poll` not found for this type parameter
...
LL |         let res = self.fut.poll(cx);
   |                            ^^^^ method not found in `F`
   |
help: consider pinning the expression
   |
LL ~         let mut pinned = std::pin::pin!(self.fut);
LL ~         let res = pinned.as_mut().poll(cx);
   |
```

Fix rust-lang#125661.
@bors bors closed this as completed in 5585f31 Jun 12, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jun 12, 2024
Rollup merge of rust-lang#125684 - estebank:pin-to-binding-suggestion, r=pnkfelix

Account for existing bindings when suggesting `pin!()`

When we encounter a situation where we'd suggest `pin!()`, we now account for that expression existing as part of an assignment and provide an appropriate suggestion:

```
error[E0599]: no method named `poll` found for type parameter `F` in the current scope
  --> $DIR/pin-needed-to-poll-3.rs:19:28
   |
LL | impl<F> Future for FutureWrapper<F>
   |      - method `poll` not found for this type parameter
...
LL |         let res = self.fut.poll(cx);
   |                            ^^^^ method not found in `F`
   |
help: consider pinning the expression
   |
LL ~         let mut pinned = std::pin::pin!(self.fut);
LL ~         let res = pinned.as_mut().poll(cx);
   |
```

Fix rust-lang#125661.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants