This repository has been archived by the owner on Apr 2, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
Cannot call poll once value is consumed #36
Comments
I suspect a rustc bug in Reduced to avoid external dependency on futures-await: #![feature(conservative_impl_trait, generators, generator_trait)]
extern crate futures;
extern crate tokio_core;
extern crate tokio_timer;
use std::time::Duration;
use tokio_core::reactor::Core;
use futures::prelude::*;
pub mod __rt {
pub use std::ops::Generator;
use futures::Poll;
use futures::{Future, Async};
use std::ops::GeneratorState;
pub trait MyFuture<T: IsResult>: Future<Item=T::Ok, Error = T::Err> {}
impl<F, T> MyFuture<T> for F
where F: Future<Item = T::Ok, Error = T::Err > + ?Sized,
T: IsResult
{}
pub trait IsResult {
type Ok;
type Err;
fn into_result(self) -> Result<Self::Ok, Self::Err>;
}
impl<T, E> IsResult for Result<T, E> {
type Ok = T;
type Err = E;
fn into_result(self) -> Result<Self::Ok, Self::Err> { self }
}
struct GenFuture<T>(T);
pub enum Mu {}
pub fn gen<T>(gen: T) -> impl MyFuture<T::Return>
where T: Generator<Yield = Async<Mu>>,
T::Return: IsResult,
{
GenFuture(gen)
}
impl<T> Future for GenFuture<T>
where T: Generator<Yield = Async<Mu>>,
T::Return: IsResult,
{
type Item = <T::Return as IsResult>::Ok;
type Error = <T::Return as IsResult>::Err;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match self.0.resume() {
GeneratorState::Yielded(Async::NotReady)
=> Ok(Async::NotReady),
GeneratorState::Yielded(Async::Ready(mu))
=> match mu {},
GeneratorState::Complete(e)
=> e.into_result().map(Async::Ready),
}
}
}
}
fn ola(lv: u32) -> impl __rt::MyFuture<Result<u32, String>> + 'static {
__rt::gen(move || -> Result<u32, String> {
let __e: Result<u32, String> =
{
{
let wheel = tokio_timer::wheel().build();
let timer = wheel.sleep(Duration::new(5, 0));
let mut future = timer;
let _ = loop {
match ::futures::Future::poll(&mut future)
{
Ok(::futures::Async::Ready(e)) => break Ok(e),
Ok(::futures::Async::NotReady) => (),
Err(e) => break Err(e),
}
yield ::futures::Async::NotReady
};
println!("ola");
Ok(lv)
}
};
return __e;
})
}
fn grr() -> impl Future<Item=u32, Error=()> {
let wheel = tokio_timer::wheel().build();
let ft = ola(42).map_err(|_| ());
let timeout = wheel.timeout(ft, Duration::new(10, 0));
timeout
}
fn main() {
let mut core = Core::new().unwrap();
core.run(grr()).unwrap();
} |
Perhaps relevant: I am able to reproduce this problem on MacOS, but not on Linux. |
/cc @alexcrichton @Zoxc |
I've been able to reproduce this problem on Linux now, as well. |
This is fixed in the latest nightly rustc, which includes rust-lang/rust#47270. Thanks @Zoxc! |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Hi Carl,
Nested timers combined with futures-await lead to a panic with the above message:
(fired from await!(timer) in the grr() function).
Just swapping two lines, i.e. replacing:
with
makes the panic go awayand the executable work as expected.
Any idea why? Alex Crichton suspects a bug in tokio-timer.
The text was updated successfully, but these errors were encountered: