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

Stack overflow on recursive type #25439

Closed
terpstra opened this issue May 15, 2015 · 5 comments
Closed

Stack overflow on recursive type #25439

terpstra opened this issue May 15, 2015 · 5 comments
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.

Comments

@terpstra
Copy link

I was trying to write a statically dispatched fixed-point function (aka Y combinator) in rust. My hope was to use it to make recursive closures. While implementing it, I triggered a compiler stack overflow which can be reproduced with this small example code:

struct Helper<'a,F:'a>(&'a F);

fn fix<F>(f: F) -> i32
  where F: Fn(Helper<F>, i32) -> i32      
{
  f(Helper(&f), 8) 
}

fn main() {  
  fix(|_,x| x);  
}

This was on "rustc 1.0.0-beta (9854143 2015-04-02) (built 2015-04-02)", but it still happens on nightly.

I've seen there are a couple other stack overflow bugs related to recursive types. The examples I saw, however, were situations where the compiler should have just given a nicer error message. In my case, I think this is a legitimate piece of code that should compile.

This is analagous to the SML datatype 'a t = T of 'a t -> 'a

Rust should be able to do this, too.

@Stebalien
Copy link
Contributor

This works:

struct Helper<'a>(&'a Fn(Helper, i32) -> i32);

fn fix<F>(f: F) -> i32
  where F: Fn(Helper, i32) -> i32      
{
  f(Helper(&f), 8) 
}

fn main() {  
  fix(|_,x| x);  
}

Rust allows types to refer to themselves in the body but not in the signature. In this case, f's type signature is recursive: SomeFn(Helper<SomeFn(Helper<....

@terpstra
Copy link
Author

While your version does not kill the compiler, it is inadequate to implement a statically dispatched fixed point combinator. I already have a version that uses dynamic dispatch.

I really do want the infinitely recursive type. ML can do it.

@Stebalien
Copy link
Contributor

Sorry. You're right; I'm wrong. This works:

fn fix<F>(f: F) -> i32
  where F: Fn(&F, i32) -> i32      
{
  f(&f, 8) 
}

fn main() {  
  fix(|_,x| x);  
}

It seems like using F as a type parameter (in Helper) is confusing rust?

@arielb1 arielb1 added E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. and removed I-wrong labels Oct 1, 2015
@arielb1
Copy link
Contributor

arielb1 commented Oct 1, 2015

Does not crash 1.3+

@steveklabnik
Copy link
Member

Oh I guess i will leave open for E-needstest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
Projects
None yet
Development

No branches or pull requests

4 participants