Hi SIL experts,
The begin_access doc says:
The operand must be a root address derivation:
a function argument,
ref_element_addr instruction, or
Does it mean that
begin_access cannot be used on
struct_element_addr when I'm writing an element to an aggregate, and should be used on the entire struct buffer instead? If that's the case, why can the operand be a
@Andrew_Trick or @John_McCall can answer in a lot more detail than I can, but the basic idea is that class properties have individual identity and struct properties don't. This is in line with the idea of
mutating methods—remember, formally a struct mutation is copy-in/copy-out (or maybe move-in/move-out some day).
On a very practical level, too, the run-time checking for exclusivity violations would be a lot more expensive if it broke structs down into their individual fields, and it would still have to treat structs as aggregates for
mutating methods (and
inout access in general).
I like @jrose's explanation. Additionally...
begin_access certainly can operate on a
struct_element_addr, but only if it's nested within the "real" formal access. That happens after inlining @inout parameters. The top-level
begin_access must be reachable via a straightforward SSA use-def walk.
We must be able to identify the object being formally accessed and all accesses to shared mutable state need to be precisely identified. So, if you declare a class property with a struct type, we need to recognize that accessing a member of that struct is actually an access of that class property. The struct does not have a separate identity. It's a semantic property but also a physical property.