<div dir="ltr">i support this™<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 25, 2017 at 6:41 AM, David Hart via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">I got bit again by a sneaky memory leak concerning local functions and would like to discuss a small language change. I vaguely remember this being discussed in the past, but can’t find the thread (if anybody could point me to it, I’d appreciate it). Basically, here’s an example of the leak:<div><br></div><div><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;word-wrap:normal;padding:16px;overflow:auto;line-height:1.45;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;color:rgb(36,41,46)"><span class="m_-4024258538432358349pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">class</span> <span class="m_-4024258538432358349pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">A</span> {
    <span class="m_-4024258538432358349pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-4024258538432358349pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">foo</span>() {
        <span class="m_-4024258538432358349pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-4024258538432358349pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">local</span>() {
            <span class="m_-4024258538432358349pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">bar</span>()
        }
    
        methodWithEscapingClosure { [<span class="m_-4024258538432358349pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">unowned</span> <span class="m_-4024258538432358349pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">self</span>] <span class="m_-4024258538432358349pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">_</span> <span class="m_-4024258538432358349pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">in</span>
            <span class="m_-4024258538432358349pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">self</span>.<span class="m_-4024258538432358349pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">bar</span>()
            <span class="m_-4024258538432358349pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">local</span>() <span class="m_-4024258538432358349pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="m_-4024258538432358349pl-c" style="box-sizing:border-box">//</span> this leaks because local captures self</span>
<span class="m_-4024258538432358349pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"></span>        }
    }
    
    <span class="m_-4024258538432358349pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-4024258538432358349pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">bar</span>() {
    }
}</pre><div><br></div></div><div>Its sneaky because local’s capturing of self is not obvious if you’ve trained your brain to watch out for calls prefixed with self. I would suggest having the compiler force users to make self capturing explicit, the same way it does for closures:</div><div><br></div><div><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;word-wrap:normal;padding:16px;overflow:auto;line-height:1.45;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;color:rgb(36,41,46)"><span class="m_-4024258538432358349pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">class</span> <span class="m_-4024258538432358349pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">A</span> {
    <span class="m_-4024258538432358349pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-4024258538432358349pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">foo</span>() {
        <span class="m_-4024258538432358349pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-4024258538432358349pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">local</span>() {
            <span class="m_-4024258538432358349pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">bar</span>() // error: Call to method ‘bar&#39; in function ‘local&#39; requires explicit &#39;self.&#39; to make capture semantics explicit
        }
    
<span class="m_-4024258538432358349Apple-tab-span" style="white-space:pre-wrap">        </span>// ...
    }
}</pre><div><br></div></div><div>What do you think?</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>David.</div><div><br></div></font></span></div><br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br></blockquote></div><br></div>