Swift 6.2 can't verify usage of a noncopyable type (and wants me to report this bug)

With

$ swift --version 
swift-driver version: 1.127.14.1 Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1) 
Target: arm64-apple-macosx15.0

And this file:

import Foundation

struct Foo: ~Copyable {
    init() {}
}

func bar() {
    var foo: Foo?
    NSFileCoordinator().coordinate(writingItemAt: URL(filePath: "/tmp/irrelevant"), options: .forMerging, error: nil, byAccessor: { url in
        foo = Foo()
    })
    _ = foo
}

bar()  // usage so the function isn't compiled outr

the compiler complains and tells me to file a bug, so here’s a first attempt at that :slight_smile:

$ swift test.swift 
test.swift:8:9: error: usage of a noncopyable type that compiler can't verify. This is a compiler bug. Please file a bug with a small example of the bug
 6 | 
 7 | func bar() {
 8 |     var foo: Foo?
   |         `- error: usage of a noncopyable type that compiler can't verify. This is a compiler bug. Please file a bug with a small example of the bug
 9 |     NSFileCoordinator().coordinate(writingItemAt: URL(filePath: "/tmp/irrelevant"), options: .forMerging, error: nil, byAccessor: { url in
10 |         foo = Foo()
1 Like

Probably unrelated but I think you should use extendLifetime(foo) instead of _ = foo to avoid inconsistencies between debug and release caused by optimizations.

1 Like

Thanks – yes, unrelated, but a good habit to pick up :+1:

i took the liberty of reporting this as a GitHub issue here: Potential issues with NS_NOESCAPE + non-copyable types · Issue #85172 · swiftlang/swift · GitHub. after a brief test, my suspicion is that it has to do with the use of NS_NOESCAPE on the byAccessor closure, and some objc-bridging behavior.

2 Likes

Assuming that’s the case, I also ran into this issue recently. The workaround for me was to wrap the ObjC method in a Swift function that takes a Swift non-escaping closure. That got rid of the compiler error.