I decided try out building MongoSwift using the newly released Swift 5.0 development snapshots and encountered some interesting behavior. In particular, the Swift interfaces for a number of C functions are different and there are OpaquePointers expected in many places that expect UnsafeMutablePointers in Swift 4.
MongoSwift uses two C libraries under the hood, libbson and libmongoc. To illustrate the change with a particular example, consider the function bson_new.
Its C signature:
bson_t *
bson_new (void);
Printing out type(of: bson_new) in Swift 4.2 gives me () -> Optional<UnsafeMutablePointer<_bson_t>>.
But with the 5.0 snapshot, I get: () -> Optional<OpaquePointer>
I haven't had any luck finding any discussion of these changes in Swift evolution proposals or in the forums. Does anyone have any insight into this?
cc @jrose. There wasn't any intentional change here that I know about. Swift will use OpaquePointer to import a pointer to any type Swift can't import, including incomplete forward-declared C structs. What is the definition of bson_t, and is there any chance it changed its definition between libbson library versions? If it was a struct with a definition that became forward-declared, or it was changed to a typedef to some other kind of type Swift's importer doesn't handle, that could explain the change.
Well, sizeof(bson_t) does equal 128, so maybe it was intentional. But I have no idea why it would be intentional.
EDIT: You will be shocked to learn that bson_malloc is implemented as simply calling malloc by default and so does not in fact return 128-byte-aligned memory.
So I can understand that this puts you in an awkward position, because the library is doing something a little silly and it's leading to poor import results, but you may not feel empowered to actually do anything about it. As a short-term solution, you can hack your headers; as a longer-term solution, you can bring it up with the libbson maintainers; otherwise you might feel a little stuck.
In the long run, Swift should be capable of importing types like this; we just can't allow them to be abstracted over. That's not something we can express right now, so instead we're doing something conservative but correct, and it's not great.