Skip to content
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

rustc overflows its stack when type checking ~~a simple program~~ polymorphmic recursion #38591

Closed
jhjourdan opened this issue Dec 24, 2016 · 14 comments · Fixed by #62085
Closed
Labels
A-typesystem Area: The type system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jhjourdan
Copy link
Contributor

jhjourdan commented Dec 24, 2016

The following program triggers a stack overflow in rustc:

struct S<T> {
    t : T,
    s : Box<S<fn(u : T)>>
}

fn f(x : S<u32>) { }

fn main () { }

My version of rustc:

$ rustc --version
rustc 1.15.0-nightly (71c06a56a 2016-12-18)

The problem also appears when replacing fn(u : T) with fn() -> T.

@achanda
Copy link
Contributor

achanda commented Dec 24, 2016

Interestingly, I don't see a stack trace with RUST_BACKTRACE

:~/src$ RUST_BACKTRACE=1 rustc test.rs

thread 'rustc' has overflowed its stack
fatal runtime error: stack overflow

Same version of rustc

@AraHaan
Copy link

AraHaan commented Dec 24, 2016

Well oddly than not it does look to see if there is about half a GB left on disk and if there is not updating would not work. Which is bad because there actually is enough space if I have an older version of it.

@AraHaan
Copy link

AraHaan commented Dec 25, 2016

This also happens that sometimes it actually uses over than 1 GB of RAM as well for some insanely small code for some unknown reason.

@jhjourdan
Copy link
Contributor Author

jhjourdan commented Dec 25, 2016

The struct is obviously infinitely recursive.

I don't know what you mean by this, but I do no think this is the problem here. The following program also reveals the problem:
rust

struct S<T> {
    t : T,
    s : Box<S<Option<fn(u : T)>>>
}

But the following is accepted:

struct S<T> {
    t : T,
    s : Box<S<T>>
}

fn f(x : S<u32>) { }

fn main () { }

Recursive structs are a well-known and important feature of Rust.

@sfackler
Copy link
Member

@jhjourdan S<()> contains an S<fn(u: ())>, which contains an S<fn(u: fn(u: ()))>, which contains an S<fn(u: fn(u: fn(u: ())))>, which contains...

@jhjourdan
Copy link
Contributor Author

@sfackler : it does not /contain/ it. It /refers/ to it.

Again, recursive structs are a well-known, important feature of Rust. For example, you cannot define linked lists without them.

@sfackler
Copy link
Member

The issue is not the storage of the struct. The issue is that you are asking the compiler to generate code for an infinite number of instantiations of S.

struct List<T>(Option<Box<List<T>>>)

Is a very different thing than

struct Foo<T>(Option<Box<List<fn(T)>>>);

@jhjourdan
Copy link
Contributor Author

Well, but I am not asking the compiler to generate any code here... Or at least, the code that is generated is not used anywhere.

@sfackler
Copy link
Member

I'm confused then - why is it valuable for it to be possible to define but never use this type?

@jhjourdan
Copy link
Contributor Author

Btw, now I understand better why my code provokes a stack overflow.

But still, there is no reason this code is generated if the code is never used, and even then, this is not an excuse for rustc to do a stack overflow.

@brson
Copy link
Contributor

brson commented Dec 30, 2016

Yes there should be some reasonable recursion limit here.

@brson brson added A-typesystem Area: The type system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 30, 2016
@insaneinside
Copy link
Contributor

More importantly, rustc should issue a diagnostic instead of overflowing its stack. 😮

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

This is no longer reproducible with rustc 1.26.0-nightly (2789b06 2018-03-06).

@pnkfelix
Copy link
Member

The phenomenon that @sfackler is describing above is technically known as "polymorphic recursion."

cc #4287

But, as noted by @istankovic above, this particular instance of the diagnostic issue with polymorphic recursion (that I believe persists to this day) no longer seems to replicate.

Marking as E-needstest.

@pnkfelix pnkfelix added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Apr 19, 2019
@pnkfelix pnkfelix changed the title rustc overflows its stack when type checking a simple program rustc overflows its stack when type checking ~~a simple program~~ polymorphmic recursion Apr 19, 2019
Centril added a commit to Centril/rust that referenced this issue Jun 24, 2019
Centril added a commit to Centril/rust that referenced this issue Jun 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-typesystem Area: The type system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants