<p dir="auto">I tried writing tarai function with Rust, version info is:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ rustc --version
rustc 1.0.0-dev (3d5fbae33 2015-01-13 01:08:03 +0000)"><pre class="notranslate"><code class="notranslate">$ rustc --version
rustc 1.0.0-dev (3d5fbae33 2015-01-13 01:08:03 +0000)
</code></pre></div>
<p dir="auto">written code is:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#![feature(unboxed_closures)]

fn tarai&lt;F:Fn() -&gt; i32&gt;(x:i32, y:i32, z:F) -&gt; i32 {
    if x &lt;= y {
        y
    }
    else {
        let fz = z();
        let nx = tarai(x - 1, y, z);
        let ny = tarai(y - 1, fz, |&amp;:| { x });
        let nz = |&amp;:|  { tarai(fz - 1, x, |&amp;:| { y }) };

        tarai(nx, ny, nz)
    }
}

fn main() {
    println!(&quot;{}&quot;, tarai(12, 6, |&amp;:| { 0 }));
}
"><pre class="notranslate"><span class="pl-c1">#!<span class="pl-kos">[</span>feature<span class="pl-kos">(</span>unboxed_closures<span class="pl-kos">)</span><span class="pl-kos">]</span></span>

<span class="pl-k">fn</span> <span class="pl-en">tarai</span><span class="pl-kos">&lt;</span><span class="pl-smi">F</span><span class="pl-kos">:</span><span class="pl-smi">Fn</span><span class="pl-kos">(</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">i32</span><span class="pl-kos">&gt;</span><span class="pl-kos">(</span><span class="pl-s1">x</span><span class="pl-kos">:</span><span class="pl-smi">i32</span><span class="pl-kos">,</span> <span class="pl-s1">y</span><span class="pl-kos">:</span><span class="pl-smi">i32</span><span class="pl-kos">,</span> <span class="pl-s1">z</span><span class="pl-kos">:</span><span class="pl-smi">F</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">i32</span> <span class="pl-kos">{</span>
    <span class="pl-k">if</span> x &lt;= y <span class="pl-kos">{</span>
        y
    <span class="pl-kos">}</span>
    <span class="pl-k">else</span> <span class="pl-kos">{</span>
        <span class="pl-k">let</span> fz = <span class="pl-en">z</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-k">let</span> nx = <span class="pl-en">tarai</span><span class="pl-kos">(</span>x - <span class="pl-c1">1</span><span class="pl-kos">,</span> y<span class="pl-kos">,</span> z<span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-k">let</span> ny = <span class="pl-en">tarai</span><span class="pl-kos">(</span>y - <span class="pl-c1">1</span><span class="pl-kos">,</span> fz<span class="pl-kos">,</span> |<span class="pl-c1">&amp;</span><span class="pl-kos">:</span>| <span class="pl-kos">{</span> x <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-k">let</span> nz = |<span class="pl-c1">&amp;</span><span class="pl-kos">:</span>|  <span class="pl-kos">{</span> <span class="pl-en">tarai</span><span class="pl-kos">(</span>fz - <span class="pl-c1">1</span><span class="pl-kos">,</span> x<span class="pl-kos">,</span> |<span class="pl-c1">&amp;</span><span class="pl-kos">:</span>| <span class="pl-kos">{</span> y <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">}</span><span class="pl-kos">;</span>

        <span class="pl-en">tarai</span><span class="pl-kos">(</span>nx<span class="pl-kos">,</span> ny<span class="pl-kos">,</span> nz<span class="pl-kos">)</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">fn</span> <span class="pl-en">main</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-en">println</span><span class="pl-en">!</span><span class="pl-kos">(</span><span class="pl-s">"{}"</span>, tarai<span class="pl-kos">(</span><span class="pl-c1">12</span>, <span class="pl-c1">6</span>, |&amp;:| <span class="pl-kos">{</span> <span class="pl-c1">0</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">but compiling this code, occurs an error like this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ rustc ./21-161505.rs
21-161505.rs:3:1: 15:2 error: reached the recursion limit during monomorphization
21-161505.rs:3 fn tarai&lt;F:Fn() -&gt; i32&gt;(x:i32, y:i32, z:F) -&gt; i32 {
21-161505.rs:4     if x &lt;= y {
21-161505.rs:5         y
21-161505.rs:6     }
21-161505.rs:7     else {
21-161505.rs:8         let fz = z();
               ..."><pre class="notranslate"><code class="notranslate">$ rustc ./21-161505.rs
21-161505.rs:3:1: 15:2 error: reached the recursion limit during monomorphization
21-161505.rs:3 fn tarai&lt;F:Fn() -&gt; i32&gt;(x:i32, y:i32, z:F) -&gt; i32 {
21-161505.rs:4     if x &lt;= y {
21-161505.rs:5         y
21-161505.rs:6     }
21-161505.rs:7     else {
21-161505.rs:8         let fz = z();
               ...
</code></pre></div>
<p dir="auto">Why my code is wrong? And what should I do for pass compiling without errors?<br>
Please show me these. Sorry for poor my english. Thank you.</p>
<p dir="auto">Came up with this issue while "unboxing" the <a href="https://github.com/rust-lang/rust/blob/6f4c11be3b9706d1ba0e1b74b89de1478410a56f/src/libcollections/trie/map.rs#L709-712"><code class="notranslate">collections::trie::map::InternalNode::each_reverse</code></a> method.</p>
<h3 dir="auto">Reduced test case</h3>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#![feature(unboxed_closures)]

struct Struct;

impl Struct {
    fn method_ok(&amp;self, f: |()| -&gt; bool) -&gt; bool {
        self.method_ok(|t| f(t))
    }

    fn method_bad&lt;F&gt;(&amp;self, f: F) -&gt; bool where F: Fn(()) -&gt; bool {
        self.method_bad(|t| f(t))
    }

    fn method_bad2&lt;F&gt;(&amp;self, f: F) -&gt; bool where F: Fn(()) -&gt; bool {
        let f: &amp;Fn(()) -&gt; bool = &amp;f;

        self.method_bad2(|t| f.call((t,)))
    }
}

fn main() {
    Struct.method_ok(|_| true);
    // Pick one
    Struct.method_bad(|_| true);
    //Struct.method_bad2(|_| true);
}"><pre class="notranslate"><span class="pl-c1">#!<span class="pl-kos">[</span>feature<span class="pl-kos">(</span>unboxed_closures<span class="pl-kos">)</span><span class="pl-kos">]</span></span>

<span class="pl-k">struct</span> <span class="pl-smi">Struct</span><span class="pl-kos">;</span>

<span class="pl-k">impl</span> <span class="pl-smi">Struct</span> <span class="pl-kos">{</span>
    <span class="pl-k">fn</span> <span class="pl-en">method_ok</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span><span class="pl-smi">self</span><span class="pl-kos">,</span> f<span class="pl-kos">:</span> |<span class="pl-kos">(</span><span class="pl-kos">)</span>| -&gt; bool<span class="pl-kos">)</span> -&gt; <span class="pl-smi">bool</span> <span class="pl-kos">{</span>
        <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">method_ok</span><span class="pl-kos">(</span>|t| <span class="pl-en">f</span><span class="pl-kos">(</span>t<span class="pl-kos">)</span><span class="pl-kos">)</span>
    <span class="pl-kos">}</span>

    <span class="pl-k">fn</span> <span class="pl-en">method_bad</span><span class="pl-kos">&lt;</span><span class="pl-smi">F</span><span class="pl-kos">&gt;</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span><span class="pl-smi">self</span><span class="pl-kos">,</span> <span class="pl-s1">f</span><span class="pl-kos">:</span> <span class="pl-smi">F</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">bool</span> <span class="pl-k">where</span> <span class="pl-smi">F</span><span class="pl-kos">:</span> <span class="pl-smi">Fn</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">bool</span> <span class="pl-kos">{</span>
        <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">method_bad</span><span class="pl-kos">(</span>|t| <span class="pl-en">f</span><span class="pl-kos">(</span>t<span class="pl-kos">)</span><span class="pl-kos">)</span>
    <span class="pl-kos">}</span>

    <span class="pl-k">fn</span> <span class="pl-en">method_bad2</span><span class="pl-kos">&lt;</span><span class="pl-smi">F</span><span class="pl-kos">&gt;</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span><span class="pl-smi">self</span><span class="pl-kos">,</span> <span class="pl-s1">f</span><span class="pl-kos">:</span> <span class="pl-smi">F</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">bool</span> <span class="pl-k">where</span> <span class="pl-smi">F</span><span class="pl-kos">:</span> <span class="pl-smi">Fn</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">bool</span> <span class="pl-kos">{</span>
        <span class="pl-k">let</span> f<span class="pl-kos">:</span> <span class="pl-c1">&amp;</span><span class="pl-smi">Fn</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">bool</span> = <span class="pl-c1">&amp;</span>f<span class="pl-kos">;</span>

        <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">method_bad2</span><span class="pl-kos">(</span>|t| f<span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-kos">(</span>t<span class="pl-kos">,</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">fn</span> <span class="pl-en">main</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-v">Struct</span><span class="pl-kos">.</span><span class="pl-en">method_ok</span><span class="pl-kos">(</span>|_| <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-c">// Pick one</span>
    <span class="pl-v">Struct</span><span class="pl-kos">.</span><span class="pl-en">method_bad</span><span class="pl-kos">(</span>|_| <span class="pl-c1">true</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-c">//Struct.method_bad2(|_| true);</span>
<span class="pl-kos">}</span></pre></div>
<h3 dir="auto">Output</h3>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="limit.rs:10:5: 12:6 error: reached the recursion limit during monomorphization
limit.rs:10     fn method_bad&lt;F&gt;(&amp;self, f: F) -&gt; bool where F: Fn(()) -&gt; bool {
limit.rs:11         self.method_bad(|t| f(t))
limit.rs:12     }"><pre class="notranslate">limit<span class="pl-kos">.</span><span class="pl-c1">rs</span><span class="pl-kos">:</span><span class="pl-c1">10</span><span class="pl-kos">:</span><span class="pl-c1">5</span><span class="pl-kos">:</span> <span class="pl-c1">12</span><span class="pl-kos">:</span><span class="pl-c1">6</span> error<span class="pl-kos">:</span> reached the recursion limit during monomorphization
limit<span class="pl-kos">.</span><span class="pl-c1">rs</span><span class="pl-kos">:</span><span class="pl-c1">10</span>     <span class="pl-k">fn</span> <span class="pl-en">method_bad</span><span class="pl-kos">&lt;</span><span class="pl-smi">F</span><span class="pl-kos">&gt;</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span><span class="pl-smi">self</span><span class="pl-kos">,</span> <span class="pl-s1">f</span><span class="pl-kos">:</span> <span class="pl-smi">F</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">bool</span> <span class="pl-k">where</span> <span class="pl-smi">F</span><span class="pl-kos">:</span> <span class="pl-smi">Fn</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span> -&gt; <span class="pl-smi">bool</span> <span class="pl-kos">{</span>
limit<span class="pl-kos">.</span><span class="pl-c1">rs</span><span class="pl-kos">:</span><span class="pl-c1">11</span>         <span class="pl-smi">self</span><span class="pl-kos">.</span><span class="pl-en">method_bad</span><span class="pl-kos">(</span>|t| <span class="pl-en">f</span><span class="pl-kos">(</span>t<span class="pl-kos">)</span><span class="pl-kos">)</span>
limit<span class="pl-kos">.</span><span class="pl-c1">rs</span><span class="pl-kos">:</span><span class="pl-c1">12</span>     <span class="pl-kos">}</span></pre></div>
<h3 dir="auto">Version</h3>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="rustc 0.13.0-dev (d9c7c00b9 2014-12-04 21:33:07 +0000)"><pre class="notranslate">rustc <span class="pl-c1">0.13</span><span class="pl-kos">.</span><span class="pl-c1">0</span>-<span class="pl-en">dev</span> <span class="pl-kos">(</span>d9c7c00b9 <span class="pl-c1">2014</span>-<span class="pl-c1">12</span>-<span class="pl-c1">04</span> <span class="pl-c1">21</span><span class="pl-kos">:</span><span class="pl-c1">33</span><span class="pl-kos">:</span><span class="pl-c1">07</span> +<span class="pl-c1">0000</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">cc <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/nikomatsakis/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/nikomatsakis">@nikomatsakis</a> (you already know, but I want to keep track of the issue)</p>