rustc 1.20.0-nightly (086eaa78e 2017-07-15)
binary: rustc
commit-hash: 086eaa78ea70075abe4e6b7fb9dc76259867b4be
commit-date: 2017-07-15
host: x86_64-pc-windows-msvc
release: 1.20.0-nightly
LLVM version: 4.0
#![feature(conservative_impl_trait)]
trait Future {
type Item;
fn and_then<M>(self, m: M) -> AndThen<Self, M> where Self: Sized {
AndThen(self, m)
}
}
struct AndThen<F, M>(F, M);
impl<F, M, F2> Future for AndThen<F, M> where F: Future, M: FnOnce(F::Item) -> F2, F2: Future {
type Item = F2::Item;
}
struct FutureOk<T>(T);
impl<T> Future for FutureOk<T> {
type Item = T;
}
fn foo(x: i32) -> impl Future<Item = i32> {
FutureOk(x)
.and_then(foo)
}
fn main() {
let _ = foo(5);
}
This crashes the compiler with:
thread 'rustc' has overflowed its stack
because of the recursive return type of foo (X = AndThen<FutureOk<i32>, fn(i32) -> X>). Of course without impl trait I could not have written the type in the first place.
Replace .and_then(foo) with .and_then(|x| foo(x)) fixes it, possibly because the type then becomes AndThen<FutureOk<i32>, [closure]> so the recursive part is separated into the closure type.
This crashes the compiler with:
because of the recursive return type of
foo(X = AndThen<FutureOk<i32>, fn(i32) -> X>). Of course withoutimpl traitI could not have written the type in the first place.Replace
.and_then(foo)with.and_then(|x| foo(x))fixes it, possibly because the type then becomesAndThen<FutureOk<i32>, [closure]>so the recursive part is separated into the closure type.