<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="">Hi Kevin,<div class=""><br class=""></div><div class="">Thanks for your thoughts. In general, I think I’m going to put off thinking more about the more general extension-shadowing warning until the related proposal on swift-evolution is decided upon, as decisions made there will undoubtedly impact what will trigger this warning and how to resolve it.&nbsp;</div><div class=""><br class=""></div><div class="">I’ll continue to work on the more specialized warning Doug brought up.&nbsp;</div><div class=""><br class=""></div><div class="">A few more comments below for when if/when we circle back to this.</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 3, 2016, at 7:33 PM, Kevin Ballard &lt;<a href="mailto:kevin@sb.org" class="">kevin@sb.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">


<title class=""></title>

<div class=""><div class="">On Sun, Jan 3, 2016, at 09:30 AM, Jesse Rusak wrote:<br class=""></div>
<blockquote type="cite" class=""><div class=""><div class=""><div class=""><div class="">Some things from Kevin:<br class=""></div>
<div class="">&nbsp;</div>
<div class=""><blockquote type="cite" class="">But the warning that Jesse was talking about, the one that was discussed in the older threads, I think is completely different. If I declare a method on my type that matches a protocol extension method, it is <i class="">not</i>&nbsp;safe to assume I was trying to override the (non-overridable) method. It's very likely that I'm simply providing a specialization of the method that will be called by anyone who's working with my type directly (with the acknowledgement that working with the type generically won't call my type's version).<br class=""></blockquote></div>
<div class="">&nbsp;</div>
<div class="">Can I ask for examples of cases where you’d want to do this intentionally? In those cases, would moving such members (or the protocol conformance) to an extension be a hassle? The point about stored properties is one way this is awkward; are there others?<br class=""></div>
</div>
</div>
</div>
</blockquote><div class="">&nbsp;</div>
<div class="">The suggested way to suppress the warning wasn't for this warning. It was for the warning about trying to conform to a protocol but having a member that doesn't actually match the protocol requirements (e.g. having a CollectionType with a `func generate()` that returns a type that doesn't actually conform to `GeneratorType`).<br class=""></div>
<div class="">&nbsp;</div>
<div class="">The warning we're discussing here, of attempting to override a protocol extension method even though it's not a member of the protocol, can't work with this suppression mechanism unless the warning simply doesn't work at all for subclasses who inherit the protocol from their superclass. If you inherit the protocol declaration, then you can't possibly put the protocol conformance into its own extension because you're not declaring the conformance to begin with. </div></div></div></blockquote><div><br class=""></div><div>My intent was that you could move the conflicting member into an extension rather than the conformance in the case when the main class declaration conforms to a protocol or inherits it from its superclass. (Same proviso about stored properties, of course.)</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><div class="">Even if you ignore classes, the suppression mechanism doesn't really work for this warning anyway as it would suppress a lot of the cases that you actually want to warn about. I say that because it seems quite reasonable for people to declare things like `var last` in an extension on a type (which would trigger this suppression mechanism). This is doubly true for members declared with where clauses, because those are required to be in extensions (and can't declare protocol conformance). So e.g. if I say<br class=""></div>
<div class="">&nbsp;</div>
<div class="">struct MyCollection&lt;Base : CollectionType&gt; : CollectionType {<br class=""></div>
<div class="">&nbsp; &nbsp; // ...<br class=""></div>
<div class="">}<br class=""></div>
<div class="">&nbsp;</div>
<div class="">extension MyCollection where Base.Index : BidirectionalIndexType {<br class=""></div>
<div class="">&nbsp; &nbsp; var last: Generator.Element? {<br class=""></div>
<div class="">&nbsp; &nbsp; &nbsp; &nbsp; // ...<br class=""></div>
<div class="">&nbsp; &nbsp; }<br class=""></div>
<div class="">}<br class=""></div>
<div class="">&nbsp;</div>
<div class="">then, assuming you think the warning is valid to begin with, you'd want to warn about that `var last`.</div></div></div></blockquote><div><br class=""></div><div>Sure, we might miss that. I will add it to the “we should try to get this” pile.</div><div>&nbsp;</div><blockquote type="cite" class=""><div class="">
<blockquote type="cite" class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="">My belief is that a warning in this case would end up being unwanted in a disproportionate number of cases. I believe it's better to clearly differentiate between protocol methods and extension methods and how they behave in our documentation and education for programmers than to add spurious warnings that will annoy everyone who does understand the distinction.<br class=""></div>
</div>
</blockquote><div class="">&nbsp;</div>
<div class="">How often are you doing this intentionally in your code? If it’s frequent, we should see if there’s a way to suppress it for your common cases.&nbsp;<br class=""></div>
</div>
</div>
</div>
</blockquote><div class="">&nbsp;</div>
<div class="">I don't currently have any examples of this in my code. But I've also never had any cases where the warning would have triggered either. But the standard library provides examples of this!<br class=""></div>
<div class="">&nbsp;</div>
<div class="">SequenceType has an extension that declares a `var lazy`. LazySequence also declares `var lazy`. It's obviously not overriding SequenceType's `lazy` property (especially because the type is slightly different), but it is very intentionally trying to shadow it, to make it so anyone who types `foo.lazy.lazy` gets back a `LazySequence&lt;Foo&gt;` instead of a `LazySequence&lt;LazySequence&lt;Foo&gt;&gt;`.</div></div></blockquote><blockquote type="cite" class=""><div class=""><div class=""><br class=""></div>
<div class="">Same thing also happens with `SequenceType.flatMap` and `LazySequence.flatMap`.<br class=""></div>
<div class="">&nbsp;</div>
<div class="">CollectionType and LazyCollection is another example. At the very least the `lazy` property is an example. I'm not sure offhand if there's any other examples with those types but I wouldn't be surprised to find that there are.</div></div></blockquote><blockquote type="cite" class=""><br class=""></blockquote><blockquote type="cite" class=""><div class="">

<div class="">Set defines a method `contains(_ element:)` that's an exact match for the SequenceType extension method `contains(_ element:)`, but that's not actually an override. It also has `indexOf(_:)` which matches CollectionType's extension method `indexOf(_:)`.<br class=""></div>
<div class="">&nbsp;</div>
<div class="">There may be others, I didn't do an exhaustive search of the standard library. But these should illustrate legitimate use-cases for shadowing protocol extension methods.</div></div></blockquote><div><br class=""></div>Thanks for this! I will definitely be looking through the rest of the standard lib for other examples.</div><div class=""><br class=""></div></div><div class="">- Jesse</div></body></html>