Incompatible types with correct function signatures

Viewed 1361

I have 2 functions which return the same type impl Future<Item = (), Error = ()>

extern crate tokio;
extern crate futures;

use tokio::timer::Interval;
use std::time::{Duration, Instant};
use tokio::prelude::*;
use futures::future;

fn run2() -> impl Future<Item = (), Error = ()> {
    future::ok(())
}

fn run() -> impl Future<Item = (), Error = ()> {
    Interval::new(Instant::now(), Duration::from_millis(1000))
        .for_each(move |instant| {
            println!("fire; instant={:?}", instant);
            Ok(())
        })
        .map_err(|e| panic!("interval errored; err={:?}", e))
}

fn main_run() -> impl Future<Item = (), Error = ()> {
    if 1 == 1 {
        run()
    } else {
        run2()
    }
}

fn main() {
    tokio::run(main_run());
}

playground

I'm trying to execute functions conditionally in main_run, but I get a weird error:

error[E0308]: if and else have incompatible types
  --> src/main.rs:23:5
   |
23 | /     if 1 == 1 {
24 | |         run()
25 | |     } else {
26 | |         run2()
27 | |     }
   | |_____^ expected opaque type, found a different opaque type
   |
   = note: expected type `impl futures::Future` (opaque type)
          found type `impl futures::Future` (opaque type)

Both functions return the same type: impl Future<Item = (), Error = ()>
Why is compiler not happy?

EDIT:
Since it was a duplicate I found a solution in the response to the original question, however here is the solution to this particular question if someone stumbles upon this question in the future:

extern crate tokio;
extern crate futures;

use tokio::timer::Interval;
use std::time::{Duration, Instant};
use tokio::prelude::*;
use futures::future;

fn run2() -> Box<Future<Item = (), Error = ()> + Send> {
    Box::new(future::ok(()))
}

fn run() -> Box<Future<Item = (), Error = ()> + Send> {
    Box::new(Interval::new(Instant::now(), Duration::from_millis(1000))
        .for_each(move |instant| {
            println!("fire; instant={:?}", instant);
            Ok(())
        })
        .map_err(|e| panic!("interval errored; err={:?}", e)))
}

fn main_run() -> impl Future<Item = (), Error = ()> {
    if 1 == 1 {
        run()
    } else {
        run2()
    }
}

fn main() {
    tokio::run(main_run());
}

playgound

0 Answers
Related