mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Concurrency] Diagnose mutating accesses to locals from concurrent code.
Replace the existing warning about any access to a local variable from concurrently-executing code with a more tailored error: concurrently-executing code may read a mutable varable, but cannot modify it. This is safe so long as we either always do by-value captures in concurrent closures or we ensure that no mutation of that variable can occur after the point of capture. We'll follow up with one of those. For now... be careful out there. Since we're promoting this to an error, narrow it down to concurrent closures and local functions, dropping the assumption that escaping closures "may execute concurrently."
This commit is contained in:
@@ -53,3 +53,43 @@ func closures() {
|
||||
acceptsConcurrent(closure1) // expected-error{{converting non-concurrent function value to '@concurrent (Int) -> Int' may introduce data races}}
|
||||
}
|
||||
|
||||
// Mutation of captured locals from within @concurrent functions.
|
||||
extension Int {
|
||||
mutating func makeNegative() {
|
||||
self = -self
|
||||
}
|
||||
|
||||
func printMe() {
|
||||
print(self)
|
||||
}
|
||||
}
|
||||
|
||||
func mutationOfLocal() {
|
||||
var localInt = 17
|
||||
acceptsConcurrent { i in
|
||||
// Non-mutating accesses are okay
|
||||
print(localInt + 17)
|
||||
localInt.printMe()
|
||||
|
||||
// Mutations of locally-defined variables are fine.
|
||||
var localResult = localInt + 1
|
||||
print(localResult)
|
||||
|
||||
_ = {
|
||||
localResult = localResult + 1
|
||||
}()
|
||||
|
||||
// Mutations of captured variables executing concurrently are bad.
|
||||
localInt = 17 // expected-error{{mutation of captured var 'localInt' in concurrently-executing code}}
|
||||
localInt += 1 // expected-error{{mutation of captured var 'localInt' in concurrently-executing code}}
|
||||
localInt.makeNegative() // expected-error{{mutation of captured var 'localInt' in concurrently-executing code}}
|
||||
|
||||
_ = {
|
||||
localInt = localInt + 12 // expected-error{{mutation of captured var 'localInt' in concurrently-executing code}}
|
||||
}()
|
||||
|
||||
return i + localInt
|
||||
}
|
||||
|
||||
localInt = 20
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user