From the proposal draft, I get the idea that forming multiple borrow
or inout
bindings to members of the same struct
value is prohibited if at least one of the bindings is inout
:
struct T { var a: A; var b: B; var c: (A, B) }
var t: T
do { // Legal: multiple borrows
borrow a = t.a
borrow b = t.b
borrow b2 = t.b
}
do { // Illegal: inout and borrow of one property
inout a = &t.a
borrow a2 = t.a // 🛑 Exclusivity violation
}
do { // Illegal: borrow and inout of one property
borrow a = t.a
inout a2 = &t.a // 🛑 Exclusivity violation
}
do { // Illegal: inout and inout of one property
inout a = &t.a
inout a2 = &t.a // 🛑 Exclusivity violation
}
Is that right? How about tuples?
do {
inout (ca, cb) = &t.c
}
Is there any way to allow temporarily splitting the value into multiple distinct inout
parts without any of the examples below being an exclusivity violation? With some new syntax, if need be?
do { // Could this be allowed?
borrow a = t.a
inout b = &t.b // ✅❔
}
do { // And this?
inout a = &t.a
inout b = &t.b // ✅❔
}
Sometimes I wish there was a way to pluck multiple properties of a value into a tuple value with a syntax something like t.(.a, .b, .c.0)
for a tuple of type (A, B, A)
or t.c.(ca: .0, cb: .1)
for the tuple type with labels (ca: A, ca: B)
. Maybe something like that could be used to pluck out multiple inout bindings at once without an exclusivity violation, as long as the members are distinct in memory?
do { // Future direction?
inout (a, b, ca) = &t.(.a, .b, .c.a)
}