~Copyable and deinit

Ran into an interesting issue with non-copyable types tonight. In certain situations I fatal error in a deinit. (Basically when I have not correctly closed a resource before deinit is called). I've simplified the code down to:

struct Example: ~Copyable {
    private var failureString: String { "Goodbye." }
    public init() { }
    deinit { fatalError("FATAL ERROR: \(failureString)") }
}

which fails to compile (under Xcode 15 b8) yielding this error message:

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

Looking for a work around at the moment. Am I not supposed to be accessing computed vars during deinits on non-copyables? This works just fine as a final class.

3 Likes

To make it even smaller, it doesn't even need the empty init:

struct Example: ~Copyable {
    private var failureString: String { "Goodbye." }
    deinit { fatalError("FATAL ERROR: \(failureString)") }
}

If you haven't yet, and you have a moment, it'd be good to file this as a bug on Github. I tested on a top-of-tree compiler, and it appears that accessing failureString before calling fatalError avoids the issue:

struct Example: ~Copyable {
    private var failureString: String { "Goodbye." }
    deinit {
        let s = failureString
        fatalError("FATAL ERROR: \(s)")
    }
}
1 Like

Done

2 Likes