While trying to create a Future conditionally, for later use with select_biased!
:
let mut heartbeat_timer = if let ServerState::Leader(_, _, _) = server_state {
// if we re the Leader, we want to send out AppendEntries RPC at a
// minimum interval as required to maintain our leadership
task::sleep(HEARTBEAT_DURATION)
} else {
// if we re not the leader, no need to send those
pending::<()>()
};
// ...
select_biased! {
h = heartbeat_timer => self.heartbeat().await,
// ... some others declared in priority order
default => task::yield_now().await,
}
I am having difficulty understanding why I get a compilation error:
error[E0308]: `if` and `else` have incompatible types
--> src/raft.rs:185:17
|
182 | let heartbeat_timer = if let ServerState::Leader(_, _, _) = server_state {
| ___________________________________-
183 | | task::sleep(HEARTBEAT_DURATION)
| | ------------------------------- expected because of this
184 | | } else {
185 | | pending::<()>()
| | ^^^^^^^^^^^^^^^ expected future, found `Pending<()>`
186 | | };
| |_____________- `if` and `else` have incompatible types
|
= note: expected opaque type `impl futures::Future<Output = ()>`
found struct `futures::future::Pending<()>`
Clicking (in my IDE) through pending
shows me that its type is Pending<T>
, and I can further see that Pending<T>
implements Future<Output=T>
:
impl<T> Future for Pending<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, _: &mut Context< _>) -> Poll<T> {
Poll::Pending
}
}
For some reason I can t yet understand, the compiler fails to follow the same breadcrumbs. What secret does the compiler know that am I missing? Is there some straightforward transformation of my code that would satisfy the compiler? What should I be thinking that would have led me to supply what the compiler needs?
rustup --version
includes the output:
info: The currently active `rustc` version is `rustc 1.69.0 (84c898d65 2023-04-16)`