Skip to content

Instantly share code, notes, and snippets.

@CodaFi
Last active March 23, 2017 05:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CodaFi/fc6fa3aac64c4b1deffd1434a37e295f to your computer and use it in GitHub Desktop.
Save CodaFi/fc6fa3aac64c4b1deffd1434a37e295f to your computer and use it in GitHub Desktop.

Explicit Toll-Free Conversions

Introduction

To continue removing further implicit conversions from the language, implicit toll-free bridging should be deprecated in Swift 3 and removed in Swift 4.0.

Motivation

Swift currently allows implicit conversions between CF types and their toll-free-bridged Objective-C counterparts. This was meant to maintain parity with the feature in Objective-C. However, the presence of implicit conversions is no longer in-line with the expectations of Swift's type system. In addition, advancements in the Clang importer have made interaction with imported CF and Foundation types nearly seamless - obviating the need for this feature in general. For the sake of safety, and in the spirit of continuing the work of SE-0072 and facilitating SE-0083, we propose the deprecation and removal of this implicit conversion in favor of an explicit as cast.

Proposed solution

The implicit conversion between toll-free-bridged types shall be removed. In its place, the user should use explicit as casts to convert bewteen bridged CF and Objective-C types.

Detailed Design

When in Swift 3 mode, the compiler shall warn when it encounters the need to perform an implicit conversion. At the warning site, it can offer the explicit as cast to the user as a fix-it.

func nsToCF(_ ns: NSString) -> CFString {  
  return ns // warning: 'NSString' is not implicitly convertible to 'CFString'; did you mean to use 'as' to explicitly convert?
}

func cfToNS(_ cf: CFString) -> NSString { 
  return cf // warning: 'CFString' is not implicitly convertible to 'NSString'; did you mean to use 'as' to explicitly convert?
}

When in Swift 4 mode, the compiler shall no longer perform the implicit conversion and relying on this behavior will be a hard error.

func nsToCF(_ ns: NSString) -> CFString {  
  return ns // error: cannot convert return expression of type 'NSString' to return type 'CFString'
}

func cfToNS(_ cf: CFString) -> NSString { 
  return cf // error: cannot convert return expression of type 'CFString' to return type 'NSString'
}

Source compatibility

This introduces a source-breaking change that affects consumers of APIs that are explicitly taking or vending instances of bridged CF or Objective-C types. However, recent importer advances have made APIs like this far less numerous. In practice, we expect the source breakage to eludicate places where implicit conversions were accidentally being performed behind the user's back.

Effect on ABI stability

This proposal has no effect on the Swift ABI.

Effect on API resilience

This proposal has no effect on API resilience.

Alternatives considered

Do nothing and continue to accept this implicit conversion.

@dduan
Copy link

dduan commented Mar 23, 2017

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment