<div dir="ltr">FWIW, there *is* a way to instantiate #4 case.<div><br><font face="monospace, monospace">class First {<br>    let item: First<br>    init(item: First) {<br>        self.item = item<br>    }<br>}<br><br>class Second : First {<br>    init() {<br>        super.init(item: self)<br>    }<br>}<br></font><br><br>let a: First = Second()<br><div class="gmail_extra"><br><div class="gmail_quote">2017-03-13 22:38 GMT+09:00 Dimitri Racordon via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span>:<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">
Hello swift-evolution,
<div><br>
</div>
<div>I noticed there’s some inconsistencies with recursive types and how the compiler handles them. Consider the following cases:</div>
<div><br>
</div>
<div><br>
</div>
<div><b>1. <span style="font-family:Menlo;font-size:11px;font-variant-ligatures:no-common-ligatures"><span style="font-family:Helvetica;font-size:12px">Swift is right to refuse compiling this, since there’s no way
 to initialise an instance of `</span>First<span style="font-family:Helvetica;font-size:12px"> `:</span></span></b></div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">struct</span><span style="font-variant-ligatures:no-common-ligatures"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">    <span style="color:rgb(186,45,162);font-variant-ligatures:no-common-ligatures">let</span><span style="font-variant-ligatures:no-common-ligatures"> </span>item: </span>First</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">}</span></div>
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<div style="margin:0px;line-height:normal;color:rgb(0,132,0)"><span style="font-variant-ligatures:no-common-ligatures">// Error: Value type &#39;First&#39; cannot have a stored property that references itself</span></div>
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<br>
</div>
<div style="margin:0px;line-height:normal">However, the message suggests more a compiler limitation rather than the actual impossibility to initialize the declared type.</div>
<div style="margin:0px;line-height:normal"><br>
</div>
<div style="margin:0px;line-height:normal"><br>
</div>
<div style="margin:0px;line-height:normal"><b>2. Swift is also right not to compile this, but the error messages are even less insightful:</b></div>
<div style="margin:0px;line-height:normal"><br>
</div>
<div style="margin:0px;line-height:normal">
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">struct</span><span style="font-variant-ligatures:no-common-ligatures"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">let</span><span style="font-variant-ligatures:no-common-ligatures"> item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">Second</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">}</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures"><span style="color:rgb(0,132,0)">// Error: Value type &#39;First&#39; cannot have a stored property that references itself</span></span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures"><br>
</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">
<span style="font-variant-ligatures:no-common-ligatures"></span><br>
</div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">struct</span><span style="font-variant-ligatures:no-common-ligatures"> Second {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">let</span><span style="font-variant-ligatures:no-common-ligatures"> item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">First</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">}</span></div>
<div style="margin:0px;line-height:normal"><span style="font-variant-ligatures:no-common-ligatures"><font color="#008400" face="Menlo"><span style="font-size:11px">// Error: Value type </span></font><span style="color:rgb(0,132,0);font-family:Menlo;font-size:11px">&#39;</span><font color="#008400" face="Menlo"><span style="font-size:11px">Second&#39;
 cannot have a stored property that references itself</span></font></span></div>
<div><span style="font-variant-ligatures:no-common-ligatures"><br>
</span></div>
</div>
<div style="margin:0px;line-height:normal">The problem isn’t that the value types reference
<i>themselves</i>. Instead, the problem is that there’s a cyclic dependency between `First` and `Second` that makes it impossible for neither of these structures to be instantiated.</div>
<div style="margin:0px;line-height:normal"><br>
</div>
<div style="margin:0px;line-height:normal"><br>
</div>
<div style="margin:0px;line-height:normal"><b>3. Swift should let me do that:</b></div>
<div style="margin:0px;line-height:normal"><br>
</div>
<div style="margin:0px;line-height:normal">
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">struct</span><span style="font-variant-ligatures:no-common-ligatures"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">let</span><span style="font-variant-ligatures:no-common-ligatures"> item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">First</span><span style="font-variant-ligatures:no-common-ligatures">?</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">}</span></div>
<div><span style="font-variant-ligatures:no-common-ligatures"><br>
</span></div>
<div>The compiler prevents me to declare the above struct, even if there actually is a way to initialise an instance of `First` (e.g. `First(item: nil)`). The message is identical to that of case #1 (maybe it actually
<i>is</i> a compiler limitation after all?)</div>
<div><br>
</div>
<div><br>
</div>
<div><b>4. Swift shouldn’t compile this:</b></div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">class</span><span style="font-variant-ligatures:no-common-ligatures"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">let</span><span style="font-variant-ligatures:no-common-ligatures"> item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">First</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">init</span><span style="font-variant-ligatures:no-common-ligatures">(item:
</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">First</span><span style="font-variant-ligatures:no-common-ligatures">) {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">        </span>
<span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">self</span><span style="font-variant-ligatures:no-common-ligatures">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">item</span><span style="font-variant-ligatures:no-common-ligatures">
 = item</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">    }</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">}</span></div>
</div>
<div><span style="font-variant-ligatures:no-common-ligatures"><br>
</span></div>
<div>Like in case #1, there’s no way to instantiate `First`. The fact that it’s a reference rather than a value doesn’t change the problem.</div>
<div><br>
</div>
<div><br>
</div>
<div><b>5. Similarly to case #4, Swift shouldn’t compile this:</b></div>
<div><br>
</div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(186,45,162)">
<span style="font-variant-ligatures:no-common-ligatures">indirect</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000">
</span><span style="font-variant-ligatures:no-common-ligatures">enum</span><span style="font-variant-ligatures:no-common-ligatures;color:#000000"> First {</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">    </span><span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2">case</span><span style="font-variant-ligatures:no-common-ligatures"> item(</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187">First</span><span style="font-variant-ligatures:no-common-ligatures">)</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
<span style="font-variant-ligatures:no-common-ligatures">}</span></div>
</div>
<div><span style="font-variant-ligatures:no-common-ligatures"><br>
</span></div>
<div><br>
</div>
<div><b>6. Cases #4 #5 could be written like case #2, and should also raise compilation errors.</b></div>
<div><br>
</div>
<div><br>
</div>
<div>Does someone know if these issues have already been discussed and/or addressed?</div>
<div><br>
</div>
<div>Thanks,</div>
<div>Dimitri Racordon</div>
<div><br>
</div>
</div>
</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></div></div>