When I run the following code
class OwnedValue {
var value: Int
init(_ value: Int) {
self.value = value
}
}
struct ValueOwner {
let ownedValue1: OwnedValue
let ownedValue2: OwnedValue
}
func updateValue(owndedValue ownedValue: consuming OwnedValue, with newValue: Int) {
if isKnownUniquelyReferenced(&ownedValue) {
print("Value \(ownedValue.value) is unique")
} else {
print("Value \(ownedValue.value) is not unique")
}
ownedValue.value = newValue
}
func testOwnership() {
let valueOwner = ValueOwner(
ownedValue1: OwnedValue(10),
ownedValue2: OwnedValue(15))
let valueOwner2 = consumeValueOwner(valueOwner: consume valueOwner)
print("\(valueOwner2.ownedValue1.value), \(valueOwner2.ownedValue2.value)")
}
@discardableResult
func consumeValueOwner(valueOwner: consuming ValueOwner) -> ValueOwner {
let ownedValue1 = valueOwner.ownedValue1
let actualOwnedValue1 = ownedValue1.value
let ownedValue2 = valueOwner.ownedValue2
let actualOwnedValue2 = ownedValue2.value
_ = consume valueOwner
updateValue(owndedValue: ownedValue2, with: actualOwnedValue1 + 10)
updateValue(owndedValue: ownedValue1, with: actualOwnedValue2 + 10)
return ValueOwner(
ownedValue1: OwnedValue(actualOwnedValue1),
ownedValue2: OwnedValue(actualOwnedValue2))
}
testOwnership()
the output is
Value 15 is not unique
Value 10 is unique
If I reorder the last lines in testOwnership
the output becomes
Value 10 is not unique
Value 15 is unique
Now, after this line
_ = consume valueOwner
there should be only one reference for each one of the ownedValue
s. Yet, for some reason, a reference stays alive during first call.
Now replacing
updateValue(owndedValue: ownedValue2, with: actualOwnedValue1 + 10)
updateValue(owndedValue: ownedValue1, with: actualOwnedValue2 + 10)
with
updateValue(owndedValue: consume ownedValue2, with: actualOwnedValue1 + 10)
updateValue(owndedValue: consume ownedValue1, with: actualOwnedValue2 + 10)
does result in correct output. (it is enough to do it in the first line TBH)
Value 15 is unique
Value 10 is unique
Is it a bug or a feature?
It looks like a bug TBH.
It occurs in release mode.