Skip to content

from_generator::GenFuture<[static generator@...]> in Error Message #99310

New issue

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

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

Already on GitHub? Sign in to your account

Closed
nixpulvis opened this issue Jul 16, 2022 · 5 comments
Closed

from_generator::GenFuture<[static generator@...]> in Error Message #99310

nixpulvis opened this issue Jul 16, 2022 · 5 comments
Labels
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.

Comments

@nixpulvis
Copy link

nixpulvis commented Jul 16, 2022

Given the following code: (playground link)

use std::ptr;
use std::pin::Pin;
use std::future::Future;
use std::task::{Context, Waker, RawWaker, RawWakerVTable};

static RAW_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
    |data| RawWaker::new(ptr::null(), &RAW_WAKER_VTABLE),
    |data| {},
    |data| {},
    |data| {},
);

fn main() {
    let task = async {};
    let raw_waker = RawWaker::new(ptr::null(), &RAW_WAKER_VTABLE);
    let waker = Waker::from_raw(raw_waker);
    dbg!(Pin::new(&mut task).poll(&mut Context::from_waker(&waker)));
}

The current output is:

error[E0277]: `from_generator::GenFuture<[static generator@src/main.rs:14:22: 14:24]>` cannot be unpinned
   --> src/main.rs:17:19
    |
17  |     dbg!(Pin::new(&mut task).poll(&mut Context::from_waker(&waker)));
    |          -------- ^^^^^^^^^ within `impl Future<Output = ()>`, the trait `Unpin` is not implemented for `from_generator::GenFuture<[static generator@src/main.rs:14:22: 14:24]>`
    |          |
    |          required by a bound introduced by this call
    |
    = note: consider using `Box::pin`
    = note: required because it appears within the type `impl Future<Output = ()>`
note: required by a bound in `Pin::<P>::new`

Given that the docs for from_generator are explicitly hidden to help with error messages, I would expect this error to not make reference to a hidden item.

/// Wrap a generator in a future.
///
/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
// This is `const` to avoid extra errors after we recover from `const async fn`
#[lang = "from_generator"]
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
#[rustc_const_unstable(feature = "gen_future", issue = "50547")]
#[inline]
pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
where
T: Generator<ResumeTy, Yield = ()>,

@nixpulvis nixpulvis 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 Jul 16, 2022
@conradludgate
Copy link
Contributor

conradludgate commented Jul 16, 2022

Prior art:

let mut x = 0;
let f = || x += 1;
let y = &f as  &dyn Fn();

I believe this used to generate a similar error (including a name for the anon closure type), but now the error is

error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
 --> src/main.rs:3:9
  |
3 | let f = || x += 1;
  |         ^^ - closure is `FnMut` because it mutates the variable `x` here
  |         |
  |         this closure implements `FnMut`, not `Fn`
4 | let y = &f as  &dyn Fn();
  |         -- the requirement to implement `Fn` derives from here

For more information about this error, try `rustc --explain E0525`. 

See: #26046

@compiler-errors
Copy link
Member

compiler-errors commented Jul 17, 2022

but hides it in impl Trait to give better error messages (impl Future rather than GenFuture<[closure.....]>).

Unfortunately auto traits break this rule, since they intentionally "leak" through opaque types 😅

@conradludgate
Copy link
Contributor

Looking back on this. I think we can get some special casing:

Unpin

Currently, all generators/futures are !Unpin, so there should probably be a simple error case explaining that. I'm not sure if there's been any designs about getting Unpin simple futures.

Send/Sync

A case where people may want nice error messages is in the case that a future is not send.

It seems we already have this though, which is nice: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1d6836aec8c69c3171af54252f71d322

error: future cannot be sent between threads safely
 --> src/main.rs:4:53
  |
4 |     let task: Box<dyn Future<Output = ()> + Send> = Box::new(async {
  |                                                     ^^^^^^^^^^^^^^ future created by async block is not `Send`
  |
  = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<i32>`
note: future is not `Send` as this value is used across an await
 --> src/main.rs:6:18
  |
5 |         let rc = std::rc::Rc::new(1);
  |             -- has type `Rc<i32>` which is not `Send`
6 |         ready(()).await
  |                  ^^^^^^ await occurs here, with `rc` maybe used later
7 |     });
  |     - `rc` is later dropped here
  = note: required for the cast to the object type `dyn Future<Output = ()> + Send`

@tisonkun
Copy link
Contributor

Seems that there is no longer GenFuture now?

I wonder how futures get lowered now anyway.

@compiler-errors
Copy link
Member

Futures are lowered as coroutines whose CoroutineKind specifies that they implement Future directly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.
Projects
None yet
Development

No branches or pull requests

4 participants