Daniel Duan's blog

Building Swift Projects In Source Compatibility Mode

It’s a few weeks before WWDC, so naturally¹ it’s time to try build your Swift projects in the compiler’s compatibility mode!

  1. Download and install a snapshot for the next major version on Swift.org.

    download swift toolchain install swift toolchain

  2. Choose the newly installed toolchain in Xcode.

    choose swift toolchain in Xcode

  3. Ask the compiler to use compatibility mode. This means using the complier flag -swift-version X, where “X” is the current major Swift version.

    In project’s “Build Settings”, value for “Other Swift Flags” should contain -swift-version X. This could mean setting it in Xcode, in .xcconfig files you are using and/or in your dependency managers such as Cocoapods.

    compatibility flag in xcode

    For example, with Cocoapods, you’ll need to add the following in your Podfile to compile 3rd party libraries in compatibility mode:

     post_install do |installer|
         installer.pods_projects.targets.each do |target|
             target.build_configurations.each do |config|
                 config.build_settings["OTHER_SWIFT_FLAGS"] = "$(inherited) -swift-version 3"
  4. Build your project! This is where things start to get exciting.

    You should expect some warnings. Hopefully they are self-explanatory enough. Most of them should correspond to a swift-evolution proposal.

    Improvement to the language or compiler usually means some of these warnings tell you problems in your code that has been ignored by the compiler previously. Fix them today!

    The project should compile successfully in compatibility mode (despite warnings). This where you can stop reading. Go celebrate with your coworkers, friends, and family!

    Things could go wrong for compiler snapshots, of course. Read on if see errors or crashes (whaaaaat 😸).

  5. It’s time to tell the compiler team about the error or crash you encountered.

    Reduce the error or crash to a state that your are comfortable reporting in public. Then go to bugs.swift.org and file a JIRA ticket describing the error or compiler crash.

    During the process of code reduction you may find ways to work around the compile error or crash. Make the changes for the workaround and repeat steps 4-5. Maybe your project will compile this time.

  6. The issue you discovered will be fixed in the official Swift release come fall. You’ve ensured a smooth Swift upgrade for your project and contributed to the Swift community 🎉!

¹ source compatibility mode is a thing starting with Swift 4. As new major version of Swift is released, code written in the previous version should compile without change in compatibility mode.

Replying To Old Mailing List Threads

One common complains on the Swift Evolution mailing list is about its inscrutable interface. If you see an inactive thread on the web archive but haven’t subscribed, there seems to be no way to participate or “revive” it since you never received any of its emails.

With a hint and some experiments, I’ve discovered that there is a way. This post reveals the magic step by step (without commenting on the merits of email or this solution).

Like HTTP, Email is a text-based protocol. Unlike HTTP, we directly consume payloads of this protocol and, as a consequence, don’t think much about that very fact.

Like HTTP, each email includes headers hidden by normal email clients. Each header is essentially two strings, a key and a value, separated by a colon. Among these headers are Message-Id and In-Reply-To. When we tell our email client applications to start a reply, they take the value from Message-Id and use it as value for In-Reply-To automatically.

To observe all this in action, we can open some emails with our favorite text editors and look for these headers. Of course, this require us to know where the emails exist as files. On macOS, an easy thing to do is to drag from Mail.app to Finder/Desktop and open the resulting .eml file:

Open an email in text editors

Among the (perhaps overwhelming amount of) headers, we’ll find the two fields we are looking for:

Email Headers Message-Id and

… I’ll leave the clients’ reply behavior regarding these fields for the reader to verify.

Mailing list software such as GNU Mailman, which swift.org and llvm.org use to host various mailing lists, associate emails in threads by chaining them with the headers explained above, among other things. As long as we have a message’s Message-Id, we can reply to it “officially” by adding its value to the In-Reply-To header in our email, regardless of whether we have received that email ourselves previously.

So here are the steps to reply retroactively to a mailing list thread.

  1. find Message-Id of the mailing list message we want to reply to.

    This value is contained in the mailing list web archive’s mailto link. Unfortunately Mail.app doesn’t recognize it. It’s easy enough to find it ourselves though:

    Finding Message-Id on mailman

    Note the <, >, @ characters are percent-quoted. We have to recover the id values to the format <[email protected]>.

    Another way to acquire this value is from the gzip’d archive. There they just exist as plain text. The downside is you have to dig out the message itself first.

  2. Add In-Reply-To header to our email.

    Draft a new email, make its title the same as our email chain’s title (this is a good idea because lots of email clients do use the title to thread messages). Set the appropriate recipients, and CCs, including the mailing list’s address. Now save this email as draft and open it in a text editor as we did in our investigations. Add in the line In-Reply-To: <id-we-found-in-step-one.address.com>, save it. Then send this email (for example, open it with Mail.app and use Message->Send Again in the menu).

    Of course, some email client supports adding it from their GUI.

You’ll find the in addition to functioning as an normal message to the recipients, the mailing list will properly put your message to the original thread (in the case of swift-evolution, only if your reply is within the same week).

Site Improvements

I spent a whole day making changes to this site.

You may notice a new section is now added: links. Yes, I want a link list format for this site. Often I find stuff that’s insightful and not always visible. I want to collect those and bookmark them here. Modelling after Daring Fireball, I’ve added a new feed which only contains long-form, original articles. I’ll be tagging the links so that they show up along side my normal posts in tag pages. Each tag page now gets its own feed! You can read about it in the about page.

A few small issues has been fixed.

I wrote the most Ruby in my life today. Yay?