Double pointer in ObjC function signature importing incorrectly in Swift 3?


(Michael Gardner) #1

I'm using an Objective-C library that has me provide a callback that takes a double-pointer parameter like this, where only the inner pointer is nullable:

CKRecord *_Nonnull *_Nullable inOutRecordPtr

Swift 2 imported this as an AutoreleasingUnsafeMutablePointer<CKRecord?>, as expected. However, Swift 3 is importing it as AutoreleasingUnsafeMutablePointer<CKRecord>?, which breaks the library's API since there's no way to return a new record.

Is this a Swift 3 bug, or am I missing something?


(Jordan Rose) #2

C represents pointers the other way around; that declaration says only the outer pointer is nullable. There are two things going on here:

- Swift 2 made all pointers implicitly nullable, without using an optional type. Swift 3 makes that explicit.
- Swift 2 had a bug that assumed that all pointers-to-references were optional, instead of just those without nullability annotations. Swift 3 "fixes" that…but that reveals places where headers used _Nonnull to mean "always produces a nonnull pointer", forgetting that it also applies to input.

If this is an API in CloudKit itself, please file a Radar at bugreport.apple.com. If it's a third-party library built on CloudKit, you'll have to report the issue to them.

Sorry for the trouble!
Jordan

···

On Sep 20, 2016, at 10:32, Michael Gardner via swift-users <swift-users@swift.org> wrote:

I'm using an Objective-C library that has me provide a callback that takes a double-pointer parameter like this, where only the inner pointer is nullable:

CKRecord *_Nonnull *_Nullable inOutRecordPtr

Swift 2 imported this as an AutoreleasingUnsafeMutablePointer<CKRecord?>, as expected. However, Swift 3 is importing it as AutoreleasingUnsafeMutablePointer<CKRecord>?, which breaks the library's API since there's no way to return a new record.

Is this a Swift 3 bug, or am I missing something?
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(first account 2) #3

C represents pointers the other way around; that declaration says only the outer pointer is nullable. There are two things going on here:

- Swift 2 made all pointers implicitly nullable, without using an optional type. Swift 3 makes that explicit.
- Swift 2 had a bug that assumed that all pointers-to-references were optional, instead of just those without nullability annotations. Swift 3 "fixes" that…but that reveals places where headers used _Nonnull to mean "always produces a nonnull pointer", forgetting that it also applies to input.

If this is an API in CloudKit itself, please file a Radar at bugreport.apple.com. If it's a third-party library built on CloudKit, you'll have to report the issue to them.

Sorry for the trouble!
Jordan

···

Sent from Alto
On Tuesday, 20 September 2016 Jordan Rose via swift-users <swift-users@swift.org> wrote:

On Sep 20, 2016, at 10:32, Michael Gardner via swift-users wrote:

I'm using an Objective-C library that has me provide a callback that takes a double-pointer parameter like this, where only the inner pointer is nullable:

CKRecord *_Nonnull *_Nullable inOutRecordPtr

Swift 2 imported this as an AutoreleasingUnsafeMutablePointer, as expected. However, Swift 3 is importing it as AutoreleasingUnsafeMutablePointer?, which breaks the library's API since there's no way to return a new record.

Is this a Swift 3 bug, or am I missing something?
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users