<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 30, 2017, at 5:11 AM, David Hart via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On 28 Jul 2017, at 18:55, Joe Groff &lt;<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Jul 28, 2017, at 12:06 AM, David Hart via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Hello,<div class=""><br class=""></div><div class="">Indeed, I had reduced the code too much. John McCall was kind enough to have a look and here’s the offending code:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">func&nbsp;layoutHorizontally(leftRect:&nbsp;inout&nbsp;CGRect, rightRect:&nbsp;inout&nbsp;CGRect) {<br class="">&nbsp; &nbsp; let&nbsp;totalWidth =&nbsp;imageRect.size.width&nbsp;+&nbsp;titleRect.size.width&nbsp;+&nbsp;contentSpacing<br class="">&nbsp; &nbsp; rightRect.origin.x&nbsp;= leftRect.maxX&nbsp;+&nbsp;contentSpacing<br class="">}</font></div><div class=""><br class=""></div><div class="">The problem is that<span class="Apple-converted-space">&nbsp;</span><font face="Menlo" class="">imageRect</font><span class="Apple-converted-space">&nbsp;</span>and<span class="Apple-converted-space">&nbsp;</span><font face="Menlo" class="">titleRect</font><span class="Apple-converted-space">&nbsp;</span>are referenced both directly and in the inout parameters.</div><div class=""><br class=""></div><div class="">But there’s something I’m not understanding. I went back to the ownership manifesto and re-read the law of exclusivity to make sure I understand it:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><i class="">If a storage reference expression evaluates to a storage reference that is implemented by a variable, then the formal access duration of&nbsp;that access may not overlap the formal access duration of any other access to the same variable unless both accesses are reads.</i></div></blockquote><div class=""><br class=""></div><div class="">So I tried to write a test to trigger the runtime error, but was unsuccessful:</div><div class=""><br class=""></div><font face="Menlo" class="">class&nbsp;MyClass {<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;p:&nbsp;CGRect&nbsp;= .zero<br class="">}<br class=""><br class="">func&nbsp;trigger(a:&nbsp;MyClass, b:&nbsp;MyClass) {<br class="">&nbsp; &nbsp;&nbsp;a.p = b.p<br class="">}<br class=""><br class="">let&nbsp;m =&nbsp;MyClass()<br class=""></font><div class=""><font face="Menlo" class="">trigger(a: m, b: m)</font></div><div class=""><br class=""></div><div class="">Here, a storage reference expression (a.p) evaluates to a storage reference that is implemented by a variable (the p property of an instance m of MyClass) and its formal access duration (the trigger function) overlaps the formal access duration of another access to the same variable (through the b.p storage reference expression) and both accesses are not reads (a.p is on the LHS of an assignment).</div><div class=""><br class=""></div><div class="">Why does this not trigger the Law of Exclusivity?</div></div></div></blockquote><br class=""></div><div class="" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">`b.p` is loaded before `a.p` is written to, so the accesses do not overlap even when a === b. Something like swap(&amp;a.p, &amp;b.p) (using the Swift 3 global definition of 'swap') would trigger an exclusivity trap when a === b, since the access to storage passed as an inout argument needs to last for the duration of the call.</div></div></blockquote><div class=""><br class=""></div><div class="">Thanks for the explanation! It’s starting to make sense :) Is it possible to trigger the exclusivity trap without an inout argument?</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">-Joe</div></div></blockquote></div></div></blockquote></div><div class=""><br class=""></div>Users are probably more likely to run into problems with mutating methods, which are implicitly `inout`:&nbsp;<br class=""><div class=""><br class=""></div><div class=""><div class="">struct S {</div><div class="">&nbsp; var x = 1</div><div class=""><br class=""></div><div class="">&nbsp; mutating func updateX(_ getOtherS: ()-&gt;S) {</div><div class="">&nbsp; &nbsp; x += getOtherS().x</div><div class="">&nbsp; }</div><div class="">}</div><div class=""><br class=""></div><div class="">class C {</div><div class="">&nbsp; var s = S()</div><div class="">}</div><div class=""><br class=""></div><div class="">let c = C()</div><div class="">c.s.updateX( { c.s } )</div></div><div class=""><br class=""></div><div class="">-Andy</div></body></html>