Skip to content

Recursive impl-trait type causes compiler stack overflow #43263

@Arnavion

Description

@Arnavion
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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions