<p dir="auto">This is a vague bug but here is my intention:</p>
<ol dir="auto">
<li>Look at common bugs (returning a closure, etc) and see if we can improve the error messages for those</li>
<li>Try to improve the heuristics that suggest how to report a region inference failure, which frequently give nonsense results</li>
</ol>
<p dir="auto"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/jimtla/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/jimtla">@jimtla</a> pasted his code he was working with on IRC and I simplified it a bit:</p>
<div class="highlight highlight-source-rust notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#[derive(Clone)]
struct A (B);

impl A {
    pub fn matches&lt;F: Fn()&gt;(&amp;self, f: &amp;F) {
        let &amp;A(ref term) = self;
        term.matches(f);
    }
}

#[derive(Clone)]
enum B {
    Variant1,
    Variant2(C),
}

impl B {
    pub fn matches&lt;F: Fn()&gt;(&amp;self, f: &amp;F) {
        match self {
            &amp;B::Variant2(ref factor) =&gt; {
                factor.matches(&amp;|| ())
            }
            _ =&gt; unreachable!(&quot;&quot;)
        }
    }
}

#[derive(Clone)]
struct C (D);

impl C {
    pub fn matches&lt;F: Fn()&gt;(&amp;self, f: &amp;F) {
        let &amp;C(ref base) = self;
        base.matches(&amp;|| {
            C(base.clone()).matches(f)
        })
    }
}

#[derive(Clone)]
struct D (Box&lt;A&gt;);

impl D {
    pub fn matches&lt;F: Fn()&gt;(&amp;self, f: &amp;F) {
        let &amp;D(ref a) = self;
        a.matches(f)
    }
}

pub fn matches() {
    A(B::Variant1).matches(&amp;(|| ()))
}

fn main() {}"><pre class="notranslate"><span class="pl-c1">#<span class="pl-kos">[</span>derive<span class="pl-kos">(</span><span class="pl-v">Clone</span><span class="pl-kos">)</span><span class="pl-kos">]</span></span>
<span class="pl-k">struct</span> <span class="pl-smi">A</span> <span class="pl-kos">(</span><span class="pl-smi">B</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">impl</span> <span class="pl-smi">A</span> <span class="pl-kos">{</span>
    <span class="pl-k">pub</span> <span class="pl-k">fn</span> <span class="pl-en">matches</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><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-c1">&amp;</span><span class="pl-smi">F</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">let</span> <span class="pl-c1">&amp;</span><span class="pl-v">A</span><span class="pl-kos">(</span><span class="pl-k">ref</span> term<span class="pl-kos">)</span> = <span class="pl-smi">self</span><span class="pl-kos">;</span>
        term<span class="pl-kos">.</span><span class="pl-en">matches</span><span class="pl-kos">(</span>f<span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-c1">#<span class="pl-kos">[</span>derive<span class="pl-kos">(</span><span class="pl-v">Clone</span><span class="pl-kos">)</span><span class="pl-kos">]</span></span>
<span class="pl-k">enum</span> <span class="pl-smi">B</span> <span class="pl-kos">{</span>
    <span class="pl-v">Variant1</span><span class="pl-kos">,</span>
    <span class="pl-v">Variant2</span><span class="pl-kos">(</span><span class="pl-smi">C</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
<span class="pl-kos">}</span>

<span class="pl-k">impl</span> <span class="pl-smi">B</span> <span class="pl-kos">{</span>
    <span class="pl-k">pub</span> <span class="pl-k">fn</span> <span class="pl-en">matches</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><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-c1">&amp;</span><span class="pl-smi">F</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">match</span> <span class="pl-smi">self</span> <span class="pl-kos">{</span>
            <span class="pl-c1">&amp;</span><span class="pl-smi">B</span><span class="pl-kos">::</span><span class="pl-v">Variant2</span><span class="pl-kos">(</span><span class="pl-k">ref</span> factor<span class="pl-kos">)</span> =&gt; <span class="pl-kos">{</span>
                factor<span class="pl-kos">.</span><span class="pl-en">matches</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</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-en">unreachable</span><span class="pl-en">!</span><span class="pl-kos">(</span><span class="pl-s">""</span><span class="pl-kos">)</span>
        <span class="pl-kos">}</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-c1">#<span class="pl-kos">[</span>derive<span class="pl-kos">(</span><span class="pl-v">Clone</span><span class="pl-kos">)</span><span class="pl-kos">]</span></span>
<span class="pl-k">struct</span> <span class="pl-smi">C</span> <span class="pl-kos">(</span><span class="pl-smi">D</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">impl</span> <span class="pl-smi">C</span> <span class="pl-kos">{</span>
    <span class="pl-k">pub</span> <span class="pl-k">fn</span> <span class="pl-en">matches</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><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-c1">&amp;</span><span class="pl-smi">F</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">let</span> <span class="pl-c1">&amp;</span><span class="pl-v">C</span><span class="pl-kos">(</span><span class="pl-k">ref</span> base<span class="pl-kos">)</span> = <span class="pl-smi">self</span><span class="pl-kos">;</span>
        base<span class="pl-kos">.</span><span class="pl-en">matches</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</span>|| <span class="pl-kos">{</span>
            <span class="pl-v">C</span><span class="pl-kos">(</span>base<span class="pl-kos">.</span><span class="pl-en">clone</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">matches</span><span class="pl-kos">(</span>f<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-c1">#<span class="pl-kos">[</span>derive<span class="pl-kos">(</span><span class="pl-v">Clone</span><span class="pl-kos">)</span><span class="pl-kos">]</span></span>
<span class="pl-k">struct</span> <span class="pl-smi">D</span> <span class="pl-kos">(</span><span class="pl-smi">Box</span><span class="pl-kos">&lt;</span><span class="pl-smi">A</span><span class="pl-kos">&gt;</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">impl</span> <span class="pl-smi">D</span> <span class="pl-kos">{</span>
    <span class="pl-k">pub</span> <span class="pl-k">fn</span> <span class="pl-en">matches</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><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-c1">&amp;</span><span class="pl-smi">F</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-k">let</span> <span class="pl-c1">&amp;</span><span class="pl-v">D</span><span class="pl-kos">(</span><span class="pl-k">ref</span> a<span class="pl-kos">)</span> = <span class="pl-smi">self</span><span class="pl-kos">;</span>
        a<span class="pl-kos">.</span><span class="pl-en">matches</span><span class="pl-kos">(</span>f<span class="pl-kos">)</span>
    <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">pub</span> <span class="pl-k">fn</span> <span class="pl-en">matches</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-v">A</span><span class="pl-kos">(</span><span class="pl-smi">B</span><span class="pl-kos">::</span><span class="pl-v">Variant1</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">matches</span><span class="pl-kos">(</span><span class="pl-c1">&amp;</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-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-kos">}</span></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/t/m/h/src (master|…) $ rustc lib.rs
lib.rs:18:36: 18:37 warning: unused variable: `f`, #[warn(unused_variables)] on by default
lib.rs:18     pub fn matches&lt;F: Fn()&gt;(&amp;self, f: &amp;F) {
                                             ^

thread 'rustc' has overflowed its stack
fish: Job 1, 'rustc lib.rs ' terminated by signal SIGILL (Illegal instruction)"><pre class="notranslate"><code class="notranslate">/t/m/h/src (master|…) $ rustc lib.rs
lib.rs:18:36: 18:37 warning: unused variable: `f`, #[warn(unused_variables)] on by default
lib.rs:18     pub fn matches&lt;F: Fn()&gt;(&amp;self, f: &amp;F) {
                                             ^

thread 'rustc' has overflowed its stack
fish: Job 1, 'rustc lib.rs ' terminated by signal SIGILL (Illegal instruction)
</code></pre></div>
<p dir="auto">This might be a duplicate of <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="54847405" data-permission-text="Title is private" data-url="https://github.com/rust-lang/rust/issues/21410" data-hovercard-type="issue" data-hovercard-url="/rust-lang/rust/issues/21410/hovercard" href="https://github.com/rust-lang/rust/issues/21410">#21410</a></p>