Welcome to issue #28! This week the Swift 3.0 preview 2 branch was cut on GitHub and there’s a new milestone tracking pull requests to include.

Starter tasks

  • SR-1894: Return type of NSCoding.Protocol is considered ObjC-compatible, but crashes
  • SR-1872: Use runloop source in XCTestCase waitForExpectations(withTimeout:file:line:handler:)
  • SR-1840: Calendar range(of:, start:, interval:, for:) has incorrect type for start parameter

Submit a task by sending a pull request or a tweet.

Commits and pull requests

Saleem Abdulrasool opened a pull request to add PS4 support.

Rintaro Ishizaki improved diagnostics for a trailing closure in a condition statement.

Jamal Rogers resolved SR-1048, a longstanding starter task to support building and testing debug and release builds of swift-corelibs-xctest.

Arsen Gasparyan started implementing proposal SE-0089: Renaming String.init<T>(_: T).

Rintaro Ishizaki implemented proposal SE-0060: Enforcing order of defaulted parameters.

Robert Widmann started work on enabling leaks tracking for the stblib.

Accepted proposals

Erica Sadun’s proposal, SE-0106: Add a macOS Alias for the OSX Platform Configuration Test, was accepted.

The core team is proactively accepting SE-0106 “Add a macOS Alias for the OSX Platform Configuration Test” without a formal review, under the rationale that the proposal is “obvious” and probably should have been treated as a bug fix. Adding aliases for other uses of “OS X” in the language to use macOS are also proactively accepted.

Adrian Zubarev’s and Austin Zheng’s proposal, SE-0095: Replace protocol<P1,P2> syntax with P1 & P2 syntax, was accepted.

This syntax has been extensively discussed by the community, and is a cornerstone of the “generalized existentials” work for future Swift releases. The community was overall positive on the feature with a few subjective concerns about “&” being tightly associated with bitwise logical operations. The core team believes this will not be contextually confusing since it appears in a type position, between two names that are obviously nominal types (e.g. they are capitalized).

I filed SR-1938 to track implementation of this work, this is a somewhat advanced starter project which would be a great place for someone to dive into the parsing logic in Swift.

Proposals in review

Andrew Trick’s proposal, SE-0107: UnsafeRawPointer API is under review.

Swift enforces type safe access to memory and follows strict aliasing rules. However, code that uses unsafe APIs or imported types can circumvent the language’s natural type safety. […]

Swift already protects against undefined behavior as long as the code does not use “unsafe” constructs. However, UnsafePointer is an important API for interoperability and building high performance data structures. As such, the rules for safe, well-defined usage of the API should be clear. Currently, it is too easy to use UnsafePointer improperly.

Anton Zhilin’s and Chris Lattner’s proposal, SE-0109: Remove the Boolean protocol, is under review.

For legacy and historical reasons Swift has supported a protocol named Boolean for abstracting over different concrete Boolean types. This causes problems primarily because it is pointless and very confusing to newcomers to Swift: is quite different than Bool, but shows up right next to it in documentation and code completion. Once you know that it is something you don’t want, you constantly ignore it. Boolean values are simple enough that we don’t need a protocol to abstract over multiple concrete implementations.

From a historical perspective, it was a very early solution to the bridging challenge of BOOL (which comes in as ObjCBool). In the time since then, Swift has developed a number of more advanced ways to solve these sorts of bridging problems, and BOOL is already bridged in automatically as Bool in almost all cases.

Another pragmatic problem with the Boolean protocol is that it isn’t used consistently in APIs that take Boolean parameters: almost everything takes Bool concretely. This means that its supposed abstraction isn’t useful. The only significant users are the unary !, and binary && and || operators.

Austin Zheng’s and Douglas Gregor’s proposal, SE-0108: Remove associated type inference, is under review.

In Swift, a type T may choose to conform to a protocol P, where P has associated types that may be used in the protocol requirements. If the associated types are used in the requirements, the types that T chooses to bind those associated types to can currently be inferred by the type checker by examining how T chooses to implement P’s requirements.

The main advantage of removing associated type witness inference is that it decreases the complexity of the type checker. Doing so removes the only aspect of Swift that depends upon global type inference. Simplifying the type checker makes it easier to improve the performance and correctness of the type checker code. Given that both are widely acknowledged issues with current versions of Swift, any opportunity for improvement should be carefully considered.

Anton Zhilin’s proposal, SE-0077: Improved operator declarations, is under review for the second time. The previous rationale here.

In the beginning, operators had nice precedence values: 90, 100, 110, 120, 130, 140, 150, 160.

As time went, new and new operators were introduced. Precedence could not be simply changed, as this would be a breaking change. Ranges got precedence 135, as got precedence 132. ?? had precedence greater than <, but less than as, so it had to be given precedence 131.

Now it is not possible to insert any custom operator between < and ??. It is an inevitable consequence of current design: it will be impossible to insert an operator between two existing ones at some point.

Mailing lists

Jordan Rose started a discussion about the behavior of @objc on a class. However, it looks like changes will not be made.

Hey, all. An engineer at Apple noticed the following behavior:

  1. class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
  2. @objc class Foo: NSObject → exposed to Objective-C, Swift-style (mangled) runtime name
  3. @objc(Foo) class Foo: NSObject → exposed to Objective-C, unmangled runtime name

(and 4. @objc class Foo → illegal, classes must have ObjC heritage to be @objc.)

They specifically observed that (1) and (2) have the same behavior, and suggested that maybe (2) should be shorthand for (3).

[…]

Doug Gregor proposed a draft proposal for NSError bridging. These changes would dramatically improve error handling interoperability, which is surprisingly more nuanced than you might expect.

Swift bridges between ErrorProtocol-conforming types and NSError so, for example, a Swift enum that conforms to ErrorProtocol can be thrown and will be reflected as an NSError with a suitable domain and code. Moreover, an NSError produced with that domain and code can be caught as the Swift enum type, providing round-tripping so that Swift can deal in ErrorProtocol values while Objective-C deals in NSError objects.

However, the interoperability is incomplete in a number of ways, which results in Swift programs having to walk a careful line between the ErrorProtocol-based Swift way and the NSError-based way. This proposal attempts to bridge those gaps.

A problem with SE-0025? Jordan Rose and Robert Widmann proposed an amendment to SE-0025: Scoped Access Level. In short, private types get tricky when you consider nested types. Consider this example:

class Outer {
   private class Inner {
      var value = 0
   }

   func test() {
      // Can Outer.test reference Inner's initializer?
      let inner = Inner()

      // Can Outer.test reference Inner's 'value' property?
      print(inner.value)
   }
}

A new section in proposal, Complications with private types, explains the behavior of private types in detail.

Finally

And finally — 🤔 the Swift compiler is like a lamp… 😂