<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">The issue I raised is when we truly replace the type in an existing function:<div class=""><br class=""></div><div class="">====</div><div class=""><br class=""></div><div class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">protocol Proto :class {}</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">class SingleImpl : Proto {}</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">class User {</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">&nbsp; func useProto(p: Proto) {}</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">}</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">If i understand you correctly your pass changes this program to:</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">class User {</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">&nbsp; func useProto(p: SingleImpl) {}</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">}</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">One way in which this could be iffy is that we mangle type information</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">as part of the function name. So if you did not implement this as a function</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">specialization but a true replacement the mangled name no longer</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">agrees with the actual type.</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">// User.useProto(p:)</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">sil hidden @_T03Foo4UserC8useProtoyAA0D0_</span><wbr style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">p1p_tF : $@convention(method)</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">(@owned Proto, @guaranteed User) -&gt; () {</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">$ swift-macosx-x86_64/bin/swift-</span><wbr style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">demangle _T03Foo4UserC8useProtoyAA0D0_</span><wbr style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">p1p_tF</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">_T03Foo4UserC8useProtoyAA0D0_</span><wbr style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">p1p_tF ---&gt; Foo.User.useProto(p: Foo.Proto) -&gt; ()</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><br class="">True replacement (note the class type in the signature):</div><div class=""><br class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">sil hidden @_T03Foo4UserC8useProtoyAA0D0_</span><wbr style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">p1p_tF : $@convention(method)</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">(@owned SingleImpl, @guaranteed User) -&gt; () {}</span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><span style="background-color: rgb(255, 255, 255);" class=""><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""></span><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">(Function specialization is different in that it actually creates a</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">different function, of course the original function is still there in</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">e.g the vtable which is not what you want)</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">You would have to make sure to update the mangled names in all places</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">... I am not sure of what problems that could entail, maybe none as</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">long as your type is internal. I would bring up this idea on swift</span><br style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px;" class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">dev.</span></div><div class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class=""><br class=""></span></div><div class=""><span style="color: rgb(34, 34, 34); font-family: arial, sans-serif; font-size: 12.800000190734863px; background-color: rgb(255, 255, 255);" class="">====</span></div><div class=""><div><br class=""></div><div>But, it seems you are actually doing function signature specialization which does not suffer the issue above.</div><div><br class=""></div><div>You will however still have the original function with the protocol in the v-table of User in my example.</div><div><br class=""></div><div>I don’t know how important getting rid of those is for you …</div><div><br class=""></div><div><blockquote type="cite" class=""><div class="">On Nov 29, 2017, at 11:30 AM, Raj Barik via swift-dev &lt;<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div style="font-size:12.8px" class=""><div class="">Hi,</div><div class=""><br class=""></div><div class="">I am thinking about writing a Protocol Devirtualizer Pass that specializes functions that take Protocols as arguments to transform them with concrete types instead of protocol types when the concrete types can be determined statically by some compiler analysis. This is the first step of the transformation that I am proposing. My goal is to extend this to eliminate the original function implementation and also to remove the corresponding protocol type (by deleting it from the witness table), if possible. For simple cases, where the protocol is only used for mocking for example and that there is just one class that conforms to it, we should be able to eliminate the protocol altogether. This is the second and final step of the transformation. Does anyone see any issues with both these steps? Arnold from Apple pointed out that there might be demangling issues when the protocol is eliminated. Any ideas on how to fix the demangling issues? Moreover, would such a pass be helpful to Swift folks?</div><div class=""><br class=""></div><div class=""><div style="font-size:12.8px" class=""><b class="">Original code:</b></div></div><div class=""><b class=""><br class=""></b></div><div class=""><br class=""></div><div class="">protocol SumProtocol: class {</div><div class="">&nbsp; func increment(i:Int)&nbsp; -&gt; Int</div><div class="">}</div><div class=""><br class=""></div><div class="">internal class SumClass: SumProtocol {</div><div class="">&nbsp; var a:Int</div><div class="">&nbsp; init(base:Int) {</div><div class="">&nbsp; &nbsp; self.a = base</div><div class="">&nbsp; }</div><div class="">&nbsp; func increment(i:Int) -&gt; Int {</div><div class="">&nbsp; &nbsp;self.a += i</div><div class="">&nbsp; &nbsp;return self.a</div><div class="">&nbsp; }</div><div class="">}</div><div class=""><br class=""></div><div class="">@inline(never) internal func wrap_inc(a:SumProtocol, val:Int) -&gt; Int{</div><div class="">&nbsp;return a.increment(i:val)</div><div class="">}</div><div class=""><br class=""></div><div class="">internal let magic:SumProtocol = SumClass(base:10)</div><div class="">print("c=\(wrap_inc(a:magic,<wbr class="">val:10))")</div></div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class=""><b class="">After Step 1:</b></div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class=""><div class="">protocol SumProtocol: class {</div><div class="">&nbsp; func increment(i:Int)&nbsp; -&gt; Int</div><div class="">}</div><div class=""><br class=""></div><div class="">internal class SumClass: SumProtocol {</div><div class="">&nbsp; var a:Int</div><div class="">&nbsp; init(base:Int) {</div><div class="">&nbsp; &nbsp; self.a = base</div><div class="">&nbsp; }</div><div class="">&nbsp; func increment(i:Int) -&gt; Int {</div><div class="">&nbsp; &nbsp;self.a += i</div><div class="">&nbsp; &nbsp;return self.a</div><div class="">&nbsp; }</div><div class="">}</div><div class=""><br class=""></div><div class=""><div style="font-size:12.8px" class="">@inline(never) internal func wrap_inc(a:SumProtocol, val:Int) -&gt; Int{</div><div style="font-size:12.8px" class="">&nbsp;return a.increment(i:val)</div><div style="font-size:12.8px" class="">}</div></div><div class=""><br class=""></div><div class="">@inline(never) internal func wrap_inc_1(a:SumClass, val:Int) -&gt; Int{</div><div class="">&nbsp;return a.increment(i:val)</div><div class="">}</div><div class=""><br class=""></div><div class="">internal let magic:SumClass = SumClass(base:10)</div><div class="">print("c=\(wrap_inc_1(a:magic,<wbr class="">val:10))")</div></div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class=""><div class=""><b class="">After Step 2:</b></div><div class=""><b class=""><br class=""></b></div><div class=""><div class="">internal class SumClass {</div><div class="">&nbsp; var a:Int</div><div class="">&nbsp; init(base:Int) {</div><div class="">&nbsp; &nbsp; self.a = base</div><div class="">&nbsp; }</div><div class="">&nbsp; func increment(i:Int) -&gt; Int {</div><div class="">&nbsp; &nbsp;self.a += i</div><div class="">&nbsp; &nbsp;return self.a</div><div class="">&nbsp; }</div><div class="">}</div><div class=""><br class=""></div><div class="">@inline(never)&nbsp;<span style="font-size:12.8px" class="">internal&nbsp;</span><span style="font-size:12.8px" class="">func wrap_inc(a:SumClass, val:Int) -&gt; Int{</span></div><div class="">&nbsp;return a.increment(i:val)</div><div class="">}</div><div class=""><br class=""></div><div class="">internal let magic:SumClass = SumClass(base:10)</div><div class="">print("c=\(wrap_inc(a:magic,<wbr class="">val:10))")</div></div></div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class="">Any comments/thought on this transformation?</div><div style="font-size:12.8px" class=""><br class=""></div><div style="font-size:12.8px" class="">Best,</div><div style="font-size:12.8px" class="">Raj&nbsp;</div></div>
_______________________________________________<br class="">swift-dev mailing list<br class=""><a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-dev<br class=""></div></blockquote></div><br class=""></div></body></html>