Files
swift-mirror/test/Concurrency/Runtime/actor_keypaths.swift
Doug Gregor 052cc7d022 [Concurrency] Revert 'nonisolated let' change.
The change made to SE-0306 to require 'nonisolated let' is undercutting
the effectiveness of the model. Revert while we work on a better
solution.
2021-05-06 17:30:11 -07:00

80 lines
1.9 KiB
Swift

// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-concurrency %import-libdispatch)
// REQUIRES: executable_test
// REQUIRES: concurrency
// REQUIRES: libdispatch
// UNSUPPORTED: use_os_stdlib
// UNSUPPORTED: back_deployment_runtime
actor Page {
let initialNumWords : Int
@actorIndependent(unsafe)
var numWords : Int
init(_ words : Int) {
numWords = words
initialNumWords = words
}
}
actor Book {
let pages : [Page]
init(_ numPages : Int) {
var stack : [Page] = []
for i in 0 ..< numPages {
stack.append(Page(i))
}
pages = stack
}
@actorIndependent
subscript(_ page : Int) -> Page {
return pages[page]
}
}
func bookHasChanged(_ b : Book,
currentGetter : KeyPath<Page, Int>,
initialGetter : (Page) -> Int) -> Bool {
let numPages = b[keyPath: \.pages.count]
for i in 0 ..< numPages {
let pageGetter = \Book.[i]
let currentWords = pageGetter.appending(path: currentGetter)
if (b[keyPath: currentWords] != initialGetter(b[keyPath: pageGetter])) {
return true
}
}
return false
}
func enumeratePageKeys(from : Int, to : Int) -> [KeyPath<Book, Page>] {
var keys : [KeyPath<Book, Page>] = []
for i in from ..< to {
keys.append(\Book.[i])
}
return keys
}
func erasePages(_ book : Book, badPages: [KeyPath<Book, Page>]) {
for page in badPages {
book[keyPath: page].numWords = 0
}
}
let book = Book(100)
if bookHasChanged(book, currentGetter: \Page.numWords, initialGetter: \Page.initialNumWords) {
fatalError("book should not be changed")
}
erasePages(book, badPages: enumeratePageKeys(from: 0, to: 100))
guard bookHasChanged(book, currentGetter: \Page.numWords, initialGetter: \Page.initialNumWords) else {
fatalError("book should be wiped!")
}