Is Memory Safety doc outdated?

I'm reading the Memory Safety chapter of official Swift 6 doc. It says:

var stepSize = 1

func increment(_ number: inout Int) {
    number += stepSize
}

increment(&stepSize)
// Error: conflicting accesses to stepSize

However, when I tried the code in Xcode it doesn't trigger the error. My SWIFT_VERSION is set to Swift 6 and SWIFT_ENFORCE_EXCLUSIVE_ACCESS is Full Enforcement (Run-time Checks in All Builds).

Is the doc outdated?

Some of other content doesn't match my tests either. For example:

var playerInformation = (health: 10, energy: 20)
balance(&playerInformation.health, &playerInformation.energy)
// Error: conflicting access to properties of playerInformation

It doesn't trigger compiling error in my test.

var holly = Player(name: "Holly", health: 10, energy: 10)
balance(&holly.health, &holly.energy)  // Error

It doesn't trigger compiling error in my test.

Notice I defined all the vars of stepSize, playerInformation and holly as global because the last section of the doc says these rules don't apply to local vars (even if the doc is correct the current wording and organization makes it hard to understand the truth):

Specifically, it can prove that overlapping access to properties of a structure is safe if the following conditions apply:

  • You’re accessing only stored properties of an instance, not computed properties or class properties.
  • The structure is the value of a local variable, not a global variable.
  • The structure is either not captured by any closures, or it’s captured only by nonescaping closures.
1 Like

This works exactly as advertised for me:

% swift repl
Welcome to Apple Swift version 6.1 (swift-6.1-RELEASE).
Type :help for assistance.
  1> var stepSize = 1 
  2.  
  3. func increment(_ number: inout Int) { 
  4.     number += stepSize 
  5. } 
  6.  
  7. increment(&stepSize)
Simultaneous accesses to 0x100018040, but modification requires exclusive access.
Previous access (a modification) started at  (0x1000142dc).
Current access (a read) started at:
0    libswiftCore.dylib                 0x000000019e37efe4 swift::runtime::AccessSet::insert(swift::runtime::Access*, void*, void*, swift::ExclusivityFlags) + 432
1    libswiftCore.dylib                 0x000000019e37f1fc swift_beginAccess + 84
4    repl_swift                         0x0000000100003e6c main + 0
5    dyld                               0x000000018df767a8 start + 2476
Fatal access conflict detected.

It seems I misunderstood. I thought it would trigger compile time errors. In fact, some do trigger compile time errors which makes it even more confusing.

Runtime errors are scary. Any chance for turning all these into compile time errors?

Swift only does runtime checks for accesses to shared mutable state, like accessing class members and global variables. If you only use locally-stored value types, then you'll always get compile-time errors.

1 Like