Skip to content

rustc thread stack overflow when iterating recursively #39555

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
torkleyy opened this issue Feb 5, 2017 · 2 comments
Closed

rustc thread stack overflow when iterating recursively #39555

torkleyy opened this issue Feb 5, 2017 · 2 comments
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@torkleyy
Copy link

torkleyy commented Feb 5, 2017

There is a bug in the compiler which causes it to crash when I try to iterate through a recursive structure (using flat_map):

thread 'rustc' has overflowed its stack
fatal runtime error: stack overflow
Aborted (core dumped)

Here's my code:

#![feature(conservative_impl_trait)]

pub struct Foo {
    children: Vec<Foo>,
}

impl Foo {
    pub fn iter_all_children<'a>(&'a self) -> impl Iterator<Item = &'a Foo> {
        self.children.iter().flat_map(|x| x.iter_all_children())
    }
}

fn main() {
    let foo = Foo { children: Vec::new() };
    let v: Vec<_> = foo.iter_all_children().collect();
}

Version

I'm using the most recent nightly (rustc 1.17.0-nightly (0648517 2017-02-03)), however this is also reproducable with rustc 1.16 using the Playground (https://is.gd/QYkYTk).


I don't know much about how rustc works but I think the problem is somewhere in the conversion from MIR to LLVM IR because generating MIR works.

@Stebalien
Copy link
Contributor

Stebalien commented Feb 6, 2017

It's actually a problem with the type hidden by impl Iterator<Item = &Foo>: it's an infinitely sized recursive type:

struct FlatMap<Iter<'a>, FlatMap<Iter<'a>>, ...> {
    iter: Iter<'a>,
    subiter: Option<Self> // recursive
}

You can fix this by boxing:

use std::slice::Iter;

pub struct Foo {
    children: Vec<Foo>,
}

impl Foo {
    pub fn iter_all_children<'a>(&'a self) -> Box<Iterator<Item=&'a Foo> + 'a> {
        Box::new(self.children.iter().flat_map(|x| x.iter_all_children())) as Box<Iterator<Item=&'a Foo> + 'a>
    }
}

fn main() {
    let foo = Foo { children: Vec::new() };
    let v: Vec<_> = foo.iter_all_children().collect();
}

Note: this is still a bug in rustc (it shouldn't just crash).

@steveklabnik steveklabnik added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Feb 7, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@cramertj
Copy link
Member

cramertj commented Jan 5, 2018

Dup of #38064

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

5 participants