Closed
Description
I've tried to write code that would work like this:
let mut f = some_fn; // many other some_fns also exist
loop {
f = f()
}
To make coding some_fn and its friends easier, I wanted to create a type:
type SomeFn = fn() -> SomeFn;
Unfortunately, this results in some type-theoretic error message that isn't really understandable by mere mortals:
<anon>:1:15: 1:29 error: illegal recursive type; insert an enum or struct in the cycle, if this is desired
<anon>:1 type SomeFn = fn() -> SomeFn;
^~~~~~~~~~~~~~
It's not at all clear what 'the cycle' is and where to insert an enum or struct. Turns out that if you know what the compiler is talking about, the fix is simple:
struct SomeFn(fn() -> SomeFn);
// ergonomy suffers
fn fn1() -> SomeFn { println!("1"); SomeFn(fn2) }
fn fn2() -> SomeFn { println!("2"); SomeFn(fn1) }
fn main() {
let mut f = SomeFn(fn1);
f = { let SomeFn(ff) = f; ff() };
f = { let SomeFn(ff) = f; ff() };
}
Output:
1
2
But I was very confused by the message and tried a contraption like this instead:
type SomeFn = fn() -> Option<SomeFn>;
A hint in the error message that points the programmer to the right direction would be very helpful. Ergonomy of the solution is also questionable, but at least it compiles.