<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 26, 2016, at 5:18 PM, Douglas Gregor via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><h1 style="box-sizing: border-box; margin-right: 0px; margin-bottom: 16px; margin-left: 0px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(238, 238, 238); color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255); margin-top: 0px !important;" class="">Conditional conformances</h1><h3 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; font-size: 1.25em; line-height: 1.25; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-disallow-overlapping-conformances" class="anchor" href="https://github.com/DougGregor/swift-evolution/tree/conditional-conformances#disallow-overlapping-conformances" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none; float: left; padding-right: 4px; margin-left: -20px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Disallow overlapping conformances</h3><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">With conditional conformances, it is possible to express that a given generic type can conform to the same protocol in two different ways, depending on the capabilities of its type arguments. For example:</p><div class="">…</div></div></div></blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Note that, for an arbitrary type <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">T</code>, there are four potential answers to the question of whether <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">SomeWrapper<T></code> conforms to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Equatable</code>:</p><ol style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box;" class="">No, it does not conform because <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">T</code> is neither <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Equatable</code> nor <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">HasIdentity</code>.</li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Yes, it conforms via the first extension of <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">SomeWrapper</code> because <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">T</code> conforms to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Equatable</code>.</li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Yes, it conforms via the second extension of <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">SomeWrapper</code> because <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">T</code> conforms to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">HasIdentity</code>.</li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">Ambiguity, because <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">T</code> conforms to both <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">Equatable</code> and <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">HasIdentity</code>.</li></ol><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">It is due to the possibility of #4 occurring that we refer to the two conditional conformances in the example as <em style="box-sizing: border-box;" class="">overlapping</em>. There are designs that would allow one to address the ambiguity</p><div class="">…</div></div></div></blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class=""><span style="color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">For these reasons, this proposal </span><em class="" style="color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255); box-sizing: border-box;">bans overlapping conformances</em><span style="color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""> entirely. </span><br class=""></blockquote><div><br class=""></div><div>What other designs were considered and rejected? It seems like some kind of escape hatch would be preferred if you happen to get into this situation, though you make some really good points about the pitfalls.</div><div><br class=""></div><div>Just to clarify when you say “bans” do you mean if Wrapped: Equatable & HasIdentity then SomeWrapper is not Equatable, or do you mean you get a compile error because there are two constrained conformances SomeWrapper: Equatable? What would be the problem with allowing multiple conformances to Equatable so long as the constraints are disjoint or the concrete type only adopts one of the available protocols?</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><h3 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; font-size: 1.25em; line-height: 1.25; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-implied-conditional-conformances" class="anchor" href="https://github.com/DougGregor/swift-evolution/tree/conditional-conformances#implied-conditional-conformances" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; -webkit-text-decoration-skip: objects; color: rgb(64, 120, 192); text-decoration: none; float: left; padding-right: 4px; margin-left: -20px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Implied conditional conformances</h3><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Stating conformance to a protocol implicitly states conformances to any of the protocols that it inherits. This is the case in Swift today, although most developers likely don't realize the rules it follows. For example:</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">protocol</span> P { }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">protocol</span> Q <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> P { }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">protocol</span> R <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> P { }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">struct</span> X1 { }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">struct</span> X2 { }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">struct</span> X3 { }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">extension</span> X1: Q { } <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// implies conformance to P</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">extension</span> X2: Q { } <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// would imply conformance to P, but...</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">extension</span> X2: P { } <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// explicitly-stated conformance to P "wins"</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">extension</span> X3: Q { } <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// implies conformance to P</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">extension</span> X3: R { } <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// also implies conformance to P</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// one will "win"; which is unspecified</span></pre></div></div></blockquote><div>On X2 you’re declaring a redundant conformance to P but any protocol extensions will prefer Q and the compiler won’t let you redefine any members so you’ll have an incomplete conformance. Any explicit conformances (on the type or in extensions) are preferred over the defaults from the protocol extension, but that’s not new. I must be missing something, how would this be visible in Swift 3?</div><div><br class=""></div><div>On X3, multiple implementations in protocol extensions are errors today and the resolution is to provide an explicit implementation on X3.</div><div><br class=""></div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">With conditional conformances, the question of which extension "wins" the implied conformance begins to matter, because the extensions might have different constraints on them. For example:</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">struct</span> X4<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>T<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span> { }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">extension</span> X4: Q <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">where</span> T: Q { } <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// implies conformance to P</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">extension</span> X4: R <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">where</span> T: R { } <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// error: implies overlapping conformance to P</span></pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Both of these constrained extensions imply a conformance to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">P</code>, but the actual <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">P</code> implied conformances to <code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; padding: 0.2em 0px; margin: 0px; background-color: rgba(0, 0, 0, 0.0392157); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class="">P</code> are overlapping and, therefore, result in an error.</p></div></div></blockquote><div>If the related P conformance were inherited from conformance to Q or R then the rules would (IMHO) make more sense. Wouldn’t the extra rule you need simply be that either Q or R must provide a complete conformance to P (no mix-n-match)? </div><div><br class=""></div><div>If T implements Q & P why not just ignore T: P which means the X4: R extension is no longer relevant. </div><div><br class=""></div><div>It seems like the tricky case is T: P and the same question applies - why not just ignore the extensions (X4<T> in that scenario doesn’t implement Q, R, or P). </div><div><br class=""></div><div><br class=""></div><div>Not allowing ambiguity seems like it solves the “which one” problem and requiring an extension to provide the entire implementation (no mix-n-match) cuts down on the cleverness problem.</div><div><br class=""></div><div><br class=""></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">However, in cases where there is a reasonable ordering between the two constrained extensions (i.e., one is more specialized than the other), the less specialized constrained extension should "win" the implied conformance. Continuing the example from above:</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);"><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">protocol</span> S: R { }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">struct</span> X5<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>T<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span> { }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">extension</span> X5: R <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">where</span> T: R { } <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// "wins" implied conformance to P, because</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">extension</span> X5: S <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">where</span> T: S { } <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// the extension where "T: S" is more specialized</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);">// than the one where "T: R"</span></pre></div><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Thus, the rule for placing implied conformances is to pick the <em style="box-sizing: border-box;" class="">least specialized</em> extension that implies the conformance. If there is more than one such extension, then either:</p><ol style="box-sizing: border-box; padding-left: 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box;" class="">All such extensions are not constrained extensions (i.e., they have no requirements beyond what the type requires), in which case Swift can continue to choose arbitrarily among the extensions, or</li><li style="box-sizing: border-box; margin-top: 0.25em;" class="">All such extensions are constrained extensions, in which case the program is ill-formed due to the ambiguity. The developer can explicitly specify conformance to the protocol to disambiguate. </li></ol></div></div></blockquote><div>What is the rationale for picking the least specialized extension? That’s not what I would naively expect to happen. If T: R & S then I would expect the more specialized S:R implementation to be preferred, and the explicit R implementation to kick in when T: R. </div><div><br class=""></div><div><br class=""></div><div><br class=""></div><div>(Some of these may just be naive questions resulting from my misunderstanding)</div><div><br class=""></div><div>Russ</div><div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></div><br class=""></div><br class=""></div></body></html>