> On Jul 30, 2017, at 5:11 AM, David Hart via swift-users
> <swift-users@swift.org> wrote:
>
>>
>> On 28 Jul 2017, at 18:55, Joe Groff <jgr...@apple.com
>> <mailto:jgr...@apple.com>> wrote:
>>
>>>
>>> On Jul 28, 2017, at 12:06 AM, David Hart via swift-users
>>> <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
>>>
>>> Hello,
>>>
>>> Indeed, I had reduced the code too much. John McCall was kind enough to
>>> have a look and here’s the offending code:
>>>
>>> func layoutHorizontally(leftRect: inout CGRect, rightRect: inout CGRect) {
>>> let totalWidth = imageRect.size.width + titleRect.size.width +
>>> contentSpacing
>>> rightRect.origin.x = leftRect.maxX + contentSpacing
>>> }
>>>
>>> The problem is that imageRect and titleRect are referenced both directly
>>> and in the inout parameters.
>>>
>>> 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:
>>>
>>> If a storage reference expression evaluates to a storage reference that is
>>> implemented by a variable, then the formal access duration of that access
>>> may not overlap the formal access duration of any other access to the same
>>> variable unless both accesses are reads.
>>>
>>> So I tried to write a test to trigger the runtime error, but was
>>> unsuccessful:
>>>
>>> class MyClass {
>>> var p: CGRect = .zero
>>> }
>>>
>>> func trigger(a: MyClass, b: MyClass) {
>>> a.p = b.p
>>> }
>>>
>>> let m = MyClass()
>>> trigger(a: m, b: m)
>>>
>>> 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).
>>>
>>> Why does this not trigger the Law of Exclusivity?
>>
>> `b.p` is loaded before `a.p` is written to, so the accesses do not overlap
>> even when a === b. Something like swap(&a.p, &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.
>
> Thanks for the explanation! It’s starting to make sense :) Is it possible to
> trigger the exclusivity trap without an inout argument?
>
>> -Joe
Users are probably more likely to run into problems with mutating methods,
which are implicitly `inout`:
struct S {
var x = 1
mutating func updateX(_ getOtherS: ()->S) {
x += getOtherS().x
}
}
class C {
var s = S()
}
let c = C()
c.s.updateX( { c.s } )
-Andy
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users