mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Find all the usages of `--enable-experimental-feature` or `--enable-upcoming-feature` in the tests and replace some of the `REQUIRES: asserts` to use `REQUIRES: swift-feature-Foo` instead, which should correctly apply to depending on the asserts/noasserts mode of the toolchain for each feature. Remove some comments that talked about enabling asserts since they don't apply anymore (but I might had miss some). All this was done with an automated script, so some formatting weirdness might happen, but I hope I fixed most of those. There might be some tests that were `REQUIRES: asserts` that might run in `noasserts` toolchains now. This will normally be because their feature went from experimental to upcoming/base and the tests were not updated.
210 lines
4.6 KiB
Swift
210 lines
4.6 KiB
Swift
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-feature -Xfrontend MoveOnlyEnumDeinits -Xfrontend -sil-verify-all) | %FileCheck %s --implicit-check-not closing
|
|
// RUN: %target-run-simple-swift(-O -Xfrontend -enable-experimental-feature -Xfrontend MoveOnlyEnumDeinits -Xfrontend -sil-verify-all) | %FileCheck %s --implicit-check-not closing
|
|
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: swift_feature_MoveOnlyEnumDeinits
|
|
|
|
// NOTE: it's important that this test has the `--implicit-check-not closing` flag to catch double deinits!!
|
|
// you also want to make sure all messages start with "closing"
|
|
func posix_close(_ x: Int) { print("closing file descriptor: \(x)") }
|
|
func print_closing_MFD() { print("closing MaybeFileDescriptor") }
|
|
|
|
enum E: Error { case err }
|
|
|
|
struct FileDescriptor: ~Copyable {
|
|
var fd: Int
|
|
static var nextFD: Int = 0
|
|
|
|
consuming func discard() { discard self }
|
|
|
|
init() {
|
|
self.fd = FileDescriptor.nextFD
|
|
FileDescriptor.nextFD += 1
|
|
}
|
|
|
|
init(doDiscard: Bool) throws {
|
|
self.init()
|
|
if doDiscard {
|
|
discard()
|
|
throw E.err
|
|
}
|
|
}
|
|
|
|
__consuming func close() {
|
|
posix_close(fd)
|
|
discard self
|
|
}
|
|
|
|
__consuming func justDiscard() {
|
|
discard self
|
|
}
|
|
|
|
__consuming func empty() {}
|
|
|
|
var takeFileDescriptorWrong : Int {
|
|
__consuming get {
|
|
return fd
|
|
}
|
|
}
|
|
|
|
var takeFileDescriptorRight : Int {
|
|
__consuming get {
|
|
let x = fd
|
|
discard self
|
|
return x
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
posix_close(fd)
|
|
}
|
|
}
|
|
|
|
enum MaybeFileDescriptor: ~Copyable {
|
|
case some(FileDescriptor)
|
|
case nothing
|
|
|
|
consuming func discard() { discard self }
|
|
|
|
init(reinit: Bool) {
|
|
self = .some(FileDescriptor())
|
|
if reinit {
|
|
discard()
|
|
self = .some(FileDescriptor())
|
|
}
|
|
}
|
|
|
|
__consuming func skipDeinit() {
|
|
discard self
|
|
}
|
|
|
|
deinit {
|
|
// we can't do a borrowed switch yet so this is just printing some message
|
|
print_closing_MFD()
|
|
}
|
|
}
|
|
|
|
struct SillyEmptyGeneric<T>: ~Copyable {
|
|
consuming func identity(_ t: T) -> T {
|
|
discard self
|
|
return t
|
|
}
|
|
deinit { fatalError("ran unexpectedly!") }
|
|
}
|
|
|
|
struct SingleMutableField: ~Copyable {
|
|
var value = 0
|
|
|
|
consuming func justDiscard() {
|
|
discard self
|
|
}
|
|
|
|
deinit {
|
|
print("SingleMutableField.deinit")
|
|
}
|
|
}
|
|
|
|
// rdar://110232973 ([move-only] Checker should distinguish in between
|
|
// field of single field struct vs parent field itself (was: mutation
|
|
// of field in noncopyable struct should not trigger deinit))
|
|
//
|
|
// This test must not be in a closure.
|
|
@inline(never)
|
|
func testSingleMutableFieldNoMemberReinit() {
|
|
var x = SingleMutableField()
|
|
x.value = 20 // should not trigger deinit.
|
|
// CHECK-NOT: SingleMutableField.deinit
|
|
x.justDiscard()
|
|
}
|
|
|
|
func main() {
|
|
testSingleMutableFieldNoMemberReinit()
|
|
|
|
let _ = {
|
|
let x = FileDescriptor() // 0
|
|
x.close()
|
|
// CHECK: closing file descriptor: 0
|
|
}()
|
|
|
|
let _ = {
|
|
let _ = FileDescriptor() // 1
|
|
// CHECK: closing file descriptor: 1
|
|
}()
|
|
|
|
let _ = {
|
|
let x = FileDescriptor() // 2
|
|
x.justDiscard()
|
|
}()
|
|
|
|
let _ = {
|
|
let x = FileDescriptor() // 3
|
|
x.empty()
|
|
// CHECK: closing file descriptor: 3
|
|
}()
|
|
|
|
let _ = {
|
|
let x = FileDescriptor() // 4
|
|
_ = x.takeFileDescriptorWrong
|
|
// CHECK: closing file descriptor: 4
|
|
}()
|
|
|
|
let _ = {
|
|
let x = FileDescriptor() // 5
|
|
_ = x.takeFileDescriptorRight
|
|
}()
|
|
|
|
let _ = {
|
|
do {
|
|
// should throw before getting to close()
|
|
let x = try FileDescriptor(doDiscard: true) // 6
|
|
x.close()
|
|
} catch {}
|
|
}()
|
|
|
|
let _ = {
|
|
do {
|
|
let x = try FileDescriptor(doDiscard: false) // 7
|
|
x.close()
|
|
} catch {}
|
|
// CHECK: closing file descriptor: 7
|
|
}()
|
|
|
|
let _ = {
|
|
let _ = MaybeFileDescriptor(reinit: true) // 8 & 9
|
|
// CHECK: closing file descriptor: 8
|
|
// CHECK: closing MaybeFileDescriptor
|
|
// CHECK: closing file descriptor: 9
|
|
}()
|
|
|
|
let _ = {
|
|
let x = MaybeFileDescriptor(reinit: true) // 10 & 11
|
|
x.skipDeinit() // this skips the enum's deinit, not the file descriptor's!
|
|
// CHECK: closing file descriptor: 10
|
|
// CHECK: closing file descriptor: 11
|
|
}()
|
|
|
|
let _ = {
|
|
var maybe = MaybeFileDescriptor.nothing
|
|
maybe = .some(FileDescriptor()) // 12
|
|
// CHECK: closing MaybeFileDescriptor
|
|
// CHECK: closing MaybeFileDescriptor
|
|
// CHECK: closing file descriptor: 12
|
|
}()
|
|
|
|
let _ = {
|
|
let x = MaybeFileDescriptor(reinit: false) // 13
|
|
x.skipDeinit() // this skips the enum's deinit, not the file descriptor's!
|
|
// CHECK: closing file descriptor: 13
|
|
}()
|
|
|
|
let _ = {
|
|
let x = SillyEmptyGeneric<[Int]>()
|
|
let z = [1, 2]
|
|
let ans = x.identity(z)
|
|
assert(z == ans)
|
|
}()
|
|
|
|
}
|
|
|
|
main()
|