Unsafe APIs don't seem to handle ~Copyable types and typed throws

I noticed most low-level APIs exposing pointers neither properly handle ~Copyable types nor propagate the generic error types (typed-throws). Is this on purpose? or Swift compiler devs didn't have the time to "get there" yet?

You can pick almost any pointer API, for example, String.withUTF8(_:) or ContiguousBytes.withUnsafeBytes(_:).

try string.withUTF8 { buffer throws(CustomError) in
  guard checkSomething() else {
    throw CustomError()
  }
  return NonCopyableStruct()
}

For the previous case the compiler will tell us that:

  1. Instance method withUTF8 requires that NonCopyableStruct conforms to Copyable.
  2. Thrown expression type any Error cannot be converted to error type CustomError.

I currently have some "ugly code" to overcome these issues. I am curious if someone has a more elegant solution.

2 Likes

Something else I noticed is that throwing subscripts can't return ~Copyable types. I don't understand why would that be the case :thinking: Is there also a reason for this?

struct Dummy {
  subscript(_ index: Int) -> some ~Copyable {
    get throws {
      NonCopyableStruct()
    }
  }
}

The compiler claims "Getter of noncopyable type cannot be 'async' or 'throws'"