Merge pull request #33871 from AnthonyLatsis/o-some

diff --git a/Brewfile b/Brewfile
index cbb5045..d965eb2 100644
--- a/Brewfile
+++ b/Brewfile
@@ -1,2 +1,3 @@
 brew "cmake"
 brew "ninja"
+brew "sccache"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2b2af5d..fb765f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,29 +4,100 @@
 <details>
 <summary>Note: This is in reverse chronological order, so newer entries are added to the top.</summary>
 
-| Version                | Released   | Toolchain   |
-| :--------------------- | :--------- | :---------- |
-| [Swift 5.3](#swift-53) |            |             |
-| [Swift 5.2](#swift-52) | 2020-03-24 | Xcode 11.4  |
-| [Swift 5.1](#swift-51) | 2019-09-20 | Xcode 11.0  |
-| [Swift 5.0](#swift-50) | 2019-03-25 | Xcode 10.2  |
-| [Swift 4.2](#swift-42) | 2018-09-17 | Xcode 10.0  |
-| [Swift 4.1](#swift-41) | 2018-03-29 | Xcode 9.3   |
-| [Swift 4.0](#swift-40) | 2017-09-19 | Xcode 9.0   |
-| [Swift 3.1](#swift-31) | 2017-03-27 | Xcode 8.3   |
-| [Swift 3.0](#swift-30) | 2016-09-13 | Xcode 8.0   |
-| [Swift 2.2](#swift-22) | 2016-03-21 | Xcode 7.3   |
-| [Swift 2.1](#swift-21) | 2015-10-21 | Xcode 7.1   |
-| [Swift 2.0](#swift-20) | 2015-09-17 | Xcode 7.0   |
-| [Swift 1.2](#swift-12) | 2015-04-08 | Xcode 6.3   |
-| [Swift 1.1](#swift-11) | 2014-12-02 | Xcode 6.1.1 |
-| [Swift 1.0](#swift-10) | 2014-09-15 | Xcode 6.0   |
+| Version                   | Released   | Toolchain   |
+| :------------------------ | :--------- | :---------- |
+| [Swift Next](#swift-next) |
+| [Swift 5.3](#swift-53)    |            |             |
+| [Swift 5.2](#swift-52)    | 2020-03-24 | Xcode 11.4  |
+| [Swift 5.1](#swift-51)    | 2019-09-20 | Xcode 11.0  |
+| [Swift 5.0](#swift-50)    | 2019-03-25 | Xcode 10.2  |
+| [Swift 4.2](#swift-42)    | 2018-09-17 | Xcode 10.0  |
+| [Swift 4.1](#swift-41)    | 2018-03-29 | Xcode 9.3   |
+| [Swift 4.0](#swift-40)    | 2017-09-19 | Xcode 9.0   |
+| [Swift 3.1](#swift-31)    | 2017-03-27 | Xcode 8.3   |
+| [Swift 3.0](#swift-30)    | 2016-09-13 | Xcode 8.0   |
+| [Swift 2.2](#swift-22)    | 2016-03-21 | Xcode 7.3   |
+| [Swift 2.1](#swift-21)    | 2015-10-21 | Xcode 7.1   |
+| [Swift 2.0](#swift-20)    | 2015-09-17 | Xcode 7.0   |
+| [Swift 1.2](#swift-12)    | 2015-04-08 | Xcode 6.3   |
+| [Swift 1.1](#swift-11)    | 2014-12-02 | Xcode 6.1.1 |
+| [Swift 1.0](#swift-10)    | 2014-09-15 | Xcode 6.0   |
 
 </details>
 
+Swift Next
+----------
+
+* [SE-0287][]:
+
+  Implicit member expressions now support chains of member accesses, making the following valid:
+  
+  ```swift
+  let milky: UIColor = .white.withAlphaComponent(0.5)
+  let milky2: UIColor = .init(named: "white")!.withAlphaComponent(0.5)
+  let milkyChance: UIColor? = .init(named: "white")?.withAlphaComponent(0.5)
+  ```
+  
+  As is the case with the existing implicit member expression syntax, the resulting type of the chain must be the same as the (implicit) base, so it is not well-formed to write:
+  
+  ```swift
+  let cgMilky: CGColor = .white.withAlphaComponent(0.5).cgColor
+  ```
+  
+  (Unless, of course, appropriate `white` and `withAlphaComponent` members were defined on `CGColor`.)
+  
+  Members of a "chain" can be properties, method calls, subscript accesses, force unwraps, or optional chaining question marks. Furthermore, the type of each member along the chain is permitted to differ (again, as long as the base of the chain matches the resulting type) meaning the following successfully typechecks:
+  
+  ```swift
+  struct Foo {
+    static var foo = Foo()
+    static var bar = Bar()
+    
+    var anotherFoo: Foo { Foo() }
+    func getFoo() -> Foo { Foo() }
+    var optionalFoo: Foo? { Foo() }
+    subscript() -> Foo { Foo() }
+  }
+  
+  struct Bar {
+    var anotherFoo = Foo()
+  }
+
+  let _: Foo? = .bar.anotherFoo.getFoo().optionalFoo?.optionalFoo![]
+  ```
+
 Swift 5.3
 ---------
 
+* [SE-0279][] & [SE-0286][]:
+
+  Trailing closure syntax has been extended to allow additional labeled closures to follow the initial unlabeled closure:
+  
+  ```swift
+  // Single trailing closure argument
+  UIView.animate(withDuration: 0.3) {
+    self.view.alpha = 0
+  }
+  // Multiple trailing closure arguments
+  UIView.animate(withDuration: 0.3) {
+    self.view.alpha = 0
+  } completion: { _ in
+    self.view.removeFromSuperview()
+  }
+  ```
+  
+  Additionally, trailing closure arguments now match the appropriate parameter according to a forward-scan rule (as opposed to the previous backward-scan rule):
+  
+  ```swift
+  func takesClosures(first: () -> Void, second: (Int) -> Void = { _ in }) {}
+  
+  takesClosures {
+    print("First")
+  }
+  ```
+  
+  In the above example, the trailing closure argument matches parameter `first`, whereas pre-Swift-5.3 it would have matched `second`. In order to ease the transition to this new rule, cases in which the forward-scan and backward-scan match a single trailing closure to different parameters, the backward-scan result is preferred and a warning is emitted. This is expected to be upgraded to an error in the next major version of Swift.
+
 * [SR-7083][]:
 
   Property observers such as `willSet` and `didSet` are now supported on `lazy` properties:
@@ -8070,7 +8141,10 @@
 [SE-0268]: <https://github.com/apple/swift-evolution/blob/master/proposals/0268-didset-semantics.md>
 [SE-0269]: <https://github.com/apple/swift-evolution/blob/master/proposals/0269-implicit-self-explicit-capture.md>
 [SE-0276]: <https://github.com/apple/swift-evolution/blob/master/proposals/0276-multi-pattern-catch-clauses.md>
+[SE-0279]: <https://github.com/apple/swift-evolution/blob/master/proposals/0279-multiple-trailing-closures.md>
 [SE-0280]: <https://github.com/apple/swift-evolution/blob/master/proposals/0280-enum-cases-as-protocol-witnesses.md>
+[SE-0286]: <https://github.com/apple/swift-evolution/blob/master/proposals/0286-forward-scan-trailing-closures.md>
+[SE-0287]: <https://github.com/apple/swift-evolution/blob/master/proposals/0287-implicit-member-chains.md>
 
 [SR-75]: <https://bugs.swift.org/browse/SR-75>
 [SR-106]: <https://bugs.swift.org/browse/SR-106>
diff --git a/README.md b/README.md
index c772c53..6f11e2b 100644
--- a/README.md
+++ b/README.md
@@ -50,14 +50,9 @@
 
 - [Contributing to Swift](#contributing-to-swift)
 - [Getting Started](#getting-started)
-  - [System Requirements](#system-requirements)
-  - [Getting Sources for Swift and Related Projects](#getting-sources-for-swift-and-related-projects)
-  - [Building Swift](#building-swift)
   - [Swift Toolchains](#swift-toolchains)
   - [Build Failures](#build-failures)
-- [Testing Swift](#testing-swift)
 - [Learning More](#learning-more)
-- [Build Dependencies](#build-dependencies)
 
 ## Contributing to Swift
 
@@ -77,206 +72,15 @@
 
 ## Getting Started
 
-These instructions give the most direct path to a working Swift development
-environment. To build from source you will need about 2 GB of disk space for the
-source code and up to 70 GB of disk space for the build artifacts with full
-debugging. Depending on your machine, a clean build can take a few minutes to
-several hours. Naturally, incremental builds are much faster.
+If you are interested in:
+- Contributing fixes and features to the compiler: See our
+  [How to Submit Your First Pull Request guide](/docs/HowToGuides/FirstPullRequest.md).
+- Building the compiler as a one-off: See our [Getting Started guide][].
+- Building a toolchain as a one-off: Follow the [Getting Started guide][]
+  up until the "Building the project" section. After that, follow the
+  instructions in the [Swift Toolchains](#swift-toolchains) section below.
 
-Once you are able to build things successfully and have a compile-test-debug
-loop going, check out the [development tips](docs/DevelopmentTips.md) for
-better productivity while working on the compiler.
-
-You can also skim [docs/README.md](/docs/README.md) to understand what
-high-level documentation is available.
-
-### System Requirements
-
-macOS, Ubuntu Linux LTS, and the latest Ubuntu Linux release are currently
-supported as host development operating systems.
-
-Please make sure you use Python 2.x. Python 3.x is not supported currently.
-
-#### macOS
-
-To build for macOS, you need [Xcode 12 beta 3](https://developer.apple.com/xcode/resources/).
-The required version of Xcode changes frequently, and is often a beta release.
-Check this document or the host information on <https://ci.swift.org> for the
-current required version.
-
-Swift's build tooling is meant to support spaces in the paths passed to them,
-but using spaces sometimes tickles bugs in Swift's build scripts or the tools
-they rely on. For example, [SR-13441](https://bugs.swift.org/browse/SR-13441)
-is caused by a space in the Xcode path used on macOS. If you see Swift's build
-tooling misbehave due to a space in a path, please
-[report the bug on the Swift bug tracker](https://swift.org/contributing/#reporting-bugs)
-and then change the path to work around it.
-
-You will also need [CMake](https://cmake.org) and [Ninja](https://ninja-build.org),
-which can be installed via a package manager:
-
-**[Homebrew](https://brew.sh/)**
-
-    brew install cmake ninja
-    
-You can also use [homebrew-bundle](https://github.com/Homebrew/homebrew-bundle)
-from the root of this repository's working directory to install all of these
-dependencies:
-
-    brew bundle
-
-**[MacPorts](https://macports.org)**
-
-    sudo port install cmake ninja
-
-Instructions for installing CMake and Ninja directly can be found [below](#build-dependencies).
-
-#### Linux
-
-For Ubuntu, you'll need the following development dependencies:
-
-```
-sudo apt-get install    \
-  clang                 \
-  cmake                 \
-  git                   \
-  icu-devtools          \
-  libcurl4-openssl-dev  \
-  libedit-dev           \
-  libicu-dev            \
-  libncurses5-dev       \
-  libpython-dev         \
-  libsqlite3-dev        \
-  libxml2-dev           \
-  ninja-build           \
-  pkg-config            \
-  python                \
-  python-six            \
-  rsync                 \
-  swig                  \
-  systemtap-sdt-dev     \
-  tzdata                \
-  uuid-dev
-```
-
-**Note:** LLDB currently requires at least `swig-1.3.40` but will successfully build
-with version 2 shipped with Ubuntu.
-
-**Note:** For Ubuntu 20.04, use `libpython2-dev` in place of the libpython-dev package above.
-
-### Getting Sources for Swift and Related Projects
-
-First create a directory for all of the Swift sources:
-
-    mkdir swift-source
-    cd swift-source
-
-**Note:** This is important since update-checkout (see below) checks out
-repositories next to the Swift source directory. This means that if one clones
-Swift and has other unrelated repositories, update-checkout may not clone those
-repositories and will update them instead. Be aware that `update-checkout`
-currently does not support paths with non-ASCII characters. If such characters
-are present in the path to `swift-source`, `update-checkout` will fail.
-
-**Via HTTPS**  For those checking out sources as read-only, HTTPS works best:
-
-    git clone https://github.com/apple/swift.git
-    ./swift/utils/update-checkout --clone
-
-**Via SSH**  For those who plan on regularly making direct commits,
-cloning over SSH may provide a better experience (which requires
-[uploading SSH keys to GitHub](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/)):
-
-    git clone git@github.com:apple/swift.git
-    ./swift/utils/update-checkout --clone-with-ssh
-
-### Building Swift
-
-The `build-script` is a high-level build automation script that supports basic
-options such as building a Swift-compatible LLDB, building the Swift Package
-Manager, building for various platforms, running tests after builds, and more.
-
-There are two primary build systems to use: Xcode and Ninja. The Xcode build
-system allows you to work in Xcode, but Ninja is a bit faster and supports
-more environments.
-
-First, make sure that you're in the swift directory:
-
-    cd swift
-
-To build using Ninja, run:
-
-    utils/build-script --release-debuginfo
-
-When developing Swift, it helps to build what you're working on in a debug
-configuration while building the rest of the project with optimizations. Below
-are some examples of using debug variants:
-
-    utils/build-script --release-debuginfo --debug-swift # Swift frontend built in debug
-    utils/build-script --release-debuginfo --debug-swift-stdlib # Standard library built in debug
-    utils/build-script --release-debuginfo --debug-swift --force-optimized-typechecker # Swift frontend sans type checker built in debug
-
-Limiting the amount of debug code in the compiler has a very large impact on
-Swift compile times, and in turn the test execution time. If you want to build
-the entire project in debug, you can run:
-
-    utils/build-script --debug
-
-For documentation of all available arguments, as well as additional usage
-information, see the inline help:
-
-    utils/build-script -h
-
-#### Xcode
-
-To build using Xcode, specify the `--xcode` argument on any of the above commands.
-Xcode can be used to edit the Swift source code, but it is not currently
-fully supported as a build environment for SDKs other than macOS. The generated
-Xcode project does not integrate with the test runner, but the tests can be run
-with the 'check-swift' target.
-
-#### Build Products
-
-All of the build products are placed in `swift-source/build/${TOOL}-${MODE}/${PRODUCT}-${PLATFORM}/`.
-If macOS Swift with Ninja in DebugAssert mode was built, all of the products
-would be in `swift-source/build/Ninja-DebugAssert/swift-macosx-x86_64/`. It
-helps to save this directory as an environment variable for future use.
-
-    export SWIFT_BUILD_DIR="~/swift-source/build/Ninja-DebugAssert/swift-macosx-x86_64"
-
-#### Ninja
-
-Once the first build has completed, Ninja can perform fast incremental builds of
-various products. These incremental builds are a big timesaver when developing
-and debugging.
-
-    cd ${SWIFT_BUILD_DIR}
-    ninja swift-frontend
-
-This will build the Swift compiler, but will not rebuild the standard library or
-any other target. Building the `swift-stdlib` target as an additional layer of
-testing from time to time is also a good idea. To build just the standard
-library, run:
-
-    ninja swift-stdlib
-
-It is always a good idea to do a full build after using `update-checkout`.
-
-#### Using Xcode
-
-To open the Swift project in Xcode, open `${SWIFT_BUILD_DIR}/Swift.xcodeproj`.
-It will auto-create a *lot* of schemes for all of the available targets. A
-common debug flow would involve:
-
- - Select the 'swift-frontend' scheme.
- - Pull up the scheme editor (⌘⇧<).
- - Select the 'Arguments' tab and click the '+'.
- - Add the command line options.
- - Close the scheme editor.
- - Build and run.
-
-Another option is to change the scheme to "Wait for executable to be launched",
-then run the build product in Terminal.
+[Getting Started guide]: /docs/HowToGuides/GettingStarted.md
 
 ### Swift Toolchains
 
@@ -335,7 +139,12 @@
 
 ### Build Failures
 
-Make sure you are using the [correct release](#macos) of Xcode.
+Try the suggestions in
+[Troubleshooting build issues](/docs/HowToGuides/GettingStarted.md#troubleshooting-build-issues).
+
+Make sure you are using the
+[correct release](/docs/HowToGuides/GettingStared.md#installing-dependencies)
+of Xcode.
 
 If you have changed Xcode versions but still encounter errors that appear to
 be related to the Xcode version, try passing `--clean` to `build-script`.
@@ -343,76 +152,10 @@
 When a new version of Xcode is released, you can update your build without
 recompiling the entire project by passing the `--reconfigure` option.
 
-Make sure all repositories are up to date with the `update-checkout` command
-described above.
-
-## Testing Swift
-
-See [docs/Testing.md](docs/Testing.md), in particular the section on [lit.py](docs/Testing.md#using-litpy).
-
 ## Learning More
 
-Be sure to look through the [docs](https://github.com/apple/swift/tree/master/docs)
-directory for more information about the compiler. In particular, the documents
-titled [Debugging the Swift Compiler](docs/DebuggingTheCompiler.md) and
+Be sure to look at the [documentation index](/docs/README.md) for a bird's eye
+view of the available documentation. In particular, the documents titled
+[Debugging the Swift Compiler](docs/DebuggingTheCompiler.md) and
 [Continuous Integration for Swift](docs/ContinuousIntegration.md) are very
 helpful to understand before submitting your first PR.
-
-### Building Documentation
-
-To read the compiler documentation, start by installing the
-[Sphinx](http://sphinx-doc.org) documentation generator tool by running the
-command:
-
-    easy_install -U "Sphinx < 2.0"
-
-Once complete, you can build the Swift documentation by changing directory into
-[docs](https://github.com/apple/swift/tree/master/docs) and typing `make`. This
-compiles the `.rst` files in the [docs](https://github.com/apple/swift/tree/master/docs)
-directory into HTML in the `docs/_build/html` directory.
-
-Many of the docs are out of date, but you can see some historical design
-documents in the `docs` directory.
-
-Another source of documentation is the standard library itself, located in
-`stdlib`. Much of the language is actually implemented in the library
-(including `Int`), and the standard library gives some examples of what can be
-expressed today.
-
-## Build Dependencies
-
-### CMake
-[CMake](https://cmake.org) is the core infrastructure used to configure builds of
-Swift and its companion projects; at least version 3.16.5 is required.
-
-On macOS, you can download the [CMake Binary Distribution](https://cmake.org/download),
-bundled as an application, copy it to `/Applications`, and add the embedded
-command line tools to your `PATH`:
-
-    export PATH=/Applications/CMake.app/Contents/bin:$PATH
-
-On Linux, if you have not already installed Swift's [development
-dependencies](#linux), you can download and install the CMake
-package separately using the following command:
-
-    sudo apt-get install cmake
-
-
-### Ninja
-[Ninja](https://ninja-build.org) is the current recommended build system
-for building Swift and is the default configuration generated by CMake. [Pre-built
-packages](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages)
-are available for macOS and Linux distributions. You can also clone Ninja
-next to the other projects and it will be bootstrapped automatically:
-
-**Via HTTPS**
-
-    git clone https://github.com/ninja-build/ninja.git && cd ninja
-    git checkout release
-    cat README
-
-**Via SSH**
-
-    git clone git@github.com:ninja-build/ninja.git && cd ninja
-    git checkout release
-    cat README
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 1f0f581..f638601 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -91,6 +91,7 @@
     single-source/Fibonacci
     single-source/FindStringNaive
     single-source/FlattenList
+    single-source/FloatingPointConversion
     single-source/FloatingPointParsing
     single-source/FloatingPointPrinting
     single-source/Hanoi
diff --git a/benchmark/scripts/Template.swift b/benchmark/scripts/Template.swift
index 00337a1..ea25b24 100644
--- a/benchmark/scripts/Template.swift
+++ b/benchmark/scripts/Template.swift
@@ -2,7 +2,7 @@
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
+// Copyright (c) 2020 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
 // See https://swift.org/LICENSE.txt for license information
@@ -19,4 +19,4 @@
 @inline(never)
 public func run_{name}(N: Int) {{
     // TODO
-}}
\ No newline at end of file
+}}
diff --git a/benchmark/single-source/FloatingPointConversion.swift b/benchmark/single-source/FloatingPointConversion.swift
new file mode 100644
index 0000000..3ccddaa
--- /dev/null
+++ b/benchmark/single-source/FloatingPointConversion.swift
@@ -0,0 +1,162 @@
+//===--- FloatingPointConversion.swift ------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+import TestsUtils
+
+public let FloatingPointConversion = [
+  BenchmarkInfo(
+    name: "ConvertFloatingPoint.MockFloat64ToDouble",
+    runFunction: run_ConvertFloatingPoint_MockFloat64ToDouble,
+    tags: [.validation, .api],
+    setUpFunction: { blackHole(mockFloat64s) }),
+]
+
+protocol MockBinaryFloatingPoint: BinaryFloatingPoint {
+  associatedtype _Value: BinaryFloatingPoint
+  var _value: _Value { get set }
+  init(_ _value: _Value)
+}
+
+extension MockBinaryFloatingPoint {
+  static var exponentBitCount: Int { _Value.exponentBitCount }
+  static var greatestFiniteMagnitude: Self {
+    Self(_Value.greatestFiniteMagnitude)
+  }
+  static var infinity: Self { Self(_Value.infinity) }
+  static var leastNonzeroMagnitude: Self { Self(_Value.leastNonzeroMagnitude) }
+  static var leastNormalMagnitude: Self { Self(_Value.leastNormalMagnitude) }
+  static var nan: Self { Self(_Value.nan) }
+  static var pi: Self { Self(_Value.pi) }
+  static var signalingNaN: Self { Self(_Value.signalingNaN) }
+  static var significandBitCount: Int { _Value.significandBitCount }
+  
+  static func + (lhs: Self, rhs: Self) -> Self { Self(lhs._value + rhs._value) }
+  static func += (lhs: inout Self, rhs: Self) { lhs._value += rhs._value }
+  static func - (lhs: Self, rhs: Self) -> Self { Self(lhs._value - rhs._value) }
+  static func -= (lhs: inout Self, rhs: Self) { lhs._value -= rhs._value }
+  static func * (lhs: Self, rhs: Self) -> Self { Self(lhs._value * rhs._value) }
+  static func *= (lhs: inout Self, rhs: Self) { lhs._value *= rhs._value }
+  static func / (lhs: Self, rhs: Self) -> Self { Self(lhs._value / rhs._value) }
+  static func /= (lhs: inout Self, rhs: Self) { lhs._value /= rhs._value }
+  
+  init(_ value: Int) { self.init(_Value(value)) }
+  init(_ value: Float) { self.init(_Value(value)) }
+  init(_ value: Double) { self.init(_Value(value)) }
+#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
+  init(_ value: Float80) { self.init(_Value(value)) }
+#endif
+  init(integerLiteral value: _Value.IntegerLiteralType) {
+    self.init(_Value(integerLiteral: value))
+  }
+  init(floatLiteral value: _Value.FloatLiteralType) {
+    self.init(_Value(floatLiteral: value))
+  }
+  init(sign: FloatingPointSign, exponent: _Value.Exponent, significand: Self) {
+    self.init(
+      _Value(sign: sign, exponent: exponent, significand: significand._value))
+  }
+  init(
+    sign: FloatingPointSign,
+    exponentBitPattern: _Value.RawExponent,
+    significandBitPattern: _Value.RawSignificand
+  ) {
+    self.init(
+      _Value(
+        sign: sign,
+        exponentBitPattern: exponentBitPattern,
+        significandBitPattern: significandBitPattern))
+  }
+  
+  var binade: Self { Self(_value.binade) }
+  var exponent: _Value.Exponent { _value.exponent }
+  var exponentBitPattern: _Value.RawExponent { _value.exponentBitPattern }
+  var isCanonical: Bool { _value.isCanonical }
+  var isFinite: Bool { _value.isFinite }
+  var isInfinite: Bool { _value.isInfinite }
+  var isNaN: Bool { _value.isNaN }
+  var isNormal: Bool { _value.isNormal }
+  var isSignalingNaN: Bool { _value.isSignalingNaN }
+  var isSubnormal: Bool { _value.isSubnormal }
+  var isZero: Bool { _value.isZero }
+  var magnitude: Self { Self(_value.magnitude) }
+  var nextDown: Self { Self(_value.nextDown) }
+  var nextUp: Self { Self(_value.nextUp) }
+  var sign: FloatingPointSign { _value.sign }
+  var significand: Self { Self(_value.significand) }
+  var significandBitPattern: _Value.RawSignificand {
+    _value.significandBitPattern
+  }
+  var significandWidth: Int { _value.significandWidth }
+  var ulp: Self { Self(_value.ulp) }
+  
+  mutating func addProduct(_ lhs: Self, _ rhs: Self) {
+    _value.addProduct(lhs._value, rhs._value)
+  }
+  func advanced(by n: _Value.Stride) -> Self { Self(_value.advanced(by: n)) }
+  func distance(to other: Self) -> _Value.Stride {
+    _value.distance(to: other._value)
+  }
+  mutating func formRemainder(dividingBy other: Self) {
+    _value.formRemainder(dividingBy: other._value)
+  }
+  mutating func formSquareRoot() { _value.formSquareRoot() }
+  mutating func formTruncatingRemainder(dividingBy other: Self) {
+    _value.formTruncatingRemainder(dividingBy: other._value)
+  }
+  func isEqual(to other: Self) -> Bool { _value.isEqual(to: other._value) }
+  func isLess(than other: Self) -> Bool { _value.isLess(than: other._value) }
+  func isLessThanOrEqualTo(_ other: Self) -> Bool {
+    _value.isLessThanOrEqualTo(other._value)
+  }
+  mutating func round(_ rule: FloatingPointRoundingRule) { _value.round(rule) }
+}
+
+struct MockFloat64: MockBinaryFloatingPoint {
+  var _value: Double
+  init(_ _value: Double) { self._value = _value }
+}
+
+let doubles = [
+   1.8547832857295,  26.321549267719135, 98.9544480962058,    73.70286973782363,
+  82.04918555938816, 76.38902969312758,  46.35647857011161,   64.0821426030317,
+  97.82373347320156, 55.742361037720634, 23.677941665488856,  93.7347588108058,
+  80.72657040828412, 32.137580733275826, 64.78192587530002,   21.459686568896863,
+  24.88407660280718, 85.25905561999171,  12.858847331083556,  29.418845887252864,
+  67.64627066438761, 68.09883494078815,  57.781587230862094,  63.38335631088038,
+  83.31376661495327, 87.45936846358906,   0.6757674136841918, 86.45465036820696,
+  84.72715137492781, 82.67894289189142,  26.1667640621554,    21.24895661442493,
+  65.06399183516027, 90.06549073883058,  59.2736650501005,    94.5800380563246,
+  84.22617424003917, 26.93158630395639,   9.069952095976841,  96.10067836567679,
+  62.60505762081415, 29.57878462599286,  66.06040114311294,   51.709999429326636,
+  64.79777579583545, 45.25948795832151,  94.31492354198335,   52.31096166433902,
+]
+
+let mockFloat64s = doubles.map { MockFloat64($0) }
+
+@inline(__always)
+func convert<
+  T: BinaryFloatingPoint, U: BinaryFloatingPoint
+>(_ value: T, to: U.Type) -> U {
+  U(value)
+}
+
+// See also: test/SILOptimizer/floating_point_conversion.swift
+
+@inline(never)
+public func run_ConvertFloatingPoint_MockFloat64ToDouble(_ N: Int) {
+  for _ in 0..<(N * 100) {
+    for element in mockFloat64s {
+      let f = Double(identity(element))
+      blackHole(f)
+    }
+  }
+}
diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift
index aa3504b..160c4eb 100644
--- a/benchmark/utils/main.swift
+++ b/benchmark/utils/main.swift
@@ -79,6 +79,7 @@
 import Fibonacci
 import FindStringNaive
 import FlattenList
+import FloatingPointConversion
 import FloatingPointParsing
 import FloatingPointPrinting
 import Hanoi
@@ -266,6 +267,7 @@
 registerBenchmark(FindStringNaive)
 registerBenchmark(FlattenListLoop)
 registerBenchmark(FlattenListFlatMap)
+registerBenchmark(FloatingPointConversion)
 registerBenchmark(FloatingPointParsing)
 registerBenchmark(FloatingPointPrinting)
 registerBenchmark(Hanoi)
diff --git a/cmake/caches/Runtime-Windows-x86_64.cmake b/cmake/caches/Runtime-Windows-x86_64.cmake
new file mode 100644
index 0000000..5fc88c2
--- /dev/null
+++ b/cmake/caches/Runtime-Windows-x86_64.cmake
@@ -0,0 +1,20 @@
+
+set(SWIFT_HOST_VARIANT_SDK WINDOWS CACHE STRING "")
+set(SWIFT_HOST_VARIANT_ARCH x86_64 CACHE STRING "")
+
+# NOTE(compnerd) disable the tools, we are trying to build just the standard
+# library.
+set(SWIFT_INCLUDE_TOOLS NO CACHE BOOL "")
+
+# NOTE(compnerd) cannot build tests since the tests require the toolchain
+set(SWIFT_INCLUDE_TESTS NO CACHE BOOL "")
+
+# NOTE(compnerd) cannot build docs since that requires perl
+set(SWIFT_INCLUDE_DOCS NO CACHE BOOL "")
+
+# NOTE(compnerd) these are part of the toolchain, not the runtime.
+set(SWIFT_BUILD_SYNTAXPARSERLIB NO CACHE BOOL "")
+set(SWIFT_BUILD_SOURCEKIT NO CACHE BOOL "")
+
+# NOTE(compnerd) build with the compiler specified, not a just built compiler.
+set(SWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER YES CACHE BOOL "")
diff --git a/docs/Branches.md b/docs/Branches.md
index 083f896..036849f 100644
--- a/docs/Branches.md
+++ b/docs/Branches.md
@@ -18,11 +18,11 @@
 
 ## The Release Branches
 
-| Swift            | LLVM Project
-| ---------------- | ----------------------
-| swift-x.y-branch | swift/swift-x.y-branch
+| Swift       | LLVM Project
+| ----------- | -----------------
+| release/x.y | swift/release/x.y
 
-At some point before a release, a *release branch* will be created in every repository with a name like `swift-4.0-branch`. (The actual number is chosen by Apple.) After the branch has been created, commits must make it to this branch to make it into the release. In some cases, the [release manager][] for the branch will decide to merge in all additional changes from `master`; otherwise, cherry-picking changes and making a new pull request is the way to go. If there are any "patch" releases (e.g. Swift 4.0.1), they will also come from this branch.
+At some point before a release, a *release branch* will be created in every repository with a name like `release/5.3`. (The actual number is chosen by Apple.) After the branch has been created, commits must make it to this branch to make it into the release. In some cases, the [release manager][] for the branch will decide to merge in all additional changes from `master`; otherwise, cherry-picking changes and making a new pull request is the way to go. If there are any "patch" releases (e.g. Swift 5.3.1), they will also come from this branch.
 
 Note that these branches come not from the "development" branches (above), but the "upstream" branches (below). This is because they need to contain the latest changes not just from Swift, but from the LLVM project as well. For some releases, the release branch for the LLVM project will be timed to coincide with the corresponding llvm.org release branch.
 
@@ -35,7 +35,7 @@
 
 `swift/master-next` is a branch for LLVM that includes all changes necessary to support Swift. Changes from llvm.org's master branch are automatically merged in. Why isn't this just `swift/master`? Well, because LLVM changes *very* rapidly, and that wouldn't be very stable. However, we do want to make sure the Swift stuff keeps working.
 
-If you are making changes to LLVM to support Swift, you'll probably need to work on them in `swift/master` to test them against Swift itself, but they should be committed to `swift/master-next`, and cherry-picked to the current release branch (`swift/swift-x.y-branch`) if needed. Remember, the release branches are automerged into `swift/master` on a regular basis.
+If you are making changes to LLVM to support Swift, you'll probably need to work on them in `swift/master` to test them against Swift itself, but they should be committed to `swift/master-next`, and cherry-picked to the current release branch (`swift/release/x.y`) if needed. Remember, the release branches are automerged into `swift/master` on a regular basis.
 
 (If you're making changes to LLVM Project that *aren't* about Swift, they should generally be made on llvm.org instead, then cherry-picked to the active release branch or `swift/master`.)
 
@@ -83,6 +83,6 @@
 - `master` is automerged into `master-next`
 
 ### LLVM Project
-- `swift/swift-x.y-branch` (the *latest* release branch) is automerged into `swift/master`
+- `swift/release/x.y` (the *latest* release branch) is automerged into `swift/master`
 - llvm.org's `master` is automerged into `swift/master-next`
-- llvm.org's release branch *may* be automerged into `swift/swift-x.y-branch`, if they are in sync
+- llvm.org's release branch *may* be automerged into `swift/release/x.y`, if they are in sync
diff --git a/docs/DynamicCasting.md b/docs/DynamicCasting.md
index 72b369b..0efc4fc 100644
--- a/docs/DynamicCasting.md
+++ b/docs/DynamicCasting.md
@@ -43,7 +43,12 @@
 a as! Int == a // true
 ```
 
-## Classes
+## Class and Foreign Types
+
+Class types generally follow standard object-oriented casting conventions.
+Objective-C and CoreFoundation (CF) types follow the behaviors expected from Objective-C.
+
+### Classes
 
 Casting among class types follows standard object-oriented programming conventions:
 
@@ -62,31 +67,80 @@
 * For any class type `C`: `c is C` iff `(c as! AnyObject) is C`
 * For any class type `C`: if `c is C`, then `(c as! AnyObject) as! C === c`
 
-## Structs and Enums
+### CoreFoundation types
+
+* If `CF` is a CoreFoundation type, `cf` is an instance of `CF`, and `NS` is the corresponding Objective-C type, then `cf is NS == true`
+* Further, since every Objective-C type inherits from `NSObject`, `cf is NSObject == true`
+* In the above situation, if `T` is some other type and `cf is NS == true`, then `cf as! NS is T` iff `cf is T`.
+
+The intention of the above is to treat instances of CoreFoundation types as being simultaneously instances of the corresponding Objective-C type, in keeping with the general dual nature of these types.
+In particular, if a protocol conformance is declared on the Objective-C type, then instances of the CoreFoundation type can be cast to the protocol type directly.
+
+XXX TODO: Converse?  If ObjC instance has CF equivalent and CF type is extended, ... ??
+
+### Objective-C types
+
+The following discussion applies in three different cases:
+* _Explicit_ conversions from use of the `is`, `as?`, and `as!` operators.
+* _Implicit_ conversions from Swift to Objective-C:  These conversions are generated automatically when Swift code calls an Objective-C function or method with an argument that is not already of an Objective-C type, or when a Swift function returns a value to an Objective-C caller.
+* _Implicit_ conversions from Objective-C to Swift:  These are generated automatically when arguments are passed from an Objective-C caller to a Swift function, or when an Objective-C function returns a value to a Swift caller.
+Unless stated otherwise, all of the following cases apply equally to all three of the above cases.
+
+Explicit casts among Swift and Objective-C class types follow the same general rules described earlier for class types in general.
+Likewise, explicitly casting a class instance to an Objective-C protocol type follows the general rules for casts to protocol types.
+
+XXX TODO EXPLAIN Implicit conversions from Objective-C types to Swift types XXXX.
+
+CoreFoundation types can be explicitly cast to and from their corresponding Objective-C types as described above.
+
+Objective-C types and protocols
+* `T` is an Objective-C class type iff `T.self is NSObject.Type`
+* `P` is an Objective-C protocol iff XXX TODO XXX
+
+### The `_ObjectiveCBridgeable` Protocol
+
+The `_ObjectiveCBridgeable` protocol allows certain types to opt into custom casting behavior.
+Note that although this mechanism was explicitly designed to simplify Swift interoperability with Objective-C, it is not necessarily tied to Objective-C.
+
+The `_ObjectiveCBridgeable` protocol defines an associated reference type `_ObjectiveCType`, along with a collection of methods that support casting to and from the associated `_ObjectiveCType`.
+This protocol allows library code to provide tailored mechanisms for casting Swift types to reference types.
+When casting to `AnyObject`, the casting logic prefers this tailored mechanism to the general `_SwiftValue` container mentioned above.
+
+Note: The associated `_ObjectiveCType` is constrained to be a subtype of `AnyObject`; it is not limited to being an actual Objective-C type.
+In particular, this mechanism is equally available to the Swift implementation of Foundation on non-Apple platforms and the Objective-C Foundation on Apple platforms.
+
+Example #1:  Foundation extends the `Array` type in the standard library with an `_ObjectiveCBridgeable` conformance to `NSArray`.  This allows Swift arrays to be cast to and from Foundation `NSArray` instances.
+```
+let a = [1, 2, 3] // Array<Int>
+let b = a as? AnyObject // casts to NSArray
+```
+
+Example #2:  Foundation also extends each Swift numeric type with an `_ObjectiveCBridgeable` conformance to `NSNumber`.
+```
+let a = 1 // Int
+// After the next line, b is an Optional<AnyObject>
+// holding a reference to an NSNumber
+let b = a as? AnyObject
+// NSNumber is bridgeable to Double
+let c = b as? Double
+```
+
+## Other Concrete Types
+
+In addition to the class types described earlier, Swift has several other kinds of concrete types.
+
+Casting between the different kinds described below (such as casting an enum to a tuple) will always fail.
+
+### Structs and Enums
 
 You cannot cast between different concrete struct or enum types.
 More formally:
 
 * If `S` and `T` are struct or enum types and `s is S == true`, then `s is T` iff `S.self == T.self`.
 
-## Tuples
+Struct or enum types can be cast to class types if the struct or enum implements the `_ObjectiveCBridgeable` protocol as described earlier.
 
-Casting from a tuple type T1 to a tuple type T2 will succeed iff the following hold:
-* T1 and T2 have the same number of elements
-* If an element has a label in both T1 and T2, the labels are identical
-* Each element of T1 can be individually cast to the corresponding type of T2
-
-## Functions
-
-Casting from a function type F1 to a function type F2 will succeed iff the following hold:
-* The two types have the same number of arguments
-* Corresponding arguments have identical types
-* The return types are identical
-* If F1 is a throwing function type, then F2 must be a throwing function type.  If F1 is not throwing, then F2 may be a throwing or non-throwing function type.
-
-Note that it is _not_ sufficient for argument and return types to be castable; they must actually be identical.
-
-## Optionals
+### Optionals
 
 Casting to and from optional types will transparently unwrap optionals as much as necessary, including nested optional types.
 
@@ -156,92 +210,7 @@
 t4 as? U?? // Produces .some(.none)
 ```
 
-## Any
-
-Any Swift instance can be cast to the type `Any`.
-An instance of `Any` has no useful methods or properties; to utilize the contents, you must cast it to another type.
-Every type identifier is an instance of the metatype `Any.Type`.
-
-Invariants
-* If `t` is any instance, then `t is Any == true`
-* If `t` is any instance, `t as! Any` always succeeds
-* For every type `T` (including protocol types), `T.self is Any.Type`
-* If `t` is any instance and `U` is any `Equatable` type, then `t as? U == (t as! Any) as? U`.
-
-This last invariant deserves some explanation, as a similar pattern appears repeatedly throughout this document.
-In essence, this invariant just says that putting something into an "Any box" (`t as! Any`) and taking it out again (`as? U`) does not change the result.
-The requirement that `U` be `Equatable` is a technical necessity for using `==` in this statement.
-
-Note that in many cases, we've shortened such invariants to the form `t is U == (t as! Any) is U`.
-Using `is` here simply avoids the technical necessity that `U` be `Equatable` but except where explicitly called out, the intention in every case is that such casting does not change the value.
-
-## AnyObject
-
-Any class, enum, struct, tuple, function, metatype, or existential metatype instance can be cast to `AnyObject`.
-
-XXX TODO The runtime logic has code to cast protocol types to `AnyObject` only if they are compatible with `__SwiftValue`.  What is the practical effect of this logic?  Does it mean that casting a protocol type to `AnyObject` will sometimes unwrap (if the protocol is incompatible) and sometimes not?  What protocols are affected by this?
-
-The contents of an `AnyObject` container can be accessed by casting to another type:
-* If `t` is any instance, `U` is any type, `t is AnyObject` and `t is U`, then `(t as! AnyObject) is U`.
-
-Implementation Note: `AnyObject` is represented in memory as a pointer to a refcounted object.  The dynamic type of the object can be recovered from the "isa" field of the object.  The optional form `AnyObject?` is the same except that it allows null.  Reference types (class, metatype, or existential metatype instances) can be directly assigned to an `AnyObject` without any conversion.  For non-reference types -- including struct, enum, and tuple types -- the casting logic will first look for an `_ObjectiveCBridgeable` conformance that it can use to convert the source into a tailored reference type.  If that fails, the value will be copied into an opaque `_SwiftValue` container.
-
-(See "The _ObjectiveCBridgeable Protocol" below for more details.)
-
-### Objective-C Interactions
-
-Note the invariant above cannot be an equality because Objective-C bridging allows libraries to introduce new relationships that can alter the behavior of seemingly-unrelated casts.
-One example of this is Foundation's `NSNumber` type which conditionally bridges to several Swift numeric types.
-As a result, when Foundation is in scope, `Int(7) is Double == false` but `(Int(7) as! AnyObject) is Double == true`.
-In general, the ability to add new bridging behaviors from a single type to several distinct types implies that Swift casting cannot be transitive.
-
-## Error (SE-0112)
-
-Although the Error protocol is specially handled by the Swift compiler and runtime (as detailed in [SE-0112](https://github.com/apple/swift-evolution/blob/master/proposals/0112-nserror-bridging.md)), it behaves like an ordinary protocol type for casting purposes.
-
-(See "Note: 'Self-conforming' protocols" below for additional details relevant to the Error protocol.)
-
-## AnyHashable (SE-0131)
-
-For casting purposes, `AnyHashable` behaves like a protocol type.
-
-## Existential/Protocol types
-
-Caveat:
-Protocols that have `associatedtype` properties or which make use of the `Self` typealias cannot be used as independent types.
-As such, the discussion below does not apply to them.
-
-Any Swift instance of a concrete type `T` can be cast to `P` iff `T` conforms to `P`.
-The result is a "protocol witness" instance that provides access only to those methods and properties defined on `P`.
-Other capabilities of the type `T` are not accessible from a `P` instance.
-
-The contents of a protocol witness can be accessed by casting to some other appropriate type:
-* For any protocol `P`, instance `t`, and type `U`, if `t is P`, then `t as? U == (t as! P) as? U`
-
-XXX TODO: The invariant above does not apply to AnyObject, AnyHashable.
-Does it suffice to explicitly exclude those two, or do other protocols share that behavior?  The alternative would seem to be to change the equality here into an implication.
-
-In addition to the protocol witness type, every Swift protocol `P` implicitly defines two other types:
-`P.Protocol` is the "protocol metatype", the type of `P.self`.
-`P.Type` is the "protocol existential metatype".
-These are described in more detail below.
-
-Regarding Protocol casts and Optionals
-
-When casting an Optional to a protocol type, the optional is preserved if possible.
-Given an instance `o` of type `Optional<T>` and a protocol `P`, the cast request `o as? P` will produce different results depending on whether `Optional<T>` directly conforms to `P`:
-
-* If `Optional<T>` conforms to `P`, then the result will be a protocol witness wrapping the `o` instance.  In this case, a subsequent cast to `Optional<T>` will restore the original instance.  In particular, this case will preserve `nil` instances.
-
-* If `Optional<T>` does not directly conform, then `o` will be unwrapped and the cast will be attempted with the contained object.  If `o == nil`, this will fail.  In the case of a nested optional `T???` this will result in fully unwrapping the inner non-optional.
-
-* If all of the above fail, then the cast will fail.
-
-For example, `Optional` conforms to `CustomDebugStringConvertible` but not to `CustomStringConvertible`.
-Casting an optional instance to the first of these protocols will result in an item whose `.debugDescription` will describe the optional instance.
-Casting an optional instance to the second will provide an instance whose `.description` property describes the inner non-Optional instance.
-
-## Array/Set/Dictionary Casts
+### Array/Set/Dictionary Casts
 
 For Array, Set, or Dictionary types, you can use the casting operators to translate to another instance of the same outer container (Array, Set, or Dictionary respectively) with a different component type.
 Note that the following discussion applies only to these specific types.
@@ -307,7 +276,7 @@
 }
 ```
 
-### Collection Casting performance and `as!`
+#### Collection Casting performance and `as!`
 
 For `as?` casts, the casting behavior above requires that every element be converted separately.
 This can be a particular bottleneck when trying to share large containers between Swift and Objective-C code.
@@ -317,8 +286,131 @@
 Such lazy conversion can provide a significant performance improvement in cases where the data is known (by the programmer) to be safe and where the inner component casts are non-trivial.
 However, if the conversion cannot be completed, it is indeterminate whether the cast request will fail immediately or whether the program will fail at some later point.
 
+### Tuples
+
+Casting from a tuple type T1 to a tuple type T2 will succeed iff the following hold:
+* T1 and T2 have the same number of elements
+* If an element has a label in both T1 and T2, the labels are identical
+* Each element of T1 can be individually cast to the corresponding type of T2
+
+### Functions
+
+Casting from a function type F1 to a function type F2 will succeed iff the following hold:
+* The two types have the same number of arguments
+* Corresponding arguments have identical types
+* The return types are identical
+* If F1 is a throwing function type, then F2 must be a throwing function type.  If F1 is not throwing, then F2 may be a throwing or non-throwing function type.
+
+Note that it is _not_ sufficient for argument and return types to be castable; they must actually be identical.
+
+## Existential Types
+
+Conceptually, an "existential type" is an opaque wrapper that carries a type and an instance of that type.
+The various existential types differ in what kinds of types they can hold (for example, `AnyObject` can only hold reference types) and in the capabilities exposed by the container (`AnyHashable` exposes equality testing and hashing).
+
+The key invariant for existential types `E` is the following:
+* Strong existential invariant: If `t` is any instance, `U` is any type, and `t is E` then `(t as! E) as? U` produces the same result as `t as? U`
+
+Intuitively, this simply says that if you can put an instance `t` into an existential `E`, then you can take it back out again via casting.
+For Equatable types, this implies that the results of the two operations here are equal to each other when they succeed.
+It also implies that if either of these `as?` casts fails, so will the other.
+
+`AnyObject` and `AnyHashable` do not fully satisfy the strong invariant described above.  Instead, they satisfy the following weaker version:
+* Weak existential invariant: If `t` is any instance, `U` is any type, and both `t is U` and `t is E`, then `(t as! E) as? U` produces the same result as `t as? U`
+
+### Objective-C Interactions
+
+The difference between the strong and weak existential invariants comes about because casting to `AnyObject` or `AnyHashable` can trigger Objective-C bridging conversions.
+The result of these conversions may support casts that the original type did not.
+As a result, `(t as! E)` may be castable to `U` even if `t` alone is not directly castable.
+
+One example of this is Foundation's `NSNumber` type which conditionally bridges to several Swift numeric types.
+As a result, when Foundation is in scope, `Int(7) is Double == false` but `(Int(7) as! AnyObject) is Double == true`.
+In general, the ability to add new bridging behaviors from a single type to several distinct types implies that Swift casting cannot be transitive.
+
+### Any
+
+Any Swift instance can be cast to the type `Any`.
+An instance of `Any` has no useful methods or properties; to utilize the contents, you must cast it to another type.
+Every type identifier is an instance of the metatype `Any.Type`.
+
+Invariants
+* If `t` is any instance, then `t is Any == true`
+* If `t` is any instance, `t as! Any` always succeeds
+* For every type `T` (including protocol types), `T.self is Any.Type`
+* Strong existential invariant: If `t` is any instance and `U` is any type, then `(t as! Any) as? U` produces the same result as `t as? U`.
+
+### AnyObject
+
+Any class, enum, struct, tuple, function, metatype, or existential metatype instance can be cast to `AnyObject`.
+
+XXX TODO The runtime logic has code to cast protocol types to `AnyObject` only if they are compatible with `__SwiftValue`.  What is the practical effect of this logic?  Does it mean that casting a protocol type to `AnyObject` will sometimes unwrap (if the protocol is incompatible) and sometimes not?  What protocols are affected by this?
+
+The contents of an `AnyObject` container can be accessed by casting to another type:
+* Weak existential invariant: If `t` is any instance, `U` is any type, `t is AnyObject`, and `t is U`, then `(t as! AnyObject) as? U` will produce the same result as `t as? U`
+
+Implementation Note: `AnyObject` is represented in memory as a pointer to a refcounted object.  The dynamic type of the object can be recovered from the "isa" field of the object.  The optional form `AnyObject?` is the same except that it allows null.  Reference types (class, metatype, or existential metatype instances) can be directly assigned to an `AnyObject` without any conversion.  For non-reference types -- including struct, enum, and tuple types -- the casting logic will first look for an `_ObjectiveCBridgeable` conformance that it can use to convert the source into a tailored reference type.  If that fails, the value will be copied into an opaque `_SwiftValue` container.
+
+(See "The _ObjectiveCBridgeable Protocol" below for more details.)
+
+### Error (SE-0112)
+
+The `Error` type behaves like an ordinary existential type for casting purposes.
+
+(See "Note: 'Self-conforming' protocols" below for additional details relevant to the `Error` protocol.)
+
+### AnyHashable (SE-0131)
+
+For casting purposes, `AnyHashable` behaves like an existential type.
+It satisfies the weak existential invariant above.
+
+However, note that `AnyHashable` does not act like an existential for other purposes.
+For example, it's metatype is named `AnyHashable.Type` and it does not have an existential metatype.
+
+### Protocol Witness types
+
+Any protocol definition (except those that include an `associatedtype` property or which makes use of the `Self` typealias) has an associated existential type named after the protocol.
+
+Specifically, assume you have a protocol definition
+```
+protocol P {}
+```
+
+As a result of this definition, there is an existential type (also called `P`).
+This existential type is also known as a "protocol witness type" since it exposes exactly the capabilities that are defined by the protocol.
+Other capabilities of the type `T` are not accessible from a `P` instance.
+Any Swift instance of a concrete type `T` can be cast to the type `P` iff `T` conforms to the protocol `P`.
+
+The contents of a protocol witness can be accessed by casting to some other appropriate type:
+* Strong existential Invariant: For any protocol `P`, instance `t`, and type `U`, if `t is P`, then `t as? U` produces the same result as `(t as! P) as? U`
+
+In addition to the protocol witness type `P`, every Swift protocol `P` implicitly defines two other types:
+`P.Protocol` is the "protocol metatype", the type of `P.self`.
+`P.Type` is the "protocol existential metatype".
+These are described in more detail below.
+
+Regarding Protocol casts and Optionals
+
+When casting an Optional to a protocol type, the optional is preserved if possible.
+Given an instance `o` of type `Optional<T>` and a protocol `P`, the cast request `o as? P` will produce different results depending on whether `Optional<T>` directly conforms to `P`:
+
+* If `Optional<T>` conforms to `P`, then the result will be a protocol witness wrapping the `o` instance.  In this case, a subsequent cast to `Optional<T>` will restore the original instance.  In particular, this case will preserve `nil` instances.
+
+* If `Optional<T>` does not directly conform, then `o` will be unwrapped and the cast will be attempted with the contained object.  If `o == nil`, this will fail.  In the case of a nested optional `T???` this will result in fully unwrapping the inner non-optional.
+
+* If all of the above fail, then the cast will fail.
+
+For example, `Optional` conforms to `CustomDebugStringConvertible` but not to `CustomStringConvertible`.
+Casting an optional instance to the first of these protocols will result in an item whose `.debugDescription` will describe the optional instance.
+Casting an optional instance to the second will provide an instance whose `.description` property describes the inner non-Optional instance.
+
 ## Metatypes
 
+Swift supports two kinds of metatypes:
+In addition to the regular metatypes supported by many other languages, it also has _existential_ metatypes that can be used to access static protocol requirements.
+
+### Metatypes
+
 For every type `T`, there is a unique instance `T.self` that represents the type at runtime.
 As with all instances, `T.self` has a type.
 We call this type the "metatype of `T`".
@@ -338,9 +430,11 @@
 ```
 
 For most Swift types, the metatype of `T` is named `T.Type`.
-However, in two cases the metatype has a different name:
+However, in the following cases the metatype has a different name:
 * For a nominal protocol type `P`, the metatype is named `P.Protocol`
-* For a type bound to a generic variable `G`, the metatype is named `G.Type` _even if `G` is bound to a protocol type_.  Specifically, if `G` is bound to the nominal protocol type `P`, then `G.Type` is another name for the metatype `P.Protocol`, and hence `G.Type.self == P.Protocol.self`.
+* For non-protocol existential types `E`, the metatype is also named `E.Protocol`.  For example, `Any.Protocol`, `AnyObject.Protocol`, and `Error.Protocol`.
+* For a type bound to a generic variable `G`, the metatype is named `G.Type` _even if `G` is bound to a protocol or existential type_.  Specifically, if `G` is bound to the nominal protocol type `P`, then `G.Type` is another name for the metatype `P.Protocol`, and hence `G.Type.self == P.Protocol.self`.
+* As explained above, although `AnyHashable` behaves like an existential type in some respects, its metatype is called `AnyHashable.Type`.
 
 Example:
 ```
@@ -352,7 +446,7 @@
 type(of: s) == S.self // always true
 type(of: S.self) == S.Type.self
 
-// Metatype of a protocol type
+// Metatype of a protocol (or other existential) type
 protocol P {}
 P.self is P.Protocol // always true
 // P.Protocol is a metatype, not a protocol, so:
@@ -372,12 +466,12 @@
 * For a nominal non-protocol type `T`, `T.self is T.Type`
 * For a nominal protocol type `P`, `P.self is P.Protocol`
 * `P.Protocol` is a singleton: `T.self is P.Protocol` iff `T` is exactly `P`
-* A non-protocol type `T` conforms to a protocol `P` iff `T.self is P.Type`
+* A non-protocol type `T` conforms to a protocol `P` iff `T.self is P.Type`  (If `T` is a protocol type, see "Self conforming existential types" below for details.)
 * `T` is a subtype of a non-protocol type `U` iff `T.self is U.Type`
 * Subtypes define metatype subtypes: if `T` and `U` are non-protocol types, `T.self is U.Type == T.Type.self is U.Type.Type`
 * Subtypes define metatype subtypes: if `T` is a non-protocol type and `P` is a protocol type, `T.self is P.Protocol == T.Type.self is P.Protocol.Type`
 
-## Existential Metatypes
+### Existential Metatypes
 
 Protocols can specify constraints and provide default implementations for instances of types.
 They can also specify constraints and provide default implementations for static members of types.
@@ -412,7 +506,7 @@
 * Since every type `T` conforms to `Any`, `T.self is Any.Type` is always true
 * Since every class type `C` conforms to `AnyObject`, `C.self is AnyObject.Type` is always true (this includes Objective-C class types)
 
-### Note: "Self conforming" protocols
+### Note: "Self conforming" existential types
 
 As mentioned above, a protocol definition for `P` implicitly defines types `P.Type` (the existential metatype) and `P.Protocol` (the metatype).
 It also defines an associated type called `P` which is the type of a container that can hold any object whose concrete type conforms to the protocol `P`.
@@ -438,9 +532,10 @@
 let b : MyGenericType(a)
 ```
 As above, since `a` has type `P`, this code is instantiating `MyGenericType` with `T = P`, which is only valid if `P` conforms to `P`.
-
 Note that any protocol that specifies static methods, static properties, associated types, or initializers cannot possibly be self-conforming.
-As of Swift 5.3, the only self-conforming protocols are `Any`, `Error`, and Objective-C protocols that have no static requirements.
+
+Although the discussion above specifically talks about protocols, it applies equally well to other existential types.
+As of Swift 5.3, the only self-conforming existential types are `Any`, `Error`, and Objective-C protocols that have no static requirements.
 
 Invariants
 * `Any` self-conforms: `Any.self is Any.Type == true`
@@ -449,64 +544,6 @@
 
 For example, the last invariant here implies that for any Objective-C protocol `OP` that has no static requirements, `OP.self is AnyObject.Type`.  This follows from the fact that `OP` self-conforms and that every Objective-C protocol has `AnyObject` as an implicit parent protocol.
 
-## CoreFoundation types
-
-* If `CF` is a CoreFoundation type, `cf` is an instance of `CF`, and `NS` is the corresponding Objective-C type, then `cf is NS == true`
-* Further, since every Objective-C type inherits from `NSObject`, `cf is NSObject == true`
-* In the above situation, if `T` is some other type and `cf is NS == true`, then `cf as! NS is T` iff `cf is T`.
-
-The intention of the above is to treat instances of CoreFoundation types as being simultaneously instances of the corresponding Objective-C type, in keeping with the general dual nature of these types.
-In particular, if a protocol conformance is declared on the Objective-C type, then instances of the CoreFoundation type can be cast to the protocol type directly.
-
-XXX TODO: Converse?  If ObjC instance has CF equivalent and CF type is extended, ... ??
-
-## Objective-C types
-
-The following discussion applies in three different cases:
-* _Explicit_ conversions from use of the `is`, `as?`, and `as!` operators.
-* _Implicit_ conversions from Swift to Objective-C:  These conversions are generated automatically when Swift code calls an Objective-C function or method with an argument that is not already of an Objective-C type, or when a Swift function returns a value to an Objective-C caller.
-* _Implicit_ conversions from Objective-C to Swift:  These are generated automatically when arguments are passed from an Objective-C caller to a Swift function, or when an Objective-C function returns a value to a Swift caller.
-Unless stated otherwise, all of the following cases apply equally to all three of the above cases.
-
-Explicit casts among Swift and Objective-C class types follow the same general rules described earlier for class types in general.
-Likewise, explicitly casting a class instance to an Objective-C protocol type follows the general rules for casts to protocol types.
-
-XXX TODO EXPLAIN Implicit conversions from Objective-C types to Swift types XXXX.
-
-CoreFoundation types can be explicitly cast to and from their corresponding Objective-C types as described above.
-
-Objective-C types and protocols
-* `T` is an Objective-C class type iff `T.self is NSObject.Type`
-* `P` is an Objective-C protocol iff XXX TODO XXX
-
-## The `_ObjectiveCBridgeable` Protocol
-
-The `_ObjectiveCBridgeable` protocol allows certain types to opt into custom casting behavior.
-Note that although this mechanism was explicitly designed to simplify Swift interoperability with Objective-C, it is not necessarily tied to Objective-C.
-
-The `_ObjectiveCBridgeable` protocol defines an associated reference type `_ObjectiveCType`, along with a collection of methods that support casting to and from the associated `_ObjectiveCType`.
-This protocol allows library code to provide tailored mechanisms for casting Swift types to reference types.
-When casting to `AnyObject`, the casting logic prefers this tailored mechanism to the general `_SwiftValue` container mentioned above.
-
-Note: The associated `_ObjectiveCType` is constrained to be a subtype of `AnyObject`; it is not limited to being an actual Objective-C type.
-In particular, this mechanism is equally available to the Swift implementation of Foundation on non-Apple platforms and the Objective-C Foundation on Apple platforms.
-
-Example #1:  Foundation extends the `Array` type in the standard library with an `_ObjectiveCBridgeable` conformance to `NSArray`.  This allows Swift arrays to be cast to and from Foundation `NSArray` instances.
-```
-let a = [1, 2, 3] // Array<Int>
-let b = a as? AnyObject // casts to NSArray
-```
-
-Example #2:  Foundation also extends each Swift numeric type with an `_ObjectiveCBridgeable` conformance to `NSNumber`.
-```
-let a = 1 // Int
-// After the next line, b is an Optional<AnyObject>
-// holding a reference to an NSNumber
-let b = a as? AnyObject
-// NSNumber is bridgeable to Double
-let c = b as? Double
-```
-
 ## Implementation Notes
 
 Casting operators that appear in source code are translated into SIL in a variety of ways depending on the details of the types involved.
diff --git a/docs/GitHubCreatePRScreenshot.png b/docs/GitHubCreatePRScreenshot.png
new file mode 100644
index 0000000..e98f4c0
--- /dev/null
+++ b/docs/GitHubCreatePRScreenshot.png
Binary files differ
diff --git a/docs/HowToGuides/FAQ.md b/docs/HowToGuides/FAQ.md
new file mode 100644
index 0000000..51cd6d0
--- /dev/null
+++ b/docs/HowToGuides/FAQ.md
@@ -0,0 +1,131 @@
+# Frequently Asked Questions
+
+## Build System and CMake Configuration
+
+### How do I add a new file to CMake?
+
+If you forget to add a new file to the CMake configuration, you may end up with
+undefined symbol errors at link time.
+
+There should be a `CMakeLists.txt` in the directory where you added the new
+file, which has the list of different .h/.cpp files to be included in the build.
+Add your new file to that list.
+
+### How do I speed up iterating on changes to the build system?
+
+The general idea is to build as little as you can.
+- [Use `sccache`](/docs/HowToGuides/GettingStarted.md) or `ccache` if you
+  aren't doing so already.
+- Use `build-script`'s various `--skip-*` flags to skip configuring for
+  platforms that you do not care about.
+- If you're on macOS, use `--swift-darwin-supported-archs="x86_64"`.
+- Use a release build without assertions (`--release --no-assertions`).
+  While debuginfo and assertions are valuable to enable when working on the
+  toolchain itself, they are not so useful if you are working only on changes
+  to the build system.
+
+## Using a Locally Built Toolchain
+
+### How do I use a locally built compiler to build X?
+
+You can use the `SWIFT_EXEC` environment variable to use a locally
+built compiler to compile both packages and Xcode projects.
+
+1. For SwiftPM packages, pass the environment variable when invoking SwiftPM.
+   ```sh
+   # Assuming the current working directory contains the package, build the
+   # package using a custom compiler.
+   SWIFT_EXEC=/path/to/swiftc swift build
+   ```
+2. For Xcode projects, select the project in the Project Navigator. In the
+   Build Settings tab, click '+' and then 'Add User-Defined Setting'.
+   Create a build setting `SWIFT_EXEC` with the value set to `/path/to/swiftc`.
+   If you now do a clean build, your locally built compiler will be used.
+
+   At the time of writing, in the latest Xcode 12 beta, `SWIFT_EXEC` does not
+   work for SwiftPM integration inside Xcode, so this will not work for Xcode
+   projects that depend on SwiftPM packages.
+
+**Note:** Even thought the variable says 'SWIFT', it needs to point to
+'swift**c**', not 'swift'. The extra 'c' is not a typo.
+
+## Testing and CI
+
+### How do I reproduce/fix a test that fails in CI but passes for me locally?
+
+TODO: Write some tips here, point to Testing.md for simulator setup.
+
+## Documentation
+
+### Where can I find documentation on X?
+
+This very depends on what X is, but some broad guidelines are:
+
+1. Do a case-insensitive recursive string search.
+   - Use a specialized tool like [ripgrep](https://github.com/BurntSushi/ripgrep)
+     or [ag](https://github.com/ggreer/the_silver_searcher).
+   - Use 'Find in Workspace' in Xcode (<kbd>⌘</kbd>+<kbd>⇧</kbd>+<kbd>F</kbd>).
+   - Use `grep -i -r "mypattern" .`.
+2. Go through the [Documentation Index](/docs/README.md).
+
+### How do I build the documentation as HTML?
+
+You can build the ReST formatted documentation as HTML using Sphinx. Follow
+[Sphinx's installation instructions][] and check that `sphinx-build` is
+available on your `PATH`:
+
+[Sphinx's installation instructions]: https://www.sphinx-doc.org/en/master/usage/installation.html
+
+```sh
+sphinx-build --version
+```
+
+If that succeeds, you can build the documentation using `make`
+
+```sh
+make -C docs
+```
+
+(Tested with `sphinx-build` version 3.2.1.)
+
+This compiles the `.rst` files in the `docs` directory into HTML in the
+`docs/_build/html` directory.
+
+For the Markdown documentation, you can view the rendered HTML directly on
+GitHub. For example, this file is rendered on GitHub at
+https://github.com/apple/swift/tree/master/docs/HowToGuides/FAQ.md .
+
+HTML documentation for the standard library on Darwin platforms is hosted on the
+[Apple Developer website](https://developer.apple.com/documentation/swift/swift_standard_library).
+
+## Pull Request Workflow
+
+### How do I format my changes?
+
+First, install `clang-format` using your system's package manager. This should
+also install the `git-clang-format` script (try `git-clang-format --help`).
+In case it doesn't, you can replace `git-clang-format` in the following
+commands with `../llvm-project/clang/tools/clang-format/git-clang-format`.
+
+Start out at the tip of the branch where you want to reformat the commits.
+
+```
+# If there is only one commit that needs to be reformatted.
+git-clang-format HEAD~1
+git add .
+git commit --amend --no-edit
+
+# Say the last N commits need to be reformatted.
+# Mark them as 'edit' instead of 'pick'.
+git rebase -i HEAD~N
+# Re-run N times, reformatting each commit.
+git-clang-format HEAD~1
+git add .
+git commit --amend --no-edit
+git rebase --continue
+```
+
+### How do I clean up my git history?
+
+TODO: Link to a beginner-friendly external resource, or (less preferably)
+describe basic usage of rebase here.
diff --git a/docs/HowToGuides/FirstPullRequest.md b/docs/HowToGuides/FirstPullRequest.md
new file mode 100644
index 0000000..ea7d523
--- /dev/null
+++ b/docs/HowToGuides/FirstPullRequest.md
@@ -0,0 +1,179 @@
+# How to Submit Your First Pull Request
+
+So you've decided to contribute to the Swift toolchain, welcome!
+Maybe this is your first time contributing to an open source project, or maybe
+you are an experienced open source contributor who is excited about Swift, or
+maybe you are somewhere in-between. Regardless of your background, we are
+excited to have you contribute and improve the developer experience for Swift
+programmers all over the globe.
+:sparkles::child::student::woman_technologist::technologist::man_technologist::sparkles:
+
+This document provides a high-level overview of different parts of the
+contribution process.
+
+## How do I pick something to work on?
+
+In case you don't have something specific you'd like to work on, such as
+implementing something for a Swift Evolution pitch, you could start off by
+working on a bug labeled `StarterBug` on [Swift JIRA][StarterBug]. If the
+bug hasn't been assigned to someone, check the comments in case someone has
+already started working on it. If not, feel free to assign it to yourself and
+start working on it!
+
+[StarterBug]: https://bugs.swift.org/issues/?jql=labels%20%3D%20StarterBug%20AND%20(status%20%3D%20Open%20OR%20status%20%3D%20Reopened)%20AND%20project%20%3D%20Swift
+
+## Getting Help
+
+Usually, Starter Bugs try to provide some instructions to help you get started.
+In case those are missing, please ask the bug reporter for more detailed steps
+and they will be happy to help.
+
+Once you start working on the bug, you will inevitably end up having a lot of
+questions. Don't be afraid to ask for help! The codebase is large and wrapping
+your head around it will take time. For example, you might have questions like:
+
+- Where can I find documentation on X?
+- I'm seeing a cryptic error E when trying to build the compiler. How do I fix
+  it or work around it?
+- I'm seeing very long build times even for incremental builds. How do I speed
+  up iteration time?
+- I'm not sure how to implement X. Any suggestions on where I should start?
+- What is the difference between types T1 and T2? They look very similar.
+- Should I split my new X into a separate file?
+- Should I create a new test file or update an existing test?
+- How should I test that I actually fixed this bug?
+- Test X is failing and I can't understand why. What might be going wrong here?
+- Test X is failing in CI but passing locally. Any tips for debugging?
+- I made some change but that seems to be not getting picked up. What should
+  I do to fix it?
+- I need to update the CMake but I'm not familiar with CMake. Could you give me
+  more guidance?
+- How do I do X in git?
+
+Some of these already have answers in our [FAQ](/docs/HowToGuides/FAQ.md).
+Maybe you have a question that's not on this list. That's fine.
+We're here to help. There are a couple of options to ask for help:
+
+- [Development category on the Swift forums](https://forums.swift.org/c/development):
+  Prefer using the forums for broad questions, such as those related to
+  building the toolchain, or understanding how something works at a high-level.
+  Since more people are likely to see and be able to answer your question, the
+  question is likely to get an answer sooner. Another benefit of asking in
+  public is that the answers you receive will be helpful to bystanders too.
+- Bug report/Pull request comments: Prefer asking in the bug report/pull request
+  when the question involves additional context specific to the
+  bug report/pull request.
+
+These are suggestions, not rules. For example, it's okay if you ask a broad
+question in a bug report or a pull request.
+
+When asking for help, prefer giving as much information as possible, while
+highlighting the parts that you think are important.
+
+Remember that the [Swift Code of Conduct][] applies whenever you are
+participating in the Swift project.
+
+[Swift Code of Conduct]: https://swift.org/community/#code-of-conduct
+
+### I didn't get a response from someone. What should I do?
+
+It's possible that you ask someone a question in a bug report/pull request and
+you don't get a response as quickly as you'd like. Maybe they are juggling
+several tasks and the discussion with you accidentally slipped by. Maybe they
+are on vacation or on leave for some reason. If you don't get a response
+within a week, it's okay to politely ping them using an `@` mention with a
+reminder. If you don't get a response for 2-3 weeks in a row, please ping
+someone else.
+
+## Working on a change
+
+Please see our [Getting Started guide][] to understand how to build the code,
+make changes, run tests and debug issues.
+
+[Getting Started guide]: /docs/HowToGuides/GettingStarted.md
+
+## Submitting a pull request
+
+### Tidying up
+
+Alright! You've implemented a change and would like to submit it.
+Double-check that you've tidied your Git history, such as squashing
+work-in-progress commits, and that your commit messages provide context.
+For example, if a commit fixes a bug, then include a "Fixes SR-NNNNN" with the
+bug number in the commit message.
+
+Next, [format your changes](/docs/HowToGuides/FAQ.md#how-do-i-format-my-changes)
+using `clang-format`.
+
+### Pushing and creating a pull request
+
+Assuming you followed the steps in our [Getting Started guide][], you should now
+be able to push your latest changes to GitHub using `git push`.
+
+Next, [create a pull request][] (PR). Usually, if you navigate to
+https://github.com/apple/swift right after pushing your change, GitHub will
+show a helpful "Compare & Pull Request" button.
+
+![Compare & Pull Request button in GitHub UI](/docs/GitHubCreatePRScreenshot.png)
+
+[create a pull request]: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request#creating-the-pull-request
+
+## Asking for code review
+
+If you had an active discussion with someone on how to implement your change,
+you can `@` mention them in the PR description and ask for code review.
+If you directly implemented the change without any guidance from anyone else,
+`@` mention someone from GitHub's suggested reviewers. If GitHub doesn't
+make any suggestions, ask the [Code Owner](/CODE_OWNERS.txt) based on the
+component for your change. Please ask someone though! We don't want you to get
+stuck because you were not sure who to ask for code review.
+
+At the beginning, contributors are not able to run the continuous integration
+(CI) bot, which builds the project and runs tests. Please ask your code
+reviewer(s) to invoke the bot for you.
+
+## Responding to code review comments
+
+During the process of code review, someone might suggest changes or have
+questions about the implementation. If something is unclear, such as someone
+using a technical term you don't recognize, check our
+[Lexicon](/docs/Lexicon.md) or ask someone instead of trying to figure out
+everything by yourself. Code review does not need to be a one-way
+street. It is also a good opportunity for you to ask highly contextual
+questions on topics that you struggled with or were unable to understand.
+
+While making changes based on code review, if you are comfortable with
+rebasing, prefer rebasing and force-pushing for small patches (say < 100 lines).
+For larger patches, you can add fixup commits (`git commit --fixup ...`)
+addressing the suggestions and rebase after it the patch has been approved
+to clean up the history.
+
+When you push again and want the tests to be re-run, please ask the reviewer
+to invoke `swift-ci` for you.
+
+At the end, once the tests are passing, the pull request is approved by
+the reviewer, and you are satisfied with your changes, ask your reviewer
+to merge your changes. :tada:
+
+## I can't finish the contribution I started. :frowning_face:
+
+That's totally okay! There is no shame in that. You only have limited time and
+energy in a day. If you can, leave a comment on the bug report/pull request
+that you will not be able to continue and unassign yourself from the bug on
+JIRA. Don't worry about trying to explain _why_ you aren't able to contribute
+further. We understand. Unanticipated things come up all the time and you
+should do what _works for you_.
+
+This point also applies if you don't have time right now but hope to get to
+something in the near future. Please don't feel sad or apologetic!
+
+## I submitted and merged my first pull request. What now?
+
+Awesome! You could try fixing a few more Starter Bugs until you feel some
+level of comfort working with the codebase. You could also start looking at
+other bugs which interest you and you think you might be able to tackle.
+Don't forget to ask for help if you need directions or you get stuck!
+
+Once you've made multiple substantial contributions, you can
+[ask for commit access](https://swift.org/contributing/#commit-access),
+which will allow you to pick reviewers, trigger the CI bot and merge changes.
diff --git a/docs/HowToGuides/GettingStarted.md b/docs/HowToGuides/GettingStarted.md
new file mode 100644
index 0000000..bda3f2a
--- /dev/null
+++ b/docs/HowToGuides/GettingStarted.md
@@ -0,0 +1,609 @@
+# How to Set Up an Edit-Build-Test-Debug Loop
+
+This document describes how to set up a development loop for people interested
+in contributing to Swift.
+
+If you are only interested in building the
+toolchain as a one-off, there are a couple of differences:
+1. You can ignore the parts related to Sccache.
+2. You can stop reading after
+   [Building the project for the first time](#building-the-project-for-the-first-time).
+
+## Table of Contents
+
+- [System Requirements](#system-requirements)
+- [Cloning the project](#cloning-the-project)
+  - [Troubleshooting cloning issues](#troubleshooting-cloning-issues)
+- [Installing dependencies](#installing-dependencies)
+  - [macOS](#macOS)
+  - [Ubuntu Linux](#ubuntu-linux)
+- [Building the project for the first time](#building-the-project-for-the-first-time)
+  - [Spot check dependencies](#spot-check-dependencies)
+  - [Understanding the pieces](#understanding-the-pieces)
+  - [The actual build](#the-actual-build)
+  - [Troubleshooting build issues](#troubleshooting-build-issues)
+- [Editing code](#editing-code)
+  - [Setting up your fork](#setting-up-your-fork)
+  - [First time Xcode setup](#first-time-xcode-setup)
+  - [Editing](#editing)
+  - [Incremental builds with Ninja](#incremental-builds-with-ninja)
+  - [Incremental builds with Xcode](#incremental-builds-with-xcode)
+  - [Spot checking an incremental build](#spot-checking-an-incremental-build)
+- [Reproducing an issue](#reproducing-an-issue)
+- [Running tests](#running-tests)
+- [Debugging issues](#debugging-issues)
+  - [Print debugging](#print-debugging)
+  - [Debugging using LLDB](#debugging-using-lldb)
+- [Next steps](#next-steps)
+
+## System Requirements
+
+1. Operating system:
+   The supported operating systems for developing the Swift toolchain are:
+   macOS, Ubuntu Linux LTS, and the latest Ubuntu Linux release.
+   At the moment, Windows is not supported as a host development operating
+   system. Experimental instructions for Windows are available under
+   [Windows.md](/docs/Windows.md).
+2. Python 3: Several utility scripts are written in Python.
+3. Disk space:
+   Make sure that you have enough available disk space before starting.
+   The source code, including full git history, requires about 3.5 GB.
+   Build artifacts take anywhere between 5 GB to 70 GB, depending on the
+   build settings.
+4. Time:
+   Depending on your machine and build settings,
+   a from-scratch build can take a few minutes to several hours,
+   so you might want to grab a beverage while you follow the instructions.
+   Incremental builds are much faster.
+
+## Cloning the project
+
+1. Create a directory for the whole project:
+   ```sh
+   mkdir -p swift-project/swift
+   cd swift-project/swift
+   ```
+2. Clone the sources:
+   - Via SSH (recommended):
+     If you plan on contributing regularly, cloning over SSH provides a better
+     experience. After you've [uploaded your SSH keys to GitHub][]:
+     ```sh
+     git clone git@github.com:apple/swift.git .
+     utils/update-checkout --clone-with-ssh
+     ```
+   - Via HTTPS:
+     If you want to check out the sources as read-only,
+     or are not familiar with setting up SSH,
+     you can use HTTPS instead:
+     ```sh
+     git clone https://github.com/apple/swift.git .
+     utils/update-checkout --clone
+     ```
+   **Note:** If you've already forked the project on GitHub at this stage,
+   **do not clone your fork** to start off. We describe
+   [how to setup your fork](#setting-up-your-fork) in a subsection below.
+   <!-- Recommending against cloning the fork due to SR-13476 and SR-13505. -->
+3. Double-check that `swift`'s sibling directories are present.
+   ```sh
+   ls ..
+   ```
+   This should list directories like `llvm-project`, `swiftpm` and so on.
+4. Checkout the right branch/tag:
+   If you are building the toolchain for local development, you can skip this
+   step, as Step 2 will checkout `swift`'s `master` branch and matching
+   branches for other projects. <!-- [TODO: master-to-main-rename] -->
+   If you are building the toolchain as a one-off, it is more likely that you
+   want a specific branch or a tag, often corresponding to a specific release
+   or a specific snapshot. You can update the branch/tag for all repositories
+   as follows:
+   ```sh
+   utils/update-checkout --branch mybranchname
+   # OR
+   utils/update-checkout --tag mytagname
+   ```
+   Detailed branching information, including names for release branches, can
+   be found in [Branches.md](/docs/Branches.md).
+
+**Note:**
+The commands used in the rest of this guide assumes that the absolute path
+to your working directory is something like `/path/to/swift-project/swift`.
+Double-check that running `pwd` prints a path ending with `swift`.
+
+[uploaded your SSH keys to GitHub]: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/
+
+### Troubleshooting cloning issues
+
+- If `update-checkout` failed, double-check that the absolute path to your
+  working directory does not have non-ASCII characters.
+- If `update-checkout` failed and the absolute path to your working directory
+  had spaces in it, please [file a bug report][Swift JIRA] and change the path
+  to work around it.
+- Before running `update-checkout`, double-check that `swift` is the only
+  repository inside the `swift-project` directory. Otherwise,
+  `update-checkout` may not clone the necessary dependencies.
+
+## Installing dependencies
+
+### macOS
+
+1. Install [Xcode 12 beta 3][Xcode] or newer:
+   The required version of Xcode changes frequently and is often a beta release.
+   Check this document or the host information on <https://ci.swift.org> for the
+   current required version.
+2. Install [CMake][], [Ninja][] and [Sccache][]:
+   - Via [Homebrew][] (recommended):
+     ```sh
+     brew install cmake ninja sccache
+     ```
+   - Via [Homebrew Bundle][]:
+     ```sh
+     brew bundle
+     ```
+
+[Xcode]: https://developer.apple.com/xcode/resources/
+[CMake]: https://cmake.org
+[Ninja]: https://ninja-build.org
+[Sccache]: https://github.com/mozilla/sccache
+[Homebrew]: https://brew.sh/
+[Homebrew Bundle]: https://github.com/Homebrew/homebrew-bundle
+
+### Ubuntu Linux
+
+1. For Ubuntu 16.04 LTS and 18.04 LTS, run the following:
+
+   ```sh
+   sudo apt-get install    \
+     clang                 \
+     cmake                 \
+     git                   \
+     icu-devtools          \
+     libcurl4-openssl-dev  \
+     libedit-dev           \
+     libicu-dev            \
+     libncurses5-dev       \
+     libpython3-dev        \
+     libsqlite3-dev        \
+     libxml2-dev           \
+     ninja-build           \
+     pkg-config            \
+     python                \
+     python-six            \
+     rsync                 \
+     swig                  \
+     systemtap-sdt-dev     \
+     tzdata                \
+     uuid-dev
+   sudo snap install sccache --candidate --classic
+   ```
+
+   **Note:** LLDB currently requires at least `swig-1.3.40` but will
+   successfully build with version 2 shipped with Ubuntu.
+
+## Building the project for the first time
+
+### Spot check dependencies
+
+* Run `cmake --version`: This should be 3.18.1 or higher for macOS.
+* Run `python3 --version`: Check that this succeeds.
+* Run `ninja --version`: Check that this succeeds.
+* Run `sccache --version`: Check that this succeeds.
+
+### The roles of different tools
+
+At this point, it is worthwhile to pause for a moment
+to understand what the different tools do:
+
+1. On macOS and Windows, IDEs (Xcode and Visual Studio resp.) serve as an
+   easy way to install development dependencies such as a C++ compiler,
+   a linker, header files, etc. The IDE's build system need not be used to
+   build Swift. On Linux, these dependencies are installed by the
+   distribution's package manager.
+2. CMake is a cross-platform build system for C and C++.
+   It forms the core infrastructure used to _configure_ builds of
+   Swift and its companion projects.
+3. Ninja is a low-level build system that can be used to _build_ the project,
+   as an alternative to Xcode's build system. Ninja is somewhat faster,
+   especially for incremental builds, and supports more build environments.
+4. Sccache is a caching tool:
+   If you ever delete your build directory and rebuild from scratch
+   (i.e. do a "clean build"), Sccache can accelerate the new build
+   significantly. There are few things more satisfying than seeing Sccache
+   cut through build times.
+5. `utils/update-checkout` is a script to help you work with all the individual
+   git repositories together, instead of manually cloning/updating each one.
+6. `utils/build-script` (we will introduce this shortly)
+   is a high-level automation script that handles configuration (via CMake),
+   building (via Ninja or Xcode), caching (via Sccache), running tests and more.
+
+> **Pro Tip**: Most tools support `--help` flags describing the options they
+> support. Additionally, both Clang and the Swift compiler have hidden flags
+> (`clang --help-hidden`/`swiftc --help-hidden`) and frontend flags
+> (`clang -cc1 --help`/`swiftc -frontend --help`) and the Swift compiler
+> even has hidden frontend flags (`swiftc -frontend --help-hidden`). Sneaky!
+
+Phew, that's a lot to digest! Now let's proceed to the actual build itself!
+
+### The actual build
+
+1. Make sure you have Sccache running.
+   ```sh
+   sccache --start-server
+   ```
+   (Optional) Sccache defaults to a cache size of 10GB, which is relatively
+   small compared to build artifacts. You can bump it up, say by setting
+   `export SCCACHE_CACHE_SIZE="50G"` in your dotfile(s). For more details,
+   see the [Sccache README][Sccache].
+2. Decide if you would like to build the toolchain using Ninja or using Xcode.
+   - If you use an editor other than Xcode and/or you want somewhat faster builds,
+     go with Ninja.
+   - If you are comfortable with using Xcode and would prefer to use it,
+     go with Xcode.
+   There is also a third option, which is somewhat more involved:
+   [using both Ninja and Xcode](#using-both-ninja-and-xcode).
+3. Build the toolchain with optimizations, debuginfo, and assertions and run
+   the tests.
+   - Via Ninja:
+     ```sh
+     utils/build-script --skip-build-benchmarks \
+       --skip-ios --skip-watchos --skip-tvos --swift-darwin-supported-archs "x86_64" \
+       --cmake-c-launcher="$(which sccache)" --cmake-cxx-launcher="$(which sccache)" \
+       --release-debuginfo --test
+     ```
+   - Via Xcode:
+     ```sh
+     utils/build-script --skip-build-benchmarks \
+       --skip-ios --skip-watchos --skip-tvos --swift-darwin-supported-archs "x86_64" \
+       --cmake-c-launcher="$(which sccache)" --cmake-cxx-launcher="$(which sccache)" \
+       --release-debuginfo --test \
+       --xcode
+     ```
+   This will create a directory
+   `swift-project/build/Ninja-RelWithDebInfoAssert`
+   (with `Xcode` instead of `Ninja` if you used `--xcode`)
+   containing the build artifacts.
+   - If the build succeeds: Once the build is complete, the tests will run.
+     - If the tests are passing: Great! We can go to the next step.
+     - If some tests are failing:
+       - Consider [filing a bug report](https://swift.org/contributing/#reporting-bugs).
+       - Note down which tests are failing as a baseline. This baseline will be
+         handy later when you run the tests after making a change.
+   - If the build fails:
+     See [Troubleshooting build issues](#troubleshooting-build-issues).
+
+In the following sections, for simplicity, we will assume that you are using a
+`Ninja-RelWithDebInfoAssert` build on macOS running on an Intel-based Mac,
+unless explicitly mentioned otherwise. You will need to slightly tweak the paths
+for other build configurations.
+
+#### Using both Ninja and Xcode
+
+Some contributors find it more convenient to use both Ninja and Xcode.
+Typically this configuration consists of:
+
+1. A Ninja build created with `--release-debuginfo`.
+2. An Xcode build created with `--release-debuginfo --debug-swift`.
+
+The Ninja build can be used for fast incremental compilation and running tests
+quickly. The Xcode build can be used for debugging with high fidelity.
+
+The additional flexibility comes with two issues: (1) consuming much more disk
+space and (2) you need to maintain the two builds in sync, which needs extra
+care when moving across branches.
+
+### Troubleshooting build issues
+
+- Double-check that all projects are checked out at the right branches.
+  A common failure mode is using `git checkout` to change the branch only
+  for `swift` (often to a release branch), leading to an unsupported
+  configuration. See Step 4 of [Cloning the Project](#cloning-the-project)
+  on how to fix this.
+- Double-check that all your dependencies
+  [meet the minimum required versions](#spot-check-dependencies).
+- Check if there are spaces in the paths being used by `build-script` in
+  the log. While `build-script` should work with paths containing spaces,
+  sometimes bugs do slip through, such as
+  [SR-13441](https://bugs.swift.org/browse/SR-13441).
+  If this is the case, please [file a bug report][Swift JIRA] and change the path
+  to work around it.
+- Check that your `build-script` invocation doesn't have typos. You can compare
+  the flags you passed against the supported flags listed by
+  `utils/build-script --help`.
+- Check the error logs and see if there is something you can fix.
+  In many situations, there are several errors, so scrolling further back
+  and looking at the first error may be more helpful than simply looking
+  at the last error.
+- Check if others have encountered the same issue on the Swift forums or on
+  [Swift JIRA][].
+- Create a new Swift forums thread in the Development category. Include
+  information about your configuration and the errors you are seeing.
+  - You can [create a gist](https://gist.github.com) with the entire build
+    output and link it, while highlighting the most important part of the
+    build log in the post.
+  - Include the output of `utils/update-checkout --dump-hashes`.
+
+[Swift JIRA]: https://bugs.swift.org
+
+## Editing code
+
+### Setting up your fork
+
+If you are building the toolchain for development and submitting patches,
+you will need to setup a GitHub fork.
+
+First fork the `apple/swift` [repository](https://github.com/apple/swift.git),
+using the "Fork" button in the web UI, near the top-right. This will create a
+repository `username/swift` for your GitHub username. Next, add it as a remote:
+```sh
+# Using 'my-remote' as a placeholder name.
+
+# If you set up SSH in step 2
+git remote add my-remote git@github.com:username/swift.git
+
+# If you used HTTPS in step 2
+git remote add my-remote https://github.com/username/swift.git
+```
+Finally, create a new branch.
+```sh
+# Using 'my-branch' as a placeholder name
+git checkout my-branch
+git push --set-upstream my-remote my-branch
+```
+
+### First time Xcode setup
+
+If you used `--xcode` earlier, you will see an Xcode project generated under
+`../build/Xcode-RelWithDebInfoAssert/swift-macosx-x86_64`. When you open the
+project, Xcode might helpfully suggest "Automatically Create Schemes". Most of
+those schemes are not required in day-to-day work, so you can instead manually
+select the following schemes:
+- `swift-frontend`: If you will be working on the compiler.
+- `check-swift-all`: This can be used to run the tests. The test runner does
+  not integrate with Xcode though, so it may be easier to run tests directly
+  on the commandline for more fine-grained control over which exact tests are
+  run.
+<!-- TODO: Insert SourceKit/stdlib specific instructions? -->
+
+### Editing
+
+Make changes to the code as appropriate. Implement a shiny new feature!
+Or fix a nasty bug! Update the documentation as you go! <!-- please 🙏 -->
+The codebase is your oyster!
+
+:construction::construction_worker::building_construction:
+
+Now that you have made some changes, you will need to rebuild...
+
+### Incremental rebuilds with Ninja
+
+To rebuild the compiler:
+```sh
+ninja -C ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64 swift-frontend
+```
+
+To rebuild everything, including the standard library:
+```sh
+ninja -C ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64
+```
+
+### Incremental builds with Xcode
+
+Rebuilding works the same way as with any other Xcode project; you can use
+<kbd>⌘</kbd>+<kbd>B</kbd> or Product → Build.
+
+### Spot checking an incremental build
+
+As a quick test, go to `lib/Basic/Version.cpp` and tweak the version
+printing code slightly. Next, do an incremental build as above. This incremental
+build should be much faster than the from-scratch build at the beginning.
+Now check if the version string has been updated:
+
+```sh
+../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/bin/swift-frontend --version
+```
+
+This should print your updated version string.
+
+## Reproducing an issue
+
+Starter bugs typically have small code examples that fit within a single file.
+You can reproduce such an issue in various ways, such as compiling it from the
+commandline using `/path/to/swiftc MyFile.swift`, pasting the code into
+[Compiler Explorer][] (aka godbolt) or using an Xcode Playground.
+
+[Compiler Explorer]: https://godbolt.org
+
+For files using frameworks from an SDK bundled with Xcode, you need the pass
+the SDK explicitly. Here are a couple of examples:
+```sh
+# Compile a file to an executable for your local machine.
+xcrun -sdk macosx /path/to/swiftc MyFile.swift
+
+# Say you are trying to compile a file importing an iOS-only framework.
+xcrun -sdk iphoneos /path/to/swiftc -target arm64-apple-ios13.0 MyFile.swift
+```
+You can see the full list of `-sdk` options using `xcodebuild -showsdks`,
+and check some potential `-target` options for different operating systems by
+skimming the compiler's test suite under `test/`.
+
+Sometimes bug reports come with SwiftPM packages or Xcode projects as minimal
+reproducers. While we do not add packages or projects to the compiler's test
+suite, it is generally helpful to first reproduce the issue in context before
+trying to create a minimal self-contained test case. If that's the case with
+the bug you're working on, check out our
+[instructions on building packages and Xcode projects with a locally built compiler](/docs/HowToGuides/FAQ.md#how-do-i-use-a-locally-built-compiler-to-build-x).
+
+## Running tests
+
+There are two main ways to run tests:
+
+1. `utils/run-test`: By default, `run-test` builds the tests' dependencies
+   before running them.
+   ```sh
+   # Rebuild all test dependencies and run all tests under test/.
+   utils/run-test --lit ../llvm-project/llvm/utils/lit/lit.py \
+     ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/test-macosx-x86_64
+
+   # Rebuild all test dependencies and run tests containing "MyTest".
+   utils/run-test --lit ../llvm-project/llvm/utils/lit/lit.py \
+     ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/test-macosx-x86_64 \
+     --filter="MyTest"
+   ```
+2. `lit.py`: lit doesn't know anything about dependencies. It just runs tests.
+   ```sh
+   # Run all tests under test/.
+   ../llvm-project/llvm/utils/lit/lit.py -s -vv \
+     ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/test-macosx-x86_64
+
+   # Run tests containing "MyTest"
+   ../llvm-project/llvm/utils/lit/lit.py -s -vv \
+     ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/test-macosx-x86_64 \
+     --filter="MyTest"
+   ```
+   The `-s` and `-vv` flags print a progress bar and the executed commands
+   respectively.
+
+If you making small changes to the compiler or some other component, you'll
+likely want to [incrementally rebuild](#editing-code) only the relevant
+Ninja/Xcode target and use `lit.py` with `--filter`. One potential failure
+mode with this approach is accidental use of stale binaries. For example, say
+that you want to rerun a SourceKit test but you only incrementally rebuilt the
+compiler. Then your changes will not be reflected when the test runs because the
+`sourcekitd` binary was not rebuilt. Using `run-test` instead is the safer
+option, but it will lead to a longer feedback loop due to more things getting
+rebuilt.
+
+If you want to rerun all the tests, you can either rebuild the whole project
+and use `lit.py` without `--filter` or use `run-test` to handle both aspects.
+
+Recall the baseline failures mentioned in
+[the build section](#the-actual-build). If your baseline had failing tests, make
+sure you compare the failures seen after your changes to the baseline. If some
+test failures look totally unrelated to your changes, there is a good chance
+that they were already failing as part of the baseline.
+
+For more details on running tests and understanding the various Swift-specific
+lit customizations, see [Testing.md](/docs/Testing.md). Also check out the
+[lit documentation](https://llvm.org/docs/CommandGuide/lit.html) to understand
+how the different lit commands work.
+
+## Debugging issues
+
+In this section, we briefly describe two common ways of debugging: print
+debugging and using LLDB.
+
+Depending on the code you're interested in, LLDB may be significantly more
+effective when using a debug build. Depending on what components you are
+working on, you could turn off optimizations for only a few things.
+Here are some example invocations:
+
+```sh
+# optimized Stdlib + debug Swiftc + optimized Clang/LLVM
+utils/build-script --release-debuginfo --debug-swift # other flags...
+
+# debug Stdlib + optimized Swiftc + optimized Clang/LLVM
+utils/build-script --release-debuginfo --debug-swift-stdlib # other flags...
+
+# optimized Stdlib + debug Swiftc (expect typechecker) + optimized Clang/LLVM
+utils/build-script --release-debuginfo --debug-swift --force-optimized-typechecker
+
+# Last resort option, it is highly unlikely that you will need this
+# debug Stdlib + debug Swiftc + debug Clang/LLVM
+utils/build-script --debug # other flags...
+```
+
+Debug builds have two major drawbacks:
+- A debug compiler is much slower, leading to longer feedback loops in case you
+  need to repeatedly compile the Swift standard library and/or run a large
+  number of tests.
+- The build artifacts consume a lot more disk space.
+
+[DebuggingTheCompiler.md](/docs/DebuggingTheCompiler.md) goes into a LOT
+more detail on how you can level up your debugging skills! Make sure you check
+it out in case you're trying to debug a tricky issue and aren't sure how to
+go about it.
+
+### Print debugging
+
+A large number of types have `dump(..)`/`print(..)` methods which can be used
+along with `llvm::errs()` or other LLVM streams. For example, if you have a
+variable `std::vector<CanType> canTypes` that you want to print, you could do:
+```cpp
+auto &e = llvm::errs();
+e << "canTypes = [";
+llvm::interleaveComma(canTypes, e, [&](auto ty) { ty.dump(e); });
+e << "]\n";
+```
+You can also crash the compiler using `assert`/`llvm_unreachable`/
+`llvm::report_fatal_error`, after accumulating the result in a stream:
+```cpp
+std::string msg; llvm::raw_string_ostream os(msg);
+os << "unexpected canTypes = [";
+llvm::interleaveComma(canTypes, os, [&](auto ty) { ty.dump(os); });
+os << "] !!!\n";
+llvm::report_fatal_error(os.str());
+```
+
+### Debugging using LLDB
+
+When the compiler crashes, the commandline arguments passed to it will be
+printed to stderr. It will likely look something like:
+
+```
+/path/to/swift-frontend <args>
+```
+
+- Using LLDB on the commandline: Copy the entire invocation and pass it to LLDB.
+  ```sh
+  lldb -- /path/to/swift-frontend <args>
+  ```
+  Now you can use the usual LLDB commands like `run`, `breakpoint set` and so
+  on. If you are new to LLDB, check out the [official LLDB documentation][] and
+  [nesono's LLDB cheat sheet][].
+- Using LLDB within Xcode:
+  Select the current scheme 'swift-frontend' → Edit Scheme → Run phase →
+  Arguments tab. Under "Arguments Passed on Launch", copy-paste the `<args>`
+  and make sure that "Expand Variables Based On" is set to swift-frontend.
+  Close the scheme editor. If you now run the compiler
+  (<kbd>⌘</kbd>+<kbd>R</kbd> or Product → Run), you will be able to use the
+  Xcode debugger.
+
+  Xcode also has the ability to attach to and debug Swift processes launched
+  elsewhere. Under Debug → Attach to Process by PID or name..., you can enter
+  a compiler process's PID or name (`swift-frontend`) to debug a compiler
+  instance invoked elsewhere. This can be helpful if you have a single compiler
+  process being invoked by another tool, such as SwiftPM or another open Xcode
+  project.
+
+  > **Pro Tip**: Xcode 12's terminal does not support colors, so you may see
+  > explicit color codes printed by `dump()` methods on various types. To avoid
+  > color codes in dumped output, run `expr llvm::errs().enable_color(false)`.
+
+[official LLDB documentation]: https://lldb.llvm.org
+[nesono's LLDB cheat sheet]: https://www.nesono.com/sites/default/files/lldb%20cheat%20sheet.pdf
+
+## Next steps
+
+Make sure you check out the following resources:
+
+* [LLVM Coding Standards](https://llvm.org/docs/CodingStandards.html): A style
+  guide followed by both LLVM and Swift. If there is a mismatch between the LLVM
+  Coding Standards and the surrounding code that you are editing, please match
+  the style of existing code.
+* [LLVM Programmer's Manual](https://llvm.org/docs/ProgrammersManual.html):
+  A guide describing common programming idioms and data types used by LLVM and
+  Swift.
+* [docs/README.md](/docs/README.md): Provides a bird's eye view of the available
+  documentation.
+* [Lexicon.md](/docs/Lexicon.md): Provides definitions for jargon. If you run
+  into a term frequently that you don't recognize, it's likely that this file
+  has a definition for it.
+* [Testing.md](/docs/Testing.md) and
+  [DebuggingTheCompiler.md](/docs/DebuggingTheCompiler.md): These cover more
+  ground on testing and debugging respectively.
+* [Development Tips](/docs/DevelopmentTips.md): Tips for being more productive.
+<!-- Link to Compiler Architecture.md once that is ready -->
+
+If you see mistakes in the documentation (including typos, not just major
+errors) or identify gaps that you could potentially improve the contributing
+experience, please start a discussion on the forums, submit a pull request
+or file a bug report on [Swift JIRA][]. Thanks!
diff --git a/docs/Lexicon.md b/docs/Lexicon.md
index 32e2d4a..bc8ed1e 100644
--- a/docs/Lexicon.md
+++ b/docs/Lexicon.md
@@ -111,6 +111,11 @@
    context. This type may contain [archetypes](#archetype) and cannot be
    used directly from outside the context. Compare with [interface type](#interface-type).
 
+## critical edge
+
+An edge in a control flow graph where the destination has multiple predecessors
+and the source has multiple successors.
+
 ## customization point
 
 Informal term for a protocol requirement that has a default implementation,
diff --git a/docs/LibraryEvolution.rst b/docs/LibraryEvolution.rst
index e2813f4..dac3495 100644
--- a/docs/LibraryEvolution.rst
+++ b/docs/LibraryEvolution.rst
@@ -578,7 +578,9 @@
 - The ``@discardableResult`` and ``@warn_unqualified_access`` attributes may
   be added to or removed from a function requirement.
 - A new ``associatedtype`` requirement may be added (with the appropriate
-  availability), as long as it has a default implementation.
+  availability), as long as it has a default implementation. If the protocol
+  did not have one or more ``associatedtype`` requirements before the change,
+  then this is a `binary-compatible source-breaking change`.
 - A new non-type requirement may be added (with the appropriate availability),
   as long as it has an unconstrained default implementation. If the requirement
   uses ``Self`` and the protocol has no other requirements using ``Self`` and
diff --git a/docs/Modules.rst b/docs/Modules.rst
index fbea23d..fbaa386 100644
--- a/docs/Modules.rst
+++ b/docs/Modules.rst
@@ -441,10 +441,6 @@
 
     __ https://en.wikipedia.org/wiki/Name_mangling#C.2B.2B
 
-  module
-    An entity containing the API for a library, to be `imported <import>` into
-    a source file.
-
   qualified name
     A multi-piece name like ``Foundation.NSWindow``, which names an entity
     within a particular context. This document is concerned with the case where
@@ -463,9 +459,3 @@
   SIL
     "Swift Intermediate Language", a stable IR for the distribution of
     inlineable code.
-
-
-  target
-    A dynamic library, framework, plug-in, or application to be built.
-    A natural LTO boundary, and roughly the same as what Xcode requires
-    separate targets to build.
diff --git a/docs/README.md b/docs/README.md
index d5b028f..0c10bb1 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -55,6 +55,14 @@
 
 ## How-To Guides
 
+- [FAQ.md](/docs/HowToGuides/FAQ.md):
+  Answers "How do I do X?" for a variety of common tasks.
+- [FirstPullRequest.md](/docs/HowToGuides/FirstPullRequest.md):
+  Describes how to submit your first pull request. This is the place to start
+  if you're new to the project!
+- [GettingStarted.md](/docs/HowToGuides/GettingStarted.md):
+  Describes how to set up a working Swift development environment
+  for Linux and macOS, and get an edit-build-test-debug loop going.
 - [DebuggingTheCompiler.md](/docs/DebuggingTheCompiler.md):
   Describes a variety of techniques for debugging.
 - Building for Android:
diff --git a/docs/Refactoring.md b/docs/Refactoring.md
deleted file mode 100644
index f0fabeb..0000000
--- a/docs/Refactoring.md
+++ /dev/null
@@ -1,2 +0,0 @@
-This is placeholder for documentation related to Swift local refactoring.
-It will be expanded soon..
diff --git a/docs/WebAssembly.md b/docs/WebAssembly.md
new file mode 100644
index 0000000..b8b730f
--- /dev/null
+++ b/docs/WebAssembly.md
@@ -0,0 +1,29 @@
+# WebAssembly support in Swift
+
+WebAssembly is a platform that significantly differs from hardware platforms that Swift already supports.
+While it's a virtual machine, there are considerations to be taken into account when targeting it:
+
+* WebAssembly is still at an early stage, so many features you'd be expect from other platforms are not
+available yet, specifically:
+  1. `wasm64` variant is not specified yet, only the 32-bit `wasm32` variant is supported in WebAssembly
+  hosts such as browsers.
+  2. While a preview of multi-threading and atomics is available in some browsers and stand-alone 
+  WebAssembly hosts, [the corresponding proposal](https://github.com/WebAssembly/threads/) haven't 
+  formally reached the implementation phase yet.
+  3. Dynamic linking is not formally specified and tooling for it is not available yet.
+* Binary size is a high priority requirement. Since WebAssembly payloads are usually served in browsers,
+one wouldn't want end users to download multi-megabyte binaries.
+
+Nevertheless, an early implementation of the WebAssembly target is available [in a separate 
+fork](https://github.com/SwiftWasm). Here we're describing some decisions that were made while developing
+the implementation.
+
+## Relative Pointers
+
+Relative pointers are used in Swift runtime, but currently it's not feasible to use them for the WebAssembly
+target due to the design of WebAssembly and lack of LLVM support. If LLVM supported subtraction relocation 
+type on WebAssembly like `R_X86_64_PC32` or `X86_64_RELOC_SUBTRACTOR`, this issue can be solved easily.
+
+Since `R_X86_64_PC32` and `X86_64_RELOC_SUBTRACTOR` are mainly used to generate PIC but WebAssembly doesn't
+require PIC because it doesn't support dynamic linking. In addition, the memory space also begins at 0, so
+it's unnecessary to relocate at load time. All absolute addresses can be embedded in wasm binary file directly.
diff --git a/docs/WindowsBuild.md b/docs/WindowsBuild.md
index 4260e19..2d779b4 100644
--- a/docs/WindowsBuild.md
+++ b/docs/WindowsBuild.md
@@ -8,11 +8,10 @@
 
 ### Visual Studio
 
-An easy way to get most of the tools to build Swift is using the [Visual Studio installer](https://www.visualstudio.com/downloads/). This command installs all needed Visual Studio components as well as Python and Git:
+An easy way to get most of the tools to build Swift is using the [Visual Studio installer](https://www.visualstudio.com/downloads/). This command installs all needed Visual Studio components as well as Python, Git, CMake and Ninja:
 
 ```
 vs_community ^
-  --add Component.CPython2.x86 ^
   --add Component.CPython3.x64 ^
   --add Microsoft.VisualStudio.Component.Git ^
   --add Microsoft.VisualStudio.Component.VC.ATL ^
@@ -28,13 +27,7 @@
 
 ### Python
 
-The command above already installs Python 2 and 3. Alternatively, in the Visual Studio installation program, under *Individual Components*
-
-1. Install *Python 2*, either the 32-bit version (C:\Python27\\) or the 64-bit version (C:\Python27amd64\\)
-
-   **Note:** If you install the 64-bit version only, you will need to adjust `PYTHON_EXECUTABLE` below to `C:\Python27amd64\python.exe`
-
-2. Install *Python 3 64 bits (3.7.x)*
+The command above already installs Python 3. Alternatively, in the Visual Studio installation program, under *Individual Components*, install *Python 3 64 bits (3.7.x)*.
 
 If you are building a debug version of Swift, you should also install the Python debug binaries.
 
@@ -50,8 +43,8 @@
 
 ## Clone the repositories
 
-1. Clone `apple/llvm-project` into a directory for the toolchain
-2. Clone `apple/swift-cmark`, `apple/swift`, `apple/swift-corelibs-libdispatch`, `apple/swift-corelibs-foundation`, `apple/swift-corelibs-xctest`, `apple/swift-llbuild`, `apple/swift-package-manager` into the toolchain directory
+1. Clone `swift/master` branch of `apple/llvm-project` into the build workspace
+2. Clone `apple/swift-cmark`, `apple/swift`, `apple/swift-corelibs-libdispatch`, `apple/swift-corelibs-foundation`, `apple/swift-corelibs-xctest`, `apple/swift-tools-support-core`, `apple/swift-llbuild`, `apple/swift-argument-parser`, `apple/swift-driver`, `apple/swift-package-manager`, `JPSim/Yams`, `apple/indexstore-db` into the build workspace
 
 - Currently, other repositories in the Swift project have not been tested and may not be supported.
 
@@ -69,9 +62,13 @@
 git clone https://github.com/apple/swift-corelibs-libdispatch swift-corelibs-libdispatch
 git clone https://github.com/apple/swift-corelibs-foundation swift-corelibs-foundation
 git clone https://github.com/apple/swift-corelibs-xctest swift-corelibs-xctest
-git clone https://github.com/apple/swift-llbuild llbuild
 git clone https://github.com/apple/swift-tools-support-core swift-tools-support-core
-git clone -c core.autocrlf=input https://github.com/apple/swift-package-manager swiftpm
+git clone -c core.symlinks=true https://github.com/apple/swift-llbuild swift-llbuild
+git clone https://github.com/JPSim/Yams Yams
+git clone https://github.com/apple/swift-driver swift-driver
+git clone https://github.com/apple/swift-argument-parser swift-argument-parser
+git clone -c core.autocrlf=input https://github.com/apple/swift-package-manager swift-package-manager
+git clone https://github.com/apple/indexstore-db indexstore-db
 ```
 
 ## Dependencies (ICU, SQLite3, curl, libxml2 and zlib)
@@ -119,119 +116,267 @@
 ## Build the toolchain
 
 ```cmd
-cmake -B "S:\b\toolchain" ^
+cmake -B "S:\b\1" ^
   -C S:\swift\cmake\caches\Windows-x86_64.cmake ^
   -D CMAKE_BUILD_TYPE=Release ^
-  -D SWIFT_PATH_TO_LIBDISPATCH_SOURCE=S:\swift-corelibs-libdispatch ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D LLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-windows-msvc ^
   -D LLVM_ENABLE_PDB=YES ^
-  -D LLVM_EXTERNAL_SWIFT_SOURCE_DIR=S:\swift ^
   -D LLVM_EXTERNAL_CMARK_SOURCE_DIR=S:\cmark ^
-  -D SWIFT_WINDOWS_x86_64_ICU_UC_INCLUDE=S:\Library\icu-67\usr\include ^
-  -D SWIFT_WINDOWS_x86_64_ICU_UC=S:\Library\icu-67\usr\lib\icuuc67.lib ^
+  -D LLVM_EXTERNAL_SWIFT_SOURCE_DIR=S:\swift ^
+  -D SWIFT_PATH_TO_LIBDISPATCH_SOURCE=S:\swift-corelibs-libdispatch ^
   -D SWIFT_WINDOWS_x86_64_ICU_I18N_INCLUDE=S:\Library\icu-67\usr\include ^
   -D SWIFT_WINDOWS_x86_64_ICU_I18N=S:\Library\icu-67\usr\lib\icuin67.lib ^
-  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D SWIFT_WINDOWS_x86_64_ICU_UC_INCLUDE=S:\Library\icu-67\usr\include ^
+  -D SWIFT_WINDOWS_x86_64_ICU_UC=S:\Library\icu-67\usr\lib\icuuc67.lib ^
   -G Ninja ^
   -S S:\llvm-project\llvm
 
-ninja -C S:\b\toolchain
+ninja -C S:\b\1
 ```
 
-**Note:** If you installed only the 64-bit version of Python, you will need to adjust `PYTHON_EXECUTABLE` argument to `C:\Python27amd64\python.exe`
-
-
 ## Running Swift tests on Windows
 
 ```cmd
-path S:\Library\icu-67\usr\bin;S:\b\toolchain\bin;S:\b\toolchain\tools\swift\libdispatch-prefix\bin;%PATH%;%ProgramFiles%\Git\usr\bin
+path S:\Library\icu-67\usr\bin;S:\b\1\bin;S:\b\1\tools\swift\libdispatch-prefix\bin;%PATH%;%ProgramFiles%\Git\usr\bin
 ninja -C S:\b\toolchain check-swift
 ```
 
 ## Build swift-corelibs-libdispatch
 
 ```cmd
-cmake -B S:\b\libdispatch -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_CXX_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D ENABLE_SWIFT=YES -G Ninja -S S:\swift-corelibs-libdispatch
-ninja -C S:\b\libdispatch
+cmake -B S:\b\2 ^
+  -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+  -D CMAKE_CXX_COMPILER=S:/b/1/bin/clang-cl.exe ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D ENABLE_SWIFT=YES ^
+  -G Ninja ^
+  -S S:\swift-corelibs-libdispatch
+
+ninja -C S:\b\2
 ```
 
 ## Test swift-corelibs-libdispatch
 
 ```cmd
-ninja -C S:\b\libdispatch check
+ninja -C S:\b\2 check
 ```
 
 ## Build swift-corelibs-foundation
 
 ```cmd
-cmake -B S:\b\foundation -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D CURL_LIBRARY="S:/Library/libcurl-development/usr/lib/libcurl.lib" -D CURL_INCLUDE_DIR="S:/Library/libcurl-development/usr/include" -D ICU_ROOT="S:/Library/icu-67" -D ICU_INCLUDE_DIR=S:/Library/icu-67/usr/include -D LIBXML2_LIBRARY="S:/Library/libxml2-development/usr/lib/libxml2s.lib" -D LIBXML2_INCLUDE_DIR="S:/Library/libxml2-development/usr/include/libxml2" -D ENABLE_TESTING=NO -D dispatch_DIR=S:/b/libdispatch/cmake/modules -G Ninja -S S:\swift-corelibs-foundation
-ninja -C S:\b\foundation
+cmake -B S:\b\3 ^
+  -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D CURL_LIBRARY="S:/Library/libcurl-development/usr/lib/libcurl.lib" ^
+  -D CURL_INCLUDE_DIR="S:/Library/libcurl-development/usr/include" ^
+  -D ICU_I18N_LIBRARY_RELEASE=S:\library\icu-67\usr\lib\icuin67.lib ^
+  -D ICU_ROOT=S:\Library\icu-67\usr ^
+  -D ICU_UC_LIBRARY_RELEASE=S:\Library\icu-67\usr\lib\icuuc67.lib ^
+  -D LIBXML2_LIBRARY=S:\Library\libxml2-development\usr\lib\libxml2s.lib ^
+  -D LIBXML2_INCLUDE_DIR=S:\Library\libxml2-development\usr\include\libxml2 ^
+  -D ENABLE_TESTING=NO ^
+  -D dispatch_DIR=S:\b\2\cmake\modules ^
+  -G Ninja ^
+  -S S:\swift-corelibs-foundation
+
+ninja -C S:\b\3
 ```
 
 - Add Foundation to your path:
 
 ```cmd
-path S:\b\foundation\Foundation;%PATH%
+path S:\b\3\bin;%PATH%
 ```
 
 ## Build swift-corelibs-xctest
 
 ```cmd
-cmake -B S:\b\xctest -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D dispatch_DIR=S:\b\dispatch\cmake\modules -D Foundation_DIR=S:\b\foundation\cmake\modules -D LIT_COMMAND=S:\toolchain\llvm\utils\lit\lit.py -D PYTHON_EXECUTABLE=C:\Python27\python.exe -G Ninja -S S:\swift-corelibs-xctest
-ninja -C S:\b\xctest
+cmake -B S:\b\4 ^
+  -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D dispatch_DIR=S:\b\2\cmake\modules ^
+  -D Foundation_DIR=S:\b\3\cmake\modules ^
+  -D LIT_COMMAND=S:\llvm-project\llvm\utils\lit\lit.py ^
+  -G Ninja ^
+  -S S:\swift-corelibs-xctest
+
+ninja -C S:\b\4
 ```
 
 - Add XCTest to your path:
 
 ```cmd
-path S:\b\xctest;%PATH%
+
+path S:\b\4;%PATH%
 ```
 
 ## Test XCTest
 
 ```cmd
-ninja -C S:\b\xctest check-xctest
+ninja -C S:\b\4 check-xctest
 ```
 
 ## Rebuild Foundation
 
 ```cmd
-cmake -B S:\b\foundation -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D CURL_LIBRARY="S:/Library/libcurl-development/usr/lib/libcurl.lib" -D CURL_INCLUDE_DIR="S:/Library/libcurl-development/usr/include" -D ICU_ROOT="S:/Library/icu-67" -D LIBXML2_LIBRARY="S:/Library/libxml2-development/usr/lib/libxml2.lib" -D LIBXML2_INCLUDE_DIR="S:/Library/libxml2-development/usr/include" -D ENABLE_TESTING=YES -D dispatch_DIR=S:/b/libdispatch/cmake/modules -D XCTest_DIR=S:/b/xctest/cmake/modules -G Ninja -S S:\swift-corelibs-foundation
-ninja -C S:\b\foundation
+cmake -B S:\b\3 ^
+  -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D CURL_LIBRARY="S:/Library/libcurl-development/usr/lib/libcurl.lib" ^
+  -D CURL_INCLUDE_DIR="S:/Library/libcurl-development/usr/include" ^
+  -D ICU_I18N_LIBRARY_RELEASE=S:\library\icu-67\usr\lib\icuin67.lib ^
+  -D ICU_ROOT=S:\Library\icu-67\usr ^
+  -D ICU_UC_LIBRARY_RELEASE=S:\Library\icu-67\usr\lib\icuuc67.lib ^
+  -D LIBXML2_LIBRARY=S:\Library\libxml2-development\usr\lib\libxml2s.lib ^
+  -D LIBXML2_INCLUDE_DIR=S:\Library\libxml2-development\usr\include\libxml2 ^
+  -D ENABLE_TESTING=YES ^
+  -D dispatch_DIR=S:\b\2\cmake\modules ^
+  -D XCTest_DIR=S:\b\4\cmake\modules ^
+  -G Ninja ^
+  -S S:\swift-corelibs-foundation
+
+ninja -C S:\b\3
 ```
 
 ## Test Foundation
 
 ```cmd
-cmake --build S:\b\foundation
-ninja -C S:\b\foundation test
-```
-
-## Build llbuild
-
-```cmd
-set AR=llvm-ar
-cmake -B S:\b\llbuild -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_CXX_COMPILER=cl -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D Foundation_DIR=S:/b/foundation/cmake/modules -D dispatch_DIR=S:/b/libdispatch/cmake/modules -D SQLite3_INCLUDE_DIR=S:\Library\sqlite-3.28.0\usr\include -D SQLite3_LIBRARY=S:\Library\sqlite-3.28.0\usr\lib\sqlite3.lib -D LLBUILD_SUPPORT_BINDINGS=Swift -G Ninja -S S:\llbuild
-ninja -C S:\b\llbuild
-```
-
-- Add llbuild to your path:
-
-```cmd
-path S:\b\llbuild\bin;%PATH%
+ninja -C S:\b\3 test
 ```
 
 ## Build swift-tools-core-support
 
 ```cmd
-cmake -B S:\b\tsc -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=cl -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D Foundation_DIR=S:/b/foundation/cmake/modules -D dispatch_DIR=S:/b/libdispatch/cmake/modules -G Ninja -S S:\swift-tools-support-core
-ninja -C S:\b\tsc
+cmake -B S:\b\5 ^
+  -D BUILD_SHARED_LIBS=YES ^
+  -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D dispatch_DIR=S:\b\2\cmake\modules ^
+  -D Foundation_DIR=S:\b\3\cmake\modules ^
+  -D SQLite3_INCLUDE_DIR=S:\Library\sqlite-3.28.0\usr\include ^
+  -D SQLite3_LIBRARY=S:\Library\sqlite-3.28.0\usr\lib\SQLite3.lib ^
+  -G Ninja ^
+  -S S:\swift-tools-support-core
+
+ninja -C S:\b\5
+```
+
+## Build swift-llbuild
+
+```cmd
+cmake -B S:\b\6 ^
+  -D BUILD_SHARED_LIBS=YES ^
+  -D CMAKE_BUILD_TYPE=RelWithDebInfo ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D CMAKE_CXX_COMPILER=S:/b/1/bin/clang-cl.exe ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D CMAKE_CXX_FLAGS="-Xclang -fno-split-cold-code" ^
+  -D LLBUILD_SUPPORT_BINDINGS=Swift ^
+  -D dispatch_DIR=S:\b\2\cmake\modules ^
+  -D Foundation_DIR=S:\b\3\cmake\modules ^
+  -D SQLite3_INCLUDE_DIR=S:\Library\sqlite-3.28.0\usr\include ^
+  -D SQLite3_LIBRARY=S:\Library\sqlite-3.28.0\usr\lib\sqlite3.lib ^
+  -G Ninja ^
+  -S S:\swift-llbuild
+
+ninja -C S:\b\6
+```
+
+- Add llbuild to your path:
+
+```cmd
+path S:\b\6\bin;%PATH%
+```
+
+## Build Yams
+
+```cmd
+cmake -B S:\b\7 ^
+  -D BUILD_SHARED_LIBS=YES ^
+  -D CMAKE_BUILD_TYPE=Release ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D dispatch_DIR=S:\b\2\cmake\modules ^
+  -D Foundation_DIR=S:\b\3\cmake\modules ^
+  -D XCTest_DIR=S:\b\4\cmake\modules ^
+  -G Ninja ^
+  -S S:\Yams
+
+ninja -C S:\b\7
+```
+
+## Build swift-argument-parser
+
+```cmd
+cmake -B S:\b\8 ^
+  -D BUILD_SHARED_LIBS=YES ^
+  -D CMAKE_BUILD_TYPE=Release ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D dispatch_DIR=S:\b\2\cmake\modules ^
+  -D Foundation_DIR=S:\b\3\cmake\modules ^
+  -D XCTest_DIR=S:\b\4\cmake\modules ^
+  -G Ninja ^
+  -S S:\swift-argument-parser
+
+ninja -C S:\b\8
+```
+
+## Build swift-driver
+
+```cmd
+cmake -B S:\b\9 ^
+  -D BUILD_SHARED_LIBS=YES ^
+  -D CMAKE_BUILD_TYPE=Release ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D dispatch_DIR=S:\b\2\cmake\modules ^
+  -D Foundation_DIR=S:\b\3\cmake\modules ^
+  -D TSC_DIR=S:\b\5\cmake\modules ^
+  -D LLBuild_DIR=S:\b\6\cmake\modules ^
+  -D Yams_DIR=S:\b\7\cmake\modules ^
+  -D ArgumentParser_DIR=S:\b\8\cmake\modules ^
+  -G Ninja ^
+  -S S:\swift-driver
+
+ninja -C S:\b\9
 ```
 
 ## Build swift-package-manager
 
 ```cmd
-cmake -B S:\b\spm -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_C_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_CXX_COMPILER=S:/b/toolchain/bin/clang-cl.exe -D CMAKE_Swift_COMPILER=S:/b/toolchain/bin/swiftc.exe -D USE_VENDORED_TSC=YES -D Foundation_DIR=S:/b/foundation/cmake/modules -D dispatch_DIR=S:/b/libdispatch/cmake/modules -D LLBuild_DIR=S:/b/llbuild/cmake/modules -G Ninja -S S:\swiftpm
-ninja -C S:\b\spm
+cmake -B S:\b\10 ^
+  -D BUILD_SHARED_LIBS=YES ^
+  -D CMAKE_BUILD_TYPE=Release ^
+  -D CMAKE_C_COMPILER=S:/b/1/bin/clang-cl.exe ^
+  -D CMAKE_Swift_COMPILER=S:/b/1/bin/swiftc.exe ^
+  -D CMAKE_INSTALL_PREFIX=C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr ^
+  -D dispatch_DIR=S:\b\2\cmake\modules ^
+  -D Foundation_DIR=S:\b\3\cmake\modules ^
+  -D TSC_DIR=S:\b\5\cmake\modules ^
+  -D LLBuild_DIR=S:\b\6\cmake\modules ^
+  -D Yams_DIR=S:\b\7\cmake\modules ^
+  -D ArgumentParser_DIR=S:\b\8\cmake\modules ^
+  -D SwiftDriver_DIR=S:\b\9\cmake\modules ^
+  -G Ninja ^
+  -S S:\swift-package-manager
+
+ninja -C S:\b\10
+```
+
+Indicate to swift-package-manager where to find the Package Description before installation:
+```cmd
+set SWIFTPM_PD_LIBS=S:\b\10\pm
 ```
 
 ## Install the Swift toolchain on Windows
@@ -239,7 +384,7 @@
 - Run ninja install:
 
 ```cmd
-ninja -C S:\b\toolchain install
+ninja -C S:\b\1 install
 ```
 
 - Add the Swift on Windows binaries path (`C:\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr\bin`) to the `PATH` environment variable.
diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h
index 7697baf..264af7e 100644
--- a/include/swift/AST/ASTContext.h
+++ b/include/swift/AST/ASTContext.h
@@ -122,6 +122,7 @@
   class IndexSubset;
   struct SILAutoDiffDerivativeFunctionKey;
   struct InterfaceSubContextDelegate;
+  class TypeCheckCompletionCallback;
 
   enum class KnownProtocolKind : uint8_t;
 
@@ -214,7 +215,9 @@
   void operator=(const ASTContext&) = delete;
 
   ASTContext(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
-             SearchPathOptions &SearchPathOpts, SourceManager &SourceMgr,
+             SearchPathOptions &SearchPathOpts,
+             ClangImporterOptions &ClangImporterOpts,
+             SourceManager &SourceMgr,
              DiagnosticEngine &Diags);
 
 public:
@@ -228,6 +231,7 @@
 
   static ASTContext *get(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
                          SearchPathOptions &SearchPathOpts,
+                         ClangImporterOptions &ClangImporterOpts,
                          SourceManager &SourceMgr, DiagnosticEngine &Diags);
   ~ASTContext();
 
@@ -246,12 +250,17 @@
   /// The search path options used by this AST context.
   SearchPathOptions &SearchPathOpts;
 
+  /// The clang importer options used by this AST context.
+  ClangImporterOptions &ClangImporterOpts;
+
   /// The source manager object.
   SourceManager &SourceMgr;
 
   /// Diags - The diagnostics engine.
   DiagnosticEngine &Diags;
 
+  TypeCheckCompletionCallback *CompletionCallback = nullptr;
+
   /// The request-evaluator that is used to process various requests.
   Evaluator evaluator;
 
diff --git a/include/swift/AST/ASTScope.h b/include/swift/AST/ASTScope.h
index 0cac9c8..2f3588e 100644
--- a/include/swift/AST/ASTScope.h
+++ b/include/swift/AST/ASTScope.h
@@ -44,11 +44,10 @@
 /// try disabling it.
 /// \p message must be a string literal
 #define ASTScopeAssert(predicate, message)                                     \
-  assert((predicate) && message                                                \
-         " Try compiling with '-disable-astscope-lookup'.")
+  assert((predicate) && message)
 
 #define ASTScope_unreachable(message)                                          \
-  llvm_unreachable(message " Try compiling with '-disable-astscope-lookup'.")
+  llvm_unreachable(message)
 
 namespace swift {
 
diff --git a/include/swift/AST/Builtins.h b/include/swift/AST/Builtins.h
index 1654e7c..516f7dc 100644
--- a/include/swift/AST/Builtins.h
+++ b/include/swift/AST/Builtins.h
@@ -26,7 +26,7 @@
 #include "llvm/Support/ErrorHandling.h"
 
 namespace llvm {
-enum class AtomicOrdering;
+enum class AtomicOrdering : unsigned;
 }
 
 namespace swift {
diff --git a/include/swift/AST/ClangNode.h b/include/swift/AST/ClangNode.h
index 73a633b..ec82998 100644
--- a/include/swift/AST/ClangNode.h
+++ b/include/swift/AST/ClangNode.h
@@ -49,8 +49,8 @@
   template <typename T>
   using Box = detail::ClangNodeBox<T>;
 
-  llvm::PointerUnion4<Box<clang::Decl>, Box<clang::MacroInfo>,
-                      Box<clang::ModuleMacro>, Box<clang::Module>> Ptr;
+  llvm::PointerUnion<Box<clang::Decl>, Box<clang::MacroInfo>,
+                     Box<clang::ModuleMacro>, Box<clang::Module>> Ptr;
 
 public:
   ClangNode() = default;
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 5842456..79f3bce 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -239,10 +239,14 @@
   /// Whether this declaration has an opaque return type.
   unsigned HasOpaqueReturnType : 1;
 
+  /// Whether this declaration is 'async'
+  unsigned HasAsync : 1;
+
   OverloadSignature()
       : UnaryOperator(UnaryOperatorKind::None), IsInstanceMember(false),
         IsVariable(false), IsFunction(false), InProtocolExtension(false),
-        InExtensionOfGenericType(false), HasOpaqueReturnType(false) {}
+        InExtensionOfGenericType(false), HasOpaqueReturnType(false),
+        HasAsync(false) {}
 };
 
 /// Determine whether two overload signatures conflict.
@@ -284,7 +288,7 @@
 protected:
   union { uint64_t OpaqueBits;
 
-  SWIFT_INLINE_BITFIELD_BASE(Decl, bitmax(NumDeclKindBits,8)+1+1+1+1,
+  SWIFT_INLINE_BITFIELD_BASE(Decl, bitmax(NumDeclKindBits,8)+1+1+1+1+1,
     Kind : bitmax(NumDeclKindBits,8),
 
     /// Whether this declaration is invalid.
@@ -301,7 +305,13 @@
 
     /// Whether this declaration was added to the surrounding
     /// DeclContext of an active #if config clause.
-    EscapedFromIfConfig : 1
+    EscapedFromIfConfig : 1,
+
+    /// Whether this declaration is syntactically scoped inside of
+    /// a local context, but should behave like a top-level
+    /// declaration for name lookup purposes. This is used by
+    /// lldb.
+    Hoisted : 1
   );
 
   SWIFT_INLINE_BITFIELD_FULL(PatternBindingDecl, Decl, 1+2+16,
@@ -690,6 +700,7 @@
     Bits.Decl.Implicit = false;
     Bits.Decl.FromClang = false;
     Bits.Decl.EscapedFromIfConfig = false;
+    Bits.Decl.Hoisted = false;
   }
 
   /// Get the Clang node associated with this declaration.
@@ -837,6 +848,16 @@
   /// Mark this declaration as implicit.
   void setImplicit(bool implicit = true) { Bits.Decl.Implicit = implicit; }
 
+  /// Determine whether this declaration is syntactically scoped inside of
+  /// a local context, but should behave like a top-level declaration
+  /// for name lookup purposes. This is used by lldb.
+  bool isHoisted() const { return Bits.Decl.Hoisted; }
+
+  /// Set whether this declaration should be syntactically scoped inside
+  /// of a local context, but should behave like a top-level declaration,
+  /// but should behave like a top-level declaration. This is used by lldb.
+  void setHoisted(bool hoisted = true) { Bits.Decl.Hoisted = hoisted; }
+
 public:
   bool escapedFromIfConfig() const {
     return Bits.Decl.EscapedFromIfConfig;
@@ -3886,7 +3907,7 @@
 
   friend class SuperclassDeclRequest;
   friend class SuperclassTypeRequest;
-  friend class EmittedMembersRequest;
+  friend class SemanticMembersRequest;
   friend class HasMissingDesignatedInitializersRequest;
   friend class InheritsSuperclassInitializersRequest;
 
@@ -4074,10 +4095,6 @@
   /// Record the presence of an @objc method with the given selector.
   void recordObjCMethod(AbstractFunctionDecl *method, ObjCSelector selector);
 
-  /// Get all the members of this class, synthesizing any implicit members
-  /// that appear in the vtable if needed.
-  ArrayRef<Decl *> getEmittedMembers() const;
-
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
     return D->getKind() == DeclKind::Class;
@@ -4870,9 +4887,9 @@
   /// The backing storage property, which is a stored property of the
   /// wrapper type.
   Backing,
-  /// A storage wrapper (e.g., `$foo`), which is a wrapper over the
-  /// wrapper instance's `projectedValue` property.
-  StorageWrapper,
+  /// A projection (e.g., `$foo`), which is a computed property to access the
+  /// wrapper instance's \c projectedValue property.
+  Projection,
 };
 
 /// VarDecl - 'var' and 'let' declarations.
@@ -5195,9 +5212,9 @@
   /// bound generic version.
   VarDecl *getPropertyWrapperBackingProperty() const;
 
-  /// Retreive the storage wrapper for a property that has an attached
-  /// property wrapper.
-  VarDecl *getPropertyWrapperStorageWrapper() const;
+  /// Retreive the projection var for a property that has an attached
+  /// property wrapper with a \c projectedValue .
+  VarDecl *getPropertyWrapperProjectionVar() const;
 
   /// Retrieve the backing storage property for a lazy property.
   VarDecl *getLazyStorageProperty() const;
diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h
index 36e1f07..c41eaa4 100644
--- a/include/swift/AST/DeclContext.h
+++ b/include/swift/AST/DeclContext.h
@@ -783,6 +783,16 @@
   /// Retrieve the set of members in this context.
   DeclRange getMembers() const;
 
+  /// Get the members that were syntactically present in the source code,
+  /// and will not contain any members that are implicitly synthesized by
+  /// the implementation.
+  ArrayRef<Decl *> getParsedMembers() const;
+
+  /// Get all the members that are semantically within this context,
+  /// including any implicitly-synthesized members.
+  /// The resulting list of members will be stable across translation units.
+  ArrayRef<Decl *> getSemanticMembers() const;
+
   /// Retrieve the set of members in this context without loading any from the
   /// associated lazy loader; this should only be used as part of implementing
   /// abstractions on top of member loading, such as a name lookup table.
diff --git a/include/swift/AST/DiagnosticEngine.h b/include/swift/AST/DiagnosticEngine.h
index 6d4fe61..338f146 100644
--- a/include/swift/AST/DiagnosticEngine.h
+++ b/include/swift/AST/DiagnosticEngine.h
@@ -1058,10 +1058,19 @@
       }
     }
 
-    bool hasDiagnostics() const {
-      return std::distance(Engine.TentativeDiagnostics.begin() +
-                               PrevDiagnostics,
-                           Engine.TentativeDiagnostics.end()) > 0;
+    bool hasErrors() const {
+      ArrayRef<Diagnostic> diagnostics(Engine.TentativeDiagnostics.begin() +
+                                           PrevDiagnostics,
+                                       Engine.TentativeDiagnostics.end());
+
+      for (auto &diagnostic : diagnostics) {
+        auto behavior = Engine.state.determineBehavior(diagnostic.getID());
+        if (behavior == DiagnosticState::Behavior::Fatal ||
+            behavior == DiagnosticState::Behavior::Error)
+          return true;
+      }
+
+      return false;
     }
 
     /// Abort and close this transaction and erase all diagnostics
diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def
index 36471ec..b614aae 100644
--- a/include/swift/AST/DiagnosticsFrontend.def
+++ b/include/swift/AST/DiagnosticsFrontend.def
@@ -125,6 +125,8 @@
       "this mode does not support emitting module source info files", ())
 ERROR(error_mode_cannot_emit_interface,none,
       "this mode does not support emitting module interface files", ())
+ERROR(error_mode_cannot_emit_module_summary,none,
+      "this mode does not support emitting module summary files", ())
 ERROR(cannot_emit_ir_skipping_function_bodies,none,
       "-experimental-skip-non-inlinable-function-bodies does not support "
       "emitting IR", ())
@@ -328,11 +330,11 @@
       (StringRef, StringRef))
 
 ERROR(error_invalid_debug_prefix_map, none,
-      "invalid argument '%0' to -debug-prefix-map; it must be of the form "
-      "'original=remapped'", (StringRef))
+      "values for '-debug-prefix-map' must be in the format 'original=remapped'"
+      ", but '%0' was provided", (StringRef))
 ERROR(error_invalid_coverage_prefix_map, none,
-      "invalid argument '%0' to -coverage-prefix-map; it must be of the form "
-      "'original=remapped'", (StringRef))
+      "values for '-coverage-prefix-map' must be in the format "
+      "'original=remapped', but '%0' was provided", (StringRef))
 
 
 ERROR(error_unable_to_write_swift_ranges_file, none,
@@ -366,6 +368,9 @@
       "error extracting flags from module interface", ())
 REMARK(rebuilding_module_from_interface,none,
        "rebuilding module '%0' from interface '%1'", (StringRef, StringRef))
+NOTE(sdk_version_pbm_version,none,
+     "SDK build version is '%0'; prebuilt modules were "
+     "built using SDK build version: '%1'", (StringRef, StringRef))
 NOTE(out_of_date_module_here,none,
      "%select{compiled|cached|forwarding|prebuilt}0 module is out of date: '%1'",
      (unsigned, StringRef))
diff --git a/include/swift/AST/DiagnosticsModuleDiffer.def b/include/swift/AST/DiagnosticsModuleDiffer.def
index d4aba30..dbcc194 100644
--- a/include/swift/AST/DiagnosticsModuleDiffer.def
+++ b/include/swift/AST/DiagnosticsModuleDiffer.def
@@ -74,7 +74,7 @@
 
 ERROR(type_witness_change,none,"%0 has type witness type for %1 changing from %2 to %3", (StringRef, StringRef, StringRef, StringRef))
 
-ERROR(decl_new_witness_table_entry,none,"%0 now requires %select{|no}1 new witness table entry", (StringRef, bool))
+ERROR(decl_new_witness_table_entry,none,"%0 now requires%select{| no}1 new witness table entry", (StringRef, bool))
 
 ERROR(new_decl_without_intro,none,"%0 is a new API without @available attribute", (StringRef))
 
@@ -88,5 +88,7 @@
 
 ERROR(enum_case_added,none,"%0 has been added as a new enum case", (StringRef))
 
+WARNING(cannot_read_allowlist,none,"cannot read breakage allowlist at '%0'", (StringRef))
+
 #define UNDEFINE_DIAGNOSTIC_MACROS
 #include "DefineDiagnosticMacros.h"
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 3a278eb..eaae1b7 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -882,8 +882,6 @@
       "expected ':' following argument label and parameter name", ())
 ERROR(expected_assignment_instead_of_comparison_operator,none,
       "expected '=' instead of '==' to assign default value for parameter", ())
-ERROR(multiple_parameter_ellipsis,none,
-      "only a single variadic parameter '...' is permitted", ())
 ERROR(parameter_vararg_default,none,
       "variadic parameter cannot have a default value", ())
 ERROR(parameter_specifier_as_attr_disallowed,none,
@@ -916,6 +914,8 @@
 
 ERROR(unlabeled_parameter_following_variadic_parameter,none,
       "a parameter following a variadic parameter requires a label", ())
+ERROR(closure_unlabeled_parameter_following_variadic_parameter,none,
+      "no parameters may follow a variadic parameter in a closure", ())
 
 ERROR(enum_element_empty_arglist,none,
       "enum element with associated values must have at least one "
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 9d36c35..13717b1 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1045,9 +1045,6 @@
         "cast from %0 to unrelated type %1 always fails", (Type, Type))
 NOTE(downcast_to_unrelated_fixit,none,
      "did you mean to call %0 with '()'?", (Identifier))
-ERROR(downcast_to_more_optional,none,
-      "cannot downcast from %0 to a more optional type %1",
-      (Type, Type))
 ERROR(optional_chain_noop,none,
       "optional chain has no effect, expression already produces %0",
       (Type))
@@ -1387,6 +1384,8 @@
       "@_cdecl symbol name cannot be empty", ())
 ERROR(cdecl_throws,none,
       "raising errors from @_cdecl functions is not supported", ())
+ERROR(cdecl_async,none,
+      "@_cdecl functions cannot be asynchronous", ())
 
 ERROR(attr_methods_only,none,
       "only methods can be declared %0", (DeclAttribute))
@@ -2742,13 +2741,17 @@
 ERROR(conformance_from_implementation_only_module,none,
       "cannot use conformance of %0 to %1 %select{here|as property wrapper here|"
       "in an extension with public or '@usableFromInline' members|"
-      "in an extension with conditional conformances}2; %3 has been imported "
-      "as implementation-only",
-      (Type, Identifier, unsigned, Identifier))
+      "in an extension with conditional conformances}2; "
+      "%select{%3 has been imported as implementation-only|"
+      "the conformance is declared as SPI in %3|"
+      "the conformance is declared as SPI}4",
+      (Type, Identifier, unsigned, Identifier, unsigned))
 ERROR(assoc_conformance_from_implementation_only_module,none,
       "cannot use conformance of %0 to %1 in associated type %3 (inferred as "
-      "%4); %2 has been imported as implementation-only",
-      (Type, Identifier, Identifier, Type, Type))
+      "%4); %select{%2 has been imported as implementation-only|"
+      "the conformance is declared as SPI in %2|"
+      "the conformance is declared as SPI}5",
+      (Type, Identifier, Identifier, Type, Type, unsigned))
 ERROR(unexportable_clang_function_type,none,
       "cannot export the underlying C type of the function type %0; "
       "it may use anonymous types or types defined outside of a module",
@@ -3348,6 +3351,16 @@
 ERROR(missing_builtin_precedence_group,none,
       "broken standard library: missing builtin precedence group %0",
       (Identifier))
+WARNING(nan_comparison, none, 
+       "comparison with '.nan' using %0 is always %select{false|true}1, use "
+       "'%2.isNaN' to check if '%3' %select{is not a number|is a number}1",
+       (Identifier, bool, StringRef, StringRef))
+WARNING(nan_comparison_without_isnan, none, 
+       "comparison with '.nan' using %0 is always %select{false|true}1", 
+       (Identifier, bool))
+WARNING(nan_comparison_both_nan, none, 
+       "'.nan' %0 '.nan' is always %select{false|true}1", 
+       (StringRef, bool))
 
 // If you change this, also change enum TryKindForDiagnostics.
 #define TRY_KIND_SELECT(SUB) "%select{try|try!|try?|await}" #SUB
@@ -4116,6 +4129,19 @@
       "'@asyncHandler' function cannot be 'mutating'",
       ())
 
+ERROR(objc_ambiguous_async_convention,none,
+      "%0 overrides or implements protocol requirements for Objective-C "
+      "declarations with incompatible async conventions",
+      (DeclName))
+NOTE(objc_ambiguous_async_convention_candidate,none,
+     "%0 provides async here", (DeclName))
+
+ERROR(satisfy_async_objc,none,
+      "satisfying an asychronous @objc %select{method|initializer}0 with "
+      "a synchronous %select{method|initializer}0 is not supported", (bool))
+ERROR(async_objc_dynamic_self,none,
+      "asynchronous method returning 'Self' cannot be '@objc'", ())
+
 //------------------------------------------------------------------------------
 // MARK: Type Check Types
 //------------------------------------------------------------------------------
@@ -5249,6 +5275,16 @@
         "function builder %0 does not implement 'buildLimitedAvailability'; "
         "this code may crash on earlier versions of the OS",
         (Type))
+ERROR(function_builder_static_buildblock, none,
+      "function builder must provide at least one static 'buildBlock' "
+      "method", ())
+NOTE(function_builder_non_static_buildblock, none,
+     "did you mean to make instance method 'buildBlock' static?", ())
+NOTE(function_builder_buildblock_enum_case, none,
+     "enum case 'buildBlock' cannot be used to satisfy the function builder "
+     "requirement", ())
+NOTE(function_builder_buildblock_not_static_method, none,
+     "potential match 'buildBlock' is not a static method", ())
 
 //------------------------------------------------------------------------------
 // MARK: Tuple Shuffle Diagnostics
diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h
index 55ea27b..6f25872 100644
--- a/include/swift/AST/ExtInfo.h
+++ b/include/swift/AST/ExtInfo.h
@@ -30,6 +30,7 @@
 
 namespace clang {
 class Type;
+class ASTContext;
 } // namespace clang
 
 namespace swift {
@@ -77,7 +78,7 @@
   /// Use the ClangModuleLoader to print the Clang type as a string.
   void printType(ClangModuleLoader *cml, llvm::raw_ostream &os) const;
 
-  void dump(llvm::raw_ostream &os) const;
+  void dump(llvm::raw_ostream &os, const clang::ASTContext &ctx) const;
 };
 
 // MARK: - FunctionTypeRepresentation
diff --git a/include/swift/AST/ForeignAsyncConvention.h b/include/swift/AST/ForeignAsyncConvention.h
index f365776..35b6c64 100644
--- a/include/swift/AST/ForeignAsyncConvention.h
+++ b/include/swift/AST/ForeignAsyncConvention.h
@@ -24,38 +24,78 @@
 
 /// A small structure describing the async convention of a foreign declaration.
 class ForeignAsyncConvention {
-  /// The index of the completion handler parameters.
-  unsigned CompletionHandlerParamIndex;
-
-  /// When non-zero, indicates which parameter to the completion handler is the
-  /// Error? parameter (minus one) that makes this async function also throwing.
-  unsigned CompletionHandlerErrorParamIndex;
 public:
-  ForeignAsyncConvention()
+  struct Info {
+    /// The index of the completion handler parameters.
+    unsigned CompletionHandlerParamIndex;
+
+    /// When non-zero, indicates which parameter to the completion handler is
+    /// the Error? parameter (minus one) that makes this async function also
+    /// throwing.
+    unsigned CompletionHandlerErrorParamIndex;
+
+    Info()
       : CompletionHandlerParamIndex(0), CompletionHandlerErrorParamIndex(0) { }
 
-  ForeignAsyncConvention(unsigned completionHandlerParamIndex,
-                         Optional<unsigned> completionHandlerErrorParamIndex)
+    Info(
+        unsigned completionHandlerParamIndex,
+        Optional<unsigned> completionHandlerErrorParamIndex)
       : CompletionHandlerParamIndex(completionHandlerParamIndex),
         CompletionHandlerErrorParamIndex(
-          completionHandlerErrorParamIndex
-            ? *completionHandlerErrorParamIndex + 1
-            : 0) {}
+            completionHandlerErrorParamIndex
+              ? *completionHandlerErrorParamIndex + 1
+              : 0) {}
+
+    /// Retrieve the index of the \c Error? parameter in the completion handler's
+    /// parameter list. When argument passed to this parameter is non-null, the
+    /// provided error will be thrown by the async function.
+    Optional<unsigned> completionHandlerErrorParamIndex() const {
+      if (CompletionHandlerErrorParamIndex == 0)
+        return None;
+
+      return CompletionHandlerErrorParamIndex - 1;
+    }
+
+    /// Whether the async function is throwing due to the completion handler
+    /// having an \c Error? parameter.
+    ///
+    /// Equivalent to \c static_cast<bool>(completionHandlerErrorParamIndex()).
+    bool isThrowing() const {
+      return CompletionHandlerErrorParamIndex != 0;
+    }
+  };
+
+  /// The type of the completion handler parameter.
+  CanType CompletionHandlerType;
+
+  /// Information about the async convention that can be determined from an
+  /// Objective-C declaration by itself.
+  Info TheInfo;
+
+public:
+  ForeignAsyncConvention() : TheInfo() { }
+
+  ForeignAsyncConvention(CanType completionHandlerType,
+                         unsigned completionHandlerParamIndex,
+                         Optional<unsigned> completionHandlerErrorParamIndex)
+      : CompletionHandlerType(completionHandlerType),
+        TheInfo(completionHandlerParamIndex, completionHandlerErrorParamIndex)
+  { }
+
+  /// Retrieve the type of the completion handler parameter.
+  CanType completionHandlerType() const { return CompletionHandlerType; }
 
   /// Retrieve the index of the completion handler parameter, which will be
   /// erased from the Swift signature of the imported async function.
   unsigned completionHandlerParamIndex() const {
-    return CompletionHandlerParamIndex;
+    return TheInfo.CompletionHandlerParamIndex;
   }
 
   /// Retrieve the index of the \c Error? parameter in the completion handler's
   /// parameter list. When argument passed to this parameter is non-null, the
   /// provided error will be thrown by the async function.
   Optional<unsigned> completionHandlerErrorParamIndex() const {
-    if (CompletionHandlerErrorParamIndex == 0)
-      return None;
-
-    return CompletionHandlerErrorParamIndex - 1;
+    return TheInfo.completionHandlerErrorParamIndex();
   }
 
   /// Whether the async function is throwing due to the completion handler
@@ -63,14 +103,17 @@
   ///
   /// Equivalent to \c static_cast<bool>(completionHandlerErrorParamIndex()).
   bool isThrowing() const {
-    return CompletionHandlerErrorParamIndex != 0;
+    return TheInfo.isThrowing();
   }
 
   bool operator==(ForeignAsyncConvention other) const {
-    return CompletionHandlerParamIndex == other.CompletionHandlerParamIndex
-      && CompletionHandlerErrorParamIndex ==
-        other.CompletionHandlerErrorParamIndex;
+    return CompletionHandlerType == other.CompletionHandlerType
+        && TheInfo.CompletionHandlerParamIndex ==
+          other.TheInfo.CompletionHandlerParamIndex
+        && TheInfo.CompletionHandlerErrorParamIndex ==
+          other.TheInfo.CompletionHandlerErrorParamIndex;
   }
+
   bool operator!=(ForeignAsyncConvention other) const {
     return !(*this == other);
   }
diff --git a/include/swift/AST/Identifier.h b/include/swift/AST/Identifier.h
index 85e4101..2aa585e 100644
--- a/include/swift/AST/Identifier.h
+++ b/include/swift/AST/Identifier.h
@@ -109,7 +109,14 @@
     // Handle the high unicode case out of line.
     return isOperatorSlow();
   }
-  
+
+  // Returns whether this is a standard comparison operator,
+  // such as '==', '>=' or '!=='.
+  bool isStandardComparisonOperator() const {
+    return is("==") || is("!=") || is("===") || is("!==") || is("<") ||
+           is(">") || is("<=") || is(">=");
+  }
+
   /// isOperatorStartCodePoint - Return true if the specified code point is a
   /// valid start of an operator.
   static bool isOperatorStartCodePoint(uint32_t C) {
diff --git a/include/swift/AST/KnownProtocols.def b/include/swift/AST/KnownProtocols.def
index 18a8062..e530e38 100644
--- a/include/swift/AST/KnownProtocols.def
+++ b/include/swift/AST/KnownProtocols.def
@@ -87,6 +87,8 @@
 PROTOCOL(AdditiveArithmetic)
 PROTOCOL(Differentiable)
 
+PROTOCOL(FloatingPoint)
+
 EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByArrayLiteral, "Array", false)
 EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByBooleanLiteral, "BooleanLiteralType", true)
 EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByDictionaryLiteral, "Dictionary", false)
diff --git a/include/swift/AST/PlatformKinds.def b/include/swift/AST/PlatformKinds.def
index 29ae592..55d2f2e 100644
--- a/include/swift/AST/PlatformKinds.def
+++ b/include/swift/AST/PlatformKinds.def
@@ -32,5 +32,6 @@
 AVAILABILITY_PLATFORM(macOSApplicationExtension, "application extensions for macOS")
 AVAILABILITY_PLATFORM(macCatalyst, "Mac Catalyst")
 AVAILABILITY_PLATFORM(macCatalystApplicationExtension, "application extensions for Mac Catalyst")
+AVAILABILITY_PLATFORM(OpenBSD, "OpenBSD")
 
 #undef AVAILABILITY_PLATFORM
diff --git a/include/swift/AST/PrettyStackTrace.h b/include/swift/AST/PrettyStackTrace.h
index e08b7bb..001c760 100644
--- a/include/swift/AST/PrettyStackTrace.h
+++ b/include/swift/AST/PrettyStackTrace.h
@@ -26,6 +26,7 @@
 
 namespace clang {
   class Type;
+  class ASTContext;
 }
 
 namespace swift {
@@ -141,11 +142,13 @@
 /// PrettyStackTraceClangType - Observe that we are processing a
 /// specific Clang type.
 class PrettyStackTraceClangType : public llvm::PrettyStackTraceEntry {
+  const clang::ASTContext &Context;
   const clang::Type *TheType;
   const char *Action;
 public:
-  PrettyStackTraceClangType(const char *action, const clang::Type *type)
-    : TheType(type), Action(action) {}
+  PrettyStackTraceClangType(clang::ASTContext &ctx,
+                            const char *action, const clang::Type *type)
+    : Context(ctx), TheType(type), Action(action) {}
   virtual void print(llvm::raw_ostream &OS) const override;
 };
 
diff --git a/include/swift/AST/PrintOptions.h b/include/swift/AST/PrintOptions.h
index abfebaf..2b99e4a 100644
--- a/include/swift/AST/PrintOptions.h
+++ b/include/swift/AST/PrintOptions.h
@@ -380,10 +380,13 @@
   /// has no associated doc-comment by itself.
   bool CascadeDocComment = false;
 
+  static const std::function<bool(const ExtensionDecl *)>
+      defaultPrintExtensionContentAsMembers;
+
   /// Whether to print the content of an extension decl inside the type decl where it
   /// extends from.
   std::function<bool(const ExtensionDecl *)> printExtensionContentAsMembers =
-    [] (const ExtensionDecl *) { return false; };
+    PrintOptions::defaultPrintExtensionContentAsMembers;
 
   /// How to print the keyword argument and parameter name in functions.
   ArgAndParamPrintingMode ArgAndParamPrinting =
diff --git a/include/swift/AST/PropertyWrappers.h b/include/swift/AST/PropertyWrappers.h
index f1a1b57..2f78ad4 100644
--- a/include/swift/AST/PropertyWrappers.h
+++ b/include/swift/AST/PropertyWrappers.h
@@ -145,9 +145,9 @@
   /// The backing property.
   VarDecl *backingVar = nullptr;
 
-  /// The storage wrapper property, if any. When present, this takes the name
-  /// '$foo' from `backingVar`.
-  VarDecl *storageWrapperVar = nullptr;
+  /// The synthesized projection property, if any. When present, this takes the name
+  /// of the original wrapped property prefixed with \c $
+  VarDecl *projectionVar = nullptr;
 
   /// An expression that initializes the backing property from a value of
   /// the original property's type (e.g., via `init(wrappedValue:)`), or
@@ -161,10 +161,10 @@
   PropertyWrapperBackingPropertyInfo() { }
   
   PropertyWrapperBackingPropertyInfo(VarDecl *backingVar,
-                                     VarDecl *storageWrapperVar,
+                                     VarDecl *projectionVar,
                                      Expr *initializeFromOriginal,
                                      PropertyWrapperValuePlaceholderExpr *placeholder)
-    : backingVar(backingVar), storageWrapperVar(storageWrapperVar),
+    : backingVar(backingVar), projectionVar(projectionVar),
       initializeFromOriginal(initializeFromOriginal),
       wrappedValuePlaceholder(placeholder) { }
 
diff --git a/include/swift/AST/SILOptions.h b/include/swift/AST/SILOptions.h
index af8d8c2..5eaac7a 100644
--- a/include/swift/AST/SILOptions.h
+++ b/include/swift/AST/SILOptions.h
@@ -128,6 +128,11 @@
   /// Assume that code will be executed in a single-threaded environment.
   bool AssumeSingleThreaded = false;
 
+  /// Turn @inline(__always) attributes into no-ops.
+  ///
+  /// For experimentation around code size reduction.
+  bool IgnoreAlwaysInline = false;
+
   /// Indicates which sanitizer is turned on.
   OptionSet<SanitizerKind> Sanitizers;
 
diff --git a/include/swift/AST/SimpleRequest.h b/include/swift/AST/SimpleRequest.h
index 42751e1..d59c616 100644
--- a/include/swift/AST/SimpleRequest.h
+++ b/include/swift/AST/SimpleRequest.h
@@ -24,6 +24,7 @@
 #include "swift/Basic/TypeID.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Error.h"
 #include <tuple>
 #include <type_traits>
 
diff --git a/include/swift/AST/SourceFile.h b/include/swift/AST/SourceFile.h
index 96c25e4..5fc32b5 100644
--- a/include/swift/AST/SourceFile.h
+++ b/include/swift/AST/SourceFile.h
@@ -187,6 +187,10 @@
   /// have been removed, this can become an optional ArrayRef.
   Optional<std::vector<Decl *>> Decls;
 
+  /// The list of hoisted declarations. See Decl::isHoisted().
+  /// This is only used by lldb.
+  std::vector<Decl *> Hoisted;
+
   using SeparatelyImportedOverlayMap =
     llvm::SmallDenseMap<ModuleDecl *, llvm::SmallPtrSet<ModuleDecl *, 1>>;
 
@@ -231,9 +235,16 @@
     Decls->insert(Decls->begin(), d);
   }
 
+  /// Add a hoisted declaration. See Decl::isHoisted().
+  void addHoistedDecl(Decl *d);
+
   /// Retrieves an immutable view of the list of top-level decls in this file.
   ArrayRef<Decl *> getTopLevelDecls() const;
 
+  /// Retrieves an immutable view of the list of hoisted decls in this file.
+  /// See Decl::isHoisted().
+  ArrayRef<Decl *> getHoistedDecls() const;
+
   /// Retrieves an immutable view of the top-level decls if they have already
   /// been parsed, or \c None if they haven't. Should only be used for dumping.
   Optional<ArrayRef<Decl *>> getCachedTopLevelDecls() const {
@@ -692,9 +703,11 @@
                               StringRefDMI::getTombstoneKey());
   }
   static inline unsigned getHashValue(const ImportedModuleDesc &import) {
-    return combineHashValue(ImportedModuleDMI::getHashValue(import.module),
-           combineHashValue(ImportOptionsDMI::getHashValue(import.importOptions),
-                            StringRefDMI::getHashValue(import.filename)));
+    return detail::combineHashValue(
+        ImportedModuleDMI::getHashValue(import.module),
+        detail::combineHashValue(
+            ImportOptionsDMI::getHashValue(import.importOptions),
+            StringRefDMI::getHashValue(import.filename)));
   }
   static bool isEqual(const ImportedModuleDesc &a,
                       const ImportedModuleDesc &b) {
diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h
index c73b37d..8e03a00 100644
--- a/include/swift/AST/TypeCheckRequests.h
+++ b/include/swift/AST/TypeCheckRequests.h
@@ -1080,9 +1080,9 @@
   void cacheResult(AccessorDecl *value) const;
 };
 
-class EmittedMembersRequest :
-    public SimpleRequest<EmittedMembersRequest,
-                         ArrayRef<Decl *>(ClassDecl *),
+class SemanticMembersRequest :
+    public SimpleRequest<SemanticMembersRequest,
+                         ArrayRef<Decl *>(IterableDeclContext *),
                          RequestFlags::Cached> {
 public:
   using SimpleRequest::SimpleRequest;
@@ -1092,7 +1092,7 @@
 
   // Evaluation.
   ArrayRef<Decl *>
-  evaluate(Evaluator &evaluator, ClassDecl *classDecl) const;
+  evaluate(Evaluator &evaluator, IterableDeclContext *idc) const;
 
 public:
   bool isCached() const { return true; }
diff --git a/include/swift/AST/TypeCheckerTypeIDZone.def b/include/swift/AST/TypeCheckerTypeIDZone.def
index fdc1614..bcc4148 100644
--- a/include/swift/AST/TypeCheckerTypeIDZone.def
+++ b/include/swift/AST/TypeCheckerTypeIDZone.def
@@ -65,8 +65,8 @@
 SWIFT_REQUEST(TypeChecker, DynamicallyReplacedDeclRequest,
               ValueDecl *(ValueDecl *),
               Cached, NoLocationInfo)
-SWIFT_REQUEST(TypeChecker, EmittedMembersRequest, ArrayRef<Decl *>(ClassDecl *),
-              Cached, NoLocationInfo)
+SWIFT_REQUEST(TypeChecker, SemanticMembersRequest,
+              ArrayRef<Decl *>(IterableDeclContext *), Cached, NoLocationInfo)
 SWIFT_REQUEST(TypeChecker, EnumRawValuesRequest,
               evaluator::SideEffect (EnumDecl *, TypeResolutionStage),
               SeparatelyCached, NoLocationInfo)
diff --git a/include/swift/Basic/FileTypes.def b/include/swift/Basic/FileTypes.def
index 1435813..2a05138 100644
--- a/include/swift/Basic/FileTypes.def
+++ b/include/swift/Basic/FileTypes.def
@@ -51,6 +51,7 @@
 TYPE("swiftdoc",            SwiftModuleDocFile,        "swiftdoc",        "")
 TYPE("swiftinterface",      SwiftModuleInterfaceFile,  "swiftinterface",  "")
 TYPE("private-swiftinterface", PrivateSwiftModuleInterfaceFile,  "private.swiftinterface",  "")
+TYPE("swiftmodulesummary",  SwiftModuleSummaryFile,    "swiftmodulesummary", "")
 TYPE("swiftsourceinfo",     SwiftSourceInfoFile,       "swiftsourceinfo", "")
 TYPE("assembly",            Assembly,                  "s",               "")
 TYPE("raw-sil",             RawSIL,                    "sil",             "")
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index 6531ecd..6810676 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -248,28 +248,12 @@
     /// This is a staging flag; eventually it will be removed.
     bool EnableDeserializationRecovery = true;
 
-    /// Should we use \c ASTScope-based resolution for unqualified name lookup?
-    /// Default is in \c ParseLangArgs
-    ///
-    /// This is a staging flag; eventually it will be removed.
-    bool EnableASTScopeLookup = true;
-
     /// Someday, ASTScopeLookup will supplant lookup in the parser
     bool DisableParserLookup = false;
 
-    /// Should  we compare to ASTScope-based resolution for debugging?
-    bool CrosscheckUnqualifiedLookup = false;
-
     /// Should  we stress ASTScope-based resolution for debugging?
     bool StressASTScopeLookup = false;
 
-    /// Since some tests fail if the warning is output, use a flag to decide
-    /// whether it is. The warning is useful for testing.
-    bool WarnIfASTScopeLookup = false;
-
-    /// Build the ASTScope tree lazily
-    bool LazyASTScopes = true;
-
     /// Whether to enable the new operator decl and precedencegroup lookup
     /// behavior. This is a staging flag, and will be removed in the future.
     bool EnableNewOperatorLookup = false;
@@ -577,6 +561,115 @@
     /// parameters of closures.
     bool EnableOneWayClosureParameters = false;
   };
+
+  /// Options for controlling the behavior of the Clang importer.
+  class ClangImporterOptions final {
+  public:
+    /// The module cache path which the Clang importer should use.
+    std::string ModuleCachePath;
+
+    /// Extra arguments which should be passed to the Clang importer.
+    std::vector<std::string> ExtraArgs;
+
+    /// A directory for overriding Clang's resource directory.
+    std::string OverrideResourceDir;
+
+    /// The target CPU to compile for.
+    ///
+    /// Equivalent to Clang's -mcpu=.
+    std::string TargetCPU;
+
+    /// The path to which we should store indexing data, if any.
+    std::string IndexStorePath;
+
+    /// The bridging header or PCH that will be imported.
+    std::string BridgingHeader;
+
+    /// When automatically generating a precompiled header from the bridging
+    /// header, place it in this directory.
+    std::string PrecompiledHeaderOutputDir;
+
+    /// The optimizaton setting.  This doesn't typically matter for
+    /// import, but it can affect Clang's IR generation of static functions.
+    std::string Optimization;
+
+    /// Disable validating the persistent PCH.
+    bool PCHDisableValidation = false;
+
+    /// \see Mode
+    enum class Modes : uint8_t {
+      /// Set up Clang for importing modules into Swift and generating IR from
+      /// Swift code.
+      Normal,
+      /// Set up Clang for backend compilation only.
+      EmbedBitcode,
+      /// Set up Clang to emit a precompiled module from a C/Objective-C module
+      /// map or dump debugging info about a precompiled module.
+      PrecompiledModule
+    };
+
+    /// Controls how Clang is initially set up.
+    Modes Mode = Modes::Normal;
+
+    /// When set, preserves more information during import.
+    ///
+    /// Also \em disables some information that is only needed for object file
+    /// generation.
+    bool DetailedPreprocessingRecord = false;
+
+    /// If true, Clang diagnostics will be dumped to stderr using Clang's
+    /// diagnostic printer as well as being passed to Swift's diagnostic engine.
+    bool DumpClangDiagnostics = false;
+
+    /// If true, forward declarations will be imported using unavailable types
+    /// instead of dropped altogether when possible.
+    bool ImportForwardDeclarations = false;
+
+    /// Whether to use the import as member inference system
+    ///
+    /// When importing a global, try to infer whether we can import it as a
+    /// member of some type instead. This includes inits, computed properties,
+    /// and methods.
+    bool InferImportAsMember = false;
+
+    /// If true ignore the swift bridged attribute.
+    bool DisableSwiftBridgeAttr = false;
+
+    /// When set, don't look for or load overlays.
+    bool DisableOverlayModules = false;
+
+    /// When set, don't enforce warnings with -Werror.
+    bool DebuggerSupport = false;
+
+    /// When set, ClangImporter is disabled, and all requests go to the
+    /// DWARFImporter delegate.
+    bool DisableSourceImport = false;
+
+    /// When set, use ExtraArgs alone to configure clang instance because ExtraArgs
+    /// contains the full option set.
+    bool ExtraArgsOnly = false;
+
+    /// Return a hash code of any components from these options that should
+    /// contribute to a Swift Bridging PCH hash.
+    llvm::hash_code getPCHHashComponents() const {
+      using llvm::hash_combine;
+      using llvm::hash_combine_range;
+
+      return hash_combine(ModuleCachePath,
+                          hash_combine_range(ExtraArgs.begin(), ExtraArgs.end()),
+                          OverrideResourceDir,
+                          TargetCPU,
+                          BridgingHeader,
+                          PrecompiledHeaderOutputDir,
+                          static_cast<uint8_t>(Mode),
+                          DetailedPreprocessingRecord,
+                          ImportForwardDeclarations,
+                          InferImportAsMember,
+                          DisableSwiftBridgeAttr,
+                          DisableOverlayModules);
+    }
+  };
+
 } // end namespace swift
 
 #endif // SWIFT_BASIC_LANGOPTIONS_H
diff --git a/include/swift/Basic/Platform.h b/include/swift/Basic/Platform.h
index 3585c6a..a5f13d9 100644
--- a/include/swift/Basic/Platform.h
+++ b/include/swift/Basic/Platform.h
@@ -106,6 +106,13 @@
   /// Retrieve the target SDK version for the given SDKInfo and target triple.
   llvm::VersionTuple getTargetSDKVersion(clang::driver::DarwinSDKInfo &SDKInfo,
                                          const llvm::Triple &triple);
+
+  /// Get SDK build version.
+  std::string getSDKBuildVersion(StringRef SDKPath);
+  std::string getSDKBuildVersionFromPlist(StringRef Path);
+
+  /// Get SDK name.
+  std::string getSDKName(StringRef SDKPath);
 } // end namespace swift
 
 #endif // SWIFT_BASIC_PLATFORM_H
diff --git a/include/swift/Basic/PrimarySpecificPaths.h b/include/swift/Basic/PrimarySpecificPaths.h
index 1e73810..f21ec9e 100644
--- a/include/swift/Basic/PrimarySpecificPaths.h
+++ b/include/swift/Basic/PrimarySpecificPaths.h
@@ -49,6 +49,9 @@
     return !SupplementaryOutputs.ModuleOutputPath.empty() ||
            !SupplementaryOutputs.ModuleDocOutputPath.empty();
   }
+  bool haveModuleSummaryOutputPath() const {
+    return !SupplementaryOutputs.ModuleSummaryOutputPath.empty();
+  }
 };
 } // namespace swift
 
diff --git a/include/swift/Basic/STLExtras.h b/include/swift/Basic/STLExtras.h
index fa06044..21d2993 100644
--- a/include/swift/Basic/STLExtras.h
+++ b/include/swift/Basic/STLExtras.h
@@ -69,51 +69,6 @@
   using argument_types = std::tuple<Args...>;
 };
 
-} // end namespace swift
-
-#if !defined(swiftCore_EXPORTS)
-namespace llvm {
-
-/// @{
-
-/// An STL-style algorithm similar to std::for_each that applies a second
-/// functor between every pair of elements.
-///
-/// This provides the control flow logic to, for example, print a
-/// comma-separated list:
-/// \code
-///   interleave(names.begin(), names.end(),
-///              [&](StringRef name) { OS << name; },
-///              [&] { OS << ", "; });
-/// \endcode
-template <typename ForwardIterator, typename UnaryFunctor,
-          typename NullaryFunctor>
-inline void interleave(ForwardIterator begin, ForwardIterator end,
-                       UnaryFunctor each_fn,
-                       NullaryFunctor between_fn) {
-  if (begin == end)
-    return;
-  each_fn(*begin);
-  ++begin;
-  for (; begin != end; ++begin) {
-    between_fn();
-    each_fn(*begin);
-  }
-}
-
-template <typename Container, typename UnaryFunctor, typename NullaryFunctor>
-inline void interleave(const Container &c, UnaryFunctor each_fn,
-                       NullaryFunctor between_fn) {
-  interleave(c.begin(), c.end(), each_fn, between_fn);
-}
-
-/// @}
-
-} // end namespace llvm
-#endif
-
-namespace swift {
-
 /// @{
 
 /// The equivalent of std::for_each, but for two lists at once.
diff --git a/include/swift/Basic/SupplementaryOutputPaths.h b/include/swift/Basic/SupplementaryOutputPaths.h
index c1d0494..3649d4d 100644
--- a/include/swift/Basic/SupplementaryOutputPaths.h
+++ b/include/swift/Basic/SupplementaryOutputPaths.h
@@ -165,6 +165,9 @@
   /// name per symbol, we should eventually remove this.
   std::string LdAddCFilePath;
 
+  /// The path to which we should emit module summary file.
+  std::string ModuleSummaryOutputPath;
+
   SupplementaryOutputPaths() = default;
   SupplementaryOutputPaths(const SupplementaryOutputPaths &) = default;
 
diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h
index 128886f..42896fd 100644
--- a/include/swift/ClangImporter/ClangImporter.h
+++ b/include/swift/ClangImporter/ClangImporter.h
@@ -115,7 +115,7 @@
 private:
   Implementation &Impl;
 
-  ClangImporter(ASTContext &ctx, const ClangImporterOptions &clangImporterOpts,
+  ClangImporter(ASTContext &ctx,
                 DependencyTracker *tracker,
                 DWARFImporterDelegate *dwarfImporterDelegate);
 
@@ -137,8 +137,6 @@
   /// \param ctx The ASTContext into which the module will be imported.
   /// The ASTContext's SearchPathOptions will be used for the Clang importer.
   ///
-  /// \param importerOpts The options to use for the Clang importer.
-  ///
   /// \param swiftPCHHash A hash of Swift's various options in a compiler
   /// invocation, used to create a unique Bridging PCH if requested.
   ///
@@ -150,12 +148,12 @@
   /// \returns a new Clang module importer, or null (with a diagnostic) if
   /// an error occurred.
   static std::unique_ptr<ClangImporter>
-  create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
+  create(ASTContext &ctx,
          std::string swiftPCHHash = "", DependencyTracker *tracker = nullptr,
          DWARFImporterDelegate *dwarfImporterDelegate = nullptr);
 
   static std::vector<std::string>
-  getClangArguments(ASTContext &ctx, const ClangImporterOptions &importerOpts);
+  getClangArguments(ASTContext &ctx);
 
   static std::unique_ptr<clang::CompilerInvocation>
   createClangInvocation(ClangImporter *importer,
@@ -378,6 +376,7 @@
   /// construction of the replica.
   bool dumpPrecompiledModule(StringRef modulePath, StringRef outputPath);
 
+  bool runPreprocessor(StringRef inputPath, StringRef outputPath);
   const clang::Module *getClangOwningModule(ClangNode Node) const;
   bool hasTypedef(const clang::Decl *typeDecl) const;
 
@@ -473,7 +472,6 @@
 
   bool isSerializable(const clang::Type *type,
                       bool checkCanonical) const override;
-  ArrayRef<std::string> getExtraClangArgs() const;
 };
 
 ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,
diff --git a/include/swift/ClangImporter/ClangImporterOptions.h b/include/swift/ClangImporter/ClangImporterOptions.h
deleted file mode 100644
index 173abc2..0000000
--- a/include/swift/ClangImporter/ClangImporterOptions.h
+++ /dev/null
@@ -1,133 +0,0 @@
-//===--- ClangImporterOptions.h ---------------------------------*- C++ -*-===//
-//
-// This source file is part of the Swift.org open source project
-//
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See https://swift.org/LICENSE.txt for license information
-// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SWIFT_CLANGIMPORTER_CLANGIMPORTEROPTIONS_H
-#define SWIFT_CLANGIMPORTER_CLANGIMPORTEROPTIONS_H
-
-#include "llvm/ADT/Hashing.h"
-
-#include <string>
-#include <vector>
-
-namespace swift {
-
-/// Options for controlling the behavior of the Clang importer.
-class ClangImporterOptions {
-public:
-  /// The module cache path which the Clang importer should use.
-  std::string ModuleCachePath;
-
-  /// Extra arguments which should be passed to the Clang importer.
-  std::vector<std::string> ExtraArgs;
-
-  /// A directory for overriding Clang's resource directory.
-  std::string OverrideResourceDir;
-
-  /// The target CPU to compile for.
-  ///
-  /// Equivalent to Clang's -mcpu=.
-  std::string TargetCPU;
-
-  /// The path to which we should store indexing data, if any.
-  std::string IndexStorePath;
-
-  /// The bridging header or PCH that will be imported.
-  std::string BridgingHeader;
-
-  /// When automatically generating a precompiled header from the bridging
-  /// header, place it in this directory.
-  std::string PrecompiledHeaderOutputDir;
-
-  /// The optimizaton setting.  This doesn't typically matter for
-  /// import, but it can affect Clang's IR generation of static functions.
-  std::string Optimization;
-
-  /// Disable validating the persistent PCH.
-  bool PCHDisableValidation = false;
-
-  /// \see Mode
-  enum class Modes : uint8_t {
-    /// Set up Clang for importing modules into Swift and generating IR from
-    /// Swift code.
-    Normal,
-    /// Set up Clang for backend compilation only.
-    EmbedBitcode,
-    /// Set up Clang to emit a precompiled module from a C/Objective-C module
-    /// map or dump debugging info about a precompiled module.
-    PrecompiledModule
-  };
-
-  /// Controls how Clang is initially set up.
-  Modes Mode = Modes::Normal;
-
-  /// When set, preserves more information during import.
-  ///
-  /// Also \em disables some information that is only needed for object file
-  /// generation.
-  bool DetailedPreprocessingRecord = false;
-
-  /// If true, Clang diagnostics will be dumped to stderr using Clang's
-  /// diagnostic printer as well as being passed to Swift's diagnostic engine.
-  bool DumpClangDiagnostics = false;
-
-  /// If true, forward declarations will be imported using unavailable types
-  /// instead of dropped altogether when possible.
-  bool ImportForwardDeclarations = false;
-
-  /// Whether to use the import as member inference system
-  ///
-  /// When importing a global, try to infer whether we can import it as a
-  /// member of some type instead. This includes inits, computed properties,
-  /// and methods.
-  bool InferImportAsMember = false;
-
-  /// If true ignore the swift bridged attribute.
-  bool DisableSwiftBridgeAttr = false;
-
-  /// When set, don't look for or load overlays.
-  bool DisableOverlayModules = false;
-
-  /// When set, don't enforce warnings with -Werror.
-  bool DebuggerSupport = false;
-
-  /// When set, ClangImporter is disabled, and all requests go to the
-  /// DWARFImporter delegate.
-  bool DisableSourceImport = false;
-
-  /// When set, use ExtraArgs alone to configure clang instance because ExtraArgs
-  /// contains the full option set.
-  bool ExtraArgsOnly = false;
-
-  /// Return a hash code of any components from these options that should
-  /// contribute to a Swift Bridging PCH hash.
-  llvm::hash_code getPCHHashComponents() const {
-    using llvm::hash_combine;
-    using llvm::hash_combine_range;
-
-    return hash_combine(ModuleCachePath,
-                        hash_combine_range(ExtraArgs.begin(), ExtraArgs.end()),
-                        OverrideResourceDir,
-                        TargetCPU,
-                        BridgingHeader,
-                        PrecompiledHeaderOutputDir,
-                        static_cast<uint8_t>(Mode),
-                        DetailedPreprocessingRecord,
-                        ImportForwardDeclarations,
-                        InferImportAsMember,
-                        DisableSwiftBridgeAttr,
-                        DisableOverlayModules);
-  }
-};
-
-} // end namespace swift
-
-#endif
diff --git a/include/swift/ClangImporter/ClangModule.h b/include/swift/ClangImporter/ClangModule.h
index 90cc2c9..f1f1579 100644
--- a/include/swift/ClangImporter/ClangModule.h
+++ b/include/swift/ClangImporter/ClangModule.h
@@ -19,6 +19,7 @@
 #include "swift/AST/FileUnit.h"
 #include "swift/ClangImporter/ClangImporter.h"
 #include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/Module.h"
 
 namespace clang {
   class ASTContext;
@@ -37,7 +38,7 @@
   llvm::PointerIntPair<ModuleDecl *, 1, bool> overlayModule;
   mutable Optional<ArrayRef<ModuleDecl::ImportedModule>> importedModulesForLookup;
   /// The metadata of the underlying Clang module.
-  clang::ExternalASTSource::ASTSourceDescriptor ASTSourceDescriptor;
+  clang::ASTSourceDescriptor ASTSourceDescriptor;
 
 public:
   /// True if the given Module contains an imported Clang module unit.
@@ -115,8 +116,7 @@
 
   /// Returns the ASTSourceDescriptor of the associated Clang module if one
   /// exists.
-  Optional<clang::ExternalASTSource::ASTSourceDescriptor>
-  getASTSourceDescriptor() const;
+  Optional<clang::ASTSourceDescriptor> getASTSourceDescriptor() const;
 
   virtual StringRef getModuleDefiningPath() const override;
 
diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h
index 074e4aa..f7a5a22 100644
--- a/include/swift/Demangling/TypeDecoder.h
+++ b/include/swift/Demangling/TypeDecoder.h
@@ -349,9 +349,8 @@
 
   BuilderType &Builder;
 
- public:
-  explicit TypeDecoder(BuilderType &Builder)
-    : Builder(Builder) {}
+public:
+  explicit TypeDecoder(BuilderType &Builder) : Builder(Builder) {}
 
   /// Given a demangle tree, attempt to turn it into a type.
   TypeLookupErrorOr<BuiltType> decodeMangledType(NodePointer Node) {
diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h
index 5e05535..d55121e 100644
--- a/include/swift/Driver/Driver.h
+++ b/include/swift/Driver/Driver.h
@@ -366,6 +366,11 @@
                                  file_types::ID fileType,
                                  CommandOutput *output) const;
 
+  void chooseModuleSummaryPath(Compilation &C, const TypeToPathMap *OutputMap,
+                               StringRef workingDirectory,
+                               llvm::SmallString<128> &Buf,
+                               CommandOutput *Output) const;
+
   void chooseRemappingOutputPath(Compilation &C, const TypeToPathMap *OutputMap,
                                  CommandOutput *Output) const;
 
diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h
index 39ab041..0fa9e0e 100644
--- a/include/swift/Frontend/Frontend.h
+++ b/include/swift/Frontend/Frontend.h
@@ -30,7 +30,6 @@
 #include "swift/Basic/LangOptions.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/ClangImporter/ClangImporter.h"
-#include "swift/ClangImporter/ClangImporterOptions.h"
 #include "swift/Frontend/DiagnosticVerifier.h"
 #include "swift/Frontend/FrontendOptions.h"
 #include "swift/Frontend/ModuleInterfaceSupport.h"
@@ -329,11 +328,6 @@
     return CodeCompletionOffset != ~0U;
   }
 
-  /// Called from lldb, see rdar://53971116
-  void disableASTScopeLookup() {
-    LangOpts.EnableASTScopeLookup = false;
-  }
-
   /// Retrieve a module hash string that is suitable for uniquely
   /// identifying the conditions under which the module was built, for use
   /// in generating a cached PCH file for the bridging header.
diff --git a/include/swift/Frontend/FrontendInputsAndOutputs.h b/include/swift/Frontend/FrontendInputsAndOutputs.h
index 76f5ef1..84a85ec 100644
--- a/include/swift/Frontend/FrontendInputsAndOutputs.h
+++ b/include/swift/Frontend/FrontendInputsAndOutputs.h
@@ -17,6 +17,7 @@
 #include "swift/Basic/SupplementaryOutputPaths.h"
 #include "swift/Frontend/InputFile.h"
 #include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringMap.h"
 
 #include <string>
 #include <vector>
@@ -239,6 +240,7 @@
   bool hasModuleSourceInfoOutputPath() const;
   bool hasModuleInterfaceOutputPath() const;
   bool hasPrivateModuleInterfaceOutputPath() const;
+  bool hasModuleSummaryOutputPath() const;
   bool hasTBDPath() const;
 
   bool hasDependencyTrackerPath() const;
diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h
index c961794..e2f84da 100644
--- a/include/swift/Frontend/FrontendOptions.h
+++ b/include/swift/Frontend/FrontendOptions.h
@@ -340,6 +340,7 @@
   static bool canActionEmitLoadedModuleTrace(ActionType);
   static bool canActionEmitModule(ActionType);
   static bool canActionEmitModuleDoc(ActionType);
+  static bool canActionEmitModuleSummary(ActionType);
   static bool canActionEmitInterface(ActionType);
 
 public:
diff --git a/include/swift/Frontend/ModuleInterfaceLoader.h b/include/swift/Frontend/ModuleInterfaceLoader.h
index 7878298..9996d8e 100644
--- a/include/swift/Frontend/ModuleInterfaceLoader.h
+++ b/include/swift/Frontend/ModuleInterfaceLoader.h
@@ -420,8 +420,8 @@
                                   DiagnosticEngine &Diags,
                                   const SearchPathOptions &searchPathOpts,
                                   const LangOptions &langOpts,
+                                  const ClangImporterOptions &clangImporterOpts,
                                   ModuleInterfaceLoaderOptions LoaderOpts,
-                                  ClangModuleLoader *clangImporter,
                                   bool buildModuleCacheDirIfAbsent,
                                   StringRef moduleCachePath,
                                   StringRef prebuiltCachePath,
@@ -448,7 +448,6 @@
                                     llvm::SmallString<256> &OutPath,
                                     StringRef &CacheHash);
   std::string getCacheHash(StringRef useInterfacePath);
-  void addExtraClangArg(StringRef Arg);
 };
 }
 
diff --git a/include/swift/IDE/CodeCompletion.h b/include/swift/IDE/CodeCompletion.h
index 4324cc9..60f1938 100644
--- a/include/swift/IDE/CodeCompletion.h
+++ b/include/swift/IDE/CodeCompletion.h
@@ -57,6 +57,20 @@
                                        StringRef TokenName,
                                        unsigned *CompletionOffset);
 
+StringRef copyString(llvm::BumpPtrAllocator &Allocator,
+                     StringRef Str);
+
+const char *copyCString(llvm::BumpPtrAllocator &Allocator,
+                        StringRef Str);
+
+template <typename T>
+ArrayRef<T> copyArray(llvm::BumpPtrAllocator &Allocator,
+                            ArrayRef<T> Arr) {
+  T *Buffer = Allocator.Allocate<T>(Arr.size());
+  std::copy(Arr.begin(), Arr.end(), Buffer);
+  return llvm::makeArrayRef(Buffer, Arr.size());
+}
+
 namespace detail {
 class CodeCompletionStringChunk {
   friend class swift::ide::CodeCompletionResultBuilder;
@@ -870,7 +884,7 @@
     /// but should not hide any results.
     SingleExpressionBody,
 
-    /// There are known contextual types.
+    /// There are known contextual types, or there aren't but a nonvoid type is expected.
     Required,
   };
 
diff --git a/include/swift/IDE/CompletionInstance.h b/include/swift/IDE/CompletionInstance.h
index 51687b9..2c114ee 100644
--- a/include/swift/IDE/CompletionInstance.h
+++ b/include/swift/IDE/CompletionInstance.h
@@ -37,8 +37,10 @@
 
 /// Manages \c CompilerInstance for completion like operations.
 class CompletionInstance {
-  unsigned MaxASTReuseCount = 100;
-  unsigned DependencyCheckIntervalSecond = 5;
+  struct Options {
+    unsigned MaxASTReuseCount = 100;
+    unsigned DependencyCheckIntervalSecond = 5;
+  } Opts;
 
   std::mutex mtx;
 
@@ -59,7 +61,7 @@
   /// argument has changed, primary file is not the same, the \c Offset is not
   /// in function bodies, or the interface hash of the file has changed.
   bool performCachedOperationIfPossible(
-      const swift::CompilerInvocation &Invocation, llvm::hash_code ArgsHash,
+      llvm::hash_code ArgsHash,
       llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
       llvm::MemoryBuffer *completionBuffer, unsigned int Offset,
       DiagnosticConsumer *DiagC,
@@ -78,7 +80,9 @@
       llvm::function_ref<void(CompilerInstance &, bool)> Callback);
 
 public:
-  void setDependencyCheckIntervalSecond(unsigned Value);
+  CompletionInstance() {}
+
+  void setOptions(Options NewOpts);
 
   /// Calls \p Callback with a \c CompilerInstance which is prepared for the
   /// second pass. \p Callback is resposible to perform the second pass on it.
@@ -94,7 +98,7 @@
       swift::CompilerInvocation &Invocation, llvm::ArrayRef<const char *> Args,
       llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
       llvm::MemoryBuffer *completionBuffer, unsigned int Offset,
-      bool EnableASTCaching, std::string &Error, DiagnosticConsumer *DiagC,
+      std::string &Error, DiagnosticConsumer *DiagC,
       llvm::function_ref<void(CompilerInstance &, bool)> Callback);
 };
 
diff --git a/include/swift/IDE/Utils.h b/include/swift/IDE/Utils.h
index 8eaf34a..c916f77 100644
--- a/include/swift/IDE/Utils.h
+++ b/include/swift/IDE/Utils.h
@@ -101,10 +101,6 @@
 
 void collectModuleNames(StringRef SDKPath, std::vector<std::string> &Modules);
 
-std::string getSDKName(StringRef Path);
-
-std::string getSDKVersion(StringRef Path);
-
 struct PlaceholderOccurrence {
   /// The complete placeholder string.
   StringRef FullPlaceholder;
diff --git a/include/swift/Localization/LocalizationFormat.h b/include/swift/Localization/LocalizationFormat.h
index efd3d53..ccea867 100644
--- a/include/swift/Localization/LocalizationFormat.h
+++ b/include/swift/Localization/LocalizationFormat.h
@@ -17,6 +17,7 @@
 #ifndef SWIFT_LOCALIZATIONFORMAT_H
 #define SWIFT_LOCALIZATIONFORMAT_H
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
@@ -42,6 +43,20 @@
 
 using namespace llvm::support;
 
+class DefToYAMLConverter {
+  llvm::ArrayRef<const char *> IDs;
+  llvm::ArrayRef<const char *> Messages;
+
+public:
+  DefToYAMLConverter(llvm::ArrayRef<const char *> ids,
+                     llvm::ArrayRef<const char *> messages)
+      : IDs(ids), Messages(messages) {
+    assert(IDs.size() == Messages.size());
+  }
+
+  void convert(llvm::raw_ostream &out);
+};
+
 class LocalizationWriterInfo {
 public:
   using key_type = uint32_t;
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index 8996c61..cf788d0 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -160,12 +160,6 @@
 def stress_astscope_lookup : Flag<["-"], "stress-astscope-lookup">,
   HelpText<"Stress ASTScope-based unqualified name lookup (for testing)">;
   
-def warn_if_astscope_lookup : Flag<["-"], "warn-if-astscope-lookup">,
-  HelpText<"Print a warning if ASTScope lookup is used">;
-  
-def lazy_astscopes : Flag<["-"], "lazy-astscopes">,
-  HelpText<"Build ASTScopes lazily">;
-
 def use_clang_function_types : Flag<["-"], "use-clang-function-types">,
   HelpText<"Use stored Clang function types for computing canonical types.">;
 
@@ -601,6 +595,9 @@
   Flag<["-"], "disable-incremental-llvm-codegen">,
        HelpText<"Disable incremental llvm code generation.">;
 
+def ignore_always_inline : Flag<["-"], "ignore-always-inline">,
+  HelpText<"Ignore @inline(__always) attributes.">;
+
 def emit_sorted_sil : Flag<["-"], "emit-sorted-sil">,
   HelpText<"When printing SIL, print out all sil entities sorted by name to "
            "ease diffing">;
diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td
index 8273359..e75d2f8 100644
--- a/include/swift/Option/Options.td
+++ b/include/swift/Option/Options.td
@@ -443,6 +443,17 @@
          ArgumentIsPath, SupplementaryOutput]>,
   Alias<emit_module_path>;
 
+def emit_module_summary :
+  Flag<["-"], "emit-module-summary">,
+  Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild,
+         SupplementaryOutput]>,
+  HelpText<"Output module summary file">;
+def emit_module_summary_path :
+  Separate<["-"], "emit-module-summary-path">,
+  Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
+         ArgumentIsPath, SupplementaryOutput]>,
+  MetaVarName<"<path>">, HelpText<"Output module summary file to <path>">;
+
 def emit_module_interface :
   Flag<["-"], "emit-module-interface">,
   Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild,
@@ -1107,14 +1118,6 @@
   HelpText<"Scan dependencies of the given Clang module">, ModeOpt,
   Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>;
 
-def enable_astscope_lookup : Flag<["-"], "enable-astscope-lookup">,
-  Flags<[FrontendOption]>,
-  HelpText<"Enable ASTScope-based unqualified name lookup">;
-
-def disable_astscope_lookup : Flag<["-"], "disable-astscope-lookup">,
-  Flags<[FrontendOption]>,
-  HelpText<"Disable ASTScope-based unqualified name lookup">;
-
 def disable_parser_lookup : Flag<["-"], "disable-parser-lookup">,
   Flags<[FrontendOption]>,
   HelpText<"Disable parser lookup & use ast scope lookup only (experimental)">;
diff --git a/include/swift/Parse/CodeCompletionCallbacks.h b/include/swift/Parse/CodeCompletionCallbacks.h
index eeee748..d11c82e 100644
--- a/include/swift/Parse/CodeCompletionCallbacks.h
+++ b/include/swift/Parse/CodeCompletionCallbacks.h
@@ -119,7 +119,7 @@
   virtual void setAttrTargetDeclKind(Optional<DeclKind> DK) {}
 
   /// Complete expr-dot after we have consumed the dot.
-  virtual void completeDotExpr(Expr *E, SourceLoc DotLoc) {};
+  virtual void completeDotExpr(CodeCompletionExpr *E, SourceLoc DotLoc) {};
 
   /// Complete the beginning of a statement or expression.
   virtual void completeStmtOrExpr(CodeCompletionExpr *E) {};
diff --git a/include/swift/Parse/ParsedRawSyntaxNode.h b/include/swift/Parse/ParsedRawSyntaxNode.h
index 916e3d8..81985d9 100644
--- a/include/swift/Parse/ParsedRawSyntaxNode.h
+++ b/include/swift/Parse/ParsedRawSyntaxNode.h
@@ -98,8 +98,8 @@
     assert(DeferredToken.NumTrailingTrivia == numTrailingTrivia &&
            "numLeadingTrivia is too large value!");
   }
-  ParsedRawSyntaxNode(ParsedRawSyntaxNode &other) = delete;
-  ParsedRawSyntaxNode &operator=(ParsedRawSyntaxNode &other) = delete;
+  ParsedRawSyntaxNode(const ParsedRawSyntaxNode &other) = delete;
+  ParsedRawSyntaxNode &operator=(const ParsedRawSyntaxNode &other) = delete;
 
 public:
   ParsedRawSyntaxNode()
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index 7f1b3dd..1c4584e 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -125,9 +125,6 @@
   CodeCompletionCallbacks *CodeCompletion = nullptr;
   std::vector<Located<std::vector<ParamDecl*>>> AnonClosureVars;
 
-  /// Tracks parsed decls that LLDB requires to be inserted at the top-level.
-  std::vector<Decl *> ContextSwitchedTopLevelDecls;
-
   /// The current token hash, or \c None if the parser isn't computing a hash
   /// for the token stream.
   Optional<llvm::MD5> CurrentTokenHash;
@@ -146,7 +143,6 @@
   ArrayRef<VarDecl *> DisabledVars;
   Diag<> DisabledVarReason;
   
-  llvm::SmallPtrSet<Decl *, 2> AlreadyHandledDecls;
   enum {
     /// InVarOrLetPattern has this value when not parsing a pattern.
     IVOLP_NotInVarOrLet,
@@ -696,6 +692,15 @@
       Context.LangOpts.ParseForSyntaxTreeOnly;
   }
 
+  /// If a function or closure body consists of a single expression, determine
+  /// whether we should turn wrap it in a return statement or not.
+  ///
+  /// We don't do this transformation for non-solver-based code completion
+  /// positions, as the source may be incomplete and the type mismatch in the
+  /// return statement will just confuse the type checker.
+  bool shouldSuppressSingleExpressionBodyTransform(
+      ParserStatus Status, MutableArrayRef<ASTNode> BodyElems);
+
 public:
   InFlightDiagnostic diagnose(SourceLoc Loc, Diagnostic Diag) {
     if (Diags.isDiagnosticPointsToFirstBadToken(Diag.getID()) &&
@@ -930,14 +935,8 @@
   void consumeDecl(ParserPosition BeginParserPosition, ParseDeclOptions Flags,
                    bool IsTopLevel);
 
-  // When compiling for the Debugger, some Decl's need to be moved from the
-  // current scope.  In which case although the Decl will be returned in the
-  // ParserResult, it should not be inserted into the Decl list for the current
-  // context.  markWasHandled asserts that the Decl is already where it
-  // belongs, and declWasHandledAlready is used to check this assertion.
-  // To keep the handled decl array small, we remove the Decl when it is
-  // checked, so you can only call declWasAlreadyHandled once for a given
-  // decl.
+  /// FIXME: Remove this, it's vestigial.
+  llvm::SmallPtrSet<Decl *, 2> AlreadyHandledDecls;
 
   void markWasHandled(Decl *D) {
     AlreadyHandledDecls.insert(D);
diff --git a/include/swift/Reflection/ReflectionContext.h b/include/swift/Reflection/ReflectionContext.h
index 6fc3df0..9e26669 100644
--- a/include/swift/Reflection/ReflectionContext.h
+++ b/include/swift/Reflection/ReflectionContext.h
@@ -680,7 +680,9 @@
   
   /// Return a description of the layout of a class instance with the given
   /// metadata as its isa pointer.
-  const TypeInfo *getMetadataTypeInfo(StoredPointer MetadataAddress) {
+  const TypeInfo *
+  getMetadataTypeInfo(StoredPointer MetadataAddress,
+                      remote::TypeInfoProvider *ExternalTypeInfo) {
     // See if we cached the layout already
     auto found = Cache.find(MetadataAddress);
     if (found != Cache.end())
@@ -702,7 +704,7 @@
 
         // Perform layout
         if (start)
-          TI = TC.getClassInstanceTypeInfo(TR, *start);
+          TI = TC.getClassInstanceTypeInfo(TR, *start, ExternalTypeInfo);
 
         break;
       }
@@ -718,7 +720,9 @@
 
   /// Return a description of the layout of a class instance with the given
   /// metadata as its isa pointer.
-  const TypeInfo *getInstanceTypeInfo(StoredPointer ObjectAddress) {
+  const TypeInfo *
+  getInstanceTypeInfo(StoredPointer ObjectAddress,
+                      remote::TypeInfoProvider *ExternalTypeInfo) {
     auto MetadataAddress = readMetadataFromInstance(ObjectAddress);
     if (!MetadataAddress)
       return nullptr;
@@ -729,7 +733,7 @@
 
     switch (*kind) {
     case MetadataKind::Class:
-      return getMetadataTypeInfo(*MetadataAddress);
+      return getMetadataTypeInfo(*MetadataAddress, ExternalTypeInfo);
 
     case MetadataKind::HeapLocalVariable: {
       auto CDAddr = this->readCaptureDescriptorFromMetadata(*MetadataAddress);
@@ -751,7 +755,7 @@
 
       auto Info = getBuilder().getClosureContextInfo(CD);
 
-      return getClosureContextInfo(ObjectAddress, Info);
+      return getClosureContextInfo(ObjectAddress, Info, ExternalTypeInfo);
     }
 
     case MetadataKind::HeapGenericLocalVariable: {
@@ -760,7 +764,8 @@
       if (auto Meta = readMetadata(*MetadataAddress)) {
         auto GenericHeapMeta =
           cast<TargetGenericBoxHeapMetadata<Runtime>>(Meta.getLocalBuffer());
-        return getMetadataTypeInfo(GenericHeapMeta->BoxedType);
+        return getMetadataTypeInfo(GenericHeapMeta->BoxedType,
+                                   ExternalTypeInfo);
       }
       return nullptr;
     }
@@ -774,15 +779,15 @@
     }
   }
 
-  bool
-  projectExistential(RemoteAddress ExistentialAddress,
-                     const TypeRef *ExistentialTR,
-                     const TypeRef **OutInstanceTR,
-                     RemoteAddress *OutInstanceAddress) {
+  bool projectExistential(RemoteAddress ExistentialAddress,
+                          const TypeRef *ExistentialTR,
+                          const TypeRef **OutInstanceTR,
+                          RemoteAddress *OutInstanceAddress,
+                          remote::TypeInfoProvider *ExternalTypeInfo) {
     if (ExistentialTR == nullptr)
       return false;
 
-    auto ExistentialTI = getTypeInfo(ExistentialTR);
+    auto ExistentialTI = getTypeInfo(ExistentialTR, ExternalTypeInfo);
     if (ExistentialTI == nullptr)
       return false;
 
@@ -846,14 +851,14 @@
   /// Returns true if the enum case could be successfully determined.  In
   /// particular, note that this code may return false for valid in-memory data
   /// if the compiler used a strategy we do not yet understand.
-  bool projectEnumValue(RemoteAddress EnumAddress,
-                        const TypeRef *EnumTR,
-                        int *CaseIndex) {
+  bool projectEnumValue(RemoteAddress EnumAddress, const TypeRef *EnumTR,
+                        int *CaseIndex,
+                        remote::TypeInfoProvider *ExternalTypeInfo) {
     // Get the TypeInfo and sanity-check it
     if (EnumTR == nullptr) {
       return false;
     }
-    auto TI = getTypeInfo(EnumTR);
+    auto TI = getTypeInfo(EnumTR, ExternalTypeInfo);
     if (TI == nullptr) {
       return false;
     }
@@ -865,11 +870,12 @@
   }
 
   /// Return a description of the layout of a value with the given type.
-  const TypeInfo *getTypeInfo(const TypeRef *TR) {
+  const TypeInfo *getTypeInfo(const TypeRef *TR,
+                              remote::TypeInfoProvider *ExternalTypeInfo) {
     if (TR == nullptr) {
       return nullptr;
     } else {
-      return getBuilder().getTypeConverter().getTypeInfo(TR);
+      return getBuilder().getTypeConverter().getTypeInfo(TR, ExternalTypeInfo);
     }
   }
 
@@ -1160,8 +1166,9 @@
   }
 
 private:
-  const TypeInfo *getClosureContextInfo(StoredPointer Context,
-                                        const ClosureContextInfo &Info) {
+  const TypeInfo *
+  getClosureContextInfo(StoredPointer Context, const ClosureContextInfo &Info,
+                        remote::TypeInfoProvider *ExternalTypeInfo) {
     RecordTypeInfoBuilder Builder(getBuilder().getTypeConverter(),
                                   RecordKind::ClosureContext);
 
@@ -1219,7 +1226,7 @@
         SubstCaptureTR = OrigCaptureTR;
 
       if (SubstCaptureTR != nullptr) {
-        Builder.addField("", SubstCaptureTR);
+        Builder.addField("", SubstCaptureTR, ExternalTypeInfo);
         if (Builder.isInvalid())
           return nullptr;
 
diff --git a/include/swift/Reflection/TypeLowering.h b/include/swift/Reflection/TypeLowering.h
index f3e59d1..9c278fa 100644
--- a/include/swift/Reflection/TypeLowering.h
+++ b/include/swift/Reflection/TypeLowering.h
@@ -22,6 +22,7 @@
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/Support/Casting.h"
 #include "swift/Remote/MetadataReader.h"
+#include "swift/Remote/TypeInfoProvider.h"
 
 #include <memory>
 
@@ -316,7 +317,8 @@
 class TypeConverter {
   TypeRefBuilder &Builder;
   std::vector<std::unique_ptr<const TypeInfo>> Pool;
-  llvm::DenseMap<const TypeRef *, const TypeInfo *> Cache;
+  llvm::DenseMap<std::pair<const TypeRef *, remote::TypeInfoProvider *>,
+                 const TypeInfo *> Cache;
   llvm::DenseSet<const TypeRef *> RecursionCheck;
   llvm::DenseMap<std::pair<unsigned, unsigned>,
                  const ReferenceTypeInfo *> ReferenceCache;
@@ -347,14 +349,16 @@
   ///
   /// The type must either be concrete, or at least fixed-size, as
   /// determined by the isFixedSize() predicate.
-  const TypeInfo *getTypeInfo(const TypeRef *TR);
+  const TypeInfo *getTypeInfo(const TypeRef *TR,
+                              remote::TypeInfoProvider *externalInfo);
 
   /// Returns layout information for an instance of the given
   /// class.
   ///
   /// Not cached.
-  const TypeInfo *getClassInstanceTypeInfo(const TypeRef *TR,
-                                           unsigned start);
+  const TypeInfo *
+  getClassInstanceTypeInfo(const TypeRef *TR, unsigned start,
+                           remote::TypeInfoProvider *ExternalTypeInfo);
 
 private:
   friend class swift::reflection::LowerType;
@@ -415,7 +419,8 @@
                     bool bitwiseTakable);
 
   // Add a field of a record type, such as a struct.
-  void addField(const std::string &Name, const TypeRef *TR);
+  void addField(const std::string &Name, const TypeRef *TR,
+                remote::TypeInfoProvider *ExternalTypeInfo);
 
   const RecordTypeInfo *build();
 
diff --git a/include/swift/Reflection/TypeRef.h b/include/swift/Reflection/TypeRef.h
index 2637f61..fb03cbc 100644
--- a/include/swift/Reflection/TypeRef.h
+++ b/include/swift/Reflection/TypeRef.h
@@ -156,8 +156,8 @@
   bool isConcrete() const;
   bool isConcreteAfterSubstitutions(const GenericArgumentMap &Subs) const;
 
-  const TypeRef *
-  subst(TypeRefBuilder &Builder, const GenericArgumentMap &Subs) const;
+  const TypeRef *subst(TypeRefBuilder &Builder,
+                       const GenericArgumentMap &Subs) const;
 
   llvm::Optional<GenericArgumentMap> getSubstMap() const;
 
@@ -301,27 +301,48 @@
 };
 
 class TupleTypeRef final : public TypeRef {
+protected:
   std::vector<const TypeRef *> Elements;
+  std::string Labels;
 
-  static TypeRefID Profile(const std::vector<const TypeRef *> &Elements) {
+  static TypeRefID Profile(const std::vector<const TypeRef *> &Elements,
+                           const std::string &Labels) {
     TypeRefID ID;
     for (auto Element : Elements)
       ID.addPointer(Element);
+    ID.addString(Labels);
     return ID;
   }
 
 public:
-  TupleTypeRef(std::vector<const TypeRef *> Elements)
-      : TypeRef(TypeRefKind::Tuple), Elements(std::move(Elements)) {}
+  TupleTypeRef(std::vector<const TypeRef *> Elements, std::string &&Labels)
+      : TypeRef(TypeRefKind::Tuple), Elements(std::move(Elements)),
+        Labels(Labels) {}
 
   template <typename Allocator>
   static const TupleTypeRef *create(Allocator &A,
-                                    std::vector<const TypeRef *> Elements) {
-    FIND_OR_CREATE_TYPEREF(A, TupleTypeRef, Elements);
+                                    std::vector<const TypeRef *> Elements,
+                                    std::string &&Labels) {
+    FIND_OR_CREATE_TYPEREF(A, TupleTypeRef, Elements, Labels);
   }
 
-  const std::vector<const TypeRef *> &getElements() const {
-    return Elements;
+  const std::vector<const TypeRef *> &getElements() const { return Elements; };
+  const std::string &getLabelString() const { return Labels; };
+  std::vector<llvm::StringRef> getLabels() const {
+    std::vector<llvm::StringRef> Vec;
+    std::string::size_type End, Start = 0;
+    while (true) {
+      End = Labels.find(' ', Start);
+      if (End == std::string::npos)
+        break;
+      Vec.push_back(llvm::StringRef(Labels.data() + Start, End - Start));
+      Start = End + 1;
+    }
+    // A canonicalized TypeRef has an empty label string.
+    // Pad the vector with empty labels.
+    for (unsigned N = Vec.size(); N < Elements.size(); ++N)
+      Vec.push_back({});
+    return Vec;
   };
 
   static bool classof(const TypeRef *TR) {
diff --git a/include/swift/Reflection/TypeRefBuilder.h b/include/swift/Reflection/TypeRefBuilder.h
index 3914810..982bcba 100644
--- a/include/swift/Reflection/TypeRefBuilder.h
+++ b/include/swift/Reflection/TypeRefBuilder.h
@@ -405,9 +405,7 @@
 
   const TupleTypeRef *createTupleType(llvm::ArrayRef<const TypeRef *> elements,
                                       std::string &&labels) {
-    // FIXME: Add uniqueness checks in TupleTypeRef::Profile and
-    // unittests/Reflection/TypeRef.cpp if using labels for identity.
-    return TupleTypeRef::create(*this, elements);
+    return TupleTypeRef::create(*this, elements, std::move(labels));
   }
 
   const FunctionTypeRef *createFunctionType(
@@ -634,16 +632,14 @@
                     const std::string &Member,
                     StringRef Protocol);
 
-  const TypeRef *
-  lookupSuperclass(const TypeRef *TR);
+  const TypeRef *lookupSuperclass(const TypeRef *TR);
 
   /// Load unsubstituted field types for a nominal type.
-  RemoteRef<FieldDescriptor>
-  getFieldTypeInfo(const TypeRef *TR);
+  RemoteRef<FieldDescriptor> getFieldTypeInfo(const TypeRef *TR);
 
   /// Get the parsed and substituted field types for a nominal type.
-  bool getFieldTypeRefs(const TypeRef *TR,
-                        RemoteRef<FieldDescriptor> FD,
+  bool getFieldTypeRefs(const TypeRef *TR, RemoteRef<FieldDescriptor> FD,
+                        remote::TypeInfoProvider *ExternalTypeInfo,
                         std::vector<FieldTypeInfo> &Fields);
 
   /// Get the primitive type lowering for a builtin type.
diff --git a/include/swift/Remote/MemoryReader.h b/include/swift/Remote/MemoryReader.h
index 6575f83..6dfd4c7 100644
--- a/include/swift/Remote/MemoryReader.h
+++ b/include/swift/Remote/MemoryReader.h
@@ -37,7 +37,8 @@
 class MemoryReader {
 public:
   /// A convenient name for the return type from readBytes.
-  using ReadBytesResult = std::unique_ptr<const void, std::function<void(const void *)>>;
+  using ReadBytesResult =
+      std::unique_ptr<const void, std::function<void(const void *)>>;
 
   virtual bool queryDataLayout(DataLayoutQueryType type, void *inBuffer,
                                void *outBuffer) = 0;
@@ -152,9 +153,8 @@
     
     return resolvePointer(address, pointerData);
   }
-          
 
-  // Parse extra inhabitants stored in a pointer.
+ // Parse extra inhabitants stored in a pointer.
   // Sets *extraInhabitant to -1 if the pointer at this address
   // is actually a valid pointer.
   // Otherwise, it sets *extraInhabitant to the inhabitant
diff --git a/include/swift/Remote/TypeInfoProvider.h b/include/swift/Remote/TypeInfoProvider.h
new file mode 100644
index 0000000..73995ca
--- /dev/null
+++ b/include/swift/Remote/TypeInfoProvider.h
@@ -0,0 +1,39 @@
+//===--- TypeInfoProvider.h - Abstract access to type info ------*- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file declares an abstract interface for reading type layout info.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_REMOTE_TYPEINFOPROVIDER_H
+#define SWIFT_REMOTE_TYPEINFOPROVIDER_H
+
+namespace swift {
+namespace reflection {
+class TypeInfo;
+}
+namespace remote {
+
+/// An abstract interface for providing external type layout information.
+struct TypeInfoProvider {
+  virtual ~TypeInfoProvider() = default;
+
+  /// Attempt to read type information about (Clang)imported types that are not
+  /// represented in the metadata. LLDB can read this information from debug
+  /// info, for example.
+  virtual const reflection::TypeInfo *
+  getTypeInfo(llvm::StringRef mangledName) = 0;
+};
+
+} // namespace remote
+} // namespace swift
+#endif
diff --git a/include/swift/Runtime/MutexSingleThreaded.h b/include/swift/Runtime/MutexSingleThreaded.h
index 4a25e90..b7323c4 100644
--- a/include/swift/Runtime/MutexSingleThreaded.h
+++ b/include/swift/Runtime/MutexSingleThreaded.h
@@ -17,6 +17,8 @@
 #ifndef SWIFT_RUNTIME_MUTEX_SINGLE_THREADED_H
 #define SWIFT_RUNTIME_MUTEX_SINGLE_THREADED_H
 
+#include "swift/Runtime/Debug.h"
+
 namespace swift {
 
 typedef void* ConditionHandle;
@@ -35,7 +37,9 @@
   static void destroy(ConditionHandle &condition) {}
   static void notifyOne(ConditionHandle &condition) {}
   static void notifyAll(ConditionHandle &condition) {}
-  static void wait(ConditionHandle &condition, MutexHandle &mutex);
+  static void wait(ConditionHandle &condition, MutexHandle &mutex) {
+    fatalError(0, "single-threaded runtime cannot wait for condition");
+  }
 };
 
 struct MutexPlatformHelper {
diff --git a/include/swift/SIL/OptimizationRemark.h b/include/swift/SIL/OptimizationRemark.h
index 32842da..3e3c05c 100644
--- a/include/swift/SIL/OptimizationRemark.h
+++ b/include/swift/SIL/OptimizationRemark.h
@@ -119,6 +119,12 @@
       : Argument(ArgumentKey(ArgumentKeyKind::Default, key), msg, decl) {}
   Argument(ArgumentKey key, StringRef msg, const ValueDecl *decl)
       : key(key), val(msg), loc(decl->getLoc()) {}
+
+  Argument(StringRef key, llvm::Twine &&msg, SILLocation loc)
+      : Argument(ArgumentKey(ArgumentKeyKind::Default, key), std::move(msg),
+                 loc) {}
+  Argument(ArgumentKey key, llvm::Twine &&msg, SILLocation loc)
+      : key(key), val(msg.str()), loc(loc.getSourceLoc()) {}
 };
 
 /// Shorthand to insert named-value pairs.
@@ -131,14 +137,26 @@
   unsigned width;
 };
 
-enum class SourceLocInferenceBehavior {
-  None,
-  ForwardScanOnly,
-  BackwardScanOnly,
-  ForwardThenBackward,
-  BackwardThenForward,
+enum class SourceLocInferenceBehavior : unsigned {
+  None = 0,
+  ForwardScan = 0x1,
+  BackwardScan = 0x2,
+  ForwardScan2nd = 0x4,
+  AlwaysInfer = 0x8,
+
+  ForwardThenBackwards = ForwardScan | BackwardScan,
+  BackwardsThenForwards = BackwardScan | ForwardScan2nd,
+  ForwardScanAlwaysInfer = ForwardScan | AlwaysInfer,
+  BackwardScanAlwaysInfer = BackwardScan | AlwaysInfer,
 };
 
+inline SourceLocInferenceBehavior operator&(SourceLocInferenceBehavior lhs,
+                                            SourceLocInferenceBehavior rhs) {
+  auto lhsVal = std::underlying_type<SourceLocInferenceBehavior>::type(lhs);
+  auto rhsVal = std::underlying_type<SourceLocInferenceBehavior>::type(rhs);
+  return SourceLocInferenceBehavior(lhsVal & rhsVal);
+}
+
 /// Infer the proper SourceLoc to use for the given SILInstruction.
 ///
 /// This means that if we have a valid location for the instruction, we just
diff --git a/include/swift/SIL/OwnershipUtils.h b/include/swift/SIL/OwnershipUtils.h
index 4f2a36d..5884a0a 100644
--- a/include/swift/SIL/OwnershipUtils.h
+++ b/include/swift/SIL/OwnershipUtils.h
@@ -196,6 +196,18 @@
   void visitConsumingUsesOfBorrowIntroducingUserResults(
       function_ref<void(Operand *)> visitor) const;
 
+  /// Compute the implicit uses that this borrowing operand "injects" into the
+  /// set of its operands uses.
+  ///
+  /// E.x.: end_apply uses.
+  ///
+  /// \p errorFunction a callback that if non-null is passed an operand that
+  /// triggers a mal-formed SIL error. This is just needed for the ownership
+  /// verifier to emit good output.
+  bool getImplicitUses(
+      SmallVectorImpl<Operand *> &foundUses,
+      std::function<void(Operand *)> *errorFunction = nullptr) const;
+
   void print(llvm::raw_ostream &os) const;
   SWIFT_DEBUG_DUMP { print(llvm::dbgs()); }
 
@@ -467,6 +479,16 @@
     llvm_unreachable("Covered switch isn't covered?!");
   }
 
+  /// Compute the list of implicit uses that this interior pointer operand puts
+  /// on its parent guaranted value.
+  ///
+  /// Example: Uses of a ref_element_addr can not occur outside of the lifetime
+  /// of the instruction's operand. The uses of that address act as liveness
+  /// requirements to ensure that the underlying class is alive at all use
+  /// points.
+  bool getImplicitUses(SmallVectorImpl<Operand *> &foundUses,
+                       std::function<void(Operand *)> *onError = nullptr);
+
 private:
   /// Internal constructor for failable static constructor. Please do not expand
   /// its usage since it assumes the code passed in is well formed.
diff --git a/include/swift/SIL/SILLocation.h b/include/swift/SIL/SILLocation.h
index d847221..9e0d07a 100644
--- a/include/swift/SIL/SILLocation.h
+++ b/include/swift/SIL/SILLocation.h
@@ -65,7 +65,7 @@
     using type = Pattern;
   };
 
-  using ASTNodeTy = llvm::PointerUnion4<Stmt *, Expr *, Decl *, Pattern *>;
+  using ASTNodeTy = llvm::PointerUnion<Stmt *, Expr *, Decl *, Pattern *>;
 
 public:
   enum LocationKind : unsigned {
diff --git a/include/swift/SIL/SILNode.h b/include/swift/SIL/SILNode.h
index 6f1f50a..829ac35 100644
--- a/include/swift/SIL/SILNode.h
+++ b/include/swift/SIL/SILNode.h
@@ -19,6 +19,7 @@
 
 #include "llvm/Support/Compiler.h"
 #include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
 #include "swift/Basic/InlineBitfield.h"
 #include "swift/Basic/LLVM.h"
 #include <type_traits>
diff --git a/include/swift/SIL/SILVTableVisitor.h b/include/swift/SIL/SILVTableVisitor.h
index de8419b..2aeb675 100644
--- a/include/swift/SIL/SILVTableVisitor.h
+++ b/include/swift/SIL/SILVTableVisitor.h
@@ -148,7 +148,7 @@
     if (!theClass->hasKnownSwiftImplementation())
       return;
 
-    for (auto member : theClass->getEmittedMembers())
+    for (auto member : theClass->getSemanticMembers())
       maybeAddMember(member);
   }
 };
diff --git a/include/swift/SILOptimizer/Analysis/DominanceAnalysis.h b/include/swift/SILOptimizer/Analysis/DominanceAnalysis.h
index 2b3b5d1..6afbc0a 100644
--- a/include/swift/SILOptimizer/Analysis/DominanceAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/DominanceAnalysis.h
@@ -24,7 +24,7 @@
 class DominanceAnalysis : public FunctionAnalysisBase<DominanceInfo> {
 protected:
   virtual void verify(DominanceInfo *DI) const override {
-    if (DI->getRoots().empty())
+    if (DI->roots().empty())
       return;
     DI->verify();
   }
@@ -52,7 +52,7 @@
 class PostDominanceAnalysis : public FunctionAnalysisBase<PostDominanceInfo> {
 protected:
   virtual void verify(PostDominanceInfo *PDI) const override {
-    if (PDI->getRoots().empty())
+    if (PDI->roots().empty())
       return;
     PDI->verify();
   }
diff --git a/include/swift/SILOptimizer/Analysis/RCIdentityAnalysis.h b/include/swift/SILOptimizer/Analysis/RCIdentityAnalysis.h
index f4ddc2e..3064fc8 100644
--- a/include/swift/SILOptimizer/Analysis/RCIdentityAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/RCIdentityAnalysis.h
@@ -55,7 +55,7 @@
   /// *NOTE* This ignores obvious ARC escapes where the a potential
   /// user of the RC is not managed by ARC. For instance
   /// unchecked_trivial_bit_cast.
-  void getRCUses(SILValue V, llvm::SmallVectorImpl<Operand *> &Uses);
+  void getRCUses(SILValue V, SmallVectorImpl<Operand *> &Uses);
 
   /// A helper method that calls getRCUses and then maps each operand to the
   /// operands user and then uniques the list.
@@ -63,7 +63,11 @@
   /// *NOTE* The routine asserts that the passed in Users array is empty for
   /// simplicity. If needed this can be changed, but it is not necessary given
   /// current uses.
-  void getRCUsers(SILValue V, llvm::SmallVectorImpl<SILInstruction *> &Users);
+  void getRCUsers(SILValue V, SmallVectorImpl<SILInstruction *> &Users);
+
+  /// Like getRCUses except uses a callback to prevent the need for an
+  /// intermediate array.
+  void visitRCUses(SILValue V, function_ref<void(Operand *)> Visitor);
 
   void handleDeleteNotification(SILNode *node) {
     auto value = dyn_cast<ValueBase>(node);
diff --git a/include/swift/SILOptimizer/Differentiation/ADContext.h b/include/swift/SILOptimizer/Differentiation/ADContext.h
index 368d7fc..4e8fd61 100644
--- a/include/swift/SILOptimizer/Differentiation/ADContext.h
+++ b/include/swift/SILOptimizer/Differentiation/ADContext.h
@@ -273,7 +273,8 @@
                                          Diag<T...> diag, U &&... args) {
   LLVM_DEBUG({
     getADDebugStream() << "Diagnosing non-differentiability.\n";
-    getADDebugStream() << "For value:\n" << value;
+    auto &s = getADDebugStream() << "For value:\n";
+    value->printInContext(s);
     getADDebugStream() << "With invoker:\n" << invoker << '\n';
   });
   // If instruction does not have a valid location, use the function location
@@ -290,7 +291,8 @@
                                          Diag<T...> diag, U &&... args) {
   LLVM_DEBUG({
     getADDebugStream() << "Diagnosing non-differentiability.\n";
-    getADDebugStream() << "For instruction:\n" << *inst;
+    auto &s = getADDebugStream() << "For instruction:\n";
+    inst->printInContext(s);
     getADDebugStream() << "With invoker:\n" << invoker << '\n';
   });
   // If instruction does not have a valid location, use the function location
diff --git a/include/swift/SILOptimizer/Utils/Existential.h b/include/swift/SILOptimizer/Utils/Existential.h
index 75c88cf..5436654 100644
--- a/include/swift/SILOptimizer/Utils/Existential.h
+++ b/include/swift/SILOptimizer/Utils/Existential.h
@@ -49,6 +49,8 @@
     assert(!OpenedArchetype || (OpenedArchetypeValue && ExistentialValue));
     return OpenedArchetype;
   }
+  
+  void dump() const;
 };
 
 /// Record conformance and concrete type info derived from an init_existential
@@ -102,6 +104,8 @@
     CanType selfTy = P->getSelfInterfaceType()->getCanonicalType();
     return ExistentialSubs.lookupConformance(selfTy, P);
   }
+  
+  void dump() const;
 
 private:
   void initializeSubstitutionMap(
@@ -131,6 +135,8 @@
     assert(CEI->isValid());
     return true;
   }
+  
+  void dump() const;
 };
 
 } // end namespace swift
diff --git a/include/swift/SILOptimizer/Utils/InstOptUtils.h b/include/swift/SILOptimizer/Utils/InstOptUtils.h
index 522abb0..86c1ab8 100644
--- a/include/swift/SILOptimizer/Utils/InstOptUtils.h
+++ b/include/swift/SILOptimizer/Utils/InstOptUtils.h
@@ -308,21 +308,22 @@
 /// A structure containing callbacks that are called when an instruction is
 /// removed or added.
 struct InstModCallbacks {
-  std::function<void(SILInstruction *)> deleteInst = [](SILInstruction *inst) {
-    inst->eraseFromParent();
-  };
-  std::function<void(SILInstruction *)> createdNewInst = [](SILInstruction *) {
-  };
-  std::function<void(SILValue, SILValue)> replaceValueUsesWith =
-      [](SILValue oldValue, SILValue newValue) {
-        oldValue->replaceAllUsesWith(newValue);
-      };
+  static const std::function<void(SILInstruction *)> defaultDeleteInst;
+  static const std::function<void(SILInstruction *)> defaultCreatedNewInst;
+  static const std::function<void(SILValue, SILValue)> defaultReplaceValueUsesWith;
+  static const std::function<void(SingleValueInstruction *, SILValue)>
+      defaultEraseAndRAUWSingleValueInst;
+
+  std::function<void(SILInstruction *)> deleteInst =
+      InstModCallbacks::defaultDeleteInst;
+  std::function<void(SILInstruction *)> createdNewInst =
+      InstModCallbacks::defaultCreatedNewInst;
+  std::function<void(SILValue, SILValue)>
+      replaceValueUsesWith =
+          InstModCallbacks::defaultReplaceValueUsesWith;
   std::function<void(SingleValueInstruction *, SILValue)>
       eraseAndRAUWSingleValueInst =
-          [](SingleValueInstruction *i, SILValue newValue) {
-            i->replaceAllUsesWith(newValue);
-            i->eraseFromParent();
-          };
+          InstModCallbacks::defaultEraseAndRAUWSingleValueInst;
 
   InstModCallbacks(decltype(deleteInst) deleteInst,
                    decltype(createdNewInst) createdNewInst,
@@ -330,10 +331,7 @@
       : deleteInst(deleteInst), createdNewInst(createdNewInst),
         replaceValueUsesWith(replaceValueUsesWith),
         eraseAndRAUWSingleValueInst(
-            [](SingleValueInstruction *i, SILValue newValue) {
-              i->replaceAllUsesWith(newValue);
-              i->eraseFromParent();
-            }) {}
+            InstModCallbacks::defaultEraseAndRAUWSingleValueInst) {}
 
   InstModCallbacks(
       decltype(deleteInst) deleteInst, decltype(createdNewInst) createdNewInst,
diff --git a/include/swift/Sema/CodeCompletionTypeChecking.h b/include/swift/Sema/CodeCompletionTypeChecking.h
new file mode 100644
index 0000000..e461217
--- /dev/null
+++ b/include/swift/Sema/CodeCompletionTypeChecking.h
@@ -0,0 +1,83 @@
+//===--- CodeCompletionTypeChecking.h  --------------------------*- C++ -*-===//
+//
+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Provides TypeCheckCompletionCallback implementations for the various kinds
+/// of code completion. These extract and persist information needed to compute
+/// completion results from the solutions formed during expression typechecking.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_SEMA_CODECOMPLETIONTYPECHECKING_H
+#define SWIFT_SEMA_CODECOMPLETIONTYPECHECKING_H
+
+namespace swift {
+  class Decl;
+  class DeclContext;
+  class Type;
+  class ValueDecl;
+  class CodeCompletionExpr;
+
+  namespace constraints {
+    class Solution;
+  }
+
+  class TypeCheckCompletionCallback {
+  public:
+    /// Called for each solution produced while  type-checking an expression
+    /// containing a code completion expression.
+    virtual void sawSolution(const constraints::Solution &solution) = 0;
+    virtual ~TypeCheckCompletionCallback() {}
+  };
+
+
+  /// Used to collect and store information needed to perform member completion
+  /// (\c CompletionKind::DotExpr ) from the solutions formed during expression
+  /// type-checking.
+  class DotExprTypeCheckCompletionCallback: public TypeCheckCompletionCallback {
+  public:
+    struct Result {
+      Type BaseTy;
+      ValueDecl* BaseDecl;
+      SmallVector<Type, 4> ExpectedTypes;
+      bool ExpectsNonVoid;
+      bool BaseIsStaticMetaType;
+      bool IsSingleExpressionBody;
+    };
+
+  private:
+    DeclContext *DC;
+    CodeCompletionExpr *CompletionExpr;
+    SmallVector<Result, 4> Results;
+    llvm::DenseMap<std::pair<Type, Decl*>, size_t> BaseToSolutionIdx;
+    bool GotCallback = false;
+
+  public:
+    DotExprTypeCheckCompletionCallback(DeclContext *DC,
+                                       CodeCompletionExpr *CompletionExpr)
+      : DC(DC), CompletionExpr(CompletionExpr) {}
+
+    /// Get the results collected from any sawSolutions() callbacks recevied so
+    /// far.
+    ArrayRef<Result> getResults() const { return Results; }
+
+    /// True if at least one solution was passed via the \c sawSolution
+    /// callback.
+    bool gotCallback() const { return GotCallback; }
+
+    /// Typecheck the code completion expression in isolation, calling
+    /// \c sawSolution for each solution formed.
+    void fallbackTypeCheck();
+
+    void sawSolution(const constraints::Solution &solution) override;
+  };
+}
+
+#endif
diff --git a/include/swift/Serialization/ModuleDependencyScanner.h b/include/swift/Serialization/ModuleDependencyScanner.h
index 0700677..dd12f8e 100644
--- a/include/swift/Serialization/ModuleDependencyScanner.h
+++ b/include/swift/Serialization/ModuleDependencyScanner.h
@@ -19,6 +19,16 @@
     /// for the purpose of determining dependencies, but does not attempt to
     /// load the module files.
     class ModuleDependencyScanner : public SerializedModuleLoaderBase {
+    public:
+      enum ScannerKind {
+        MDS_plain,
+        MDS_placeholder
+      };
+
+    private:
+      /// The kind of scanner this is (LLVM-style RTTI)
+      const ScannerKind kind;
+
       /// The module we're scanning dependencies of.
       Identifier moduleName;
 
@@ -36,10 +46,11 @@
       ModuleDependencyScanner(
           ASTContext &ctx, ModuleLoadingMode LoadMode, Identifier moduleName,
           InterfaceSubContextDelegate &astDelegate,
-          ModuleDependenciesKind dependencyKind = ModuleDependenciesKind::Swift)
+          ModuleDependenciesKind dependencyKind = ModuleDependenciesKind::Swift,
+          ScannerKind kind = MDS_plain)
           : SerializedModuleLoaderBase(ctx, nullptr, LoadMode,
                                        /*IgnoreSwiftSourceInfoFile=*/true),
-            moduleName(moduleName), astDelegate(astDelegate),
+            kind(kind), moduleName(moduleName), astDelegate(astDelegate),
             dependencyKind(dependencyKind) {}
 
       std::error_code findModuleFilesInDirectory(
@@ -55,6 +66,11 @@
           SmallVectorImpl<Identifier> &names) const override {
         llvm_unreachable("Not used");
       }
+
+      ScannerKind getKind() const { return kind; }
+      static bool classof(const ModuleDependencyScanner *MDS) {
+        return MDS->getKind() == MDS_plain;
+      }
     };
 
     /// A ModuleLoader that loads placeholder dependency module stubs specified in
@@ -90,7 +106,8 @@
                                     StringRef PlaceholderDependencyModuleMap,
                                     InterfaceSubContextDelegate &astDelegate)
           : ModuleDependencyScanner(ctx, LoadMode, moduleName, astDelegate,
-                                    ModuleDependenciesKind::SwiftPlaceholder) {
+                                    ModuleDependenciesKind::SwiftPlaceholder,
+                                    MDS_placeholder) {
 
         // FIXME: Find a better place for this map to live, to avoid
         // doing the parsing on every module.
@@ -106,5 +123,9 @@
           std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer,
           std::unique_ptr<llvm::MemoryBuffer> *ModuleSourceInfoBuffer,
                                                  bool IsFramework) override;
+
+      static bool classof(const ModuleDependencyScanner *MDS) {
+        return MDS->getKind() == MDS_placeholder;
+      }
     };
 }
diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h
index f0e84e7..ab2aed0 100644
--- a/include/swift/Serialization/Validation.h
+++ b/include/swift/Serialization/Validation.h
@@ -177,9 +177,8 @@
 /// - \p ModuleName is the name used to refer to the module in diagnostics.
 void diagnoseSerializedASTLoadFailure(
     ASTContext &Ctx, SourceLoc diagLoc, const ValidationInfo &loadInfo,
-    const ExtendedValidationInfo &extendedInfo, StringRef moduleBufferID,
-    StringRef moduleDocBufferID, ModuleFile *loadedModuleFile,
-    Identifier ModuleName);
+    StringRef moduleBufferID, StringRef moduleDocBufferID,
+    ModuleFile *loadedModuleFile, Identifier ModuleName);
 
 } // end namespace serialization
 } // end namespace swift
diff --git a/include/swift/Subsystems.h b/include/swift/Subsystems.h
index 0a99b5f..a4e545e 100644
--- a/include/swift/Subsystems.h
+++ b/include/swift/Subsystems.h
@@ -29,6 +29,7 @@
 #include <memory>
 
 namespace llvm {
+  class raw_pwrite_stream;
   class GlobalVariable;
   class MemoryBuffer;
   class Module;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 59106e0..76ddd21 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -548,6 +548,7 @@
 ASTContext *ASTContext::get(LangOptions &langOpts,
                             TypeCheckerOptions &typeckOpts,
                             SearchPathOptions &SearchPathOpts,
+                            ClangImporterOptions &ClangImporterOpts,
                             SourceManager &SourceMgr,
                             DiagnosticEngine &Diags) {
   // If more than two data structures are concatentated, then the aggregate
@@ -561,15 +562,19 @@
       llvm::alignAddr(impl, llvm::Align(alignof(Implementation))));
   new (impl) Implementation();
   return new (mem)
-      ASTContext(langOpts, typeckOpts, SearchPathOpts, SourceMgr, Diags);
+      ASTContext(langOpts, typeckOpts, SearchPathOpts, ClangImporterOpts,
+                 SourceMgr, Diags);
 }
 
 ASTContext::ASTContext(LangOptions &langOpts, TypeCheckerOptions &typeckOpts,
                        SearchPathOptions &SearchPathOpts,
+                       ClangImporterOptions &ClangImporterOpts,
                        SourceManager &SourceMgr, DiagnosticEngine &Diags)
   : LangOpts(langOpts),
     TypeCheckerOpts(typeckOpts),
-    SearchPathOpts(SearchPathOpts), SourceMgr(SourceMgr), Diags(Diags),
+    SearchPathOpts(SearchPathOpts),
+    ClangImporterOpts(ClangImporterOpts),
+    SourceMgr(SourceMgr), Diags(Diags),
     evaluator(Diags, langOpts),
     TheBuiltinModule(createBuiltinModule(*this)),
     StdlibModuleName(getIdentifier(STDLIB_NAME)),
@@ -4841,8 +4846,8 @@
   case PropertyWrapperSynthesizedPropertyKind::Backing:
     return this == wrapperInfo.backingVar ? original : nullptr;
 
-  case PropertyWrapperSynthesizedPropertyKind::StorageWrapper:
-    return this == wrapperInfo.storageWrapperVar ? original : nullptr;
+  case PropertyWrapperSynthesizedPropertyKind::Projection:
+    return this == wrapperInfo.projectionVar ? original : nullptr;
   }
   llvm_unreachable("covered switch");
 }
diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp
index bf72c01..6174ca0 100644
--- a/lib/AST/ASTDemangler.cpp
+++ b/lib/AST/ASTDemangler.cpp
@@ -144,7 +144,7 @@
     return Type();
 
   // If the declaration is generic, fail.
-  if (nominalDecl->getGenericParams())
+  if (auto list = nominalDecl->getGenericParams())
     return Type();
 
   // Imported types can be renamed to be members of other (non-generic)
@@ -200,21 +200,16 @@
   if (!genericSig)
     return SubstitutionMap();
   
-  SmallVector<GenericTypeParamType *, 4> genericParams;
-  genericSig->forEachParam([&](GenericTypeParamType *gp, bool canonical) {
-    if (canonical)
-      genericParams.push_back(gp);
-  });
-  if (genericParams.size() != args.size())
+  if (genericSig->getGenericParams().size() != args.size())
     return SubstitutionMap();
 
   return SubstitutionMap::get(
       genericSig,
       [&](SubstitutableType *t) -> Type {
-        for (unsigned i = 0, e = genericParams.size(); i < e; ++i) {
-          if (t->isEqual(genericParams[i]))
-            return args[i];
-        }
+        auto *gp = cast<GenericTypeParamType>(t);
+        unsigned ordinal = genericSig->getGenericParamOrdinal(gp);
+        if (ordinal < args.size())
+          return args[ordinal];
         return Type();
       },
       LookUpConformanceInModule(moduleDecl));
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 16fd1f6..f154469 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -18,6 +18,7 @@
 #include "swift/AST/ASTPrinter.h"
 #include "swift/AST/ASTVisitor.h"
 #include "swift/AST/ClangModuleLoader.h"
+#include "swift/AST/ForeignAsyncConvention.h"
 #include "swift/AST/ForeignErrorConvention.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/Initializer.h"
@@ -585,6 +586,9 @@
       if (D->isImplicit())
         PrintWithColorRAII(OS, DeclModifierColor) << " implicit";
 
+      if (D->isHoisted())
+        PrintWithColorRAII(OS, DeclModifierColor) << " hoisted";
+
       auto R = D->getSourceRange();
       if (R.isValid()) {
         PrintWithColorRAII(OS, RangeColor) << " range=";
@@ -952,6 +956,16 @@
         D->getCaptureInfo().print(OS);
       }
 
+      if (auto fac = D->getForeignAsyncConvention()) {
+        OS << " foreign_async=";
+        if (auto type = fac->completionHandlerType())
+          type.print(OS);
+        OS << ",completion_handler_param="
+           << fac->completionHandlerParamIndex();
+        if (auto errorParamIndex = fac->completionHandlerErrorParamIndex())
+          OS << ",error_param=" << *errorParamIndex;
+      }
+
       if (auto fec = D->getForeignErrorConvention()) {
         OS << " foreign_error=";
         OS << getForeignErrorConventionKindString(fec->getKind());
@@ -3781,7 +3795,9 @@
       if (!T->getClangTypeInfo().empty()) {
         std::string s;
         llvm::raw_string_ostream os(s);
-        T->getClangTypeInfo().dump(os);
+        auto &ctx = T->getASTContext().getClangModuleLoader()
+          ->getClangASTContext();
+        T->getClangTypeInfo().dump(os, ctx);
         printField("clang_type", os.str());
       }
       printAnyFunctionParams(T->getParams(), "input");
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index eca53f2..65b3ea8 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -48,6 +48,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/Module.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ConvertUTF.h"
@@ -58,6 +59,11 @@
 
 using namespace swift;
 
+// Defined here to avoid repeatedly paying the price of template instantiation.
+const std::function<bool(const ExtensionDecl *)>
+    PrintOptions::defaultPrintExtensionContentAsMembers
+        = [] (const ExtensionDecl *) { return false; };
+
 void PrintOptions::setBaseType(Type T) {
   if (T->is<ErrorType>())
     return;
diff --git a/lib/AST/ASTScopeCreation.cpp b/lib/AST/ASTScopeCreation.cpp
index 4623e38..d281802 100644
--- a/lib/AST/ASTScopeCreation.cpp
+++ b/lib/AST/ASTScopeCreation.cpp
@@ -354,10 +354,10 @@
   ASTScopeImpl *constructExpandAndInsert(ASTScopeImpl *parent, Args... args) {
     auto *child = new (ctx) Scope(args...);
     parent->addChild(child, ctx);
-    if (shouldBeLazy()) {
-      if (auto *ip = child->insertionPointForDeferredExpansion().getPtrOrNull())
-        return ip;
-    }
+
+    if (auto *ip = child->insertionPointForDeferredExpansion().getPtrOrNull())
+      return ip;
+
     ASTScopeImpl *insertionPoint =
         child->expandAndBeCurrentDetectingRecursion(*this);
     ASTScopeAssert(child->verifyThatThisNodeComeAfterItsPriorSibling(),
@@ -646,8 +646,6 @@
     return !n.isDecl(DeclKind::Var);
   }
 
-  bool shouldBeLazy() const { return ctx.LangOpts.LazyASTScopes; }
-
 public:
   /// For debugging. Return true if scope tree contains all the decl contexts in
   /// the AST May modify the scope tree in order to update obsolete scopes.
@@ -1086,8 +1084,6 @@
 
 ASTScopeImpl *
 ASTScopeImpl::expandAndBeCurrentDetectingRecursion(ScopeCreator &scopeCreator) {
-  assert(scopeCreator.getASTContext().LangOpts.EnableASTScopeLookup &&
-         "Should not be getting here if ASTScopes are disabled");
   return evaluateOrDefault(scopeCreator.getASTContext().evaluator,
                            ExpandASTScopeRequest{this, &scopeCreator}, nullptr);
 }
@@ -1123,14 +1119,13 @@
     disownDescendants(scopeCreator);
 
   auto *insertionPoint = expandSpecifically(scopeCreator);
-  if (scopeCreator.shouldBeLazy()) {
-    ASTScopeAssert(!insertionPointForDeferredExpansion() ||
-                       insertionPointForDeferredExpansion().get() ==
-                           insertionPoint,
-                   "In order for lookups into lazily-expanded scopes to be "
-                   "accurate before expansion, the insertion point before "
-                   "expansion must be the same as after expansion.");
-  }
+  ASTScopeAssert(!insertionPointForDeferredExpansion() ||
+                     insertionPointForDeferredExpansion().get() ==
+                         insertionPoint,
+                 "In order for lookups into lazily-expanded scopes to be "
+                 "accurate before expansion, the insertion point before "
+                 "expansion must be the same as after expansion.");
+
   replaceASTAncestorScopes(astAncestorScopes);
   setWasExpanded();
   beCurrent();
diff --git a/lib/AST/ASTScopeSourceRange.cpp b/lib/AST/ASTScopeSourceRange.cpp
index cecd970..87713be 100644
--- a/lib/AST/ASTScopeSourceRange.cpp
+++ b/lib/AST/ASTScopeSourceRange.cpp
@@ -526,8 +526,6 @@
 }
 
 bool ASTScopeImpl::checkLazySourceRange(const ASTContext &ctx) const {
-  if (!ctx.LangOpts.LazyASTScopes)
-    return true;
   const auto unexpandedRange = sourceRangeForDeferredExpansion();
   const auto expandedRange = computeSourceRangeOfScopeWithChildASTNodes();
   if (unexpandedRange.isInvalid() || expandedRange.isInvalid())
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index aebc89a..78ce700 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -20,6 +20,7 @@
 #include "swift/AST/Decl.h"
 #include "swift/AST/ExistentialLayout.h"
 #include "swift/AST/Expr.h"
+#include "swift/AST/ForeignAsyncConvention.h"
 #include "swift/AST/ForeignErrorConvention.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/GenericSignature.h"
@@ -2994,8 +2995,23 @@
         }
       }
 
-      // Throwing @objc methods must have a foreign error convention.
+      // Asynchronous @objc methods must have a foreign async convention.
       if (AFD->isObjC() &&
+          static_cast<bool>(AFD->getForeignAsyncConvention())
+            != AFD->hasAsync()) {
+        if (AFD->hasAsync())
+          Out << "@objc method async but does not have a foreign async "
+              << "convention";
+        else
+          Out << "@objc method has a foreign async convention but is not "
+              << "async";
+        abort();
+      }
+
+      // Synchronous throwing @objc methods must have a foreign error
+      // convention.
+      if (AFD->isObjC() &&
+          !AFD->hasAsync() &&
           static_cast<bool>(AFD->getForeignErrorConvention())
             != AFD->hasThrows()) {
         if (AFD->hasThrows())
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index 3a311ac..f492762 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -1747,12 +1747,12 @@
   IITDescriptor D = Table.front();
   Table = Table.slice(1);
   switch (D.Kind) {
+  case IITDescriptor::BFloat:
   case IITDescriptor::MMX:
   case IITDescriptor::Metadata:
   case IITDescriptor::ExtendArgument:
   case IITDescriptor::TruncArgument:
   case IITDescriptor::HalfVecArgument:
-  case IITDescriptor::ScalableVecArgument:
   case IITDescriptor::VarArg:
   case IITDescriptor::Token:
   case IITDescriptor::VecElementArgument:
@@ -1781,7 +1781,7 @@
   case IITDescriptor::Vector: {
     Type eltType = decodeImmediate();
     if (!eltType) return Type();
-    return makeVector(eltType, D.Vector_Width);
+    return makeVector(eltType, D.Vector_Width.Min);
   }
 
   // A pointer to an immediate type.
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index f1f17cb..979b144 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -24,6 +24,7 @@
 #include "swift/AST/DiagnosticsSema.h"
 #include "swift/AST/ExistentialLayout.h"
 #include "swift/AST/Expr.h"
+#include "swift/AST/ForeignAsyncConvention.h"
 #include "swift/AST/ForeignErrorConvention.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/GenericSignature.h"
@@ -59,6 +60,7 @@
 #include "swift/Demangling/ManglingMacros.h"
 
 #include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Module.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclObjC.h"
 
@@ -2450,7 +2452,11 @@
     return !((sig1.IsVariable && !sig2.Name.getArgumentNames().empty()) ||
              (sig2.IsVariable && !sig1.Name.getArgumentNames().empty()));
   }
-  
+
+  // If one is asynchronous and the other is not, they can't conflict.
+  if (sig1.HasAsync != sig2.HasAsync)
+    return false;
+
   // Note that we intentionally ignore the HasOpaqueReturnType bit here.
   // For declarations that can't be overloaded by type, we want them to be
   // considered conflicting independent of their type.
@@ -2673,6 +2679,8 @@
   signature.IsTypeAlias = isa<TypeAliasDecl>(this);
   signature.HasOpaqueReturnType =
                        !signature.IsVariable && (bool)getOpaqueResultTypeDecl();
+  signature.HasAsync = isa<AbstractFunctionDecl>(this) &&
+    cast<AbstractFunctionDecl>(this)->hasAsync();
 
   // Unary operators also include prefix/postfix.
   if (auto func = dyn_cast<FuncDecl>(this)) {
@@ -4181,13 +4189,6 @@
                            nullptr);
 }
 
-ArrayRef<Decl *> ClassDecl::getEmittedMembers() const {
-  ASTContext &ctx = getASTContext();
-  return evaluateOrDefault(ctx.evaluator,
-                           EmittedMembersRequest{const_cast<ClassDecl *>(this)},
-                           ArrayRef<Decl *>());
-}
-
 /// Synthesizer callback for an empty implicit function body.
 static std::pair<BraceStmt *, bool>
 synthesizeEmptyFunctionBody(AbstractFunctionDecl *afd, void *context) {
@@ -5915,8 +5916,8 @@
           PropertyWrapperSynthesizedPropertyKind::Backing))
     return PropertyWrapperSynthesizedPropertyKind::Backing;
   if (getOriginalWrappedProperty(
-          PropertyWrapperSynthesizedPropertyKind::StorageWrapper))
-    return PropertyWrapperSynthesizedPropertyKind::StorageWrapper;
+          PropertyWrapperSynthesizedPropertyKind::Projection))
+    return PropertyWrapperSynthesizedPropertyKind::Projection;
   return None;
 }
 
@@ -5924,8 +5925,8 @@
   return getPropertyWrapperBackingPropertyInfo().backingVar;
 }
 
-VarDecl *VarDecl::getPropertyWrapperStorageWrapper() const {
-  return getPropertyWrapperBackingPropertyInfo().storageWrapperVar;
+VarDecl *VarDecl::getPropertyWrapperProjectionVar() const {
+  return getPropertyWrapperBackingPropertyInfo().projectionVar;
 }
 
 VarDecl *VarDecl::getLazyStorageProperty() const {
@@ -6916,10 +6917,13 @@
   }
 
   // The number of selector pieces we'll have.
+  Optional<ForeignAsyncConvention> asyncConvention
+    = getForeignAsyncConvention();
   Optional<ForeignErrorConvention> errorConvention
     = getForeignErrorConvention();
   unsigned numSelectorPieces
-    = argNames.size() + (errorConvention.hasValue() ? 1 : 0);
+    = argNames.size() + (asyncConvention.hasValue() ? 1 : 0)
+    + (errorConvention.hasValue() ? 1 : 0);
 
   // If we have no arguments, it's a nullary selector.
   if (numSelectorPieces == 0) {
@@ -6938,6 +6942,14 @@
   unsigned argIndex = 0;
   for (unsigned piece = 0; piece != numSelectorPieces; ++piece) {
     if (piece > 0) {
+      // If we have an async convention that inserts a completion handler
+      // parameter here, add "completionHandler".
+      if (asyncConvention &&
+          piece == asyncConvention->completionHandlerParamIndex()) {
+        selectorPieces.push_back(ctx.getIdentifier("completionHandler"));
+        continue;
+      }
+
       // If we have an error convention that inserts an error parameter
       // here, add "error".
       if (errorConvention &&
@@ -6951,12 +6963,21 @@
       continue;
     }
 
-    // For the first selector piece, attach either the first parameter
-    // or "AndReturnError" to the base name, if appropriate.
+    // For the first selector piece, attach either the first parameter,
+    // "withCompletionHandker", or "AndReturnError" to the base name,
+    // if appropriate.
     auto firstPiece = baseName;
     llvm::SmallString<32> scratch;
     scratch += firstPiece.str();
-    if (errorConvention && piece == errorConvention->getErrorParameterIndex()) {
+    if (asyncConvention &&
+        piece == asyncConvention->completionHandlerParamIndex()) {
+      // The completion handler is first; append "WithCompletionHandler".
+      camel_case::appendSentenceCase(scratch, "WithCompletionHandler");
+
+      firstPiece = ctx.getIdentifier(scratch);
+      didStringManipulation = true;
+    } else if (errorConvention &&
+               piece == errorConvention->getErrorParameterIndex()) {
       // The error is first; append "AndReturnError".
       camel_case::appendSentenceCase(scratch, "AndReturnError");
 
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index 5f7733d..f1cc0b4 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -793,6 +793,23 @@
   return getCurrentMembersWithoutLoading();
 }
 
+ArrayRef<Decl *> IterableDeclContext::getParsedMembers() const {
+  ASTContext &ctx = getASTContext();
+  auto mutableThis = const_cast<IterableDeclContext *>(this);
+  return evaluateOrDefault(
+      ctx.evaluator, ParseMembersRequest{mutableThis},
+      FingerprintAndMembers())
+    .members;
+}
+
+ArrayRef<Decl *> IterableDeclContext::getSemanticMembers() const {
+  ASTContext &ctx = getASTContext();
+  return evaluateOrDefault(
+      ctx.evaluator,
+      SemanticMembersRequest{const_cast<IterableDeclContext *>(this)},
+      ArrayRef<Decl *>());
+}
+
 /// Add a member to this context.
 void IterableDeclContext::addMember(Decl *member, Decl *Hint) {
   // Add the member to the list of declarations without notification.
@@ -891,10 +908,7 @@
     // members to this context, this call is important for recording the
     // dependency edge.
     auto mutableThis = const_cast<IterableDeclContext *>(this);
-    auto members =
-        evaluateOrDefault(ctx.evaluator, ParseMembersRequest{mutableThis},
-                          FingerprintAndMembers())
-            .members;
+    auto members = getParsedMembers();
 
     // If we haven't already done so, add these members to this context.
     if (!AddedParsedMembers) {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index ea39fde..bcbd89f 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -833,16 +833,15 @@
 static APFloat getFloatLiteralValue(bool IsNegative, StringRef Text,
                                     const llvm::fltSemantics &Semantics) {
   APFloat Val(Semantics);
-  llvm::Expected<APFloat::opStatus> MaybeRes =
-      Val.convertFromString(Text, llvm::APFloat::rmNearestTiesToEven);
-  assert(MaybeRes && *MaybeRes != APFloat::opInvalidOp &&
-         "Sema didn't reject invalid number");
-  (void)MaybeRes;
+  auto Res =
+    Val.convertFromString(Text, llvm::APFloat::rmNearestTiesToEven);
+  assert(Res && "Sema didn't reject invalid number");
+  consumeError(Res.takeError());
   if (IsNegative) {
     auto NegVal = APFloat::getZero(Semantics, /*negative*/ true);
-    auto Res = NegVal.subtract(Val, llvm::APFloat::rmNearestTiesToEven);
-    assert(Res != APFloat::opInvalidOp && "Sema didn't reject invalid number");
-    (void)Res;
+    Res = NegVal.subtract(Val, llvm::APFloat::rmNearestTiesToEven);
+    assert(Res && "Sema didn't reject invalid number");
+    consumeError(Res.takeError());
     return NegVal;
   }
   return Val;
diff --git a/lib/AST/ExtInfo.cpp b/lib/AST/ExtInfo.cpp
index 5b77992..aba9bb2 100644
--- a/lib/AST/ExtInfo.cpp
+++ b/lib/AST/ExtInfo.cpp
@@ -23,12 +23,10 @@
 #ifndef NDEBUG
   if (!(type->isFunctionPointerType() || type->isBlockPointerType() ||
         type->isFunctionReferenceType())) {
-    llvm::SmallString<256> buf;
-    llvm::raw_svector_ostream os(buf);
-    os << "Expected a Clang function type wrapped in a pointer type or "
-       << "a block pointer type but found:\n";
-    type->dump(os);
-    llvm_unreachable(os.str().data());
+    llvm::errs() << "Expected a Clang function type wrapped in a pointer type "
+                 << "or a block pointer type but found:\n";
+    type->dump();
+    llvm_unreachable("\nUnexpected Clang type when creating ExtInfo!");
   }
 #endif
 }
@@ -57,9 +55,10 @@
   cml->printClangType(type, os);
 }
 
-void ClangTypeInfo::dump(llvm::raw_ostream &os) const {
+void ClangTypeInfo::dump(llvm::raw_ostream &os,
+                         const clang::ASTContext &ctx) const {
   if (type) {
-    type->dump(os);
+    type->dump(os, ctx);
   } else {
     os << "<nullptr>";
   }
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index 3399d77..33126a0 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -312,6 +312,7 @@
   FrontendStatsTracer tracer(SF.getASTContext().Stats,
                              "source-file-populate-cache");
   addToUnqualifiedLookupCache(SF.getTopLevelDecls(), false);
+  addToUnqualifiedLookupCache(SF.getHoistedDecls(), false);
 }
 
 SourceLookupCache::SourceLookupCache(const ModuleDecl &M) {
@@ -322,8 +323,9 @@
       addToUnqualifiedLookupCache(SFU->getTopLevelDecls(), false);
       continue;
     }
-    auto &SF = *cast<SourceFile>(file);
-    addToUnqualifiedLookupCache(SF.getTopLevelDecls(), false);
+    auto *SF = cast<SourceFile>(file);
+    addToUnqualifiedLookupCache(SF->getTopLevelDecls(), false);
+    addToUnqualifiedLookupCache(SF->getHoistedDecls(), false);
   }
 }
 
@@ -2047,10 +2049,8 @@
 }
 
 ArrayRef<Identifier> Decl::getSPIGroups() const {
-  if (auto vd = dyn_cast<ValueDecl>(this)) {
-    if (vd->getFormalAccess() < AccessLevel::Public)
-      return ArrayRef<Identifier>();
-  } else if (!isa<ExtensionDecl>(this))
+  if (!isa<ValueDecl>(this) &&
+      !isa<ExtensionDecl>(this))
     return ArrayRef<Identifier>();
 
   return evaluateOrDefault(getASTContext().evaluator,
@@ -2061,10 +2061,8 @@
 llvm::ArrayRef<Identifier>
 SPIGroupsRequest::evaluate(Evaluator &evaluator, const Decl *decl) const {
   // Applies only to public ValueDecls and ExtensionDecls.
-  if (auto vd = dyn_cast<ValueDecl>(decl))
-    assert(vd->getFormalAccess() >= AccessLevel::Public);
-  else
-    assert(isa<ExtensionDecl>(decl));
+  assert (isa<ValueDecl>(decl) ||
+          isa<ExtensionDecl>(decl));
 
   // First, look for local attributes.
   llvm::SetVector<Identifier> spiGroups;
@@ -2335,6 +2333,12 @@
   return true;
 }
 
+/// Add a hoisted declaration. See Decl::isHoisted().
+void SourceFile::addHoistedDecl(Decl *d) {
+  assert(d->isHoisted());
+  Hoisted.push_back(d);
+}
+
 ArrayRef<Decl *> SourceFile::getTopLevelDecls() const {
   auto &ctx = getASTContext();
   auto *mutableThis = const_cast<SourceFile *>(this);
@@ -2342,6 +2346,10 @@
                            {}).TopLevelDecls;
 }
 
+ArrayRef<Decl *> SourceFile::getHoistedDecls() const {
+  return Hoisted;
+}
+
 bool FileUnit::walk(ASTWalker &walker) {
   SmallVector<Decl *, 64> Decls;
   getTopLevelDecls(Decls);
diff --git a/lib/AST/PlatformKind.cpp b/lib/AST/PlatformKind.cpp
index ff6a003..f0f72ab 100644
--- a/lib/AST/PlatformKind.cpp
+++ b/lib/AST/PlatformKind.cpp
@@ -87,6 +87,8 @@
     case PlatformKind::watchOS:
     case PlatformKind::watchOSApplicationExtension:
       return Target.isWatchOS();
+    case PlatformKind::OpenBSD:
+      return Target.isOSOpenBSD();
     case PlatformKind::none:
       llvm_unreachable("handled above");
   }
diff --git a/lib/AST/PrettyStackTrace.cpp b/lib/AST/PrettyStackTrace.cpp
index a13caf0..dc07100 100644
--- a/lib/AST/PrettyStackTrace.cpp
+++ b/lib/AST/PrettyStackTrace.cpp
@@ -217,7 +217,7 @@
     out << "NULL clang type!\n";
     return;
   }
-  TheType->dump(out);
+  TheType->dump(out, Context);
 }
 
 void PrettyStackTraceTypeRepr::print(llvm::raw_ostream &out) const {
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 402a33a..de2636f 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -3063,8 +3063,8 @@
           }))
     return maybeOpaqueType;
 
-  // If the type still contains opaque types, recur.
-  if (substTy->hasOpaqueArchetype()) {
+  // If the type changed, but still contains opaque types, recur.
+  if (!substTy->isEqual(maybeOpaqueType) && substTy->hasOpaqueArchetype()) {
     return ::substOpaqueTypesWithUnderlyingTypes(
         substTy, inContext, contextExpansion, isContextWholeModule);
   }
diff --git a/lib/AST/UnqualifiedLookup.cpp b/lib/AST/UnqualifiedLookup.cpp
index a138f45..0581a70 100644
--- a/lib/AST/UnqualifiedLookup.cpp
+++ b/lib/AST/UnqualifiedLookup.cpp
@@ -17,17 +17,11 @@
 
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ASTVisitor.h"
-#include "swift/AST/ClangModuleLoader.h"
 #include "swift/AST/DebuggerClient.h"
-#include "swift/AST/ExistentialLayout.h"
 #include "swift/AST/ImportCache.h"
-#include "swift/AST/Initializer.h"
-#include "swift/AST/LazyResolver.h"
 #include "swift/AST/ModuleNameLookup.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/NameLookupRequests.h"
-#include "swift/AST/ParameterList.h"
-#include "swift/AST/SourceFile.h"
 #include "swift/Basic/Debug.h"
 #include "swift/Basic/STLExtras.h"
 #include "swift/Basic/SourceManager.h"
@@ -42,58 +36,6 @@
 using namespace swift;
 using namespace swift::namelookup;
 
-
-namespace {
-  
-  /// Determine whether unqualified lookup should look at the members of the
-  /// given nominal type or extension, vs. only looking at type parameters.
-  template <typename D> bool shouldLookupMembers(D *decl, SourceLoc loc) {
-    // Only look at members of this type (or its inherited types) when
-    // inside the body or a protocol's top-level 'where' clause. (Why the
-    // 'where' clause? Because that's where you put constraints on
-    // inherited associated types.)
-    
-    // When we have no source-location information, we have to perform member
-    // lookup.
-    if (loc.isInvalid() || decl->getBraces().isInvalid())
-      return true;
-
-    SourceManager &SM = decl->getASTContext().SourceMgr;
-
-    // If a code completion happens inside a function body, some lookups may
-    // happen from the 'loc' that is in a different buffer from the 'decl'.
-    // In such cases, look for members of the 'decl' because we know 'loc' is
-    // inside a function body in the 'decl'.
-    if (SM.hasCodeCompletionBuffer()) {
-      auto completionBufferID = SM.getCodeCompletionBufferID();
-      if (SM.getRangeForBuffer(completionBufferID).contains(loc)) {
-        auto declBufferID =
-            decl->getDeclContext()->getParentSourceFile()->getBufferID();
-        if (completionBufferID != declBufferID)
-          return true;
-      }
-    }
-
-    // Within the braces, always look for members.
-    auto braces = decl->getBraces();
-    if (braces.Start != braces.End &&
-        SM.rangeContainsTokenLoc(braces, loc))
-      return true;
-    
-    // Within 'where' clause, we can also look for members.
-    if (auto *whereClause = decl->getTrailingWhereClause()) {
-      SourceRange whereClauseRange = whereClause->getSourceRange();
-      if (whereClauseRange.isValid() &&
-          SM.rangeContainsTokenLoc(whereClauseRange, loc)) {
-        return true;
-      }
-    }
-    
-    // Don't look at the members.
-    return false;
-  }
-} // end anonymous namespace
-
 namespace {
   class UnqualifiedLookupFactory {
 
@@ -105,11 +47,6 @@
     using ResultsVector = SmallVector<LookupResultEntry, 4>;
     
   private:
-    struct ContextAndResolvedIsCascadingUse {
-      DeclContext *const DC;
-      const bool isCascadingUse;
-    };
-    
     /// Finds lookup results based on the types that self conforms to.
     /// For instance, self always conforms to a struct, enum or class.
     /// But in addition, self could conform to any number of protocols.
@@ -207,8 +144,6 @@
 #endif
 
   public: // for exp debugging
-    SourceFile const *recordedSF = nullptr;
-    bool recordedIsCascadingUse = false;
     unsigned resultsSizeBeforeLocalsPass = ~0;
 
   public:
@@ -224,20 +159,6 @@
     void performUnqualifiedLookup();
     
   private:
-    struct ContextAndUnresolvedIsCascadingUse {
-      DeclContext *whereToLook;
-      Optional<bool> isCascadingUse;
-      ContextAndResolvedIsCascadingUse resolve(const bool resolution) const {
-        return ContextAndResolvedIsCascadingUse{
-          whereToLook, isCascadingUse.getValueOr(resolution)};
-      }
-    };
-
-    bool useASTScopesForLookup() const;
-
-    /// For testing, assume this lookup is enabled:
-    bool wouldUseASTScopesForLookupIfItWereEnabled() const;
-
     void lookUpTopLevelNamesInModuleScopeContext(DeclContext *);
 
     void lookInASTScopes();
@@ -250,110 +171,16 @@
     /// to record the dividing line between results from first fruitful scope and
     /// the result.
     void recordCompletionOfAScope();
-    
-    template <typename Fn> void ifNotDoneYet(Fn fn) {
-      recordCompletionOfAScope();
-      if (!isFirstResultEnough())
-        fn();
-    }
-    
-    template <typename Fn1, typename Fn2> void ifNotDoneYet(Fn1 fn1, Fn2 fn2) {
-      ifNotDoneYet(fn1);
-      ifNotDoneYet(fn2);
-    }
-    
+
 #pragma mark context-based lookup declarations
-    
-    void lookupOperatorInDeclContexts(ContextAndUnresolvedIsCascadingUse);
-    
-    /// When performing a lookup, we may come across a capture of 'self'. We
-    /// will need to remember the DeclContext of the innermost captured self so
-    /// that it can be used as the base DeclContext if we find a lookup result
-    /// in the enclosing type. \c capturedSelfContext tracks this.
-    void lookupNamesIntroducedBy(const ContextAndUnresolvedIsCascadingUse,
-                                 DeclContext *capturedSelfContext);
-    
-    void finishLookingInContext(
-                                AddGenericParameters addGenericParameters,
-                                DeclContext *lookupContextForThisContext,
-                                Optional<ResultFinderForTypeContext> &&resultFinderForTypeContext,
-                                Optional<bool> isCascadingUse,
-                                DeclContext *capturedSelfContext);
-    
-    void lookupInModuleScopeContext(DeclContext *, Optional<bool> isCascadingUse);
-    
-    void lookupNamesIntroducedByPatternBindingInitializer(
-                                                          PatternBindingInitializer *PBI,
-                                                          Optional<bool> isCascadingUse,
-                                                          DeclContext *capturedSelfContext);
-    
-    void
-    lookupNamesIntroducedByLazyVariableInitializer(PatternBindingInitializer *PBI,
-                                                   ParamDecl *selfParam,
-                                                   Optional<bool> isCascadingUse,
-                                                   DeclContext *capturedSelfContext);
-    
-    void lookupNamesIntroducedByInitializerOfStoredPropertyOfAType(
-                                                                   PatternBindingInitializer *PBI, Optional<bool> isCascadingUse);
-    
-    /// An initializer of a global name, or a function-likelocal name.
-    void lookupNamesIntroducedByInitializerOfGlobalOrLocal(
-                                                           PatternBindingInitializer *PBI,
-                                                           Optional<bool> isCascadingUse,
-                                                           DeclContext *capturedSelfContext);
-    
-    void lookupNamesIntroducedByFunctionDecl(AbstractFunctionDecl *AFD,
-                                             Optional<bool> isCascadingUse,
-                                             DeclContext *capturedSelfContext);
-    
-    void lookupNamesIntroducedByMemberFunction(AbstractFunctionDecl *AFD,
-                                               bool isCascadingUse,
-                                               DeclContext *capturedSelfContext);
-    
-    void lookupNamesIntroducedByPureFunction(AbstractFunctionDecl *AFD,
-                                             bool isCascadingUse,
-                                             DeclContext *capturedSelfContext);
-    
-    void lookupNamesIntroducedByClosure(AbstractClosureExpr *ACE,
-                                        Optional<bool> isCascadingUse,
-                                        DeclContext *capturedSelfContext);
-    
-    template <typename NominalTypeDeclOrExtensionDecl>
-    void lookupNamesIntroducedByNominalTypeOrExtension(
-                                                       NominalTypeDeclOrExtensionDecl *D, Optional<bool> isCascadingUse);
-    
-    void lookupNamesIntroducedByDefaultArgumentInitializer(
-                                                           DefaultArgumentInitializer *I,
-                                                           Optional<bool> isCascadingUse,
-                                                           DeclContext *capturedSelfContext);
-    
-    void lookupNamesIntroducedByMiscContext(DeclContext *dc,
-                                            Optional<bool> isCascadingUse,
-                                            DeclContext *capturedSelfContext);
-    
-    void lookForLocalVariablesIn(AbstractFunctionDecl *AFD,
-                                 Optional<bool> isCascadingUse);
-    void lookForLocalVariablesIn(ClosureExpr *);
-    void lookForLocalVariablesIn(SourceFile *);
-    
+
     bool isOutsideBodyOfFunction(const AbstractFunctionDecl *const AFD) const;
     
-    void addGenericParametersForContext(DeclContext *dc);
-    void addGenericParametersForContext(GenericParamList *);
-    
-    /// Consume generic parameters
-    void addGenericParametersForFunction(AbstractFunctionDecl *AFD);
-    
-    static GenericParamList *getGenericParams(const DeclContext *const dc);
-    
     /// For diagnostic purposes, move aside the unavailables, and put
     /// them back as a last-ditch effort.
     /// Could be cleaner someday with a richer interface to UnqualifiedLookup.
     void setAsideUnavailableResults(size_t firstPossiblyUnavailableResult);
     
-    void recordDependencyOnTopLevelName(DeclContext *topLevelContext,
-                                        DeclNameRef name, bool isCascadingUse);
-    
     void addImportedResults(DeclContext *const dc);
     
     void addNamesKnownToDebugClient(DeclContext *dc);
@@ -372,19 +199,6 @@
                                                    : None;
     }
 
-    static bool resolveIsCascadingUse(const DeclContext *const dc,
-                                      Optional<bool> isCascadingUse,
-                                      bool onlyCareAboutFunctionBody) {
-      return isCascadingUse.getValueOr(dc->isCascadingContextForLookup(
-                                                                       /*functionsAreNonCascading=*/onlyCareAboutFunctionBody));
-    }
-    
-    static bool resolveIsCascadingUse(ContextAndUnresolvedIsCascadingUse x,
-                                      bool onlyCareAboutFunctionBody) {
-      return resolveIsCascadingUse(x.whereToLook, x.isCascadingUse,
-                                   onlyCareAboutFunctionBody);
-    }
-    
     void findResultsAndSaveUnavailables(
                                         DeclContext *lookupContextForThisContext,
                                         ResultFinderForTypeContext &&resultFinderForTypeContext,
@@ -399,13 +213,6 @@
     void print(raw_ostream &OS) const;
     void printResults(raw_ostream &OS) const;
 
-    bool verifyEqualTo(const UnqualifiedLookupFactory &&, StringRef thisLabel,
-                       StringRef otherLabel) const;
-
-    /// Legacy lookup is wrong here; we should NOT find this symbol.
-    bool shouldDiffer() const;
-    StringRef getSourceFileName() const;
-
 #ifndef NDEBUG
     bool isTargetLookup() const;
     void stopForDebuggingIfStartingTargetLookup(bool isASTScopeLookup) const;
@@ -493,50 +300,24 @@
                                   "performUnqualifedLookup",
                                   DC->getParentSourceFile());
 
-  const Optional<bool> initialIsCascadingUse = getInitialIsCascadingUse();
-
-  ContextAndUnresolvedIsCascadingUse contextAndIsCascadingUse{
-      DC, initialIsCascadingUse};
-  const bool crosscheckUnqualifiedLookup =
-      Ctx.LangOpts.CrosscheckUnqualifiedLookup;
-  if (useASTScopesForLookup()) {
-    static bool haveWarned = false;
-    if (!haveWarned && Ctx.LangOpts.WarnIfASTScopeLookup) {
-      haveWarned = true;
-      llvm::errs() << "WARNING: TRYING Scope exclusively\n";
-    }
+  if (Loc.isValid()) {
     lookInASTScopes();
   } else {
+    assert(DC->isModuleScopeContext() &&
+           "Unqualified lookup without a source location must start from "
+           "a module-scope context");
+
 #ifndef NDEBUG
     stopForDebuggingIfStartingTargetLookup(false);
 #endif
-
-    if (Name.isOperator())
-      lookupOperatorInDeclContexts(contextAndIsCascadingUse);
-    else
-      lookupNamesIntroducedBy(contextAndIsCascadingUse, NULL);
   }
 
-  if (crosscheckUnqualifiedLookup &&
-      wouldUseASTScopesForLookupIfItWereEnabled()) {
-    ResultsVector results;
-    size_t indexOfFirstOuterResult = 0;
-    UnqualifiedLookupFactory altLookup(Name, DC, Loc, options, results,
-                                       indexOfFirstOuterResult);
-    if (!useASTScopesForLookup())
-      altLookup.lookInASTScopes();
-    else if (Name.isOperator())
-      altLookup.lookupOperatorInDeclContexts(contextAndIsCascadingUse);
-    else
-      altLookup.lookupNamesIntroducedBy(contextAndIsCascadingUse, NULL);
-
-    const auto *ASTScopeLabel = "ASTScope lookup";
-    const auto *contextLabel = "context-bsed lookup";
-    const auto *mainLabel =
-        useASTScopesForLookup() ? ASTScopeLabel : contextLabel;
-    const auto *alternateLabel =
-        useASTScopesForLookup() ? contextLabel : ASTScopeLabel;
-    assert(verifyEqualTo(std::move(altLookup), mainLabel, alternateLabel));
+  recordCompletionOfAScope();
+  if (!isFirstResultEnough()) {
+    // If no result has been found yet, the dependency must be on a top-level
+    // name, since up to now, the search has been for non-top-level names.
+    auto *moduleScopeContext = DC->getModuleScopeContext();
+    lookUpTopLevelNamesInModuleScopeContext(moduleScopeContext);
   }
 }
 
@@ -561,386 +342,8 @@
   recordCompletionOfAScope();
 }
 
-bool UnqualifiedLookupFactory::useASTScopesForLookup() const {
-  return Ctx.LangOpts.EnableASTScopeLookup &&
-         wouldUseASTScopesForLookupIfItWereEnabled();
-}
-
-bool UnqualifiedLookupFactory::wouldUseASTScopesForLookupIfItWereEnabled()
-    const {
-  if (!Loc.isValid())
-    return false;
-  return (bool) DC->getParentSourceFile();
-}
-
 #pragma mark context-based lookup definitions
 
-void UnqualifiedLookupFactory::lookupOperatorInDeclContexts(
-    const ContextAndUnresolvedIsCascadingUse contextAndUseArg) {
-  ContextAndResolvedIsCascadingUse contextAndResolvedIsCascadingUse{
-      // Operators are global
-      contextAndUseArg.whereToLook->getModuleScopeContext(),
-      resolveIsCascadingUse(contextAndUseArg,
-                            /*onlyCareAboutFunctionBody*/ true)};
-  lookupInModuleScopeContext(contextAndResolvedIsCascadingUse.DC,
-                             contextAndResolvedIsCascadingUse.isCascadingUse);
-}
-
-// TODO: Unify with LookupVisibleDecls.cpp::lookupVisibleDeclsImpl
-void UnqualifiedLookupFactory::lookupNamesIntroducedBy(
-    const ContextAndUnresolvedIsCascadingUse contextAndIsCascadingUseArg,
-    DeclContext *capturedSelfContext) {
-#ifndef NDEBUG
-  stopForDebuggingIfDuringTargetLookup(false);
-#endif
-  DeclContext *const dc = contextAndIsCascadingUseArg.whereToLook;
-  const auto isCascadingUseSoFar = contextAndIsCascadingUseArg.isCascadingUse;
-  if (dc->isModuleScopeContext()) {
-    assert(capturedSelfContext == NULL && "By the time we reach module scope,"
-           " there should be no 'self'.");
-    lookupInModuleScopeContext(dc, isCascadingUseSoFar);
-  }
-  else if (auto *PBI = dyn_cast<PatternBindingInitializer>(dc))
-    lookupNamesIntroducedByPatternBindingInitializer(PBI, isCascadingUseSoFar,
-                                                     capturedSelfContext);
-  else if (auto *AFD = dyn_cast<AbstractFunctionDecl>(dc))
-    lookupNamesIntroducedByFunctionDecl(AFD, isCascadingUseSoFar,
-                                        capturedSelfContext);
-  else if (auto *ACE = dyn_cast<AbstractClosureExpr>(dc))
-    lookupNamesIntroducedByClosure(ACE, isCascadingUseSoFar,
-                                   capturedSelfContext);
-  else if (auto *ED = dyn_cast<ExtensionDecl>(dc)) {
-    assert(capturedSelfContext == NULL && "When we recurse into type context,"
-           " 'self' should be forgotten.");
-    lookupNamesIntroducedByNominalTypeOrExtension(ED, isCascadingUseSoFar);
-  }
-  else if (auto *ND = dyn_cast<NominalTypeDecl>(dc)) {
-    assert(capturedSelfContext == NULL && "When we recurse into type context,"
-           " 'self' should be forgotten.");
-    lookupNamesIntroducedByNominalTypeOrExtension(ND, isCascadingUseSoFar);
-  }
-  else if (auto I = dyn_cast<DefaultArgumentInitializer>(dc))
-    lookupNamesIntroducedByDefaultArgumentInitializer(I, isCascadingUseSoFar,
-                                                      capturedSelfContext);
-  else
-    lookupNamesIntroducedByMiscContext(dc, isCascadingUseSoFar,
-                                       capturedSelfContext);
-}
-
-void UnqualifiedLookupFactory::lookupInModuleScopeContext(
-    DeclContext *dc, Optional<bool> isCascadingUse) {
-  if (auto SF = dyn_cast<SourceFile>(dc)) {
-    resultsSizeBeforeLocalsPass = Results.size();
-    lookForLocalVariablesIn(SF);
-  }
-  ifNotDoneYet([&] {
-    // If no result has been found yet, the dependency must be on a top-level
-    // name, since up to now, the search has been for non-top-level names.
-    recordDependencyOnTopLevelName(dc, Name, isCascadingUse.getValueOr(true));
-    lookUpTopLevelNamesInModuleScopeContext(dc);
-  });
-}
-
-void UnqualifiedLookupFactory::lookupNamesIntroducedByPatternBindingInitializer(
-    PatternBindingInitializer *PBI, Optional<bool> isCascadingUse,
-    DeclContext *capturedSelfContext) {
-  // Lazy variable initializer contexts have a 'self' parameter for
-  // instance member lookup.
-  if (auto *selfParam = PBI->getImplicitSelfDecl())
-    lookupNamesIntroducedByLazyVariableInitializer(PBI, selfParam,
-                                                   isCascadingUse,
-                                                   capturedSelfContext);
-  else if (PBI->getParent()->isTypeContext()) {
-    assert(capturedSelfContext == NULL && "If we were in a type's property"
-           " initializer, there should be no 'self' to have been captured.");
-    lookupNamesIntroducedByInitializerOfStoredPropertyOfAType(
-                                                              PBI,
-                                                              isCascadingUse);
-  }
-  else
-    lookupNamesIntroducedByInitializerOfGlobalOrLocal(PBI, isCascadingUse,
-                                                      capturedSelfContext);
-}
-
-  void UnqualifiedLookupFactory::lookupNamesIntroducedByLazyVariableInitializer(
-      PatternBindingInitializer *PBI, ParamDecl *selfParam,
-      Optional<bool> isCascadingUse, DeclContext *capturedSelfContext) {
-    Consumer.foundDecl(selfParam, DeclVisibilityKind::FunctionParameter);
-    ifNotDoneYet([&] {
-      DeclContext *const patternContainer = PBI->getParent();
-      // clang-format off
-    finishLookingInContext(
-      AddGenericParameters::Yes,
-      patternContainer,
-      ResultFinderForTypeContext(this, PBI, patternContainer),
-      resolveIsCascadingUse(PBI, isCascadingUse,
-                           /*onlyCareAboutFunctionBody=*/false),
-      capturedSelfContext);
-      // clang-format on
-    });
-}
-
-void UnqualifiedLookupFactory::
-    lookupNamesIntroducedByInitializerOfStoredPropertyOfAType(
-        PatternBindingInitializer *PBI, Optional<bool> isCascadingUse) {
-  // Initializers for stored properties of types perform static
-  // lookup into the surrounding context.
-  DeclContext *const storedPropertyContainer = PBI->getParent();
-  // clang-format off
-  finishLookingInContext(
-    AddGenericParameters::Yes,
-    storedPropertyContainer,
-    ResultFinderForTypeContext(
-      this, storedPropertyContainer, storedPropertyContainer),
-    resolveIsCascadingUse(storedPropertyContainer, None,
-                          /*onlyCareAboutFunctionBody=*/false),
-    /*capturedSelfContext=*/NULL);
-  // clang-format on
-}
-
-void UnqualifiedLookupFactory::
-    lookupNamesIntroducedByInitializerOfGlobalOrLocal(
-        PatternBindingInitializer *PBI, Optional<bool> isCascadingUse,
-        DeclContext *capturedSelfContext) {
-  // There's not much to find here, we'll keep going up to a parent
-  // context.
-  // clang-format off
-  finishLookingInContext(
-                         AddGenericParameters::Yes,
-                         PBI,
-                         None, // not looking in the partic type
-                         resolveIsCascadingUse(PBI, isCascadingUse,
-                                               /*onlyCareAboutFunctionBody=*/false),
-                         capturedSelfContext);
-  // clang-format on
-}
-
-void UnqualifiedLookupFactory::lookupNamesIntroducedByFunctionDecl(
-    AbstractFunctionDecl *AFD, Optional<bool> isCascadingUseArg,
-    DeclContext *capturedSelfContext) {
-
-  // DOUG: how does this differ from isOutsideBodyOfFunction below?
-  const bool isCascadingUse =
-      AFD->isCascadingContextForLookup(false) &&
-      (isCascadingUseArg.getValueOr(
-          Loc.isInvalid() || AFD->getBodySourceRange().isInvalid() ||
-          !SM.rangeContainsTokenLoc(AFD->getBodySourceRange(), Loc)));
-
-  if (AFD->getDeclContext()->isTypeContext())
-    lookupNamesIntroducedByMemberFunction(AFD, isCascadingUse,
-                                          capturedSelfContext);
-  else
-    lookupNamesIntroducedByPureFunction(AFD, isCascadingUse,
-                                        capturedSelfContext);
-}
-
-void UnqualifiedLookupFactory::lookupNamesIntroducedByMemberFunction(
-    AbstractFunctionDecl *AFD, bool isCascadingUse,
-    DeclContext *capturedSelfContext) {
-  lookForLocalVariablesIn(AFD, isCascadingUse);
-  ifNotDoneYet(
-      [&] {
-        // If we're inside a function context, we're about to move to
-        // the parent DC, so we have to check the function's generic
-        // parameters first.
-        // Cannot start here in finishLookingInContext because AFD's
-        // getOuterParameters may be null even when AFD's parent has generics.
-        addGenericParametersForFunction(AFD);
-      },
-      [&] {
-        DeclContext *const fnDeclContext = AFD->getDeclContext();
-        // If we're not in the body of the function (for example, we
-        // might be type checking a default argument expression and
-        // performing name lookup from there), the base declaration
-        // is the nominal type, not 'self'. If we've captured self
-        // somewhere down the tree, we should use that as the context
-        // for lookup.
-        DeclContext *const BaseDC =
-            isOutsideBodyOfFunction(AFD) ? fnDeclContext
-            : capturedSelfContext ? capturedSelfContext
-            :  AFD;
-        // If we are inside of a method, check to see if there are any ivars in
-        // scope, and if so, whether this is a reference to one of them.
-        // FIXME: We should persist this information between lookups.
-        // clang-format off
-      finishLookingInContext(
-        AddGenericParameters::Yes,
-        AFD->getParent(),
-        ResultFinderForTypeContext(this, BaseDC, fnDeclContext),
-        isCascadingUse,
-        NULL);
-        // clang-format on
-      });
-}
-
-void UnqualifiedLookupFactory::lookupNamesIntroducedByPureFunction(
-    AbstractFunctionDecl *AFD, bool isCascadingUse,
-    DeclContext *capturedSelfContext) {
-  lookForLocalVariablesIn(AFD, isCascadingUse);
-  ifNotDoneYet([&] {
-    // clang-format off
-    finishLookingInContext(
-                           AddGenericParameters::Yes,
-                           AFD,
-                           None,
-                           isCascadingUse,
-                           capturedSelfContext);
-  });
-}
-
-
-void UnqualifiedLookupFactory::lookupNamesIntroducedByClosure(
-    AbstractClosureExpr *ACE, Optional<bool> isCascadingUse,
-    DeclContext *capturedSelfContext) {
-  if (auto *CE = dyn_cast<ClosureExpr>(ACE)) {
-    lookForLocalVariablesIn(CE);
-    // If we don't already have a captured self context, and this closure
-    // captures the self param (not weakly, so that implicit self is available),
-    // remember that.
-    if (capturedSelfContext == nullptr)
-      if (CE->capturesSelfEnablingImplictSelf())
-        capturedSelfContext = CE;
-  }
-  ifNotDoneYet([&] {
-    // clang-format off
-    finishLookingInContext(
-      AddGenericParameters::Yes,
-      ACE,
-      None,
-      resolveIsCascadingUse(ACE, isCascadingUse,
-                           /*onlyCareAboutFunctionBody=*/false),
-      capturedSelfContext);
-    // clang-format on
-  });
-}
-
-template <typename NominalTypeDeclOrExtensionDecl>
-void UnqualifiedLookupFactory::lookupNamesIntroducedByNominalTypeOrExtension(
-    NominalTypeDeclOrExtensionDecl *D, Optional<bool> isCascadingUse) {
-  // clang-format off
-  finishLookingInContext(
-    AddGenericParameters::Yes,
-    D,
-    shouldLookupMembers(D, Loc)
-    ? Optional<ResultFinderForTypeContext>(
-                ResultFinderForTypeContext(this, D, D))
-    : None,
-    resolveIsCascadingUse(D, isCascadingUse,
-                          /*onlyCareAboutFunctionBody=*/false),
-    /*capturedSelfContext=*/NULL);
-
-  // clang-format on
-}
-
-void UnqualifiedLookupFactory::
-    lookupNamesIntroducedByDefaultArgumentInitializer(
-        DefaultArgumentInitializer *I, Optional<bool> isCascadingUse,
-        DeclContext *capturedSelfContext) {
-  // In a default argument, skip immediately out of both the
-  // initializer and the function.
-  finishLookingInContext(AddGenericParameters::No, I->getParent(), None, false,
-                         capturedSelfContext);
-}
-
-void UnqualifiedLookupFactory::lookupNamesIntroducedByMiscContext(
-    DeclContext *dc, Optional<bool> isCascadingUse,
-    DeclContext *capturedSelfContext) {
-  // clang-format off
-  assert(isa<TopLevelCodeDecl>(dc) ||
-         isa<Initializer>(dc) ||
-         isa<TypeAliasDecl>(dc) ||
-         isa<SubscriptDecl>(dc) ||
-         isa<EnumElementDecl>(dc));
-  finishLookingInContext(
-    AddGenericParameters::Yes,
-    dc,
-    None,
-    resolveIsCascadingUse(DC, isCascadingUse,
-                          /*onlyCareAboutFunctionBody=*/false),
-    capturedSelfContext);
-  // clang-format on
-}
-
-
-void UnqualifiedLookupFactory::finishLookingInContext(
-       const AddGenericParameters addGenericParameters,
-       DeclContext *const lookupContextForThisContext,
-       Optional<ResultFinderForTypeContext> &&resultFinderForTypeContext,
-       const Optional<bool> isCascadingUse,
-       DeclContext *capturedSelfContext) {
-#ifndef NDEBUG
-  stopForDebuggingIfDuringTargetLookup(false);
-#endif
-  // When a generic has the same name as a member, Swift prioritizes the generic
-  // because the member could still be named by qualifying it. But there is no
-  // corresponding way to qualify a generic parameter.
-  // So, look for generics first.
-  if (addGenericParameters == AddGenericParameters::Yes)
-    addGenericParametersForContext(lookupContextForThisContext);
-  
-  ifNotDoneYet(
-    [&] {
-      if (resultFinderForTypeContext)
-        findResultsAndSaveUnavailables(lookupContextForThisContext,
-                                      std::move(*resultFinderForTypeContext),
-                                      *isCascadingUse, baseNLOptions);
-    },
-    // Recurse into the next context.
-    [&] {
-      lookupNamesIntroducedBy(ContextAndUnresolvedIsCascadingUse{
-        lookupContextForThisContext->getParentForLookup(), isCascadingUse},
-        capturedSelfContext);
-    });
-}
-
-
-void UnqualifiedLookupFactory::lookForLocalVariablesIn(
-    AbstractFunctionDecl *AFD, Optional<bool> isCascadingUse) {
-  // Look for local variables; normally, the parser resolves these
-  // for us, but it can't do the right thing inside local types.
-  // FIXME: when we can parse and typecheck the function body partially
-  // for code completion, AFD->getBody() check can be removed.
-
-  if (Loc.isInvalid() || AFD->getBodySourceRange().isInvalid() ||
-      !SM.rangeContainsTokenLoc(AFD->getBodySourceRange(), Loc) ||
-      !AFD->getBody()) {
-    return;
-  }
-
-  namelookup::FindLocalVal localVal(SM, Loc, Consumer);
-  localVal.visit(AFD->getBody());
-
-  ifNotDoneYet([&] {
-    if (auto *P = AFD->getImplicitSelfDecl())
-      localVal.checkValueDecl(P, DeclVisibilityKind::FunctionParameter);
-    localVal.checkParameterList(AFD->getParameters());
-  });
-}
-
-void UnqualifiedLookupFactory::lookForLocalVariablesIn(ClosureExpr *CE) {
-  // Look for local variables; normally, the parser resolves these
-  // for us, but it can't do the right thing inside local types.
-  if (Loc.isInvalid())
-    return;
-  namelookup::FindLocalVal localVal(SM, Loc, Consumer);
-  if (auto body = CE->getBody())
-    localVal.visit(body);
-  ifNotDoneYet([&] {
-    if (auto params = CE->getParameters())
-      localVal.checkParameterList(params);
-  });
-}
-
-void UnqualifiedLookupFactory::lookForLocalVariablesIn(SourceFile *SF) {
-  if (Loc.isInvalid())
-    return;
-  // Look for local variables in top-level code; normally, the parser
-  // resolves these for us, but it can't do the right thing for
-  // local types.
-  namelookup::FindLocalVal localVal(SM, Loc, Consumer);
-  localVal.checkSourceFile(*SF);
-}
-
 bool UnqualifiedLookupFactory::isOutsideBodyOfFunction(
     const AbstractFunctionDecl *const AFD) const {
   return !AFD->isImplicit() && Loc.isValid() &&
@@ -948,48 +351,6 @@
          !SM.rangeContainsTokenLoc(AFD->getBodySourceRange(), Loc);
 }
 
-GenericParamList *
-UnqualifiedLookupFactory::getGenericParams(const DeclContext *const dc) {
-  if (auto nominal = dyn_cast<NominalTypeDecl>(dc))
-    return nominal->getGenericParams();
-  if (auto ext = dyn_cast<ExtensionDecl>(dc))
-    return ext->getGenericParams();
-  if (auto subscript = dyn_cast<SubscriptDecl>(dc))
-    return subscript->getGenericParams();
-  if (auto func = dyn_cast<AbstractFunctionDecl>(dc))
-    return func->getGenericParams();
-  return nullptr;
-}
-
-void UnqualifiedLookupFactory::addGenericParametersForContext(
-    DeclContext *dc) {
-  // Generics can be nested, so visit the generic list, innermost first.
-  // Cannot use DeclContext::forEachGenericContext because this code breaks out
-  // if it finds a match and isFirstResultEnough()
-  addGenericParametersForContext(getGenericParams(dc));
-}
-
-void UnqualifiedLookupFactory::addGenericParametersForContext(
-    GenericParamList *dcGenericParams) {
-  if (!dcGenericParams)
-    return;
-  namelookup::FindLocalVal localVal(SM, Loc, Consumer);
-  localVal.checkGenericParams(dcGenericParams);
-  ifNotDoneYet([&] {
-    addGenericParametersForContext(
-        dcGenericParams->getOuterParameters());
-  });
-}
-
-void UnqualifiedLookupFactory::addGenericParametersForFunction(
-    AbstractFunctionDecl *AFD) {
-  GenericParamList *GenericParams = AFD->getGenericParams();
-  if (GenericParams) {
-    namelookup::FindLocalVal localVal(SM, Loc, Consumer);
-    localVal.checkGenericParams(GenericParams);
-  }
-}
-
 void UnqualifiedLookupFactory::ResultFinderForTypeContext::findResults(
     const DeclNameRef &Name, bool isCascadingUse, NLOptions baseNLOptions,
     DeclContext *contextForLookup,
@@ -1043,13 +404,6 @@
   filterForDiscriminator(Results, DebugClient);
 }
 
-
-void UnqualifiedLookupFactory::recordDependencyOnTopLevelName(
-    DeclContext *topLevelContext, DeclNameRef name, bool isCascadingUse) {
-  recordedSF = dyn_cast<SourceFile>(topLevelContext);
-  recordedIsCascadingUse = isCascadingUse;
-}
-
 void UnqualifiedLookupFactory::addImportedResults(DeclContext *const dc) {
   using namespace namelookup;
   SmallVector<ValueDecl *, 8> CurModuleResults;
@@ -1189,28 +543,8 @@
   stopForDebuggingIfStartingTargetLookup(true);
 #endif
 
-  const auto history = ASTScope::unqualifiedLookup(DC->getParentSourceFile(),
-                                                   Name, Loc, DC, consumer);
-
-  ifNotDoneYet([&] {
-    // Copied from lookupInModuleScopeContext
-    // If no result has been found yet, the dependency must be on a top-level
-    // name, since up to now, the search has been for non-top-level names.
-    auto *const moduleScopeContext = DC->getParentSourceFile();
-
-    const Optional<bool> isCascadingUseAtStartOfLookup =
-        !Name.isOperator()
-            ? getInitialIsCascadingUse()
-            : resolveIsCascadingUse(DC, getInitialIsCascadingUse(),
-                                    /*onlyCareAboutFunctionBody*/ true);
-
-    const Optional<bool> isCascadingUseAfterLookup =
-        ASTScope::computeIsCascadingUse(history, isCascadingUseAtStartOfLookup);
-
-    recordDependencyOnTopLevelName(moduleScopeContext, Name,
-                                   isCascadingUseAfterLookup.getValueOr(true));
-    lookUpTopLevelNamesInModuleScopeContext(moduleScopeContext);
-  });
+  ASTScope::unqualifiedLookup(DC->getParentSourceFile(),
+                              Name, Loc, DC, consumer);
 }
 
 bool ASTScopeDeclConsumerForUnqualifiedLookup::consume(
@@ -1335,124 +669,6 @@
   OS << "\n";
 }
 
-#pragma mark debugging: output utilities for grepping
-
-static void writeLine(std::string s) {
-  llvm::errs() << "\n+-+-+-+-  " << s << "\n";
-}
-
-StringRef UnqualifiedLookupFactory::getSourceFileName() const {
-  return DC->getParentSourceFile()->getFilename();
-}
-
-static void writeFirstLine(const UnqualifiedLookupFactory &ul, llvm::Twine s) {
-  std::string line =
-      std::string("In file: ") + ul.getSourceFileName().str() + ", " + s.str();
-  writeLine(line);
-}
-
-static void writeInconsistent(const UnqualifiedLookupFactory &me,
-                              StringRef thisLabel,
-                              const UnqualifiedLookupFactory &other,
-                              StringRef otherLabel, llvm::Twine s) {
-  writeFirstLine(me, s);
-  other.print(llvm::errs());
-  llvm::errs() << "\n" << thisLabel << " Results:\n";
-  me.printResults(llvm::errs());
-  llvm::errs() << "\n" << otherLabel << " Results:\n";
-  other.printResults(llvm::errs());
-  me.printScopes(llvm::errs());
-}
-
-#pragma mark comparing results
-
-bool UnqualifiedLookupFactory::verifyEqualTo(
-    const UnqualifiedLookupFactory &&other, const StringRef thisLabel,
-    StringRef otherLabel) const {
-  if (shouldDiffer()) {
-     return true;
-  }
-  auto writeErr = [&](llvm::Twine s) {
-    writeInconsistent(*this, thisLabel, other, otherLabel, s);
-  };
-  if (Results.size() != other.Results.size()) {
-    writeErr(thisLabel + " found " + std::to_string(Results.size()) + " but " +
-             otherLabel + " found " + std::to_string(other.Results.size()));
-    assert(false && "mismatch in number of results");
-  }
-  for (size_t i : indices(Results)) {
-    const auto &e = Results[i];
-    const auto &oe = other.Results[i];
-    if (e.getValueDecl() != oe.getValueDecl()) {
-      // print_ast_tc_function_bodies.swift generic from subscript vs get fn
-      std::string a; llvm::raw_string_ostream as(a);
-      std::string b; llvm::raw_string_ostream bs(b);
-      e.getValueDecl()->print(as);
-      oe.getValueDecl()->print(bs);
-      if (a == b)
-        llvm::errs() << "ValueDecls differ but print same\n";
-      else {
-        writeErr(std::string( "ValueDecls differ at ") + std::to_string(i));
-        assert(false && "other lookup found different Decl");
-      }
-    }
-    if (e.getDeclContext() != oe.getDeclContext()) {
-      writeErr((std::string("Contexts differ at ")) + std::to_string(i));
-      assert(false && "ASTScopeImpl found different context");
-    }
-    // unsigned printContext(llvm::raw_ostream &OS, unsigned indent = 0,
-    // bool onlyAPartialLine = false) const;
-  }
-  if (IndexOfFirstOuterResult != other.IndexOfFirstOuterResult) {
-    writeErr( std::string("IndexOfFirstOuterResult differs, should be: ")
-             + std::to_string(IndexOfFirstOuterResult)
-             + std::string( ", is: ")
-             + std::to_string(other.IndexOfFirstOuterResult));
-    assert(false && "other lookup IndexOfFirstOuterResult differs");
-  }
-  if (recordedSF != other.recordedSF) {
-    writeErr(std::string("recordedSF differs: shouldBe: ") +
-             (recordedSF ? recordedSF->getFilename().str()
-                         : std::string("<no name>")) +
-             std::string(" is: ") +
-             (other.recordedSF ? other.recordedSF->getFilename().str()
-                               : std::string("<no name>")));
-    assert(false && "other lookup recordedSF differs");
-  }
-  if (recordedSF && recordedIsCascadingUse != other.recordedIsCascadingUse) {
-    writeErr(std::string("recordedIsCascadingUse differs: shouldBe: ") +
-             std::to_string(recordedIsCascadingUse) + std::string(" is: ") +
-             std::to_string(other.recordedIsCascadingUse));
-    assert(false && "other lookup recordedIsCascadingUse differs");
-  }
-  return true;
-}
-
-bool UnqualifiedLookupFactory::shouldDiffer() const {
-  auto *SF = dyn_cast<SourceFile>(DC->getModuleScopeContext());
-  if (!SF)
-    return false;
-  
-  static std::vector<const char*> testsThatShouldDiffer {
-    "swift/test/Constraints/diagnostics.swift",
-    "swift/test/Constraints/enum_cases.swift",
-    "swift/test/Constraints/rdar39401774.swift",
-    "swift/test/Constraints/rdar39401774-astscope.swift",
-    "swift/test/Interpreter/repl.swift",
-    "swift/test/Sema/diag_defer_captures.swift",
-    "swift/test/Sema/diag_use_before_declaration.swift",
-    "swift/test/SourceKit/CodeFormat/indent-closure.swift",
-    "swift/test/TypeCoercion/overload_noncall.swift",
-    "swift/test/expr/capture/nested_class.swift",
-    "swift/test/expr/capture/order.swift",
-    "swift/test/NameLookup/name_lookup2.swift"
-  };
-  StringRef fileName = SF->getFilename();
-  return llvm::any_of(testsThatShouldDiffer, [&](const char *testFile) {
-    return fileName.endswith(testFile);
-  });
-}
-
 #pragma mark breakpointing
 #ifndef NDEBUG
 
diff --git a/lib/Basic/FileTypes.cpp b/lib/Basic/FileTypes.cpp
index d2c1570..f4af753 100644
--- a/lib/Basic/FileTypes.cpp
+++ b/lib/Basic/FileTypes.cpp
@@ -94,6 +94,7 @@
   case file_types::TY_SwiftModuleDocFile:
   case file_types::TY_SwiftSourceInfoFile:
   case file_types::TY_SwiftCrossImportDir:
+  case file_types::TY_SwiftModuleSummaryFile:
   case file_types::TY_LLVM_BC:
   case file_types::TY_SerializedDiagnostics:
   case file_types::TY_ClangModuleFile:
@@ -138,6 +139,7 @@
   case file_types::TY_SwiftModuleDocFile:
   case file_types::TY_SwiftSourceInfoFile:
   case file_types::TY_SwiftCrossImportDir:
+  case file_types::TY_SwiftModuleSummaryFile:
   case file_types::TY_SwiftOverlayFile:
   case file_types::TY_SerializedDiagnostics:
   case file_types::TY_ClangModuleFile:
@@ -189,6 +191,7 @@
   case file_types::TY_SwiftSourceInfoFile:
   case file_types::TY_SwiftCrossImportDir:
   case file_types::TY_SwiftOverlayFile:
+  case file_types::TY_SwiftModuleSummaryFile:
   case file_types::TY_SerializedDiagnostics:
   case file_types::TY_ClangModuleFile:
   case file_types::TY_SwiftDeps:
diff --git a/lib/Basic/Platform.cpp b/lib/Basic/Platform.cpp
index 62add57..ad1db82 100644
--- a/lib/Basic/Platform.cpp
+++ b/lib/Basic/Platform.cpp
@@ -473,3 +473,47 @@
 
   return SDKVersion;
 }
+
+static std::string getPlistEntry(const llvm::Twine &Path, StringRef KeyName) {
+  auto BufOrErr = llvm::MemoryBuffer::getFile(Path);
+  if (!BufOrErr) {
+    // FIXME: diagnose properly
+    return {};
+  }
+
+  std::string Key = "<key>";
+  Key += KeyName;
+  Key += "</key>";
+
+  StringRef Lines = BufOrErr.get()->getBuffer();
+  while (!Lines.empty()) {
+    StringRef CurLine;
+    std::tie(CurLine, Lines) = Lines.split('\n');
+    if (CurLine.find(Key) != StringRef::npos) {
+      std::tie(CurLine, Lines) = Lines.split('\n');
+      unsigned Begin = CurLine.find("<string>") + strlen("<string>");
+      unsigned End = CurLine.find("</string>");
+      return CurLine.substr(Begin, End - Begin).str();
+    }
+  }
+
+  return {};
+}
+
+std::string swift::getSDKBuildVersionFromPlist(StringRef Path) {
+  return getPlistEntry(Path, "ProductBuildVersion");
+}
+
+std::string swift::getSDKBuildVersion(StringRef Path) {
+  return getSDKBuildVersionFromPlist((llvm::Twine(Path) +
+    "/System/Library/CoreServices/SystemVersion.plist").str());
+}
+
+std::string swift::getSDKName(StringRef Path) {
+  std::string Name = getPlistEntry(llvm::Twine(Path)+"/SDKSettings.plist",
+                                   "CanonicalName");
+  if (Name.empty() && Path.endswith(".sdk")) {
+    Name = llvm::sys::path::filename(Path).drop_back(strlen(".sdk")).str();
+  }
+  return Name;
+}
diff --git a/lib/ClangImporter/ClangAdapter.cpp b/lib/ClangImporter/ClangAdapter.cpp
index a2ff142..6c38957 100644
--- a/lib/ClangImporter/ClangAdapter.cpp
+++ b/lib/ClangImporter/ClangAdapter.cpp
@@ -77,11 +77,26 @@
   return None;
 }
 
+static bool isInLocalScope(const clang::Decl *D) {
+  const clang::DeclContext *LDC = D->getLexicalDeclContext();
+  while (true) {
+    if (LDC->isFunctionOrMethod())
+      return true;
+    if (!isa<clang::TagDecl>(LDC))
+      return false;
+    if (const auto *CRD = dyn_cast<clang::CXXRecordDecl>(LDC))
+      if (CRD->isLambda())
+        return true;
+    LDC = LDC->getLexicalParent();
+  }
+  return false;
+}
+
 const clang::Decl *
 importer::getFirstNonLocalDecl(const clang::Decl *D) {
   D = D->getCanonicalDecl();
   auto iter = llvm::find_if(D->redecls(), [](const clang::Decl *next) -> bool {
-    return !next->isLexicallyWithinFunctionOrMethod();
+    return !isInLocalScope(next);
   });
   if (iter == D->redecls_end())
     return nullptr;
@@ -344,6 +359,7 @@
     case clang::BuiltinType::ARCUnbridgedCast:
     case clang::BuiltinType::BoundMember:
     case clang::BuiltinType::BuiltinFn:
+    case clang::BuiltinType::IncompleteMatrixIdx:
     case clang::BuiltinType::Overload:
     case clang::BuiltinType::PseudoObject:
     case clang::BuiltinType::UnknownAny:
@@ -376,6 +392,7 @@
     case clang::BuiltinType::SatULongFract:
     case clang::BuiltinType::Half:
     case clang::BuiltinType::LongDouble:
+    case clang::BuiltinType::BFloat16:
     case clang::BuiltinType::Float16:
     case clang::BuiltinType::Float128:
     case clang::BuiltinType::NullPtr:
@@ -446,21 +463,14 @@
 
     // OpenMP types that don't have Swift equivalents.
     case clang::BuiltinType::OMPArraySection:
+    case clang::BuiltinType::OMPArrayShaping:
+    case clang::BuiltinType::OMPIterator:
       return OmissionTypeName();
 
     // SVE builtin types that don't have Swift equivalents.
-    case clang::BuiltinType::SveInt8:
-    case clang::BuiltinType::SveInt16:
-    case clang::BuiltinType::SveInt32:
-    case clang::BuiltinType::SveInt64:
-    case clang::BuiltinType::SveUint8:
-    case clang::BuiltinType::SveUint16:
-    case clang::BuiltinType::SveUint32:
-    case clang::BuiltinType::SveUint64:
-    case clang::BuiltinType::SveFloat16:
-    case clang::BuiltinType::SveFloat32:
-    case clang::BuiltinType::SveFloat64:
-    case clang::BuiltinType::SveBool:
+#define SVE_TYPE(Name, Id, ...) \
+    case clang::BuiltinType::Id:
+#include "clang/Basic/AArch64SVEACLETypes.def"
       return OmissionTypeName();
     }
   }
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index e1f1ad5..0e4978a 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -32,7 +32,6 @@
 #include "swift/Basic/Range.h"
 #include "swift/Basic/StringExtras.h"
 #include "swift/Basic/Version.h"
-#include "swift/ClangImporter/ClangImporterOptions.h"
 #include "swift/ClangImporter/ClangModule.h"
 #include "swift/Config.h"
 #include "swift/Demangling/Demangle.h"
@@ -410,11 +409,10 @@
 }
 
 ClangImporter::ClangImporter(ASTContext &ctx,
-                             const ClangImporterOptions &clangImporterOpts,
                              DependencyTracker *tracker,
                              DWARFImporterDelegate *dwarfImporterDelegate)
     : ClangModuleLoader(tracker),
-      Impl(*new Implementation(ctx, clangImporterOpts, dwarfImporterDelegate)) {
+      Impl(*new Implementation(ctx, dwarfImporterDelegate)) {
 }
 
 ClangImporter::~ClangImporter() {
@@ -466,12 +464,11 @@
 void
 importer::getNormalInvocationArguments(
     std::vector<std::string> &invocationArgStrs,
-    ASTContext &ctx,
-    const ClangImporterOptions &importerOpts) {
+    ASTContext &ctx) {
   const auto &LangOpts = ctx.LangOpts;
   const llvm::Triple &triple = LangOpts.Target;
   SearchPathOptions &searchPathOpts = ctx.SearchPathOpts;
-
+  ClangImporterOptions &importerOpts = ctx.ClangImporterOpts;
   auto languageVersion = ctx.LangOpts.EffectiveLanguageVersion;
 
   if (llvm::sys::path::extension(importerOpts.BridgingHeader)
@@ -688,8 +685,7 @@
 
 static void
 getEmbedBitcodeInvocationArguments(std::vector<std::string> &invocationArgStrs,
-                                   ASTContext &ctx,
-                                   const ClangImporterOptions &importerOpts) {
+                                   ASTContext &ctx) {
   invocationArgStrs.insert(invocationArgStrs.end(), {
     // Backend mode.
     "-fembed-bitcode",
@@ -704,11 +700,11 @@
 void
 importer::addCommonInvocationArguments(
     std::vector<std::string> &invocationArgStrs,
-    ASTContext &ctx,
-    const ClangImporterOptions &importerOpts) {
+    ASTContext &ctx) {
   using ImporterImpl = ClangImporter::Implementation;
   const llvm::Triple &triple = ctx.LangOpts.Target;
   SearchPathOptions &searchPathOpts = ctx.SearchPathOpts;
+  const ClangImporterOptions &importerOpts = ctx.ClangImporterOpts;
 
   invocationArgStrs.push_back("-target");
   invocationArgStrs.push_back(triple.str());
@@ -920,25 +916,24 @@
 }
 
 std::vector<std::string>
-ClangImporter::getClangArguments(ASTContext &ctx,
-                                 const ClangImporterOptions &importerOpts) {
-  if (importerOpts.ExtraArgsOnly) {
-    return importerOpts.ExtraArgs;
+ClangImporter::getClangArguments(ASTContext &ctx) {
+  if (ctx.ClangImporterOpts.ExtraArgsOnly) {
+    return ctx.ClangImporterOpts.ExtraArgs;
   }
   std::vector<std::string> invocationArgStrs;
   // Clang expects this to be like an actual command line. So we need to pass in
   // "clang" for argv[0]
   invocationArgStrs.push_back("clang");
-  switch (importerOpts.Mode) {
+  switch (ctx.ClangImporterOpts.Mode) {
   case ClangImporterOptions::Modes::Normal:
   case ClangImporterOptions::Modes::PrecompiledModule:
-    getNormalInvocationArguments(invocationArgStrs, ctx, importerOpts);
+    getNormalInvocationArguments(invocationArgStrs, ctx);
     break;
   case ClangImporterOptions::Modes::EmbedBitcode:
-    getEmbedBitcodeInvocationArguments(invocationArgStrs, ctx, importerOpts);
+    getEmbedBitcodeInvocationArguments(invocationArgStrs, ctx);
     break;
   }
-  addCommonInvocationArguments(invocationArgStrs, ctx, importerOpts);
+  addCommonInvocationArguments(invocationArgStrs, ctx);
   return invocationArgStrs;
 }
 
@@ -974,19 +969,15 @@
                                                 nullptr, false, CC1Args);
 }
 
-ArrayRef<std::string> ClangImporter::getExtraClangArgs() const {
-  return Impl.ExtraClangArgs;
-}
-
 std::unique_ptr<ClangImporter>
-ClangImporter::create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
+ClangImporter::create(ASTContext &ctx,
                       std::string swiftPCHHash, DependencyTracker *tracker,
                       DWARFImporterDelegate *dwarfImporterDelegate) {
   std::unique_ptr<ClangImporter> importer{
-      new ClangImporter(ctx, importerOpts, tracker, dwarfImporterDelegate)};
-  importer->Impl.ClangArgs = getClangArguments(ctx, importerOpts);
+      new ClangImporter(ctx, tracker, dwarfImporterDelegate)};
+  auto &importerOpts = ctx.ClangImporterOpts;
+  importer->Impl.ClangArgs = getClangArguments(ctx);
   ArrayRef<std::string> invocationArgStrs = importer->Impl.ClangArgs;
-  importer->Impl.ExtraClangArgs = importerOpts.ExtraArgs;
   if (importerOpts.DumpClangDiagnostics) {
     llvm::errs() << "'";
     llvm::interleave(
@@ -1597,6 +1588,30 @@
   return false;
 }
 
+bool ClangImporter::runPreprocessor(StringRef inputPath, StringRef outputPath) {
+  auto emitInstance = cloneCompilerInstanceForPrecompiling();
+  auto &invocation = emitInstance->getInvocation();
+  auto LangOpts = invocation.getLangOpts();
+  auto &OutputOpts = invocation.getPreprocessorOutputOpts();
+  OutputOpts.ShowCPP = 1;
+  OutputOpts.ShowComments = 0;
+  OutputOpts.ShowLineMarkers = 0;
+  OutputOpts.ShowMacros = 0;
+  OutputOpts.ShowMacroComments = 0;
+  auto language = getLanguageFromOptions(LangOpts);
+  auto inputFile = clang::FrontendInputFile(inputPath, language);
+
+  auto &FrontendOpts = invocation.getFrontendOpts();
+  FrontendOpts.Inputs = {inputFile};
+  FrontendOpts.OutputFile = outputPath.str();
+  FrontendOpts.ProgramAction = clang::frontend::PrintPreprocessedInput;
+
+  auto action = wrapActionForIndexingIfEnabled(
+      FrontendOpts, std::make_unique<clang::PrintPreprocessedAction>());
+  emitInstance->ExecuteAction(*action);
+  return emitInstance->getDiagnostics().hasErrorOccurred();
+}
+
 bool ClangImporter::emitPrecompiledModule(StringRef moduleMapPath,
                                           StringRef moduleName,
                                           StringRef outputPath) {
@@ -1915,6 +1930,10 @@
         "APIs deprecated as of macOS 10.9 and earlier are unavailable in Swift";
     break;
 
+  case PlatformKind::OpenBSD:
+    deprecatedAsUnavailableMessage = "";
+    break;
+
   case PlatformKind::none:
     break;
   }
@@ -1947,6 +1966,9 @@
   case PlatformKind::watchOSApplicationExtension:
     return name == "watchos" || name == "watchos_app_extension";
 
+  case PlatformKind::OpenBSD:
+    return name == "openbsd";
+
   case PlatformKind::none:
     return false;
   }
@@ -1986,26 +2008,30 @@
   case PlatformKind::watchOSApplicationExtension:
     // No deprecation filter on watchOS
     return false;
+
+  case PlatformKind::OpenBSD:
+    // No deprecation filter on OpenBSD
+    return false;
   }
 
   llvm_unreachable("Unexpected platform");
 }
 
 ClangImporter::Implementation::Implementation(
-    ASTContext &ctx, const ClangImporterOptions &opts,
+    ASTContext &ctx,
     DWARFImporterDelegate *dwarfImporterDelegate)
     : SwiftContext(ctx),
-      ImportForwardDeclarations(opts.ImportForwardDeclarations),
-      InferImportAsMember(opts.InferImportAsMember),
-      DisableSwiftBridgeAttr(opts.DisableSwiftBridgeAttr),
-      BridgingHeaderExplicitlyRequested(!opts.BridgingHeader.empty()),
-      DisableOverlayModules(opts.DisableOverlayModules),
+      ImportForwardDeclarations(ctx.ClangImporterOpts.ImportForwardDeclarations),
+      InferImportAsMember(ctx.ClangImporterOpts.InferImportAsMember),
+      DisableSwiftBridgeAttr(ctx.ClangImporterOpts.DisableSwiftBridgeAttr),
+      BridgingHeaderExplicitlyRequested(!ctx.ClangImporterOpts.BridgingHeader.empty()),
+      DisableOverlayModules(ctx.ClangImporterOpts.DisableOverlayModules),
       IsReadingBridgingPCH(false),
       CurrentVersion(ImportNameVersion::fromOptions(ctx.LangOpts)),
       BridgingHeaderLookupTable(new SwiftLookupTable(nullptr)),
       BuffersForDiagnostics(ctx.SourceMgr),
       platformAvailability(ctx.LangOpts), nameImporter(),
-      DisableSourceImport(opts.DisableSourceImport),
+      DisableSourceImport(ctx.ClangImporterOpts.DisableSourceImport),
       DWARFImporter(dwarfImporterDelegate) {}
 
 ClangImporter::Implementation::~Implementation() {
@@ -3333,7 +3359,7 @@
   return clangSourceMgr.getFilename(clangModule->DefinitionLoc);
 }
 
-Optional<clang::ExternalASTSource::ASTSourceDescriptor>
+Optional<clang::ASTSourceDescriptor>
 ClangModuleUnit::getASTSourceDescriptor() const {
   if (clangModule) {
     assert(ASTSourceDescriptor.getModuleOrNull() == clangModule);
diff --git a/lib/ClangImporter/ClangModuleDependencyScanner.cpp b/lib/ClangImporter/ClangModuleDependencyScanner.cpp
index c465b1e..fbc693e 100644
--- a/lib/ClangImporter/ClangModuleDependencyScanner.cpp
+++ b/lib/ClangImporter/ClangModuleDependencyScanner.cpp
@@ -16,7 +16,6 @@
 #include "ImporterImpl.h"
 #include "swift/AST/ModuleDependencies.h"
 #include "swift/ClangImporter/ClangImporter.h"
-#include "swift/ClangImporter/ClangImporterOptions.h"
 #include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
 #include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
 #include "llvm/Support/FileSystem.h"
@@ -105,9 +104,7 @@
 // adds search paths to Clang's data structures rather than to its
 // command line.
 static void addSearchPathInvocationArguments(
-    std::vector<std::string> &invocationArgStrs,
-    ASTContext &ctx,
-    const ClangImporterOptions &importerOpts) {
+    std::vector<std::string> &invocationArgStrs, ASTContext &ctx) {
   SearchPathOptions &searchPathOpts = ctx.SearchPathOpts;
   for (const auto &framepath : searchPathOpts.FrameworkSearchPaths) {
     invocationArgStrs.push_back(framepath.IsSystem ? "-iframework" : "-F");
@@ -123,15 +120,14 @@
 /// Create the command line for Clang dependency scanning.
 static std::vector<std::string> getClangDepScanningInvocationArguments(
     ASTContext &ctx,
-    const ClangImporterOptions &importerOpts,
     StringRef sourceFileName) {
   std::vector<std::string> commandLineArgs;
 
   // Form the basic command line.
   commandLineArgs.push_back("clang");
-  importer::getNormalInvocationArguments(commandLineArgs, ctx, importerOpts);
-  importer::addCommonInvocationArguments(commandLineArgs, ctx, importerOpts);
-  addSearchPathInvocationArguments(commandLineArgs, ctx, importerOpts);
+  importer::getNormalInvocationArguments(commandLineArgs, ctx);
+  importer::addCommonInvocationArguments(commandLineArgs, ctx);
+  addSearchPathInvocationArguments(commandLineArgs, ctx);
 
   auto sourceFilePos = std::find(
       commandLineArgs.begin(), commandLineArgs.end(),
@@ -303,16 +299,11 @@
     // FIXME: Emit a diagnostic here.
     return None;
   }
-  // Reform the Clang importer options.
-  // FIXME: Just save a reference or copy so we can get this back.
-  ClangImporterOptions importerOpts;
-  importerOpts.ExtraArgs = getExtraClangArgs();
 
   // Determine the command-line arguments for dependency scanning.
   auto &ctx = Impl.SwiftContext;
   std::vector<std::string> commandLineArgs =
-    getClangDepScanningInvocationArguments(
-      ctx, importerOpts, *importHackFile);
+    getClangDepScanningInvocationArguments(ctx, *importHackFile);
 
   std::string workingDir =
       ctx.SourceMgr.getFileSystem()->getCurrentWorkingDirectory().get();
@@ -347,19 +338,13 @@
   // Retrieve or create the shared state.
   auto clangImpl = getOrCreateClangImpl(cache);
 
-  // Reform the Clang importer options.
-  // FIXME: Just save a reference or copy so we can get this back.
-  ClangImporterOptions importerOpts;
-  importerOpts.ExtraArgs = getExtraClangArgs();
-
   // Retrieve the bridging header.
   std::string bridgingHeader = *targetModule.getBridgingHeader();
 
   // Determine the command-line arguments for dependency scanning.
   auto &ctx = Impl.SwiftContext;
   std::vector<std::string> commandLineArgs =
-    getClangDepScanningInvocationArguments(
-      ctx, importerOpts, bridgingHeader);
+    getClangDepScanningInvocationArguments(ctx, bridgingHeader);
 
   std::string workingDir =
       ctx.SourceMgr.getFileSystem()->getCurrentWorkingDirectory().get();
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 52f26c7..db5dd76 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -16,7 +16,6 @@
 
 #include "CFTypeInfo.h"
 #include "ImporterImpl.h"
-#include "swift/Strings.h"
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ASTMangler.h"
 #include "swift/AST/Attr.h"
@@ -36,15 +35,19 @@
 #include "swift/AST/PrettyStackTrace.h"
 #include "swift/AST/ProtocolConformance.h"
 #include "swift/AST/Stmt.h"
-#include "swift/AST/Types.h"
 #include "swift/AST/TypeCheckRequests.h"
+#include "swift/AST/Types.h"
 #include "swift/Basic/Defer.h"
 #include "swift/Basic/PrettyStackTrace.h"
+#include "swift/Basic/Statistic.h"
 #include "swift/ClangImporter/ClangModule.h"
-#include "swift/Parse/Lexer.h"
 #include "swift/Config.h"
+#include "swift/Parse/Lexer.h"
+#include "swift/Strings.h"
+
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
+#include "clang/AST/DeclObjCCommon.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/Basic/CharInfo.h"
 #include "swift/Basic/Statistic.h"
@@ -374,6 +377,7 @@
       case clang::TargetInfo::VoidPtrBuiltinVaList:
       case clang::TargetInfo::PowerABIBuiltinVaList:
       case clang::TargetInfo::AAPCSABIBuiltinVaList:
+      case clang::TargetInfo::HexagonBuiltinVaList:
         assert(ClangCtx.getTypeSize(ClangCtx.VoidPtrTy) == ClangTypeSize &&
                "expected va_list type to be sizeof(void *)");
         break;
@@ -1212,15 +1216,16 @@
                                                          fieldType,
                                                          clang::VK_RValue,
                                                          clang::SourceLocation());
-    
-    auto cSetterExpr = new (Ctx) clang::BinaryOperator(cSetterMemberExpr,
-                                                       cSetterValueExpr,
-                                                       clang::BO_Assign,
-                                                       fieldType,
-                                                       clang::VK_RValue,
-                                                       clang::OK_Ordinary,
-                                                       clang::SourceLocation(),
-                                                       clang::FPOptions());
+
+    auto cSetterExpr = clang::BinaryOperator::Create(Ctx,
+                                                     cSetterMemberExpr,
+                                                     cSetterValueExpr,
+                                                     clang::BO_Assign,
+                                                     fieldType,
+                                                     clang::VK_RValue,
+                                                     clang::OK_Ordinary,
+                                                     clang::SourceLocation(),
+                                                     clang::FPOptionsOverride());
     
     cSetterDecl->setBody(cSetterExpr);
   }
@@ -2058,7 +2063,7 @@
 
 static void
 applyPropertyOwnership(VarDecl *prop,
-                       clang::ObjCPropertyDecl::PropertyAttributeKind attrs) {
+                       clang::ObjCPropertyAttribute::Kind attrs) {
   Type ty = prop->getInterfaceType();
   if (auto innerTy = ty->getOptionalObjectType())
     ty = innerTy;
@@ -2066,19 +2071,19 @@
     return;
 
   ASTContext &ctx = prop->getASTContext();
-  if (attrs & clang::ObjCPropertyDecl::OBJC_PR_copy) {
+  if (attrs & clang::ObjCPropertyAttribute::kind_copy) {
     prop->getAttrs().add(new (ctx) NSCopyingAttr(false));
     return;
   }
-  if (attrs & clang::ObjCPropertyDecl::OBJC_PR_weak) {
+  if (attrs & clang::ObjCPropertyAttribute::kind_weak) {
     prop->getAttrs().add(new (ctx)
                              ReferenceOwnershipAttr(ReferenceOwnership::Weak));
     prop->setInterfaceType(WeakStorageType::get(
         prop->getInterfaceType(), ctx));
     return;
   }
-  if ((attrs & clang::ObjCPropertyDecl::OBJC_PR_assign) ||
-      (attrs & clang::ObjCPropertyDecl::OBJC_PR_unsafe_unretained)) {
+  if ((attrs & clang::ObjCPropertyAttribute::kind_assign) ||
+      (attrs & clang::ObjCPropertyAttribute::kind_unsafe_unretained)) {
     prop->getAttrs().add(
         new (ctx) ReferenceOwnershipAttr(ReferenceOwnership::Unmanaged));
     prop->setInterfaceType(UnmanagedStorageType::get(
@@ -4375,6 +4380,7 @@
         kind = SpecialMethodKind::NSDictionarySubscriptGetter;
 
       // Import the type that this method will have.
+      Optional<ForeignAsyncConvention> asyncConvention;
       Optional<ForeignErrorConvention> errorConvention;
 
       // If we have a property accessor, find the corresponding property
@@ -4413,7 +4419,7 @@
         importedType = Impl.importMethodParamsAndReturnType(
             dc, decl, decl->parameters(), decl->isVariadic(),
             isInSystemModule(dc), &bodyParams, importedName,
-            errorConvention, kind);
+            asyncConvention, errorConvention, kind);
       }
       if (!importedType)
         return nullptr;
@@ -4435,10 +4441,10 @@
       // Determine whether the function is throwing and/or async.
       bool throws = importedName.getErrorInfo().hasValue();
       bool async = false;
-      auto asyncConvention = importedName.getAsyncInfo();
-      if (asyncConvention) {
+      auto asyncInfo = importedName.getAsyncInfo();
+      if (asyncInfo) {
         async = true;
-        if (asyncConvention->isThrowing())
+        if (asyncInfo->isThrowing())
           throws = true;
       }
 
@@ -6376,11 +6382,14 @@
   assert(ownerNominal && "Method in non-type context?");
 
   // Import the type that this method will have.
+  Optional<ForeignAsyncConvention> asyncConvention;
   Optional<ForeignErrorConvention> errorConvention;
   ParameterList *bodyParams;
   auto importedType = Impl.importMethodParamsAndReturnType(
       dc, objcMethod, args, variadic, isInSystemModule(dc), &bodyParams,
-      importedName, errorConvention, SpecialMethodKind::Constructor);
+      importedName, asyncConvention, errorConvention,
+      SpecialMethodKind::Constructor);
+  assert(!asyncConvention && "Initializers don't have async conventions");
   if (!importedType)
     return nullptr;
 
diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp
index fc0313b..972e9ca 100644
--- a/lib/ClangImporter/ImportName.cpp
+++ b/lib/ClangImporter/ImportName.cpp
@@ -29,7 +29,6 @@
 #include "swift/AST/TypeRepr.h"
 #include "swift/AST/Types.h"
 #include "swift/Basic/StringExtras.h"
-#include "swift/ClangImporter/ClangImporterOptions.h"
 #include "swift/Parse/Parser.h"
 #include "swift/Strings.h"
 #include "clang/AST/ASTContext.h"
@@ -1186,7 +1185,7 @@
   return true;
 }
 
-Optional<ForeignAsyncConvention>
+Optional<ForeignAsyncConvention::Info>
 NameImporter::considerAsyncImport(
     const clang::ObjCMethodDecl *clangDecl,
     StringRef &baseName,
@@ -1212,7 +1211,8 @@
   // Determine whether the naming indicates that this is a completion
   // handler.
   Optional<StringRef> newBaseName;
-  if (isCompletionHandlerParamName(paramNames[completionHandlerParamNameIndex])) {
+  if (isCompletionHandlerParamName(
+          paramNames[completionHandlerParamNameIndex])) {
     // The argument label itself has an appropriate name.
   } else if (!hasCustomName && completionHandlerParamIndex == 0 &&
              (newBaseName = isCompletionHandlerInBaseName(baseName))) {
@@ -1227,7 +1227,8 @@
   // Used for returns once we've determined that the method cannot be
   // imported as async, even though it has what looks like a completion handler
   // parameter.
-  auto notAsync = [&](const char *reason) -> Optional<ForeignAsyncConvention> {
+  auto notAsync = [&](const char *reason) ->
+      Optional<ForeignAsyncConvention::Info> {
 #ifdef ASYNC_IMPORT_DEBUG
     llvm::errs() << "*** failed async import: " << reason << "\n";
     clangDecl->dump(llvm::errs());
@@ -1307,7 +1308,7 @@
   if (newBaseName && !hasCustomName)
     baseName = *newBaseName;
 
-  return ForeignAsyncConvention(
+  return ForeignAsyncConvention::Info(
       completionHandlerParamIndex, completionHandlerErrorParamIndex);
 }
 
diff --git a/lib/ClangImporter/ImportName.h b/lib/ClangImporter/ImportName.h
index 09d9070..5f5d9a0 100644
--- a/lib/ClangImporter/ImportName.h
+++ b/lib/ClangImporter/ImportName.h
@@ -200,7 +200,7 @@
 
     /// For names that map Objective-C completion handlers into async
     /// Swift methods, describes how the mapping is performed.
-    ForeignAsyncConvention asyncInfo;
+    ForeignAsyncConvention::Info asyncInfo;
 
     /// For a declaration name that makes the declaration into an
     /// instance member, the index of the "Self" parameter.
@@ -270,7 +270,7 @@
 
   /// For names that map Objective-C methods with completion handlers into
   /// async Swift methods, describes how the mapping is performed.
-  Optional<ForeignAsyncConvention> getAsyncInfo() const {
+  Optional<ForeignAsyncConvention::Info> getAsyncInfo() const {
     if (info.hasAsyncInfo)
       return info.asyncInfo;
     return None;
@@ -453,7 +453,7 @@
                       ArrayRef<const clang::ParmVarDecl *> params,
                       bool isInitializer, bool hasCustomName);
 
-  Optional<ForeignAsyncConvention>
+  Optional<ForeignAsyncConvention::Info>
   considerAsyncImport(const clang::ObjCMethodDecl *clangDecl,
                       StringRef &baseName,
                       SmallVectorImpl<StringRef> &paramNames,
diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp
index e9e0599..cec3b65 100644
--- a/lib/ClangImporter/ImportType.cpp
+++ b/lib/ClangImporter/ImportType.cpp
@@ -34,6 +34,7 @@
 #include "swift/Strings.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjCCommon.h"
 #include "clang/AST/TypeVisitor.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Lex/Preprocessor.h"
@@ -248,6 +249,7 @@
       case clang::BuiltinType::ARCUnbridgedCast:
       case clang::BuiltinType::BoundMember:
       case clang::BuiltinType::BuiltinFn:
+      case clang::BuiltinType::IncompleteMatrixIdx:
       case clang::BuiltinType::Overload:
       case clang::BuiltinType::PseudoObject:
       case clang::BuiltinType::UnknownAny:
@@ -278,6 +280,7 @@
       case clang::BuiltinType::SatUShortFract:
       case clang::BuiltinType::SatUFract:
       case clang::BuiltinType::SatULongFract:
+      case clang::BuiltinType::BFloat16:
       case clang::BuiltinType::Float128:
       case clang::BuiltinType::NullPtr:
       case clang::BuiltinType::Char8:
@@ -348,32 +351,35 @@
 
       // OpenMP types that don't have Swift equivalents.
       case clang::BuiltinType::OMPArraySection:
+      case clang::BuiltinType::OMPArrayShaping:
+      case clang::BuiltinType::OMPIterator:
         return Type();
 
       // SVE builtin types that don't have Swift equivalents.
-      case clang::BuiltinType::SveInt8:
-      case clang::BuiltinType::SveInt16:
-      case clang::BuiltinType::SveInt32:
-      case clang::BuiltinType::SveInt64:
-      case clang::BuiltinType::SveUint8:
-      case clang::BuiltinType::SveUint16:
-      case clang::BuiltinType::SveUint32:
-      case clang::BuiltinType::SveUint64:
-      case clang::BuiltinType::SveFloat16:
-      case clang::BuiltinType::SveFloat32:
-      case clang::BuiltinType::SveFloat64:
-      case clang::BuiltinType::SveBool:
+#define SVE_TYPE(Name, Id, ...) \
+      case clang::BuiltinType::Id:
+#include "clang/Basic/AArch64SVEACLETypes.def"
         return Type();
       }
 
       llvm_unreachable("Invalid BuiltinType.");
     }
 
+    ImportResult VisitExtIntType(const clang::ExtIntType *) {
+      // ExtInt is not supported in Swift.
+      return Type();
+    }
+
     ImportResult VisitPipeType(const clang::PipeType *) {
       // OpenCL types are not supported in Swift.
       return Type();
     }
 
+    ImportResult VisitMatrixType(const clang::MatrixType *ty) {
+      // Matrix types are not supported in Swift.
+      return Type();
+    }
+
     ImportResult VisitComplexType(const clang::ComplexType *type) {
       // FIXME: Implement once Complex is in the library.
       return Type();
@@ -1589,8 +1595,8 @@
 ImportedType ClangImporter::Implementation::importPropertyType(
     const clang::ObjCPropertyDecl *decl, bool isFromSystemModule) {
   const auto assignOrUnsafeUnretained =
-      clang::ObjCPropertyDecl::OBJC_PR_assign |
-      clang::ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
+      clang::ObjCPropertyAttribute::kind_assign |
+      clang::ObjCPropertyAttribute::kind_unsafe_unretained;
 
   ImportTypeKind importKind;
   // HACK: Certain decls are always imported using bridged types,
@@ -1991,7 +1997,7 @@
 /// Decompose the type of a completion handler parameter in a function
 /// imported as 'async' and produce the result type of the 'async' function.
 static Type decomposeCompletionHandlerType(
-   Type paramTy, ForeignAsyncConvention info) {
+   Type paramTy, ForeignAsyncConvention::Info info) {
   auto fnType = paramTy->lookThroughAllOptionalTypes()->getAs<FunctionType>();
   if (!fnType)
     return Type();
@@ -2029,6 +2035,7 @@
     ArrayRef<const clang::ParmVarDecl *> params, bool isVariadic,
     bool isFromSystemModule, ParameterList **bodyParams,
     ImportedName importedName,
+    Optional<ForeignAsyncConvention> &asyncConvention,
     Optional<ForeignErrorConvention> &foreignErrorInfo,
     SpecialMethodKind kind) {
 
@@ -2123,6 +2130,7 @@
   swiftResultTy = mapGenericArgs(origDC, dc, swiftResultTy);
 
   CanType errorParamType;
+  CanType completionHandlerType;
 
   SmallBitVector nonNullArgs = getNonNullArgs(clangDecl, params);
 
@@ -2160,7 +2168,7 @@
     }
 
     bool paramIsCompletionHandler =
-        asyncInfo && paramIndex == asyncInfo->completionHandlerParamIndex();
+        asyncInfo && paramIndex == asyncInfo->CompletionHandlerParamIndex;
 
     // Import the parameter type into Swift.
 
@@ -2237,9 +2245,7 @@
       if (Type replacedSwiftResultTy =
               decomposeCompletionHandlerType(swiftParamTy, *asyncInfo)) {
         swiftResultTy = replacedSwiftResultTy;
-
-        // FIXME: We will need an equivalent to "error parameter is replaced"
-        // for asynchronous functions. Perhaps add "async: ()"?
+        completionHandlerType = swiftParamTy->getCanonicalType();
         continue;
       }
 
@@ -2334,6 +2340,12 @@
     swiftResultTy = SwiftContext.getNeverType();
   }
 
+  if (asyncInfo) {
+    asyncConvention = ForeignAsyncConvention(
+        completionHandlerType, asyncInfo->CompletionHandlerParamIndex,
+        asyncInfo->CompletionHandlerErrorParamIndex);
+  }
+
   if (errorInfo) {
     foreignErrorInfo = getForeignErrorInfo(*errorInfo, errorParamType,
                                            origSwiftResultTy);
diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h
index 977b2b2..8ee4000 100644
--- a/lib/ClangImporter/ImporterImpl.h
+++ b/lib/ClangImporter/ImporterImpl.h
@@ -313,7 +313,7 @@
   using Version = importer::ImportNameVersion;
 
 public:
-  Implementation(ASTContext &ctx, const ClangImporterOptions &opts,
+  Implementation(ASTContext &ctx,
                  DWARFImporterDelegate *dwarfImporterDelegate);
   ~Implementation();
 
@@ -393,8 +393,6 @@
   /// Clang arguments used to create the Clang invocation.
   std::vector<std::string> ClangArgs;
 
-  /// Extra clang args specified via "-Xcc"
-  std::vector<std::string> ExtraClangArgs;
 public:
   /// Mapping of already-imported declarations.
   llvm::DenseMap<std::pair<const clang::Decl *, Version>, Decl *> ImportedDecls;
@@ -1161,6 +1159,7 @@
                                   bool isFromSystemModule,
                                   ParameterList **bodyParams,
                                   importer::ImportedName importedName,
+                                  Optional<ForeignAsyncConvention> &asyncConv,
                                   Optional<ForeignErrorConvention> &errorConv,
                                   SpecialMethodKind kind);
 
@@ -1430,13 +1429,11 @@
 
 /// Add command-line arguments for a normal import of Clang code.
 void getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
-                                  ASTContext &ctx,
-                                  const ClangImporterOptions &importerOpts);
+                                  ASTContext &ctx);
 
 /// Add command-line arguments common to all imports of Clang code.
 void addCommonInvocationArguments(std::vector<std::string> &invocationArgStrs,
-                                  ASTContext &ctx,
-                                  const ClangImporterOptions &importerOpts);
+                                  ASTContext &ctx);
 
 /// Finds a particular kind of nominal by looking through typealiases.
 template <typename T>
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 8d94f5f..2f6fab9 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -2004,6 +2004,7 @@
       case file_types::TY_BitstreamOptRecord:
       case file_types::TY_SwiftModuleInterfaceFile:
       case file_types::TY_PrivateSwiftModuleInterfaceFile:
+      case file_types::TY_SwiftModuleSummaryFile:
       case file_types::TY_SwiftCrossImportDir:
       case file_types::TY_SwiftOverlayFile:
       case file_types::TY_JSONDependencies:
@@ -2216,6 +2217,7 @@
 #endif
 
   if (MergeModuleAction
+      && Args.hasArg(options::OPT_enable_library_evolution)
       && Args.hasFlag(options::OPT_verify_emitted_module_interface,
                       options::OPT_no_verify_emitted_module_interface,
                       verifyInterfacesByDefault)) {
@@ -2855,6 +2857,10 @@
                                       Output.get());
   }
 
+  if (isa<CompileJobAction>(JA)) {
+    chooseModuleSummaryPath(C, OutputMap, workingDirectory, Buf, Output.get());
+  }
+
   if (isa<MergeModuleJobAction>(JA) ||
       (isa<CompileJobAction>(JA) &&
        OI.CompilerMode == OutputInfo::Mode::SingleCompile)) {
@@ -3208,6 +3214,22 @@
   output->setAdditionalOutputForType(fileType, outputPath);
 }
 
+void Driver::chooseModuleSummaryPath(Compilation &C,
+                                     const TypeToPathMap *OutputMap,
+                                     StringRef workingDirectory,
+                                     llvm::SmallString<128> &Buf,
+                                     CommandOutput *Output) const {
+  StringRef pathFromArgs;
+  if (const Arg *A =
+          C.getArgs().getLastArg(options::OPT_emit_module_summary_path)) {
+    pathFromArgs = A->getValue();
+  }
+
+  addAuxiliaryOutput(C, *Output, file_types::TY_SwiftModuleSummaryFile,
+                     OutputMap, workingDirectory, pathFromArgs,
+                     /*requireArg=*/options::OPT_emit_module_summary);
+}
+
 void Driver::chooseSerializedDiagnosticsPath(Compilation &C,
                                              const JobAction *JA,
                                              const TypeToPathMap *OutputMap,
diff --git a/lib/Driver/FrontendUtil.cpp b/lib/Driver/FrontendUtil.cpp
index 7d796dd..75b95de 100644
--- a/lib/Driver/FrontendUtil.cpp
+++ b/lib/Driver/FrontendUtil.cpp
@@ -20,6 +20,7 @@
 #include "swift/Driver/ToolChain.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Host.h"
 #include "llvm/Support/StringSaver.h"
 
 using namespace swift;
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 7f669e5..0cdcd7a 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -259,8 +259,6 @@
   inputArgs.AddLastArg(arguments, options::OPT_debug_diagnostic_names);
   inputArgs.AddLastArg(arguments, options::OPT_print_educational_notes);
   inputArgs.AddLastArg(arguments, options::OPT_diagnostic_style);
-  inputArgs.AddLastArg(arguments, options::OPT_enable_astscope_lookup);
-  inputArgs.AddLastArg(arguments, options::OPT_disable_astscope_lookup);
   inputArgs.AddLastArg(arguments, options::OPT_disable_parser_lookup);
   inputArgs.AddLastArg(arguments,
                        options::OPT_enable_experimental_concise_pound_file);
@@ -620,6 +618,7 @@
   case file_types::TY_BitstreamOptRecord:
   case file_types::TY_SwiftModuleInterfaceFile:
   case file_types::TY_PrivateSwiftModuleInterfaceFile:
+  case file_types::TY_SwiftModuleSummaryFile:
   case file_types::TY_SwiftSourceInfoFile:
   case file_types::TY_SwiftCrossImportDir:
   case file_types::TY_SwiftOverlayFile:
@@ -765,6 +764,9 @@
                    "-emit-loaded-module-trace-path");
   addOutputsOfType(arguments, Output, Args, file_types::TY_TBD,
                    "-emit-tbd-path");
+  addOutputsOfType(arguments, Output, Args,
+                   file_types::TY_SwiftModuleSummaryFile,
+                   "-emit-module-summary-path");
 }
 
 ToolChain::InvocationInfo
@@ -877,6 +879,7 @@
     case file_types::TY_BitstreamOptRecord:
     case file_types::TY_SwiftModuleInterfaceFile:
     case file_types::TY_PrivateSwiftModuleInterfaceFile:
+    case file_types::TY_SwiftModuleSummaryFile:
     case file_types::TY_SwiftSourceInfoFile:
     case file_types::TY_SwiftCrossImportDir:
     case file_types::TY_SwiftOverlayFile:
diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp
index c876a44..7ab5017 100644
--- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp
+++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp
@@ -564,6 +564,11 @@
     Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_interface);
     return true;
   }
+  if (!FrontendOptions::canActionEmitModuleSummary(Opts.RequestedAction) &&
+      Opts.InputsAndOutputs.hasModuleSummaryOutputPath()) {
+    Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module_summary);
+    return true;
+  }
   return false;
 }
 
diff --git a/lib/Frontend/ArgsToFrontendOutputsConverter.cpp b/lib/Frontend/ArgsToFrontendOutputsConverter.cpp
index ef9f200..37b5afe 100644
--- a/lib/Frontend/ArgsToFrontendOutputsConverter.cpp
+++ b/lib/Frontend/ArgsToFrontendOutputsConverter.cpp
@@ -306,11 +306,13 @@
       options::OPT_emit_module_source_info_path);
   auto ldAddCFileOutput  = getSupplementaryFilenamesFromArguments(
       options::OPT_emit_ldadd_cfile_path);
+  auto moduleSummaryOutput = getSupplementaryFilenamesFromArguments(
+      options::OPT_emit_module_summary_path);
   if (!objCHeaderOutput || !moduleOutput || !moduleDocOutput ||
       !dependenciesFile || !referenceDependenciesFile ||
       !serializedDiagnostics || !fixItsOutput || !loadedModuleTrace || !TBD ||
       !moduleInterfaceOutput || !privateModuleInterfaceOutput ||
-      !moduleSourceInfoOutput || !ldAddCFileOutput) {
+      !moduleSourceInfoOutput || !ldAddCFileOutput || !moduleSummaryOutput) {
     return None;
   }
   std::vector<SupplementaryOutputPaths> result;
@@ -334,6 +336,7 @@
     sop.PrivateModuleInterfaceOutputPath = (*privateModuleInterfaceOutput)[i];
     sop.ModuleSourceInfoOutputPath = (*moduleSourceInfoOutput)[i];
     sop.LdAddCFilePath = (*ldAddCFileOutput)[i];
+    sop.ModuleSummaryOutputPath = (*moduleSummaryOutput)[i];
     result.push_back(sop);
   }
   return result;
@@ -422,6 +425,10 @@
       OPT_emit_module_source_info, pathsFromArguments.ModuleSourceInfoOutputPath,
       file_types::TY_SwiftSourceInfoFile, "",
       defaultSupplementaryOutputPathExcludingExtension);
+  auto moduleSummaryOutputPath = determineSupplementaryOutputFilename(
+      OPT_emit_module_summary, pathsFromArguments.ModuleSummaryOutputPath,
+      file_types::TY_SwiftModuleSummaryFile, "",
+      defaultSupplementaryOutputPathExcludingExtension);
 
   // There is no non-path form of -emit-interface-path
   auto ModuleInterfaceOutputPath =
@@ -456,6 +463,7 @@
   sop.PrivateModuleInterfaceOutputPath = PrivateModuleInterfaceOutputPath;
   sop.ModuleSourceInfoOutputPath = moduleSourceInfoOutputPath;
   sop.LdAddCFilePath = pathsFromArguments.LdAddCFilePath;
+  sop.ModuleSummaryOutputPath = moduleSummaryOutputPath;
   return sop;
 }
 
@@ -537,6 +545,7 @@
       {file_types::TY_TBD, paths.TBDPath},
       {file_types::TY_SwiftModuleInterfaceFile,
        paths.ModuleInterfaceOutputPath},
+      {file_types::TY_SwiftModuleSummaryFile, paths.ModuleSummaryOutputPath},
       {file_types::TY_PrivateSwiftModuleInterfaceFile,
        paths.PrivateModuleInterfaceOutputPath}};
   for (const std::pair<file_types::ID, std::string &> &typeAndString :
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 421fe05..eab504f 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -108,11 +108,11 @@
     llvm::sys::path::append(defaultPrebuiltPathWithSDKVer, ver->getAsString());
     // If the versioned prebuilt module cache exists in the disk, use it.
     if (llvm::sys::fs::exists(defaultPrebuiltPathWithSDKVer)) {
-      FrontendOpts.PrebuiltModuleCachePath = defaultPrebuiltPathWithSDKVer.str();
+      FrontendOpts.PrebuiltModuleCachePath = std::string(defaultPrebuiltPathWithSDKVer.str());
       return;
     }
   }
-  FrontendOpts.PrebuiltModuleCachePath = defaultPrebuiltPath.str();
+  FrontendOpts.PrebuiltModuleCachePath = std::string(defaultPrebuiltPath.str());
 }
 
 static void updateRuntimeLibraryPaths(SearchPathOptions &SearchPathOpts,
@@ -443,15 +443,7 @@
   }
   
   Opts.DisableParserLookup |= Args.hasArg(OPT_disable_parser_lookup);
-  Opts.EnableASTScopeLookup =
-      Args.hasFlag(options::OPT_enable_astscope_lookup,
-                   options::OPT_disable_astscope_lookup, Opts.EnableASTScopeLookup) ||
-      Opts.DisableParserLookup;
-  Opts.CrosscheckUnqualifiedLookup |=
-      Args.hasArg(OPT_crosscheck_unqualified_lookup);
   Opts.StressASTScopeLookup |= Args.hasArg(OPT_stress_astscope_lookup);
-  Opts.WarnIfASTScopeLookup |= Args.hasArg(OPT_warn_if_astscope_lookup);
-  Opts.LazyASTScopes |= Args.hasArg(OPT_lazy_astscopes);
   Opts.EnableNewOperatorLookup = Args.hasFlag(OPT_enable_new_operator_lookup,
                                               OPT_disable_new_operator_lookup,
                                               /*default*/ false);
@@ -1128,6 +1120,8 @@
     Opts.AssumeSingleThreaded = true;
   }
 
+  Opts.IgnoreAlwaysInline |= Args.hasArg(OPT_ignore_always_inline);
+
   // Parse the assert configuration identifier.
   if (const Arg *A = Args.getLastArg(OPT_AssertConfig)) {
     StringRef Configuration = A->getValue();
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index 688acbf..5efc9c5 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -204,7 +204,9 @@
 
   Context.reset(ASTContext::get(
       Invocation.getLangOptions(), Invocation.getTypeCheckerOptions(),
-      Invocation.getSearchPathOptions(), SourceMgr, Diagnostics));
+      Invocation.getSearchPathOptions(),
+      Invocation.getClangImporterOptions(),
+      SourceMgr, Diagnostics));
   registerParseRequestFunctions(Context->evaluator);
   registerTypeCheckerRequestFunctions(Context->evaluator);
   registerSILGenRequestFunctions(Context->evaluator);
@@ -481,8 +483,8 @@
   // Otherwise, we just keep it around as our interface to Clang's ABI
   // knowledge.
   std::unique_ptr<ClangImporter> clangImporter =
-    ClangImporter::create(*Context, Invocation.getClangImporterOptions(),
-                          Invocation.getPCHHash(), getDependencyTracker());
+    ClangImporter::create(*Context, Invocation.getPCHHash(),
+                          getDependencyTracker());
   if (!clangImporter) {
     Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
     return true;
@@ -536,8 +538,8 @@
     ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
     InterfaceSubContextDelegateImpl ASTDelegate(Context->SourceMgr, Context->Diags,
                                                 Context->SearchPathOpts, Context->LangOpts,
+                                                Context->ClangImporterOpts,
                                                 LoaderOpts,
-                                                Context->getClangModuleLoader(),
                                                 /*buildModuleCacheDirIfAbsent*/false,
                                                 ModuleCachePath,
                                                 FEOpts.PrebuiltModuleCachePath,
diff --git a/lib/Frontend/FrontendInputsAndOutputs.cpp b/lib/Frontend/FrontendInputsAndOutputs.cpp
index edb0bbd..52d1e82 100644
--- a/lib/Frontend/FrontendInputsAndOutputs.cpp
+++ b/lib/Frontend/FrontendInputsAndOutputs.cpp
@@ -466,6 +466,12 @@
         return outs.PrivateModuleInterfaceOutputPath;
       });
 }
+bool FrontendInputsAndOutputs::hasModuleSummaryOutputPath() const {
+  return hasSupplementaryOutputPath(
+      [](const SupplementaryOutputPaths &outs) -> const std::string & {
+        return outs.ModuleSummaryOutputPath;
+      });
+}
 bool FrontendInputsAndOutputs::hasTBDPath() const {
   return hasSupplementaryOutputPath(
       [](const SupplementaryOutputPaths &outs) -> const std::string & {
diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp
index 16fe187..20e0e84 100644
--- a/lib/Frontend/FrontendOptions.cpp
+++ b/lib/Frontend/FrontendOptions.cpp
@@ -358,6 +358,47 @@
   return canActionEmitReferenceDependencies(action);
 }
 
+bool FrontendOptions::canActionEmitModuleSummary(ActionType action) {
+  switch (action) {
+  case ActionType::NoneAction:
+  case ActionType::Parse:
+  case ActionType::ResolveImports:
+  case ActionType::DumpParse:
+  case ActionType::DumpInterfaceHash:
+  case ActionType::DumpAST:
+  case ActionType::EmitSyntax:
+  case ActionType::PrintAST:
+  case ActionType::EmitImportedModules:
+  case ActionType::EmitPCH:
+  case ActionType::DumpScopeMaps:
+  case ActionType::DumpTypeRefinementContexts:
+  case ActionType::DumpTypeInfo:
+  case ActionType::EmitSILGen:
+  case ActionType::EmitSIBGen:
+  case ActionType::CompileModuleFromInterface:
+  case ActionType::TypecheckModuleFromInterface:
+  case ActionType::Immediate:
+  case ActionType::REPL:
+  case ActionType::EmitPCM:
+  case ActionType::DumpPCM:
+  case ActionType::ScanDependencies:
+  case ActionType::ScanClangDependencies:
+  case ActionType::Typecheck:
+  case ActionType::MergeModules:
+  case ActionType::EmitModuleOnly:
+  case ActionType::PrintVersion:
+    return false;
+  case ActionType::EmitSIL:
+  case ActionType::EmitSIB:
+  case ActionType::EmitIR:
+  case ActionType::EmitBC:
+  case ActionType::EmitAssembly:
+  case ActionType::EmitObject:
+    return true;
+  }
+  llvm_unreachable("unhandled action");
+}
+
 bool FrontendOptions::canActionEmitObjCHeader(ActionType action) {
   switch (action) {
   case ActionType::NoneAction:
diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp
index 2029ff1..1f2df7b 100644
--- a/lib/Frontend/ModuleInterfaceLoader.cpp
+++ b/lib/Frontend/ModuleInterfaceLoader.cpp
@@ -286,10 +286,18 @@
   /// Emits a diagnostic for all out-of-date compiled or forwarding modules
   /// encountered while trying to load a module.
   void diagnose(ASTContext &ctx, SourceLoc loc, StringRef moduleName,
-                 StringRef interfacePath) {
+                 StringRef interfacePath, StringRef prebuiltCacheDir) {
     ctx.Diags.diagnose(loc, diag::rebuilding_module_from_interface,
                        moduleName, interfacePath);
-
+    auto SDKVer = getSDKBuildVersion(ctx.SearchPathOpts.SDKPath);
+    llvm::SmallString<64> buffer = prebuiltCacheDir;
+    llvm::sys::path::append(buffer, "SystemVersion.plist");
+    auto PBMVer = getSDKBuildVersionFromPlist(buffer.str());
+    if (!SDKVer.empty() && !PBMVer.empty()) {
+      // Remark the potential version difference.
+      ctx.Diags.diagnose(loc, diag::sdk_version_pbm_version, SDKVer,
+                         PBMVer);
+    }
     // We may have found multiple failing modules, that failed for different
     // reasons. Emit a note for each of them.
     for (auto &mod : outOfDateModules) {
@@ -624,7 +632,7 @@
 
     if (shouldLoadAdjacentModule) {
       if (fs.exists(modulePath)) {
-        result.first = modulePath;
+        result.first = modulePath.str();
       }
     }
 
@@ -641,7 +649,7 @@
       }
       if (path) {
         if (fs.exists(*path)) {
-          result.second = *path;
+          result.second = path->str();
         }
       }
     }
@@ -844,8 +852,8 @@
     }
     InterfaceSubContextDelegateImpl astDelegate(ctx.SourceMgr, ctx.Diags,
                                                 ctx.SearchPathOpts, ctx.LangOpts,
+                                                ctx.ClangImporterOpts,
                                                 Opts,
-                                                ctx.getClangModuleLoader(),
                                                 /*buildModuleCacheDirIfAbsent*/true,
                                                 cacheDir,
                                                 prebuiltCacheDir,
@@ -911,7 +919,7 @@
     // Diagnose that we didn't find a loadable module, if we were asked to.
     auto remarkRebuild = [&]() {
       rebuildInfo.diagnose(ctx, diagnosticLoc, moduleName,
-                           interfacePath);
+                           interfacePath, prebuiltCacheDir);
     };
     // If we found an out-of-date .swiftmodule, we still want to add it as
     // a dependency of the .swiftinterface. That way if it's updated, but
@@ -1084,20 +1092,12 @@
     bool SerializeDependencyHashes, bool TrackSystemDependencies,
     ModuleInterfaceLoaderOptions LoaderOpts) {
   InterfaceSubContextDelegateImpl astDelegate(SourceMgr, Diags,
-                                              SearchPathOpts, LangOpts,
+                                              SearchPathOpts, LangOpts, ClangOpts,
                                               LoaderOpts,
-                                              /*clangImporter*/nullptr,
                                               /*CreateCacheDirIfAbsent*/true,
                                               CacheDir, PrebuiltCacheDir,
                                               SerializeDependencyHashes,
                                               TrackSystemDependencies);
-  // At this point we don't have an ClangImporter instance because the instance
-  // is created later when we create a new ASTContext to build the interface.
-  // Thus, we have to add these extra clang flags manually here to ensure explict
-  // module building works.
-  for (auto &Arg: ClangOpts.ExtraArgs) {
-    astDelegate.addExtraClangArg(Arg);
-  }
   ModuleInterfaceBuilder builder(SourceMgr, Diags, astDelegate, InPath,
                                  ModuleName, CacheDir, PrebuiltCacheDir,
                                  LoaderOpts.disableInterfaceLock);
@@ -1205,7 +1205,7 @@
 
   if (CompRe.match(SB, &CompMatches)) {
     assert(CompMatches.size() == 2);
-    CompilerVersion = ArgSaver.save(CompMatches[1]);
+    CompilerVersion = ArgSaver.save(CompMatches[1]).str();
   }
   else {
     // Don't diagnose; handwritten module interfaces don't include this field.
@@ -1238,19 +1238,13 @@
   return false;
 }
 
-void InterfaceSubContextDelegateImpl::addExtraClangArg(StringRef arg) {
-  genericSubInvocation.getClangImporterOptions().ExtraArgs.push_back(arg);
-  GenericArgs.push_back("-Xcc");
-  GenericArgs.push_back(ArgSaver.save(arg));
-}
-
 InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
     SourceManager &SM,
     DiagnosticEngine &Diags,
     const SearchPathOptions &searchPathOpts,
     const LangOptions &langOpts,
+    const ClangImporterOptions &clangImporterOpts,
     ModuleInterfaceLoaderOptions LoaderOpts,
-    ClangModuleLoader *clangImporter,
     bool buildModuleCacheDirIfAbsent,
     StringRef moduleCachePath,
     StringRef prebuiltCachePath,
@@ -1287,23 +1281,22 @@
   // FIXME: we shouldn't need this. Remove it?
   StringRef explictSwiftModuleMap = searchPathOpts.ExplicitSwiftModuleMap;
   genericSubInvocation.getSearchPathOptions().ExplicitSwiftModuleMap =
-    explictSwiftModuleMap;
-  if (clangImporter) {
-    // We need to add these extra clang flags because explict module building
-    // related flags are all there: -fno-implicit-modules, -fmodule-map-file=,
-    // and -fmodule-file=.
-    // If we don't add these flags, the interface will be built with implicit
-    // PCMs.
-    for (auto arg: static_cast<ClangImporter*>(clangImporter)->getExtraClangArgs()) {
-      addExtraClangArg(arg);
-    }
-    // Respect the detailed-record preprocessor setting of the parent context.
-    // This, and the "raw" clang module format it implicitly enables, are
-    // required by sourcekitd.
-    auto &Opts = clangImporter->getClangInstance().getPreprocessorOpts();
-    if (Opts.DetailedRecord) {
-      genericSubInvocation.getClangImporterOptions().DetailedPreprocessingRecord = true;
-    }
+    explictSwiftModuleMap.str();
+  auto &subClangImporterOpts = genericSubInvocation.getClangImporterOptions();
+  // Respect the detailed-record preprocessor setting of the parent context.
+  // This, and the "raw" clang module format it implicitly enables, are
+  // required by sourcekitd.
+  subClangImporterOpts.DetailedPreprocessingRecord =
+    clangImporterOpts.DetailedPreprocessingRecord;
+  // We need to add these extra clang flags because explict module building
+  // related flags are all there: -fno-implicit-modules, -fmodule-map-file=,
+  // and -fmodule-file=.
+  // If we don't add these flags, the interface will be built with implicit
+  // PCMs.
+  subClangImporterOpts.ExtraArgs = clangImporterOpts.ExtraArgs;
+  for (auto arg: subClangImporterOpts.ExtraArgs) {
+    GenericArgs.push_back("-Xcc");
+    GenericArgs.push_back(ArgSaver.save(arg));
   }
 
   // Tell the genericSubInvocation to serialize dependency hashes if asked to do so.
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index f4b4201..ef0e5cb 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -68,6 +68,7 @@
 #include "swift/TBDGen/TBDGen.h"
 
 #include "clang/AST/ASTContext.h"
+#include "clang/Basic/Module.h"
 
 #include "llvm/ADT/Statistic.h"
 #include "llvm/IR/LLVMContext.h"
@@ -85,6 +86,7 @@
 #include "llvm/Support/YAMLTraits.h"
 #include "llvm/Target/TargetMachine.h"
 
+#include <algorithm>
 #include <memory>
 #include <unordered_set>
 #include <utility>
@@ -137,6 +139,24 @@
   return buffer.data();
 }
 
+/// This sorting function is used to stabilize the order in which dependencies
+/// are emitted into \c .d files that are consumed by external build systems.
+/// This serves to eliminate order as a source of non-determinism in these
+/// outputs.
+///
+/// The exact sorting predicate is not important. Currently, it is a
+/// lexicographic comparison that reverses the provided strings before applying
+/// the sorting predicate. This has the benefit of being somewhat
+/// invariant with respect to the installation location of various system
+/// components. e.g. on two systems, the same file identified by two different
+/// paths differing only in their relative install location such as
+///
+/// /Applications/MyXcode.app/Path/To/A/Framework/In/The/SDK/Header.h
+/// /Applications/Xcodes/AnotherXcode.app/Path/To/A/Framework/In/The/SDK/Header.h
+///
+/// should appear in roughly the same order relative to other paths. Ultimately,
+/// this makes it easier to test the contents of the emitted files with tools
+/// like FileCheck.
 static std::vector<std::string>
 reversePathSortedFilenames(const ArrayRef<std::string> elts) {
   std::vector<std::string> tmp(elts.begin(), elts.end());
@@ -179,14 +199,14 @@
     reversePathSortedFilenames(opts.InputsAndOutputs.getInputFilenames());
   for (auto const &path : inputPaths) {
     dependencyString.push_back(' ');
-    dependencyString.append(frontend::utils::escapeForMake(path, buffer));
+    dependencyString.append(frontend::utils::escapeForMake(path, buffer).str());
   }
   // Then print dependencies we've picked up during compilation.
   auto dependencyPaths =
     reversePathSortedFilenames(depTracker->getDependencies());
   for (auto const &path : dependencyPaths) {
     dependencyString.push_back(' ');
-    dependencyString.append(frontend::utils::escapeForMake(path, buffer));
+    dependencyString.append(frontend::utils::escapeForMake(path, buffer).str());
   }
   
   // FIXME: Xcode can't currently handle multiple targets in a single
@@ -351,22 +371,25 @@
 
   /// Check for cases where we have a fake cycle through an overlay.
   ///
-  /// \code
-  /// Actual stack:
-  ///    sandwichedModule -> Overlay (Swift) -> ... -> sandwichedModule
-  ///                     ^^--- wrong!
-  /// Ideal stack:
-  ///    sandwichedModule -> Underlying (Clang)
-  /// \endcode
+  /// Sometimes, we have fake cycles in the import graph due to the Clang
+  /// importer injecting overlays between Clang modules. These don't represent
+  /// an actual cycle in the build, so we should ignore them.
   ///
-  /// This happens when we have a dependency like:
-  /// \code
-  ///     Overlay (Swift) -> sandwichedModule -> Underlying (Clang)
-  /// \endcode
+  /// We check this lazily after detecting a cycle because it is difficult to
+  /// determine at the point where we see the overlay whether it was incorrectly
+  /// injected by the Clang importer or whether any of its imports will
+  /// eventually lead to a cycle.
   ///
-  /// We check this lazily because eagerly detecting if the dependency on an
-  /// overlay is correct or not is difficult.
-  bool isFakeCycleThroughOverlay(ModuleDecl **sandwichedModuleIter);
+  /// For more details, see [NOTE: ABIDependencyEvaluator-fake-cycle-detection]
+  ///
+  /// \param startOfCycle A pointer to the element of \c searchStack where
+  ///        the module \em first appeared.
+  ///
+  /// \pre The module on top of \c searchStack is the same module as
+  ///      *startOfCycle.
+  ///
+  /// \pre searchStack.begin() <= startOfCycle < searchStack.end()
+  bool isFakeCycleThroughOverlay(ModuleDecl **startOfCycle);
 
   /// Recursive step in computing ABI dependencies.
   ///
@@ -492,21 +515,87 @@
   return isOverlay;
 }
 
+// [NOTE: ABIDependencyEvaluator-fake-cycle-detection]
+//
+// First, let's consider a concrete example.
+// - In Clang-land, ToyKit #imports CoreDoll.
+// - The Swift overlay for CoreDoll imports both CoreDoll and ToyKit.
+// Importing ToyKit from CoreDoll's overlay informally violates the layering
+// of frameworks, but it doesn't actually create any cycles in the build
+// dependencies.
+//                        ┌───────────────────────────┐
+//                    ┌───│    CoreDoll.swiftmodule   │
+//                    │   └───────────────────────────┘
+//                    │                 │
+//              import ToyKit     @_exported import CoreDoll
+//                    │                 │
+//                    │                 │
+//                    ▼                 │
+//      ┌──────────────────────────┐    │
+//      │ ToyKit (ToyKit/ToyKit.h) │    │
+//      └──────────────────────────┘    │
+//                    │                 │
+//       #import <CoreDoll/CoreDoll.h>  │
+//                    │                 │
+//                    ▼                 │
+//   ┌──────────────────────────────┐   │
+//   │CoreDoll (CoreDoll/CoreDoll.h)│◀──┘
+//   └──────────────────────────────┘
+//
+// Say we are trying to build a Swift module that imports ToyKit. Due to how
+// module loading works, the Clang importer inserts the CoreDoll overlay
+// between the ToyKit and CoreDoll Clang modules, creating a cycle in the
+// import graph.
+//
+//   ┌──────────────────────────┐
+//   │ ToyKit (ToyKit/ToyKit.h) │◀──────────┐
+//   └──────────────────────────┘           │
+//                 │                        │
+//    #import <CoreDoll/CoreDoll.h>    import ToyKit
+//                 │                        │
+//                 ▼                        │
+//   ┌────────────────────────────┐         │
+//   │    CoreDoll.swiftmodule    │─────────┘
+//   └────────────────────────────┘
+//                 │
+//     @_exported import CoreDoll
+//                 │
+//                 ▼
+//   ┌──────────────────────────────┐
+//   │CoreDoll (CoreDoll/CoreDoll.h)│
+//   └──────────────────────────────┘
+//
+// This means that, at some point, searchStack will look like:
+//
+//   [others] → ToyKit → CoreDoll (overlay) → ToyKit
+//
+// In the general case, there may be arbitrarily many modules in the cycle,
+// including submodules.
+//
+//   [others] → ToyKit → [others] → CoreDoll (overlay) → [others] → ToyKit
+//
+// where "[others]" indicates 0 or more modules of any kind.
+//
+// To detect this, we check that the start of the cycle is a Clang module and
+// that there is at least one overlay between it and its recurrence at the end
+// of the searchStack. If so, we assume we have detected a benign cycle which
+// can be safely ignored.
+
 bool ABIDependencyEvaluator::isFakeCycleThroughOverlay(
-    ModuleDecl **sandwichModuleIter) {
-  assert(sandwichModuleIter >= searchStack.begin()
-         && sandwichModuleIter < searchStack.end()
-         && "sandwichModuleIter points to an element in searchStack");
-  // The sandwichedModule must be a Clang module.
-  if (!(*sandwichModuleIter)->isNonSwiftModule())
+    ModuleDecl **startOfCycle) {
+  assert(startOfCycle >= searchStack.begin() &&
+         startOfCycle < searchStack.end() &&
+         "startOfCycleIter points to an element in searchStack");
+  // The startOfCycle module must be a Clang module.
+  if (!(*startOfCycle)->isNonSwiftModule())
     return false;
-  auto nextModuleIter = sandwichModuleIter + 1;
-  if (nextModuleIter == searchStack.end())
-    return false;
-  // The next module must be a Swift overlay for a Clang module
-  if ((*nextModuleIter)->isNonSwiftModule())
-    return false;
-  return isOverlayOfClangModule(*nextModuleIter);
+  // Next, we must have zero or more modules followed by a Swift overlay for a
+  // Clang module.
+  return std::any_of(startOfCycle + 1, searchStack.end(),
+                     [this](ModuleDecl *module) {
+                       return !module->isNonSwiftModule() &&
+                              isOverlayOfClangModule(module);
+                     });
 }
 
 void ABIDependencyEvaluator::computeABIDependenciesForModule(
@@ -518,7 +607,11 @@
     crashOnInvariantViolation([&](llvm::raw_string_ostream &os) {
       os << "unexpected cycle in import graph!\n";
       for (auto m: searchStack) {
-        printModule(m, os); os << "\ndepends on ";
+        printModule(m, os);
+        if (!m->isNonSwiftModule()) {
+          os << " (isOverlay = " << isOverlayOfClangModule(m) << ")";
+        }
+        os << "\ndepends on ";
       }
       printModule(module, os); os << '\n';
     });
@@ -1523,7 +1616,7 @@
         llvm::SmallString<32> Buffer(*opts.BridgingHeaderDirForPrint);
         llvm::sys::path::append(Buffer,
           llvm::sys::path::filename(opts.ImplicitObjCHeaderPath));
-        BridgingHeaderPathForPrint = Buffer.str();
+        BridgingHeaderPathForPrint = (std::string)Buffer;
       } else {
         // By default, include the given bridging header path directly.
         BridgingHeaderPathForPrint = opts.ImplicitObjCHeaderPath;
@@ -1943,6 +2036,17 @@
   return Context.hadError();
 }
 
+static bool serializeModuleSummary(SILModule *SM,
+                                   const PrimarySpecificPaths &PSPs,
+                                   const ASTContext &Context) {
+  auto summaryOutputPath = PSPs.SupplementaryOutputs.ModuleSummaryOutputPath;
+  return withOutputFile(Context.Diags, summaryOutputPath,
+                        [&](llvm::raw_ostream &out) {
+                          out << "Some stuff";
+                          return false;
+                        });
+}
+
 static GeneratedModule
 generateIR(const IRGenOptions &IRGenOpts, const TBDGenOptions &TBDOpts,
            std::unique_ptr<SILModule> SM,
@@ -2167,6 +2271,12 @@
   if (observer)
     observer->performedSILProcessing(*SM);
 
+  if (PSPs.haveModuleSummaryOutputPath()) {
+    if (serializeModuleSummary(SM.get(), PSPs, Context)) {
+      return true;
+    }
+  }
+
   if (Action == FrontendOptions::ActionType::EmitSIB)
     return serializeSIB(SM.get(), PSPs, Context, MSF);
 
diff --git a/lib/FrontendTool/ScanDependencies.cpp b/lib/FrontendTool/ScanDependencies.cpp
index 34e9939..4adb17d 100644
--- a/lib/FrontendTool/ScanDependencies.cpp
+++ b/lib/FrontendTool/ScanDependencies.cpp
@@ -263,7 +263,7 @@
     dummyMainDependencies.addModuleDependency(modName.str());
     mainDep.addModuleDependency(modName.str());
   });
-  cache.updateDependencies({mainModuleName, ModuleDependenciesKind::Swift}, mainDep);
+  cache.updateDependencies({mainModuleName.str(), ModuleDependenciesKind::Swift}, mainDep);
 
   // Record the dummy main module's direct dependencies. The dummy main module
   // only directly depend on these newly discovered overlay modules.
@@ -641,8 +641,8 @@
   ModuleDependenciesCache cache;
   InterfaceSubContextDelegateImpl ASTDelegate(ctx.SourceMgr, ctx.Diags,
                                               ctx.SearchPathOpts, ctx.LangOpts,
+                                              ctx.ClangImporterOpts,
                                               LoaderOpts,
-                                              ctx.getClangModuleLoader(),
                                               /*buildModuleCacheDirIfAbsent*/false,
                                               ModuleCachePath,
                                               FEOpts.PrebuiltModuleCachePath,
@@ -839,8 +839,8 @@
   ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
   InterfaceSubContextDelegateImpl ASTDelegate(ctx.SourceMgr, ctx.Diags,
                                               ctx.SearchPathOpts, ctx.LangOpts,
+                                              ctx.ClangImporterOpts,
                                               LoaderOpts,
-                                              ctx.getClangModuleLoader(),
                                               /*buildModuleCacheDirIfAbsent*/false,
                                               ModuleCachePath,
                                               FEOpts.PrebuiltModuleCachePath,
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index bd5c98c..d3b9362 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -35,6 +35,7 @@
 #include "swift/IDE/Utils.h"
 #include "swift/Parse/CodeCompletionCallbacks.h"
 #include "swift/Sema/IDETypeChecking.h"
+#include "swift/Sema/CodeCompletionTypeChecking.h"
 #include "swift/Syntax/SyntaxKind.h"
 #include "swift/Strings.h"
 #include "swift/Subsystems.h"
@@ -341,6 +342,21 @@
   return CleanFile;
 }
 
+llvm::StringRef swift::ide::copyString(llvm::BumpPtrAllocator &Allocator,
+                                       llvm::StringRef Str) {
+  char *Buffer = Allocator.Allocate<char>(Str.size());
+  std::copy(Str.begin(), Str.end(), Buffer);
+  return llvm::StringRef(Buffer, Str.size());
+}
+
+const char *swift::ide::copyCString(llvm::BumpPtrAllocator &Allocator,
+                                    llvm::StringRef Str) {
+  char *Buffer = Allocator.Allocate<char>(Str.size() + 1);
+  std::copy(Str.begin(), Str.end(), Buffer);
+  Buffer[Str.size()] = '\0';
+  return Buffer;
+}
+
 CodeCompletionString::CodeCompletionString(ArrayRef<Chunk> Chunks) {
   std::uninitialized_copy(Chunks.begin(), Chunks.end(),
                           getTrailingObjects<Chunk>());
@@ -769,29 +785,6 @@
   llvm::errs() << "\n";
 }
 
-static StringRef copyString(llvm::BumpPtrAllocator &Allocator,
-                            StringRef Str) {
-  char *Mem = Allocator.Allocate<char>(Str.size());
-  std::copy(Str.begin(), Str.end(), Mem);
-  return StringRef(Mem, Str.size());
-}
-
-static ArrayRef<StringRef> copyStringArray(llvm::BumpPtrAllocator &Allocator,
-                                           ArrayRef<StringRef> Arr) {
-  StringRef *Buff = Allocator.Allocate<StringRef>(Arr.size());
-  std::copy(Arr.begin(), Arr.end(), Buff);
-  return llvm::makeArrayRef(Buff, Arr.size());
-}
-
-static ArrayRef<std::pair<StringRef, StringRef>> copyStringPairArray(
-    llvm::BumpPtrAllocator &Allocator,
-    ArrayRef<std::pair<StringRef, StringRef>> Arr) {
-  std::pair<StringRef, StringRef> *Buff = Allocator.Allocate<std::pair<StringRef,
-    StringRef>>(Arr.size());
-  std::copy(Arr.begin(), Arr.end(), Buff);
-  return llvm::makeArrayRef(Buff, Arr.size());
-}
-
 void CodeCompletionResultBuilder::withNestedGroup(
     CodeCompletionString::Chunk::ChunkKind Kind,
     llvm::function_ref<void()> body) {
@@ -1125,7 +1118,7 @@
   });
 
   if (!USRs.empty())
-    return copyStringArray(Allocator, USRs);
+    return copyArray(Allocator, ArrayRef<StringRef>(USRs));
 
   return ArrayRef<StringRef>();
 }
@@ -1162,7 +1155,7 @@
 static CodeCompletionResult::ExpectedTypeRelation
 calculateTypeRelationForDecl(const Decl *D, Type ExpectedType,
                              bool IsImplicitlyCurriedInstanceMethod,
-                             bool UseFuncResultType = true) {
+                             bool UseFuncResultType){
   auto VD = dyn_cast<ValueDecl>(D);
   auto DC = D->getDeclContext();
   if (!VD)
@@ -1197,9 +1190,9 @@
 }
 
 static CodeCompletionResult::ExpectedTypeRelation
-calculateMaxTypeRelationForDecl(
-    const Decl *D, const ExpectedTypeContext &typeContext,
-    bool IsImplicitlyCurriedInstanceMethod = false) {
+calculateMaxTypeRelationForDecl(const Decl *D,
+                                const ExpectedTypeContext &typeContext,
+                                bool IsImplicitlyCurriedInstanceMethod) {
   if (typeContext.empty())
     return CodeCompletionResult::ExpectedTypeRelation::Unknown;
 
@@ -1218,7 +1211,8 @@
       continue;
 
     Result = std::max(Result, calculateTypeRelationForDecl(
-                                  D, Type, IsImplicitlyCurriedInstanceMethod));
+                                  D, Type, IsImplicitlyCurriedInstanceMethod,
+                                  /*UseFuncResultTy*/true));
 
     // Map invalid -> unrelated when in a single-expression body, since the
     // input may be incomplete.
@@ -1334,16 +1328,19 @@
     }
 
     auto typeRelation = ExpectedTypeRelation;
+    // FIXME: we don't actually have enough info to compute
+    // IsImplicitlyCurriedInstanceMethod here.
     if (typeRelation == CodeCompletionResult::Unknown)
       typeRelation =
-          calculateMaxTypeRelationForDecl(AssociatedDecl, declTypeContext);
+          calculateMaxTypeRelationForDecl(AssociatedDecl, declTypeContext,
+                                          /*IsImplicitlyCurriedMethod*/false);
 
     return new (*Sink.Allocator) CodeCompletionResult(
         SemanticContext, NumBytesToErase, CCS, AssociatedDecl, ModuleName,
         /*NotRecommended=*/IsNotRecommended, NotRecReason,
         copyString(*Sink.Allocator, BriefComment),
         copyAssociatedUSRs(*Sink.Allocator, AssociatedDecl),
-        copyStringPairArray(*Sink.Allocator, CommentWords), typeRelation);
+        copyArray(*Sink.Allocator, CommentWords), typeRelation);
   }
 
   case CodeCompletionResult::ResultKind::Keyword:
@@ -1526,9 +1523,9 @@
 }
 
 namespace {
+
 class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
   CodeCompletionContext &CompletionContext;
-  std::vector<RequestedCachedModule> RequestedModules;
   CodeCompletionConsumer &Consumer;
   CodeCompletionExpr *CodeCompleteTokenExpr = nullptr;
   CompletionKind Kind = CompletionKind::None;
@@ -1660,7 +1657,7 @@
       AttTargetDK = DK;
   }
 
-  void completeDotExpr(Expr *E, SourceLoc DotLoc) override;
+  void completeDotExpr(CodeCompletionExpr *E, SourceLoc DotLoc) override;
   void completeStmtOrExpr(CodeCompletionExpr *E) override;
   void completePostfixExprBeginning(CodeCompletionExpr *E) override;
   void completeForEachSequenceBeginning(CodeCompletionExpr *E) override;
@@ -1709,7 +1706,7 @@
 
 private:
   void addKeywords(CodeCompletionResultSink &Sink, bool MaybeFuncBody);
-  void deliverCompletionResults();
+  bool trySolverCompletion();
 };
 } // end anonymous namespace
 
@@ -2009,8 +2006,10 @@
     IsStaticMetatype = value;
   }
 
-  void setExpectedTypes(ArrayRef<Type> Types, bool isSingleExpressionBody) {
+  void setExpectedTypes(ArrayRef<Type> Types, bool isSingleExpressionBody,
+                        bool preferNonVoid = false) {
     expectedTypeContext.isSingleExpressionBody = isSingleExpressionBody;
+    expectedTypeContext.preferNonVoid = preferNonVoid;
     expectedTypeContext.possibleTypes.clear();
     expectedTypeContext.possibleTypes.reserve(Types.size());
     for (auto T : Types)
@@ -2023,7 +2022,7 @@
   }
 
   CodeCompletionContext::TypeContextKind typeContextKind() const {
-    if (expectedTypeContext.empty()) {
+    if (expectedTypeContext.empty() && !expectedTypeContext.preferNonVoid) {
       return CodeCompletionContext::TypeContextKind::None;
     } else if (expectedTypeContext.isSingleExpressionBody) {
       return CodeCompletionContext::TypeContextKind::SingleExpressionBody;
@@ -2040,8 +2039,8 @@
     HaveLParen = Value;
   }
 
-  void setIsSuperRefExpr() {
-    IsSuperRefExpr = true;
+  void setIsSuperRefExpr(bool Value = true) {
+    IsSuperRefExpr = Value;
   }
 
   void setIsSelfRefExpr(bool value) { IsSelfRefExpr = value; }
@@ -3041,6 +3040,12 @@
 
       if (isUnresolvedMemberIdealType(ResultType))
         Builder.setSemanticContext(SemanticContextKind::ExpressionSpecific);
+
+      if (!IsImplicitlyCurriedInstanceMethod &&
+          expectedTypeContext.requiresNonVoid() &&
+          ResultType->isVoid()) {
+        Builder.setExpectedTypeRelation(CodeCompletionResult::Invalid);
+      }
     };
 
     if (!AFT || IsImplicitlyCurriedInstanceMethod) {
@@ -3725,8 +3730,12 @@
       llvm::SaveAndRestore<bool> ChangeNeedOptionalUnwrap(NeedOptionalUnwrap,
                                                           true);
       if (DotLoc.isValid()) {
+        // Let's not erase the dot if the completion is after a swift key path
+        // root because \A?.?.member is the correct way to access wrapped type
+        // member from an optional key path root.
+        auto loc = IsAfterSwiftKeyPathRoot ? DotLoc.getAdvancedLoc(1) : DotLoc;
         NumBytesToEraseForOptionalUnwrap = Ctx.SourceMgr.getByteDistance(
-            DotLoc, Ctx.SourceMgr.getCodeCompletionLoc());
+            loc, Ctx.SourceMgr.getCodeCompletionLoc());
       } else {
         NumBytesToEraseForOptionalUnwrap = 0;
       }
@@ -5153,7 +5162,8 @@
   addKeyword("setter", CodeCompletionKeywordKind::None);
 }
 
-void CodeCompletionCallbacksImpl::completeDotExpr(Expr *E, SourceLoc DotLoc) {
+void CodeCompletionCallbacksImpl::completeDotExpr(CodeCompletionExpr *E,
+                                                  SourceLoc DotLoc) {
   assert(P.Tok.is(tok::code_complete));
 
   // Don't produce any results in an enum element.
@@ -5166,9 +5176,10 @@
     CompleteExprSelectorContext = ParseExprSelectorContext;
   }
 
-  ParsedExpr = E;
+  ParsedExpr = E->getBase();
   this->DotLoc = DotLoc;
   CurDeclContext = P.CurDeclContext;
+  CodeCompleteTokenExpr = E;
 }
 
 void CodeCompletionCallbacksImpl::completeStmtOrExpr(CodeCompletionExpr *E) {
@@ -5795,9 +5806,209 @@
   }
 }
 
+static void deliverCompletionResults(CodeCompletionContext &CompletionContext,
+                                     CompletionLookup &Lookup,
+                                     SourceFile &SF,
+                                     CodeCompletionConsumer &Consumer) {
+  llvm::SmallPtrSet<Identifier, 8> seenModuleNames;
+  std::vector<RequestedCachedModule> RequestedModules;
+
+  for (auto &Request: Lookup.RequestedCachedResults) {
+    llvm::DenseSet<CodeCompletionCache::Key> ImportsSeen;
+    auto handleImport = [&](ModuleDecl::ImportedModule Import) {
+      ModuleDecl *TheModule = Import.importedModule;
+      ModuleDecl::AccessPathTy Path = Import.accessPath;
+      if (TheModule->getFiles().empty())
+        return;
+
+      // Clang submodules are ignored and there's no lookup cost involved,
+      // so just ignore them and don't put the empty results in the cache
+      // because putting a lot of objects in the cache will push out
+      // other lookups.
+      if (isClangSubModule(TheModule))
+        return;
+
+      std::vector<std::string> AccessPath;
+      for (auto Piece : Path) {
+        AccessPath.push_back(std::string(Piece.Item));
+      }
+
+      StringRef ModuleFilename = TheModule->getModuleFilename();
+      // ModuleFilename can be empty if something strange happened during
+      // module loading, for example, the module file is corrupted.
+      if (!ModuleFilename.empty()) {
+        auto &Ctx = TheModule->getASTContext();
+        CodeCompletionCache::Key K{
+            ModuleFilename.str(),
+            std::string(TheModule->getName()),
+            AccessPath,
+            Request.NeedLeadingDot,
+            SF.hasTestableOrPrivateImport(
+                AccessLevel::Internal, TheModule,
+                SourceFile::ImportQueryKind::TestableOnly),
+            SF.hasTestableOrPrivateImport(
+                AccessLevel::Internal, TheModule,
+                SourceFile::ImportQueryKind::PrivateOnly),
+            Ctx.LangOpts.CodeCompleteInitsInPostfixExpr,
+            CompletionContext.getAnnotateResult(),
+        };
+
+        using PairType = llvm::DenseSet<swift::ide::CodeCompletionCache::Key,
+            llvm::DenseMapInfo<CodeCompletionCache::Key>>::iterator;
+        std::pair<PairType, bool> Result = ImportsSeen.insert(K);
+        if (!Result.second)
+          return; // already handled.
+        RequestedModules.push_back({std::move(K), TheModule,
+          Request.OnlyTypes, Request.OnlyPrecedenceGroups});
+
+        if (Request.IncludeModuleQualifier &&
+            seenModuleNames.insert(TheModule->getName()).second)
+          Lookup.addModuleName(TheModule);
+      }
+    };
+
+    if (Request.TheModule) {
+      // FIXME: actually check imports.
+      for (auto Import : namelookup::getAllImports(Request.TheModule)) {
+        handleImport(Import);
+      }
+    } else {
+      // Add results from current module.
+      Lookup.getToplevelCompletions(Request.OnlyTypes);
+
+      // Add the qualifying module name
+      auto curModule = SF.getParentModule();
+      if (Request.IncludeModuleQualifier &&
+          seenModuleNames.insert(curModule->getName()).second)
+        Lookup.addModuleName(curModule);
+
+      // Add results for all imported modules.
+      SmallVector<ModuleDecl::ImportedModule, 4> Imports;
+      SF.getImportedModules(
+          Imports, {ModuleDecl::ImportFilterKind::Public,
+                    ModuleDecl::ImportFilterKind::Private,
+                    ModuleDecl::ImportFilterKind::ImplementationOnly});
+
+      for (auto Imported : Imports) {
+        for (auto Import : namelookup::getAllImports(Imported.importedModule))
+          handleImport(Import);
+      }
+    }
+  }
+  Lookup.RequestedCachedResults.clear();
+  CompletionContext.typeContextKind = Lookup.typeContextKind();
+
+  // Use the current SourceFile as the DeclContext so that we can use it to
+  // perform qualified lookup, and to get the correct visibility for
+  // @testable imports.
+  DeclContext *DCForModules = &SF;
+  Consumer.handleResultsAndModules(CompletionContext, RequestedModules,
+                                   DCForModules);
+}
+
+void deliverDotExprResults(
+    ArrayRef<DotExprTypeCheckCompletionCallback::Result> Results,
+    Expr *BaseExpr, DeclContext *DC, SourceLoc DotLoc, bool IsInSelector,
+    ide::CodeCompletionContext &CompletionCtx,
+    CodeCompletionConsumer &Consumer) {
+  ASTContext &Ctx = DC->getASTContext();
+  CompletionLookup Lookup(CompletionCtx.getResultSink(), Ctx, DC,
+                          &CompletionCtx);
+
+  if (DotLoc.isValid())
+    Lookup.setHaveDot(DotLoc);
+
+  Lookup.setIsSuperRefExpr(isa<SuperRefExpr>(BaseExpr));
+
+  if (auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
+    Lookup.setIsSelfRefExpr(DRE->getDecl()->getName() == Ctx.Id_self);
+
+  if (isa<BindOptionalExpr>(BaseExpr) || isa<ForceValueExpr>(BaseExpr))
+    Lookup.setIsUnwrappedOptional(true);
+
+  if (IsInSelector) {
+    Lookup.includeInstanceMembers();
+    Lookup.setPreferFunctionReferencesToCalls();
+  }
+
+  for (auto &Result: Results) {
+    Lookup.setIsStaticMetatype(Result.BaseIsStaticMetaType);
+    Lookup.getPostfixKeywordCompletions(Result.BaseTy, BaseExpr);
+    Lookup.setExpectedTypes(Result.ExpectedTypes,
+                            Result.IsSingleExpressionBody,
+                            Result.ExpectsNonVoid);
+    if (isDynamicLookup(Result.BaseTy))
+      Lookup.setIsDynamicLookup();
+    Lookup.getValueExprCompletions(Result.BaseTy, Result.BaseDecl);
+  }
+
+  SourceFile *SF = DC->getParentSourceFile();
+  deliverCompletionResults(CompletionCtx, Lookup, *SF, Consumer);
+}
+
+bool CodeCompletionCallbacksImpl::trySolverCompletion() {
+  CompletionContext.CodeCompletionKind = Kind;
+
+  if (Kind == CompletionKind::None)
+    return true;
+
+  bool MaybeFuncBody = true;
+  if (CurDeclContext) {
+    auto *CD = CurDeclContext->getLocalContext();
+    if (!CD || CD->getContextKind() == DeclContextKind::Initializer ||
+        CD->getContextKind() == DeclContextKind::TopLevelCodeDecl)
+      MaybeFuncBody = false;
+  }
+
+  if (auto *DC = dyn_cast_or_null<DeclContext>(ParsedDecl)) {
+    if (DC->isChildContextOf(CurDeclContext))
+      CurDeclContext = DC;
+  }
+
+  assert(ParsedExpr || CurDeclContext);
+
+  SourceLoc CompletionLoc = ParsedExpr
+    ? ParsedExpr->getLoc()
+    : CurDeclContext->getASTContext().SourceMgr.getCodeCompletionLoc();
+
+  switch (Kind) {
+  case CompletionKind::DotExpr: {
+    assert(CodeCompleteTokenExpr);
+    assert(CurDeclContext);
+
+    DotExprTypeCheckCompletionCallback Lookup(CurDeclContext,
+                                              CodeCompleteTokenExpr);
+    llvm::SaveAndRestore<TypeCheckCompletionCallback*>
+      CompletionCollector(Context.CompletionCallback, &Lookup);
+    typeCheckContextAt(CurDeclContext, CompletionLoc);
+
+    // This (hopefully) only happens in cases where the expression isn't
+    // typechecked during normal compilation either (e.g. member completion in a
+    // switch case where there control expression is invalid). Having normal
+    // typechecking still resolve even these cases would be beneficial for
+    // tooling in general though.
+    if (!Lookup.gotCallback())
+      Lookup.fallbackTypeCheck();
+
+    addKeywords(CompletionContext.getResultSink(), MaybeFuncBody);
+
+    Expr *CheckedBase = CodeCompleteTokenExpr->getBase();
+    deliverDotExprResults(Lookup.getResults(), CheckedBase, CurDeclContext,
+                          DotLoc, isInsideObjCSelector(), CompletionContext,
+                          Consumer);
+    return true;
+  }
+  default:
+    return false;
+  }
+}
+
 void CodeCompletionCallbacksImpl::doneParsing() {
   CompletionContext.CodeCompletionKind = Kind;
 
+  if (trySolverCompletion())
+    return;
+
   if (Kind == CompletionKind::None) {
     return;
   }
@@ -5871,27 +6082,10 @@
 
   switch (Kind) {
   case CompletionKind::None:
+  case CompletionKind::DotExpr:
     llvm_unreachable("should be already handled");
     return;
 
-  case CompletionKind::DotExpr: {
-    Lookup.setHaveDot(DotLoc);
-
-    if (isDynamicLookup(*ExprType))
-      Lookup.setIsDynamicLookup();
-
-    Lookup.getPostfixKeywordCompletions(*ExprType, ParsedExpr);
-
-    if (isa<BindOptionalExpr>(ParsedExpr) || isa<ForceValueExpr>(ParsedExpr))
-      Lookup.setIsUnwrappedOptional(true);
-
-    ExprContextInfo ContextInfo(CurDeclContext, ParsedExpr);
-    Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
-                            ContextInfo.isSingleExpressionBody());
-    Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
-    break;
-  }
-
   case CompletionKind::KeyPathExprSwift: {
     auto KPE = dyn_cast<KeyPathExpr>(ParsedExpr);
     auto BGT = (*ExprType)->getAs<BoundGenericType>();
@@ -5934,7 +6128,7 @@
     if (!OnRoot && KPE->getComponents().back().getKind() ==
                        KeyPathExpr::Component::Kind::OptionalWrap) {
       // KeyPath expr with '?' (e.g. '\Ty.[0].prop?.another').
-      // Althogh expected type is optional, we should unwrap it because it's
+      // Although expected type is optional, we should unwrap it because it's
       // unwrapped.
       baseType = baseType->getOptionalObjectType();
     }
@@ -6068,7 +6262,7 @@
 
     // TypeName at attribute position after '@'.
     // - VarDecl: Property Wrappers.
-    // - ParamDecl/VarDecl/FuncDecl: Function Buildres.
+    // - ParamDecl/VarDecl/FuncDecl: Function Builders.
     if (!AttTargetDK || *AttTargetDK == DeclKind::Var ||
         *AttTargetDK == DeclKind::Param || *AttTargetDK == DeclKind::Func)
       Lookup.getTypeCompletionsInDeclContext(
@@ -6319,112 +6513,7 @@
     break;
   }
 
-  llvm::SmallPtrSet<Identifier, 8> seenModuleNames;
-
-  for (auto &Request: Lookup.RequestedCachedResults) {
-    // Use the current SourceFile as the DeclContext so that we can use it to
-    // perform qualified lookup, and to get the correct visibility for
-    // @testable imports.
-    const SourceFile &SF = P.SF;
-
-    llvm::DenseSet<CodeCompletionCache::Key> ImportsSeen;
-    auto handleImport = [&](ModuleDecl::ImportedModule Import) {
-      ModuleDecl *TheModule = Import.importedModule;
-      ModuleDecl::AccessPathTy Path = Import.accessPath;
-      if (TheModule->getFiles().empty())
-        return;
-
-      // Clang submodules are ignored and there's no lookup cost involved,
-      // so just ignore them and don't put the empty results in the cache
-      // because putting a lot of objects in the cache will push out
-      // other lookups.
-      if (isClangSubModule(TheModule))
-        return;
-
-      std::vector<std::string> AccessPath;
-      for (auto Piece : Path) {
-        AccessPath.push_back(std::string(Piece.Item));
-      }
-
-      StringRef ModuleFilename = TheModule->getModuleFilename();
-      // ModuleFilename can be empty if something strange happened during
-      // module loading, for example, the module file is corrupted.
-      if (!ModuleFilename.empty()) {
-        auto &Ctx = TheModule->getASTContext();
-        CodeCompletionCache::Key K{
-            ModuleFilename.str(),
-            std::string(TheModule->getName()),
-            AccessPath,
-            Request.NeedLeadingDot,
-            SF.hasTestableOrPrivateImport(
-                AccessLevel::Internal, TheModule,
-                SourceFile::ImportQueryKind::TestableOnly),
-            SF.hasTestableOrPrivateImport(
-                AccessLevel::Internal, TheModule,
-                SourceFile::ImportQueryKind::PrivateOnly),
-            Ctx.LangOpts.CodeCompleteInitsInPostfixExpr,
-            CompletionContext.getAnnotateResult(),
-        };
-
-        using PairType = llvm::DenseSet<swift::ide::CodeCompletionCache::Key,
-            llvm::DenseMapInfo<CodeCompletionCache::Key>>::iterator;
-        std::pair<PairType, bool> Result = ImportsSeen.insert(K);
-        if (!Result.second)
-          return; // already handled.
-        RequestedModules.push_back({std::move(K), TheModule,
-          Request.OnlyTypes, Request.OnlyPrecedenceGroups});
-
-        if (Request.IncludeModuleQualifier &&
-            seenModuleNames.insert(TheModule->getName()).second)
-          Lookup.addModuleName(TheModule);
-      }
-    };
-
-    if (Request.TheModule) {
-      // FIXME: actually check imports.
-      for (auto Import : namelookup::getAllImports(Request.TheModule)) {
-        handleImport(Import);
-      }
-    } else {
-      // Add results from current module.
-      Lookup.getToplevelCompletions(Request.OnlyTypes);
-
-      // Add the qualifying module name
-      auto curModule = CurDeclContext->getParentModule();
-      if (Request.IncludeModuleQualifier &&
-          seenModuleNames.insert(curModule->getName()).second)
-        Lookup.addModuleName(curModule);
-
-      // Add results for all imported modules.
-      SmallVector<ModuleDecl::ImportedModule, 4> Imports;
-      auto *SF = CurDeclContext->getParentSourceFile();
-      SF->getImportedModules(
-          Imports, {ModuleDecl::ImportFilterKind::Public,
-                    ModuleDecl::ImportFilterKind::Private,
-                    ModuleDecl::ImportFilterKind::ImplementationOnly});
-
-      for (auto Imported : Imports) {
-        for (auto Import : namelookup::getAllImports(Imported.importedModule))
-          handleImport(Import);
-      }
-    }
-  }
-  Lookup.RequestedCachedResults.clear();
-
-  CompletionContext.typeContextKind = Lookup.typeContextKind();
-
-  deliverCompletionResults();
-}
-
-void CodeCompletionCallbacksImpl::deliverCompletionResults() {
-  // Use the current SourceFile as the DeclContext so that we can use it to
-  // perform qualified lookup, and to get the correct visibility for
-  // @testable imports.
-  DeclContext *DCForModules = &P.SF;
-
-  Consumer.handleResultsAndModules(CompletionContext, RequestedModules,
-                                   DCForModules);
-  RequestedModules.clear();
+  deliverCompletionResults(CompletionContext, Lookup, P.SF, Consumer);
 }
 
 void PrintingCodeCompletionConsumer::handleResults(
diff --git a/lib/IDE/CodeCompletionCache.cpp b/lib/IDE/CodeCompletionCache.cpp
index 21a3d7a..ede2b04 100644
--- a/lib/IDE/CodeCompletionCache.cpp
+++ b/lib/IDE/CodeCompletionCache.cpp
@@ -102,28 +102,6 @@
 /// cached results. This isn't expected to change very often.
 static constexpr uint32_t onDiskCompletionCacheVersion = 1;
 
-static StringRef copyString(llvm::BumpPtrAllocator &Allocator, StringRef Str) {
-  char *Mem = Allocator.Allocate<char>(Str.size());
-  std::copy(Str.begin(), Str.end(), Mem);
-  return StringRef(Mem, Str.size());
-}
-
-static ArrayRef<StringRef> copyStringArray(llvm::BumpPtrAllocator &Allocator,
-                                           ArrayRef<StringRef> Arr) {
-  StringRef *Buff = Allocator.Allocate<StringRef>(Arr.size());
-  std::copy(Arr.begin(), Arr.end(), Buff);
-  return llvm::makeArrayRef(Buff, Arr.size());
-}
-
-static ArrayRef<std::pair<StringRef, StringRef>> copyStringPairArray(
-    llvm::BumpPtrAllocator &Allocator,
-    ArrayRef<std::pair<StringRef, StringRef>> Arr) {
-  std::pair<StringRef, StringRef> *Buff = Allocator.Allocate<std::pair<StringRef,
-    StringRef>>(Arr.size());
-  std::copy(Arr.begin(), Arr.end(), Buff);
-  return llvm::makeArrayRef(Buff, Arr.size());
-}
-
 /// Deserializes CodeCompletionResults from \p in and stores them in \p V.
 /// \see writeCacheModule.
 static bool readCachedModule(llvm::MemoryBuffer *in,
@@ -251,8 +229,8 @@
       result = new (*V.Sink.Allocator) CodeCompletionResult(
           context, numBytesToErase, string, declKind, isSystem, moduleName,
           notRecommended, CodeCompletionResult::NotRecommendedReason::NoReason,
-          briefDocComment, copyStringArray(*V.Sink.Allocator, assocUSRs),
-          copyStringPairArray(*V.Sink.Allocator, declKeywords),
+          briefDocComment, copyArray(*V.Sink.Allocator, ArrayRef<StringRef>(assocUSRs)),
+          copyArray(*V.Sink.Allocator, ArrayRef<std::pair<StringRef, StringRef>>(declKeywords)),
           CodeCompletionResult::Unknown, opKind);
     } else {
       result = new (*V.Sink.Allocator)
diff --git a/lib/IDE/CodeCompletionResultBuilder.h b/lib/IDE/CodeCompletionResultBuilder.h
index bb286e2..2e7babc 100644
--- a/lib/IDE/CodeCompletionResultBuilder.h
+++ b/lib/IDE/CodeCompletionResultBuilder.h
@@ -49,8 +49,20 @@
   /// Since the input may be incomplete, we take into account that the types are
   /// only a hint.
   bool isSingleExpressionBody = false;
+  bool preferNonVoid = false;
 
   bool empty() const { return possibleTypes.empty(); }
+  bool requiresNonVoid() const {
+    if (isSingleExpressionBody)
+      return false;
+    if (preferNonVoid)
+      return true;
+    if (possibleTypes.empty())
+      return false;
+    return std::all_of(possibleTypes.begin(), possibleTypes.end(), [](Type Ty) {
+      return !Ty->isVoid();
+    });
+  }
 
   ExpectedTypeContext() = default;
   ExpectedTypeContext(ArrayRef<Type> types, bool isSingleExpressionBody)
diff --git a/lib/IDE/CompletionInstance.cpp b/lib/IDE/CompletionInstance.cpp
index 1aeffb3..2c2babd 100644
--- a/lib/IDE/CompletionInstance.cpp
+++ b/lib/IDE/CompletionInstance.cpp
@@ -275,7 +275,7 @@
 } // namespace
 
 bool CompletionInstance::performCachedOperationIfPossible(
-    const swift::CompilerInvocation &Invocation, llvm::hash_code ArgsHash,
+   llvm::hash_code ArgsHash,
     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
     llvm::MemoryBuffer *completionBuffer, unsigned int Offset,
     DiagnosticConsumer *DiagC,
@@ -285,7 +285,7 @@
 
   if (!CachedCI)
     return false;
-  if (CachedReuseCount >= MaxASTReuseCount)
+  if (CachedReuseCount >= Opts.MaxASTReuseCount)
     return false;
   if (CachedArgHash != ArgsHash)
     return false;
@@ -323,8 +323,10 @@
   TypeCheckerOptions typeckOpts = CI.getASTContext().TypeCheckerOpts;
   SearchPathOptions searchPathOpts = CI.getASTContext().SearchPathOpts;
   DiagnosticEngine tmpDiags(tmpSM);
+  ClangImporterOptions clangOpts;
   std::unique_ptr<ASTContext> tmpCtx(
-      ASTContext::get(langOpts, typeckOpts, searchPathOpts, tmpSM, tmpDiags));
+      ASTContext::get(langOpts, typeckOpts, searchPathOpts, clangOpts, tmpSM,
+                      tmpDiags));
   registerParseRequestFunctions(tmpCtx->evaluator);
   registerIDERequestFunctions(tmpCtx->evaluator);
   registerTypeCheckerRequestFunctions(tmpCtx->evaluator);
@@ -568,20 +570,21 @@
   assert(CachedCI);
   using namespace std::chrono;
   auto now = system_clock::now();
-  return DependencyCheckedTimestamp + seconds(DependencyCheckIntervalSecond) <
-         now;
+  auto threshold = DependencyCheckedTimestamp +
+                   seconds(Opts.DependencyCheckIntervalSecond);
+  return threshold < now;
 }
 
-void CompletionInstance::setDependencyCheckIntervalSecond(unsigned Value) {
+void CompletionInstance::setOptions(CompletionInstance::Options NewOpts) {
   std::lock_guard<std::mutex> lock(mtx);
-  DependencyCheckIntervalSecond = Value;
+  Opts = NewOpts;
 }
 
 bool swift::ide::CompletionInstance::performOperation(
     swift::CompilerInvocation &Invocation, llvm::ArrayRef<const char *> Args,
     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
     llvm::MemoryBuffer *completionBuffer, unsigned int Offset,
-    bool EnableASTCaching, std::string &Error, DiagnosticConsumer *DiagC,
+    std::string &Error, DiagnosticConsumer *DiagC,
     llvm::function_ref<void(CompilerInstance &, bool)> Callback) {
 
   // Always disable source location resolutions from .swiftsourceinfo file
@@ -599,29 +602,23 @@
   // We don't need token list.
   Invocation.getLangOptions().CollectParsedToken = false;
 
-  if (EnableASTCaching) {
-    // Compute the signature of the invocation.
-    llvm::hash_code ArgsHash(0);
-    for (auto arg : Args)
-      ArgsHash = llvm::hash_combine(ArgsHash, StringRef(arg));
+  // Compute the signature of the invocation.
+  llvm::hash_code ArgsHash(0);
+  for (auto arg : Args)
+    ArgsHash = llvm::hash_combine(ArgsHash, StringRef(arg));
 
-    // Concurrent completions will block so that they have higher chance to use
-    // the cached completion instance.
-    std::lock_guard<std::mutex> lock(mtx);
+  // Concurrent completions will block so that they have higher chance to use
+  // the cached completion instance.
+  std::lock_guard<std::mutex> lock(mtx);
 
-    if (performCachedOperationIfPossible(Invocation, ArgsHash, FileSystem,
-                                         completionBuffer, Offset, DiagC,
-                                         Callback))
-      return true;
+  if (performCachedOperationIfPossible(ArgsHash, FileSystem, completionBuffer,
+                                       Offset, DiagC, Callback)) {
+    return true;
+  }
 
-    if (performNewOperation(ArgsHash, Invocation, FileSystem, completionBuffer,
-                            Offset, Error, DiagC, Callback))
-      return true;
-  } else {
-    // Concurrent completions may happen in parallel when caching is disabled.
-    if (performNewOperation(None, Invocation, FileSystem, completionBuffer,
-                            Offset, Error, DiagC, Callback))
-      return true;
+  if(performNewOperation(ArgsHash, Invocation, FileSystem, completionBuffer,
+                         Offset, Error, DiagC, Callback)) {
+    return true;
   }
 
   assert(!Error.empty());
diff --git a/lib/IDE/ConformingMethodList.cpp b/lib/IDE/ConformingMethodList.cpp
index f1fcf9f..ae6cfce 100644
--- a/lib/IDE/ConformingMethodList.cpp
+++ b/lib/IDE/ConformingMethodList.cpp
@@ -45,16 +45,17 @@
 
   // Only handle callbacks for suffix completions.
   // {
-  void completeDotExpr(Expr *E, SourceLoc DotLoc) override;
+  void completeDotExpr(CodeCompletionExpr *E, SourceLoc DotLoc) override;
   void completePostfixExpr(Expr *E, bool hasSpace) override;
   // }
 
   void doneParsing() override;
 };
 
-void ConformingMethodListCallbacks::completeDotExpr(Expr *E, SourceLoc DotLoc) {
+void ConformingMethodListCallbacks::completeDotExpr(CodeCompletionExpr *E,
+                                                    SourceLoc DotLoc) {
   CurDeclContext = P.CurDeclContext;
-  ParsedExpr = E;
+  ParsedExpr = E->getBase();
 }
 
 void ConformingMethodListCallbacks::completePostfixExpr(Expr *E,
diff --git a/lib/IDE/ExprContextAnalysis.cpp b/lib/IDE/ExprContextAnalysis.cpp
index 96f0b21..904f42a 100644
--- a/lib/IDE/ExprContextAnalysis.cpp
+++ b/lib/IDE/ExprContextAnalysis.cpp
@@ -104,7 +104,7 @@
     } else if (auto *defaultArg = dyn_cast<DefaultArgumentInitializer>(DC)) {
       if (auto *AFD = dyn_cast<AbstractFunctionDecl>(defaultArg->getParent())) {
         auto *Param = AFD->getParameters()->get(defaultArg->getIndex());
-        (void*)Param->getTypeCheckedDefaultExpr();
+        (void)Param->getTypeCheckedDefaultExpr();
       }
     }
     break;
diff --git a/lib/IDE/SwiftSourceDocInfo.cpp b/lib/IDE/SwiftSourceDocInfo.cpp
index 6f44a30..bd3edf9 100644
--- a/lib/IDE/SwiftSourceDocInfo.cpp
+++ b/lib/IDE/SwiftSourceDocInfo.cpp
@@ -24,6 +24,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/Module.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Basic/CharInfo.h"
diff --git a/lib/IDE/Utils.cpp b/lib/IDE/Utils.cpp
index 5d0dda4..0ee903e 100644
--- a/lib/IDE/Utils.cpp
+++ b/lib/IDE/Utils.cpp
@@ -13,6 +13,7 @@
 #include "swift/IDE/Utils.h"
 #include "swift/Basic/Edit.h"
 #include "swift/Basic/SourceManager.h"
+#include "swift/Basic/Platform.h"
 #include "swift/ClangImporter/ClangModule.h"
 #include "swift/Driver/FrontendUtil.h"
 #include "swift/Frontend/Frontend.h"
@@ -25,8 +26,8 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticBuffer.h"
 #include "clang/Lex/PreprocessorOptions.h"
-#include "clang/Serialization/ASTReader.h"
 #include "clang/Rewrite/Core/RewriteBuffer.h"
+#include "clang/Serialization/ASTReader.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -664,46 +665,6 @@
   });
 }
 
-static std::string getPlistEntry(const llvm::Twine &Path, StringRef KeyName) {
-  auto BufOrErr = llvm::MemoryBuffer::getFile(Path);
-  if (!BufOrErr) {
-    llvm::errs() << "could not open '" << Path << "': " << BufOrErr.getError().message() << '\n';
-    return {};
-  }
-
-  std::string Key = "<key>";
-  Key += KeyName;
-  Key += "</key>";
-
-  StringRef Lines = BufOrErr.get()->getBuffer();
-  while (!Lines.empty()) {
-    StringRef CurLine;
-    std::tie(CurLine, Lines) = Lines.split('\n');
-    if (CurLine.find(Key) != StringRef::npos) {
-      std::tie(CurLine, Lines) = Lines.split('\n');
-      unsigned Begin = CurLine.find("<string>") + strlen("<string>");
-      unsigned End = CurLine.find("</string>");
-      return CurLine.substr(Begin, End - Begin).str();
-    }
-  }
-
-  return {};
-}
-
-std::string ide::getSDKName(StringRef Path) {
-  std::string Name = getPlistEntry(llvm::Twine(Path)+"/SDKSettings.plist",
-                                   "CanonicalName");
-  if (Name.empty() && Path.endswith(".sdk")) {
-    Name = llvm::sys::path::filename(Path).drop_back(strlen(".sdk")).str();
-  }
-  return Name;
-}
-
-std::string ide::getSDKVersion(StringRef Path) {
-  return getPlistEntry(llvm::Twine(Path)+"/System/Library/CoreServices/"
-                       "SystemVersion.plist", "ProductBuildVersion");
-}
-
 // Modules failing to load are commented-out.
 static const char *OSXModuleList[] = {
   "AGL",
diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp
index 292c36e..bd530aac 100644
--- a/lib/IRGen/GenCall.cpp
+++ b/lib/IRGen/GenCall.cpp
@@ -727,6 +727,13 @@
       case clang::Type::Pipe:
         llvm_unreachable("OpenCL type in ABI lowering?");
 
+      case clang::Type::ExtInt:
+        llvm_unreachable("ExtInt type in ABI lowering?");
+
+      case clang::Type::ConstantMatrix: {
+        llvm_unreachable("ConstantMatrix type in ABI lowering?");
+      }
+
       case clang::Type::ConstantArray: {
         auto array = Ctx.getAsConstantArrayType(type);
         auto elt = Ctx.getCanonicalType(array->getElementType());
@@ -875,18 +882,9 @@
         llvm_unreachable("OpenCL type in ABI lowering");
 
       // We should never see the SVE types at all.
-      case clang::BuiltinType::SveInt8:
-      case clang::BuiltinType::SveInt16:
-      case clang::BuiltinType::SveInt32:
-      case clang::BuiltinType::SveInt64:
-      case clang::BuiltinType::SveUint8:
-      case clang::BuiltinType::SveUint16:
-      case clang::BuiltinType::SveUint32:
-      case clang::BuiltinType::SveUint64:
-      case clang::BuiltinType::SveFloat16:
-      case clang::BuiltinType::SveFloat32:
-      case clang::BuiltinType::SveFloat64:
-      case clang::BuiltinType::SveBool:
+#define SVE_TYPE(Name, Id, ...) \
+      case clang::BuiltinType::Id:
+#include "clang/Basic/AArch64SVEACLETypes.def"
         llvm_unreachable("SVE type in ABI lowering");
 
       // Handle all the integer types as opaque values.
@@ -910,6 +908,8 @@
       case clang::BuiltinType::Float16:
         llvm_unreachable("When upstream support is added for Float16 in "
                          "clang::TargetInfo, use the implementation here");
+      case clang::BuiltinType::BFloat16:
+        return convertFloatingType(Ctx.getTargetInfo().getBFloat16Format());
       case clang::BuiltinType::Float128:
         return convertFloatingType(Ctx.getTargetInfo().getFloat128Format());
 
@@ -2110,7 +2110,8 @@
       Alignment(coercionTyLayout->getAlignment().value());
   auto alloca = cast<llvm::AllocaInst>(temporary.getAddress());
   if (alloca->getAlignment() < coercionTyAlignment.getValue()) {
-    alloca->setAlignment(llvm::MaybeAlign(coercionTyAlignment.getValue()));
+    alloca->setAlignment(
+        llvm::MaybeAlign(coercionTyAlignment.getValue()).valueOrOne());
     temporary = Address(temporary.getAddress(), coercionTyAlignment);
   }
 
@@ -2388,7 +2389,8 @@
         auto ABIAlign = AI.getIndirectAlign();
         if (ABIAlign > addr.getAlignment()) {
           auto *AS = cast<llvm::AllocaInst>(addr.getAddress());
-          AS->setAlignment(llvm::MaybeAlign(ABIAlign.getQuantity()));
+          AS->setAlignment(
+              llvm::MaybeAlign(ABIAlign.getQuantity()).valueOrOne());
           addr = Address(addr.getAddress(), Alignment(ABIAlign.getQuantity()));
         }
       }
@@ -3080,7 +3082,8 @@
   Alignment layoutAlignment = Alignment(layout->getAlignment().value());
   auto alloca = cast<llvm::AllocaInst>(allocaAddr.getAddress());
   if (alloca->getAlignment() < layoutAlignment.getValue()) {
-    alloca->setAlignment(llvm::MaybeAlign(layoutAlignment.getValue()));
+    alloca->setAlignment(
+        llvm::MaybeAlign(layoutAlignment.getValue()).valueOrOne());
     allocaAddr = Address(allocaAddr.getAddress(), layoutAlignment);
   }
 }
diff --git a/lib/IRGen/GenClangDecl.cpp b/lib/IRGen/GenClangDecl.cpp
index 577307c..7679773 100644
--- a/lib/IRGen/GenClangDecl.cpp
+++ b/lib/IRGen/GenClangDecl.cpp
@@ -98,6 +98,11 @@
         refFinder.TraverseDecl(executableDecl);
         next = executableDecl;
     }
+
+    if (auto var = dyn_cast<clang::VarDecl>(next))
+      if (!var->isFileVarDecl())
+	continue;
+
     ClangCodeGen->HandleTopLevelDecl(clang::DeclGroupRef(next));
   }
 }
diff --git a/lib/IRGen/GenConstant.cpp b/lib/IRGen/GenConstant.cpp
index 0d6e021..9f00592 100644
--- a/lib/IRGen/GenConstant.cpp
+++ b/lib/IRGen/GenConstant.cpp
@@ -85,7 +85,8 @@
 
   if (auto vector = BI->getType().getAs<BuiltinVectorType>()) {
     auto zero = helper(vector.getElementType());
-    return llvm::ConstantVector::getSplat(vector->getNumElements(), zero);
+    return llvm::ConstantVector::getSplat(
+        llvm::ElementCount(vector->getNumElements(), /*scalable*/ false), zero);
   }
 
   return helper(BI->getType().getASTType());
diff --git a/lib/IRGen/GenCoverage.cpp b/lib/IRGen/GenCoverage.cpp
index a5d2e6d..bdedf23 100644
--- a/lib/IRGen/GenCoverage.cpp
+++ b/lib/IRGen/GenCoverage.cpp
@@ -23,19 +23,23 @@
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
-#include "llvm/ProfileData/InstrProf.h"
 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
+#include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/FileSystem.h"
 
+// This selects the coverage mapping format defined when `InstrProfData.inc`
+// is textually included.
+#define COVMAP_V3
+
 using namespace swift;
 using namespace irgen;
 
-using llvm::coverage::CovMapVersion;
 using llvm::coverage::CounterMappingRegion;
+using llvm::coverage::CovMapVersion;
 
-static std::string getCoverageSection(IRGenModule &IGM) {
-  return llvm::getInstrProfSectionName(llvm::IPSK_covmap,
-                                       IGM.Triple.getObjectFormat());
+static std::string getInstrProfSection(IRGenModule &IGM,
+                                       llvm::InstrProfSectKind SK) {
+  return llvm::getInstrProfSectionName(SK, IGM.Triple.getObjectFormat());
 }
 
 void IRGenModule::emitCoverageMapping() {
@@ -63,8 +67,6 @@
 
   auto remapper = getOptions().CoveragePrefixMap;
   // Awkwardly munge absolute filenames into a vector of StringRefs.
-  // TODO: This is heinous - the same thing is happening in clang, but the API
-  // really needs to be cleaned up for both.
   llvm::SmallVector<std::string, 8> FilenameStrs;
   llvm::SmallVector<StringRef, 8> FilenameRefs;
   for (StringRef Name : Files) {
@@ -74,33 +76,31 @@
     FilenameRefs.push_back(FilenameStrs.back());
   }
 
-  // Encode the filenames first.
-  std::string FilenamesAndCoverageMappings;
-  llvm::raw_string_ostream OS(FilenamesAndCoverageMappings);
-  llvm::coverage::CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
-  size_t FilenamesSize = OS.str().size();
-  size_t CurrentSize, PrevSize = FilenamesSize;
-
-  // Now we need to build up the list of function records.
+  // Encode the filenames.
+  std::string Filenames;
   llvm::LLVMContext &Ctx = getLLVMContext();
+  {
+    llvm::raw_string_ostream OS(Filenames);
+    llvm::coverage::CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
+  }
+  auto *FilenamesVal =
+      llvm::ConstantDataArray::getString(Ctx, Filenames, false);
+  const int64_t FilenamesRef = llvm::IndexedInstrProf::ComputeHash(Filenames);
+  const size_t FilenamesSize = Filenames.size();
+
+  // Emit the function records.
   auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
-
-  llvm::Type *FunctionRecordTypes[] = {
-#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
-#include "llvm/ProfileData/InstrProfData.inc"
-#undef COVMAP_FUNC_RECORD
-  };
-
-  auto FunctionRecordTy =
-      llvm::StructType::get(Ctx, llvm::makeArrayRef(FunctionRecordTypes),
-                            /*isPacked=*/true);
-
-  std::vector<llvm::Constant *> FunctionRecords;
-  std::vector<CounterMappingRegion> Regions;
   for (const auto &M : Mappings) {
+    StringRef NameValue = M->getPGOFuncName();
+    assert(!NameValue.empty() && "Expected a named record");
+    uint64_t FuncHash = M->getHash();
+
+    const uint64_t NameHash = llvm::IndexedInstrProf::ComputeHash(NameValue);
+    std::string FuncRecordName = "__covrec_" + llvm::utohexstr(NameHash);
+
     unsigned FileID =
         std::find(Files.begin(), Files.end(), M->getFile()) - Files.begin();
-    Regions.clear();
+    std::vector<CounterMappingRegion> Regions;
     for (const auto &MR : M->getMappedRegions())
       Regions.emplace_back(CounterMappingRegion::makeRegion(
           MR.Counter, /*FileID=*/0, MR.StartLine, MR.StartCol, MR.EndLine,
@@ -109,73 +109,70 @@
     ArrayRef<unsigned> VirtualFileMapping(FileID);
     llvm::coverage::CoverageMappingWriter W(VirtualFileMapping,
                                             M->getExpressions(), Regions);
-    W.write(OS);
+    std::string CoverageMapping;
+    {
+      llvm::raw_string_ostream OS(CoverageMapping);
+      W.write(OS);
+    }
 
-    CurrentSize = OS.str().size();
-    unsigned MappingLen = CurrentSize - PrevSize;
-    StringRef CoverageMapping(OS.str().c_str() + PrevSize, MappingLen);
-
-    StringRef NameValue = M->getPGOFuncName();
-    assert(!NameValue.empty() && "Expected a named record");
-    uint64_t FuncHash = M->getHash();
-
-    // Create a record for this function.
-    llvm::Constant *FunctionRecordVals[] = {
-#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
+#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType,
+    llvm::Type *FunctionRecordTypes[] = {
 #include "llvm/ProfileData/InstrProfData.inc"
-#undef COVMAP_FUNC_RECORD
     };
+    auto *FunctionRecordTy =
+        llvm::StructType::get(Ctx, makeArrayRef(FunctionRecordTypes),
+                              /*isPacked=*/true);
 
-    FunctionRecords.push_back(llvm::ConstantStruct::get(
-        FunctionRecordTy, makeArrayRef(FunctionRecordVals)));
-    PrevSize = CurrentSize;
+    // Create the function record constant.
+#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init,
+    llvm::Constant *FunctionRecordVals[] = {
+#include "llvm/ProfileData/InstrProfData.inc"
+    };
+    auto *FuncRecordConstant = llvm::ConstantStruct::get(
+        FunctionRecordTy, makeArrayRef(FunctionRecordVals));
+
+    // Create the function record global.
+    auto *FuncRecord = new llvm::GlobalVariable(
+        *getModule(), FunctionRecordTy, /*isConstant=*/true,
+        llvm::GlobalValue::LinkOnceODRLinkage, FuncRecordConstant,
+        FuncRecordName);
+    FuncRecord->setVisibility(llvm::GlobalValue::HiddenVisibility);
+    FuncRecord->setSection(getInstrProfSection(*this, llvm::IPSK_covfun));
+    FuncRecord->setAlignment(llvm::Align(8));
+    if (Triple.supportsCOMDAT())
+      FuncRecord->setComdat(getModule()->getOrInsertComdat(FuncRecordName));
+
+    // Make sure the data doesn't get deleted.
+    addUsedGlobal(FuncRecord);
   }
-  size_t CoverageMappingSize = PrevSize - FilenamesSize;
-
-  // Append extra zeroes if necessary to ensure that the size of the filenames
-  // and coverage mappings is a multiple of 8.
-  if (size_t Rem = OS.str().size() % 8) {
-    CoverageMappingSize += 8 - Rem;
-    for (size_t I = 0, S = 8 - Rem; I < S; ++I)
-      OS << '\0';
-  }
-  auto *FilenamesAndMappingsVal =
-      llvm::ConstantDataArray::getString(Ctx, OS.str(), false);
-
-  auto *RecordsTy =
-      llvm::ArrayType::get(FunctionRecordTy, FunctionRecords.size());
-  auto *RecordsVal = llvm::ConstantArray::get(RecordsTy, FunctionRecords);
 
   // Create the coverage data header.
+  const unsigned NRecords = 0;
+  const unsigned CoverageMappingSize = 0;
   llvm::Type *CovDataHeaderTypes[] = {
 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType,
 #include "llvm/ProfileData/InstrProfData.inc"
-#undef COVMAP_HEADER
   };
-  auto *CovDataHeaderTy =
+  auto CovDataHeaderTy =
       llvm::StructType::get(Ctx, makeArrayRef(CovDataHeaderTypes));
   llvm::Constant *CovDataHeaderVals[] = {
 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init,
 #include "llvm/ProfileData/InstrProfData.inc"
-#undef COVMAP_HEADER
   };
-  auto *CovDataHeaderVal = llvm::ConstantStruct::get(
+  auto CovDataHeaderVal = llvm::ConstantStruct::get(
       CovDataHeaderTy, makeArrayRef(CovDataHeaderVals));
 
-  // Combine the header, function records, and mappings together.
-  llvm::Type *CovDataTypes[] = {CovDataHeaderTy, RecordsTy,
-                                FilenamesAndMappingsVal->getType()};
-  auto *CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
-  llvm::Constant *TUDataVals[] = {CovDataHeaderVal, RecordsVal,
-                                  FilenamesAndMappingsVal};
-  auto *CovDataVal =
+  // Create the coverage data record
+  llvm::Type *CovDataTypes[] = {CovDataHeaderTy, FilenamesVal->getType()};
+  auto CovDataTy = llvm::StructType::get(Ctx, makeArrayRef(CovDataTypes));
+  llvm::Constant *TUDataVals[] = {CovDataHeaderVal, FilenamesVal};
+  auto CovDataVal =
       llvm::ConstantStruct::get(CovDataTy, makeArrayRef(TUDataVals));
-
   auto CovData = new llvm::GlobalVariable(
-      *getModule(), CovDataTy, true, llvm::GlobalValue::InternalLinkage,
+      *getModule(), CovDataTy, true, llvm::GlobalValue::PrivateLinkage,
       CovDataVal, llvm::getCoverageMappingVarName());
-  std::string CovSection = getCoverageSection(*this);
-  CovData->setSection(CovSection);
-  CovData->setAlignment(llvm::MaybeAlign(8));
+
+  CovData->setSection(getInstrProfSection(*this, llvm::IPSK_covmap));
+  CovData->setAlignment(llvm::Align(8));
   addUsedGlobal(CovData);
 }
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 9ac46be..5c7c205 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -449,13 +449,15 @@
   // Emit types and other global decls.
   for (auto *decl : SF.getTopLevelDecls())
     emitGlobalDecl(decl);
+  for (auto *decl : SF.getHoistedDecls())
+    emitGlobalDecl(decl);
   for (auto *localDecl : SF.LocalTypeDecls)
     emitGlobalDecl(localDecl);
   for (auto *opaqueDecl : SF.getOpaqueReturnTypeDecls())
     maybeEmitOpaqueTypeDecl(opaqueDecl);
 
   SF.collectLinkLibraries([this](LinkLibrary linkLib) {
-      this->addLinkLibrary(linkLib);
+    this->addLinkLibrary(linkLib);
   });
 
   if (ObjCInterop)
@@ -4430,7 +4432,7 @@
   // Check whether it's already cached.
   llvm::Constant *&entry = cache[entity];
   if (entry) {
-    auto existing = cast<llvm::GlobalValue>(entry);
+    auto existing = cast<llvm::GlobalVariable>(entry);
     assert(alignment == Alignment(existing->getAlignment()));
     if (forDefinition) updateLinkageForDefinition(IGM, existing, entity);
     return Address(entry, alignment);
@@ -4589,7 +4591,7 @@
   llvm::AllocaInst *alloca =
       new llvm::AllocaInst(type, IGM.DataLayout.getAllocaAddrSpace(), name,
                            AllocaIP);
-  alloca->setAlignment(llvm::MaybeAlign(alignment.getValue()));
+  alloca->setAlignment(llvm::MaybeAlign(alignment.getValue()).valueOrOne());
   return Address(alloca, alignment);
 }
 
@@ -4600,7 +4602,7 @@
                                     const llvm::Twine &name) {
   llvm::AllocaInst *alloca = new llvm::AllocaInst(
       type, IGM.DataLayout.getAllocaAddrSpace(), ArraySize,
-      llvm::MaybeAlign(alignment.getValue()), name, AllocaIP);
+      llvm::MaybeAlign(alignment.getValue()).valueOrOne(), name, AllocaIP);
   return Address(alloca, alignment);
 }
 
diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp
index dad7aaf..a2666b7 100644
--- a/lib/IRGen/GenEnum.cpp
+++ b/lib/IRGen/GenEnum.cpp
@@ -110,6 +110,7 @@
 #include "swift/AST/LazyResolver.h"
 #include "swift/IRGen/Linking.h"
 #include "swift/SIL/SILModule.h"
+#include "llvm/IR/CFG.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/Analysis/CFG.h"
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 8108f24..d18859e 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -5044,6 +5044,7 @@
   case KnownProtocolKind::StringInterpolationProtocol:
   case KnownProtocolKind::AdditiveArithmetic:
   case KnownProtocolKind::Differentiable:
+  case KnownProtocolKind::FloatingPoint:
     return SpecialProtocol::None;
   }
 
diff --git a/lib/IRGen/GenOpaque.cpp b/lib/IRGen/GenOpaque.cpp
index a01ff1a..96f09d6 100644
--- a/lib/IRGen/GenOpaque.cpp
+++ b/lib/IRGen/GenOpaque.cpp
@@ -575,7 +575,7 @@
 
   // Emit the dynamic alloca.
   auto *alloca = Builder.IRBuilderBase::CreateAlloca(eltTy, arraySize, name);
-  alloca->setAlignment(llvm::MaybeAlign(align.getValue()));
+  alloca->setAlignment(llvm::MaybeAlign(align.getValue()).valueOrOne());
 
   assert(!isInEntryBlock ||
          getActiveDominancePoint().isUniversal() &&
diff --git a/lib/IRGen/IRBuilder.h b/lib/IRGen/IRBuilder.h
index 69ecb3d..4eaa167 100644
--- a/lib/IRGen/IRBuilder.h
+++ b/lib/IRGen/IRBuilder.h
@@ -125,7 +125,7 @@
   llvm::LoadInst *CreateLoad(llvm::Value *addr, Alignment align,
                              const llvm::Twine &name = "") {
     llvm::LoadInst *load = IRBuilderBase::CreateLoad(addr, name);
-    load->setAlignment(llvm::MaybeAlign(align.getValue()));
+    load->setAlignment(llvm::MaybeAlign(align.getValue()).valueOrOne());
     return load;
   }
   llvm::LoadInst *CreateLoad(Address addr, const llvm::Twine &name = "") {
@@ -135,7 +135,7 @@
   llvm::StoreInst *CreateStore(llvm::Value *value, llvm::Value *addr,
                                Alignment align) {
     llvm::StoreInst *store = IRBuilderBase::CreateStore(value, addr);
-    store->setAlignment(llvm::MaybeAlign(align.getValue()));
+    store->setAlignment(llvm::MaybeAlign(align.getValue()).valueOrOne());
     return store;
   }
   llvm::StoreInst *CreateStore(llvm::Value *value, Address addr) {
diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp
index 65387d0..e93c525 100644
--- a/lib/IRGen/IRGenDebugInfo.cpp
+++ b/lib/IRGen/IRGenDebugInfo.cpp
@@ -672,7 +672,7 @@
     return M;
   }
 
-  using ASTSourceDescriptor = clang::ExternalASTSource::ASTSourceDescriptor;
+  using ASTSourceDescriptor = clang::ASTSourceDescriptor;
   /// Create a DIModule from a clang module or PCH.
   /// The clang::Module pointer is passed separately because the recursive case
   /// needs to fudge the AST descriptor.
@@ -1020,7 +1020,8 @@
     SmallVector<llvm::Metadata *, 16> TemplateParams;
     for (auto Param : BGT->getGenericArgs()) {
       TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
-          TheCU, "", getOrCreateType(DebugTypeInfo::getForwardDecl(Param))));
+          TheCU, "", getOrCreateType(DebugTypeInfo::getForwardDecl(Param)),
+          false));
     }
     return DBuilder.getOrCreateArray(TemplateParams);
   }
diff --git a/lib/IRGen/LocalTypeDataKind.h b/lib/IRGen/LocalTypeDataKind.h
index f45aa30..1f8215f 100644
--- a/lib/IRGen/LocalTypeDataKind.h
+++ b/lib/IRGen/LocalTypeDataKind.h
@@ -211,8 +211,8 @@
              swift::irgen::LocalTypeDataKind::forFormalTypeMetadata() };
   }
   static unsigned getHashValue(const LocalTypeDataKey &key) {
-    return combineHashValue(CanTypeInfo::getHashValue(key.Type),
-                            key.Kind.getRawValue());
+    return detail::combineHashValue(CanTypeInfo::getHashValue(key.Type),
+                                    key.Kind.getRawValue());
   }
   static bool isEqual(const LocalTypeDataKey &a, const LocalTypeDataKey &b) {
     return a == b;
diff --git a/lib/IRGen/Outlining.cpp b/lib/IRGen/Outlining.cpp
index 68f2d17..fe39a1c 100644
--- a/lib/IRGen/Outlining.cpp
+++ b/lib/IRGen/Outlining.cpp
@@ -39,7 +39,6 @@
   }
 
   // Substitute opaque types if allowed.
-  auto origType = type;
   type =
       IGF.IGM.substOpaqueTypesWithUnderlyingTypes(type, CanGenericSignature());
 
@@ -49,9 +48,7 @@
   // We don't need the metadata for fixed size types or types that are not ABI
   // accessible. Outlining will call the value witness of the enclosing type of
   // non ABI accessible field/element types.
-  if ((!origType.getASTType()->hasOpaqueArchetype() &&
-       isa<FixedTypeInfo>(ti)) ||
-      !ti.isABIAccessible()) {
+  if (isa<FixedTypeInfo>(ti) || !ti.isABIAccessible()) {
     return;
   }
 
diff --git a/lib/IRGen/TypeLayout.h b/lib/IRGen/TypeLayout.h
index a6fa9d7..2f6a163 100644
--- a/lib/IRGen/TypeLayout.h
+++ b/lib/IRGen/TypeLayout.h
@@ -16,6 +16,7 @@
 #include "TypeInfo.h"
 #include "swift/SIL/SILType.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Debug.h"
 
 namespace swift {
 namespace irgen {
diff --git a/lib/Immediate/Immediate.cpp b/lib/Immediate/Immediate.cpp
index b491561..fe60531 100644
--- a/lib/Immediate/Immediate.cpp
+++ b/lib/Immediate/Immediate.cpp
@@ -339,7 +339,7 @@
   using MainFnTy = int(*)(int, char*[]);
 
   LLVM_DEBUG(llvm::dbgs() << "Running static constructors\n");
-  if (auto Err = JIT->runConstructors()) {
+  if (auto Err = JIT->initialize(JIT->getMainJITDylib())) {
     llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
     return -1;
   }
@@ -356,7 +356,7 @@
   int Result = llvm::orc::runAsMain(JITMain, CmdLine);
 
   LLVM_DEBUG(llvm::dbgs() << "Running static destructors\n");
-  if (auto Err = JIT->runDestructors()) {
+  if (auto Err = JIT->deinitialize(JIT->getMainJITDylib())) {
     logAllUnhandledErrors(std::move(Err), llvm::errs(), "");
     return -1;
   }
diff --git a/lib/Localization/LocalizationFormat.cpp b/lib/Localization/LocalizationFormat.cpp
index 750a436..94f73b1 100644
--- a/lib/Localization/LocalizationFormat.cpp
+++ b/lib/Localization/LocalizationFormat.cpp
@@ -14,6 +14,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "swift/Basic/Range.h"
 #include "swift/Localization/LocalizationFormat.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallString.h"
@@ -190,5 +191,28 @@
   return yin;
 }
 
+void DefToYAMLConverter::convert(llvm::raw_ostream &out) {
+  for (auto i : swift::indices(IDs)) {
+    out << "- id: " << IDs[i] << "\n";
+
+    const std::string &msg = Messages[i];
+
+    out << "  msg: \"";
+    // Add an escape character before a double quote `"` or a backslash `\`.
+    for (unsigned j = 0; j < msg.length(); ++j) {
+      if (msg[j] == '"') {
+        out << '\\';
+        out << '"';
+      } else if (msg[j] == '\\') {
+        out << '\\';
+        out << '\\';
+      } else {
+        out << msg[j];
+      }
+    }
+    out << "\"\r\n";
+  }
+}
+
 } // namespace diag
 } // namespace swift
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index ac374be..7e1ec01 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -21,6 +21,7 @@
 #include "swift/Parse/SyntaxParsingContext.h"
 #include "swift/Syntax/SyntaxKind.h"
 #include "swift/Subsystems.h"
+#include "swift/AST/ASTWalker.h"
 #include "swift/AST/Attr.h"
 #include "swift/AST/LazyResolver.h"
 #include "swift/AST/DebuggerClient.h"
@@ -60,15 +61,9 @@
   /// file scope level so it will be set up correctly for this purpose.
   ///
   /// Creating an instance of this object will cause it to figure out
-  /// whether we are in the debugger function, whether it needs to swap 
+  /// whether we are in the debugger function, and whether it needs to swap
   /// the Decl that is currently being parsed.
-  /// If you have created the object, instead of returning the result
-  /// with makeParserResult, use the object's fixupParserResult.  If
-  /// no swap has occurred, these methods will work the same.  
-  /// If the decl has been moved, then Parser::markWasHandled will be
-  /// called on the Decl, and you should call declWasHandledAlready
-  /// before you consume the Decl to see if you actually need to
-  /// consume it.
+  ///
   /// If you are making one of these objects to address issue 1, call
   /// the constructor that only takes a DeclKind, and it will be moved
   /// unconditionally.  Otherwise pass in the Name and DeclKind and the
@@ -76,32 +71,24 @@
   class DebuggerContextChange {
   protected:
     Parser &P;
-    Identifier Name;
-    SourceFile *SF;
     Optional<Parser::ContextChange> CC;
+    SourceFile *SF;
   public:
-    DebuggerContextChange (Parser &P)
-      : P(P), SF(nullptr) {
+    DebuggerContextChange(Parser &P) : P(P), SF(nullptr) {
       if (!inDebuggerContext())
         return;
-      else
-        switchContext();
+
+      switchContext();
     }
     
-    DebuggerContextChange (Parser &P, Identifier &Name, DeclKind Kind)
-      : P(P), Name(Name), SF(nullptr) {
+    DebuggerContextChange(Parser &P, Identifier Name, DeclKind Kind)
+        : P(P), SF(nullptr) {
       if (!inDebuggerContext())
         return;
-      bool globalize = false;
-        
-      DebuggerClient *debug_client = getDebuggerClient();
-      if (!debug_client)
-        return;
-      
-      globalize = debug_client->shouldGlobalize(Name, Kind);
-        
-      if (globalize)
-        switchContext();
+
+      if (auto *client = getDebuggerClient())
+        if (client->shouldGlobalize(Name, Kind))
+          switchContext();
     }
     
     bool movedToTopLevel() {
@@ -118,35 +105,27 @@
     template <typename T>
     ParserResult<T>
     fixupParserResult(T *D) {
-      if (CC.hasValue()) {
-        swapDecl(D);
-      }
+      if (movedToTopLevel())
+        hoistDecl(D);
       return ParserResult<T>(D);
     }
     
     template <typename T>
     ParserResult<T>
     fixupParserResult(ParserStatus Status, T *D) {
-      if (CC.hasValue() && !Status.isError()) {
-        // If there is an error, don't do our splicing trick,
-        // just return the Decl and the status for reporting.
-        swapDecl(D);
-      }
+      if (movedToTopLevel())
+        hoistDecl(D);
       return makeParserResult(Status, D);
     }
 
     // The destructor doesn't need to do anything, the CC's destructor will
     // pop the context if we set it.
     ~DebuggerContextChange () {}
-  protected:
-  
-    DebuggerClient *getDebuggerClient()
-    {
-      ModuleDecl *PM = P.CurDeclContext->getParentModule();
-      if (!PM)
-          return nullptr;
-      else
-           return PM->getDebugClient();
+
+  private:
+    DebuggerClient *getDebuggerClient() {
+      ModuleDecl *M = P.CurDeclContext->getParentModule();
+      return M->getDebugClient();
     }
     
     bool inDebuggerContext() {
@@ -154,29 +133,26 @@
         return false;
       if (!P.CurDeclContext)
         return false;
-      auto *func_decl = dyn_cast<FuncDecl>(P.CurDeclContext);
-      if (!func_decl)
+      auto *func = dyn_cast<FuncDecl>(P.CurDeclContext);
+      if (!func)
         return false;
-        
-      if (!func_decl->getAttrs().hasAttribute<LLDBDebuggerFunctionAttr>())
+
+      if (!func->getAttrs().hasAttribute<LLDBDebuggerFunctionAttr>())
         return false;
-      
+
       return true;
     }
     
-    void switchContext () {
+    void switchContext() {
       SF = P.CurDeclContext->getParentSourceFile();
-      CC.emplace (P, SF);
+      CC.emplace(P, SF);
     }
-    
-    void swapDecl (Decl *D)
-    {
-      assert (SF);
-      DebuggerClient *debug_client = getDebuggerClient();
-      assert (debug_client);
-      debug_client->didGlobalize(D);
-      P.ContextSwitchedTopLevelDecls.push_back(D);
-      P.markWasHandled(D);
+
+    template<typename T>
+    void hoistDecl(T *D) {
+      D->setHoisted();
+      SF->addHoistedDecl(D);
+      getDebuggerClient()->didGlobalize(D);
     }
   };
 } // end anonymous namespace
@@ -225,10 +201,6 @@
     }
   }
 
-  // First append any decls that LLDB requires be inserted at the top-level.
-  decls.append(ContextSwitchedTopLevelDecls.begin(),
-               ContextSwitchedTopLevelDecls.end());
-
   // Then append the top-level decls we parsed.
   for (auto item : items) {
     auto *decl = item.get<Decl *>();
@@ -6489,10 +6461,10 @@
   // If the body consists of a single expression, turn it into a return
   // statement.
   //
-  // But don't do this transformation during code completion, as the source
-  // may be incomplete and the type mismatch in return statement will just
-  // confuse the type checker.
-  if (BS->getNumElements() != 1 || Body.hasCodeCompletion())
+  // But don't do this transformation when performing certain kinds of code
+  // completion, as the source may be incomplete and the type mismatch in return
+  // statement will just confuse the type checker.
+  if (shouldSuppressSingleExpressionBodyTransform(Body, BS->getElements()))
     return BS;
 
   auto Element = BS->getFirstElement();
@@ -7726,8 +7698,9 @@
   SourceLoc precedenceGroupLoc = consumeToken(tok::kw_precedencegroup);
   DebuggerContextChange DCC (*this);
 
-  if (!CodeCompletion && !DCC.movedToTopLevel() && !(flags & PD_AllowTopLevel))
-  {
+  if (!CodeCompletion &&
+      !DCC.movedToTopLevel() &&
+      !(flags & PD_AllowTopLevel)) {
     diagnose(precedenceGroupLoc, diag::decl_inner_scope);
     return nullptr;
   }
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 7c753b4..8cf4c1b 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -15,6 +15,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "swift/Parse/Parser.h"
+#include "swift/AST/ASTWalker.h"
 #include "swift/AST/DiagnosticsParse.h"
 #include "swift/AST/TypeRepr.h"
 #include "swift/Basic/EditorPlaceholder.h"
@@ -394,7 +395,8 @@
 
   if (shouldParseExperimentalConcurrency() && Tok.isContextualKeyword("await")) {
     SourceLoc awaitLoc = consumeToken();
-    ParserResult<Expr> sub = parseExprUnary(message, isExprBasic);
+    ParserResult<Expr> sub =
+      parseExprSequenceElement(diag::expected_expr_after_await, isExprBasic);
     if (!sub.hasCodeCompletion() && !sub.isNull()) {
       ElementContext.setCreateSyntax(SyntaxKind::AwaitExpr);
       sub = makeParserResult(new (Context) AwaitExpr(awaitLoc, sub.get()));
@@ -428,7 +430,9 @@
     }
   }
 
-  ParserResult<Expr> sub = parseExprUnary(message, isExprBasic);
+  ParserResult<Expr> sub = hadTry
+      ? parseExprSequenceElement(message, isExprBasic)
+      : parseExprUnary(message, isExprBasic);
 
   if (hadTry && !sub.hasCodeCompletion() && !sub.isNull()) {
     ElementContext.setCreateSyntax(SyntaxKind::TryExpr);
@@ -1157,11 +1161,12 @@
       // Handle "x.<tab>" for code completion.
       if (Tok.is(tok::code_complete)) {
         assert(!InSwiftKeyPath);
-        if (CodeCompletion) {
-          CodeCompletion->completeDotExpr(Result.get(), /*DotLoc=*/TokLoc);
-        }
         auto CCExpr = new (Context) CodeCompletionExpr(Result.get(),
-                                                       consumeToken(tok::code_complete));
+                                                       Tok.getLoc());
+        if (CodeCompletion) {
+          CodeCompletion->completeDotExpr(CCExpr, /*DotLoc=*/TokLoc);
+        }
+        consumeToken(tok::code_complete);
         return makeParserCodeCompletionResult(CCExpr);
       }
 
@@ -2857,12 +2862,12 @@
   // If the body consists of a single expression, turn it into a return
   // statement.
   //
-  // But don't do this transformation during code completion, as the source
-  // may be incomplete and the type mismatch in return statement will just
-  // confuse the type checker.
+  // But don't do this transformation when performing certain kinds of code
+  // completion, as the source may be incomplete and the type mismatch in return
+  // statement will just confuse the type checker.
   bool hasSingleExpressionBody = false;
-  if (!missingRBrace && !Status.hasCodeCompletion() &&
-      bodyElements.size() == 1) {
+  if (!missingRBrace &&
+      !shouldSuppressSingleExpressionBodyTransform(Status, bodyElements)) {
     // If the closure's only body element is a single return statement,
     // use that instead of creating a new wrapping return expression.
     Expr *returnExpr = nullptr;
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index c98ea0c..9f45a77 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -574,7 +574,6 @@
   // Collect the elements of the tuple patterns for argument and body
   // parameters.
   SmallVector<ParamDecl*, 4> elements;
-  SourceLoc ellipsisLoc;
 
   for (auto &param : params) {
     // Whether the provided name is API by default depends on the parameter
@@ -625,27 +624,26 @@
     }
 
     // Warn when an unlabeled parameter follows a variadic parameter
-    if (ellipsisLoc.isValid() && elements.back()->isVariadic() &&
-        param.FirstName.empty()) {
-      parser.diagnose(param.FirstNameLoc,
-                      diag::unlabeled_parameter_following_variadic_parameter);
+    if (!elements.empty() && elements.back()->isVariadic() && argName.empty()) {
+      // Closure parameters can't have external labels, so use a more specific
+      // diagnostic.
+      if (paramContext == Parser::ParameterContextKind::Closure)
+        parser.diagnose(
+            param.FirstNameLoc,
+            diag::closure_unlabeled_parameter_following_variadic_parameter);
+      else
+        parser.diagnose(param.FirstNameLoc,
+                        diag::unlabeled_parameter_following_variadic_parameter);
     }
-    
-    // If this parameter had an ellipsis, check whether it's the last parameter.
-    if (param.EllipsisLoc.isValid()) {
-      if (ellipsisLoc.isValid()) {
-        parser.diagnose(param.EllipsisLoc, diag::multiple_parameter_ellipsis)
-          .highlight(ellipsisLoc)
-          .fixItRemove(param.EllipsisLoc);
 
-        param.EllipsisLoc = SourceLoc();
-      } else if (!result->getTypeRepr()) {
+    // If this parameter had an ellipsis, check it has a TypeRepr.
+    if (param.EllipsisLoc.isValid()) {
+      if (!result->getTypeRepr()) {
         parser.diagnose(param.EllipsisLoc, diag::untyped_pattern_ellipsis)
           .highlight(result->getSourceRange());
 
         param.EllipsisLoc = SourceLoc();
       } else {
-        ellipsisLoc = param.EllipsisLoc;
         result->setVariadic();
       }
     }
diff --git a/lib/Parse/ParseRequests.cpp b/lib/Parse/ParseRequests.cpp
index e039989..99a4b3a 100644
--- a/lib/Parse/ParseRequests.cpp
+++ b/lib/Parse/ParseRequests.cpp
@@ -49,15 +49,29 @@
 FingerprintAndMembers
 ParseMembersRequest::evaluate(Evaluator &evaluator,
                               IterableDeclContext *idc) const {
-  SourceFile &sf = *idc->getAsGenericContext()->getParentSourceFile();
-  unsigned bufferID = *sf.getBufferID();
+  SourceFile *sf = idc->getAsGenericContext()->getParentSourceFile();
+  ASTContext &ctx = idc->getDecl()->getASTContext();
+  if (!sf) {
+    // If there is no parent source file, this is a deserialized or synthesized
+    // declaration context, in which case `getMembers()` has all of the members.
+    // Filter out the implicitly-generated ones.
+    SmallVector<Decl *, 4> members;
+    for (auto decl : idc->getMembers()) {
+      if (!decl->isImplicit()) {
+        members.push_back(decl);
+      }
+    }
+
+    return FingerprintAndMembers{None, ctx.AllocateCopy(members)};
+  }
+
+  unsigned bufferID = *sf->getBufferID();
 
   // Lexer diaganostics have been emitted during skipping, so we disable lexer's
   // diagnostic engine here.
-  Parser parser(bufferID, sf, /*No Lexer Diags*/nullptr, nullptr, nullptr);
+  Parser parser(bufferID, *sf, /*No Lexer Diags*/nullptr, nullptr, nullptr);
   // Disable libSyntax creation in the delayed parsing.
   parser.SyntaxContext->disable();
-  ASTContext &ctx = idc->getDecl()->getASTContext();
   auto declsAndHash = parser.parseDeclListDelayed(idc);
   FingerprintAndMembers fingerprintAndMembers = {declsAndHash.second,
                                                  declsAndHash.first};
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 25161aa..608a5ff 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -1185,11 +1185,40 @@
                                                Segments.front().Length));
 }
 
+bool Parser::
+shouldSuppressSingleExpressionBodyTransform(ParserStatus Status,
+                                            MutableArrayRef<ASTNode> BodyElems) {
+  if (BodyElems.size() != 1)
+    return true;
+
+  if (!Status.hasCodeCompletion())
+    return false;
+
+  struct HasMemberCompletion: public ASTWalker {
+    bool Value = false;
+    std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
+      if (auto *CCE = dyn_cast<CodeCompletionExpr>(E)) {
+        // If it has a base expression this is member completion, which is
+        // performed using the new solver-based mechanism, so it's ok to go
+        // ahead with the transform (and necessary to pick up the correct
+        // expected type).
+        Value = CCE->getBase();
+        return {false, nullptr};
+      }
+      return {true, E};
+    }
+  };
+  HasMemberCompletion Check;
+  BodyElems.front().walk(Check);
+  return !Check.Value;
+}
+
 struct ParserUnit::Implementation {
   std::shared_ptr<SyntaxParseActions> SPActions;
   LangOptions LangOpts;
   TypeCheckerOptions TypeCheckerOpts;
   SearchPathOptions SearchPathOpts;
+  ClangImporterOptions clangImporterOpts;
   DiagnosticEngine Diags;
   ASTContext &Ctx;
   SourceFile *SF;
@@ -1201,8 +1230,8 @@
                  std::shared_ptr<SyntaxParseActions> spActions)
       : SPActions(std::move(spActions)), LangOpts(Opts),
         TypeCheckerOpts(TyOpts), Diags(SM),
-        Ctx(*ASTContext::get(LangOpts, TypeCheckerOpts, SearchPathOpts, SM,
-                             Diags)) {
+        Ctx(*ASTContext::get(LangOpts, TypeCheckerOpts, SearchPathOpts,
+                             clangImporterOpts, SM, Diags)) {
     auto parsingOpts = SourceFile::getDefaultParsingOptions(LangOpts);
     parsingOpts |= ParsingFlags::DisableDelayedBodies;
     parsingOpts |= ParsingFlags::DisablePoundIfEvaluation;
diff --git a/lib/PrintAsObjC/DeclAndTypePrinter.cpp b/lib/PrintAsObjC/DeclAndTypePrinter.cpp
index 4daa75d..bcdff13 100644
--- a/lib/PrintAsObjC/DeclAndTypePrinter.cpp
+++ b/lib/PrintAsObjC/DeclAndTypePrinter.cpp
@@ -18,6 +18,7 @@
 #include "swift/AST/Comment.h"
 #include "swift/AST/Decl.h"
 #include "swift/AST/ExistentialLayout.h"
+#include "swift/AST/ForeignAsyncConvention.h"
 #include "swift/AST/ForeignErrorConvention.h"
 #include "swift/AST/GenericEnvironment.h"
 #include "swift/AST/PrettyStackTrace.h"
@@ -32,6 +33,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/CharInfo.h"
+#include "clang/Basic/SourceManager.h"
 
 using namespace swift;
 using namespace swift::objc_translation;
@@ -463,6 +465,7 @@
 
   Type getForeignResultType(AbstractFunctionDecl *AFD,
                             FunctionType *methodTy,
+                            Optional<ForeignAsyncConvention> asyncConvention,
                             Optional<ForeignErrorConvention> errorConvention) {
     // A foreign error convention can affect the result type as seen in
     // Objective-C.
@@ -483,6 +486,11 @@
       }
     }
 
+    // Asynchronous methods return their results via completion handler.
+    if (asyncConvention) {
+      return getASTContext().TheEmptyTupleType;
+    }
+
     auto result = methodTy->getResult();
     if (result->isUninhabited())
       return getASTContext().TheEmptyTupleType;
@@ -512,16 +520,20 @@
       }
     }
 
+    Optional<ForeignAsyncConvention> asyncConvention
+      = AFD->getForeignAsyncConvention();
     Optional<ForeignErrorConvention> errorConvention
       = AFD->getForeignErrorConvention();
     Type rawMethodTy = AFD->getMethodInterfaceType();
     auto methodTy = rawMethodTy->castTo<FunctionType>();
-    auto resultTy = getForeignResultType(AFD, methodTy, errorConvention);
+    auto resultTy = getForeignResultType(
+        AFD, methodTy, asyncConvention, errorConvention);
 
     // Constructors and methods returning DynamicSelf return
     // instancetype.
     if (isa<ConstructorDecl>(AFD) ||
-        (isa<FuncDecl>(AFD) && cast<FuncDecl>(AFD)->hasDynamicSelfResult())) {
+        (isa<FuncDecl>(AFD) && cast<FuncDecl>(AFD)->hasDynamicSelfResult() &&
+         !AFD->hasAsync())) {
       if (errorConvention && errorConvention->stripsResultOptionality()) {
         printNullability(OTK_Optional, NullabilityPrintKind::ContextSensitive);
       } else if (auto ctor = dyn_cast<ConstructorDecl>(AFD)) {
@@ -577,6 +589,16 @@
       StringRef piece = selectorPieces[i].empty() ? StringRef("")
                                                   : selectorPieces[i].str();
 
+      // If we have an async convention and this is the completion handler
+      // parameter, print it.
+      if (asyncConvention &&
+          i == asyncConvention->completionHandlerParamIndex()) {
+        os << piece << ":(";
+        print(asyncConvention->completionHandlerType(), None);
+        os << ")completionHandler";
+        continue;
+      }
+
       // If we have an error convention and this is the error
       // parameter, print it.
       if (errorConvention && i == errorConvention->getErrorParameterIndex()) {
@@ -659,7 +681,9 @@
       if (looksLikeInitMethod(AFD->getObjCSelector())) {
         os << " SWIFT_METHOD_FAMILY(none)";
       }
-      if (methodTy->getResult()->isUninhabited()) {
+      if (asyncConvention) {
+        // Async methods don't have result types to annotate.
+      } else if (methodTy->getResult()->isUninhabited()) {
         os << " SWIFT_NORETURN";
       } else if (!methodTy->getResult()->isVoid() &&
                  !AFD->getAttrs().hasAttribute<DiscardableResultAttr>()) {
@@ -696,12 +720,15 @@
 
   void printAbstractFunctionAsFunction(FuncDecl *FD) {
     printDocumentationComment(FD);
+    Optional<ForeignAsyncConvention> asyncConvention
+      = FD->getForeignAsyncConvention();
     Optional<ForeignErrorConvention> errorConvention
       = FD->getForeignErrorConvention();
     assert(!FD->getGenericSignature() &&
            "top-level generic functions not supported here");
     auto funcTy = FD->getInterfaceType()->castTo<FunctionType>();
-    auto resultTy = getForeignResultType(FD, funcTy, errorConvention);
+    auto resultTy = getForeignResultType(
+        FD, funcTy, asyncConvention, errorConvention);
 
     // The result type may be a partial function type we need to close
     // up later.
@@ -851,6 +878,9 @@
       case PlatformKind::watchOSApplicationExtension:
         plat = "watchos_app_extension";
         break;
+      case PlatformKind::OpenBSD:
+        plat = "openbsd";
+        break;
       case PlatformKind::none:
         llvm_unreachable("handled above");
       }
diff --git a/lib/PrintAsObjC/ModuleContentsWriter.cpp b/lib/PrintAsObjC/ModuleContentsWriter.cpp
index b5b466c..6d4d53b 100644
--- a/lib/PrintAsObjC/ModuleContentsWriter.cpp
+++ b/lib/PrintAsObjC/ModuleContentsWriter.cpp
@@ -23,6 +23,7 @@
 #include "swift/ClangImporter/ClangImporter.h"
 
 #include "clang/AST/Decl.h"
+#include "clang/Basic/Module.h"
 
 #include "llvm/Support/raw_ostream.h"
 
diff --git a/lib/SIL/IR/SILDeclRef.cpp b/lib/SIL/IR/SILDeclRef.cpp
index 42c19ad..1b6f2ce 100644
--- a/lib/SIL/IR/SILDeclRef.cpp
+++ b/lib/SIL/IR/SILDeclRef.cpp
@@ -233,13 +233,11 @@
     return forDefinition ? linkage : addExternalToLinkage(linkage);
   };
 
-  // Native function-local declarations have shared linkage.
-  // FIXME: @objc declarations should be too, but we currently have no way
-  // of marking them "used" other than making them external.
+  // Function-local declarations have private linkage, unless serialized.
   ValueDecl *d = getDecl();
   DeclContext *moduleContext = d->getDeclContext();
   while (!moduleContext->isModuleScopeContext()) {
-    if (!isForeign && moduleContext->isLocalContext()) {
+    if (moduleContext->isLocalContext()) {
       return isSerialized() ? SILLinkage::Shared : SILLinkage::Private;
     }
     moduleContext = moduleContext->getParent();
@@ -249,11 +247,6 @@
   if (isForeignToNativeThunk())
     return SILLinkage::Shared;
 
-  // If a function declares a @_cdecl name, its native-to-foreign thunk
-  // is exported with the visibility of the function.
-  if (isNativeToForeignThunk() && !d->getAttrs().hasAttribute<CDeclAttr>())
-    return SILLinkage::Shared;
-
   // Declarations imported from Clang modules have shared linkage.
   if (isClangImported())
     return SILLinkage::Shared;
@@ -329,12 +322,20 @@
     }
   }
 
-  // Forced-static-dispatch functions are created on-demand and have
-  // at best shared linkage.
   if (auto fn = dyn_cast<FuncDecl>(d)) {
+    // Forced-static-dispatch functions are created on-demand and have
+    // at best shared linkage.
     if (fn->hasForcedStaticDispatch()) {
       limit = Limit::OnDemand;
     }
+
+    // Native-to-foreign thunks for top-level decls are created on-demand,
+    // unless they are marked @_cdecl, in which case they expose a dedicated
+    // entry-point with the visibility of the function.
+    if (isNativeToForeignThunk() && !fn->getAttrs().hasAttribute<CDeclAttr>()) {
+      if (fn->getDeclContext()->isModuleScopeContext())
+        limit = Limit::OnDemand;
+    }
   }
 
   if (isEnumElement()) {
@@ -613,34 +614,42 @@
 }
 
 bool SILDeclRef::isForeignToNativeThunk() const {
+  // If this isn't a native entry-point, it's not a foreign-to-native thunk.
+  if (isForeign)
+    return false;
+
   // Non-decl entry points are never natively foreign, so they would never
   // have a foreign-to-native thunk.
   if (!hasDecl())
     return false;
   if (requiresForeignToNativeThunk(getDecl()))
-    return !isForeign;
+    return true;
   // ObjC initializing constructors and factories are foreign.
   // We emit a special native allocating constructor though.
   if (isa<ConstructorDecl>(getDecl())
       && (kind == Kind::Initializer
           || cast<ConstructorDecl>(getDecl())->isFactoryInit())
       && getDecl()->hasClangNode())
-    return !isForeign;
+    return true;
   return false;
 }
 
 bool SILDeclRef::isNativeToForeignThunk() const {
+  // If this isn't a foreign entry-point, it's not a native-to-foreign thunk.
+  if (!isForeign)
+    return false;
+
   // We can have native-to-foreign thunks over closures.
   if (!hasDecl())
-    return isForeign;
-  // We can have native-to-foreign thunks over global or local native functions.
-  // TODO: Static functions too.
-  if (auto func = dyn_cast<FuncDecl>(getDecl())) {
-    if (!func->getDeclContext()->isTypeContext()
-        && !func->hasClangNode())
-      return isForeign;
-  }
-  return false;
+    return true;
+
+  // A decl with a clang node doesn't have a native entry-point to forward onto.
+  if (getDecl()->hasClangNode())
+    return false;
+
+  // Only certain kinds of SILDeclRef can expose native-to-foreign thunks.
+  return kind == Kind::Func || kind == Kind::Initializer ||
+         kind == Kind::Deallocator;
 }
 
 /// Use the Clang importer to mangle a Clang declaration.
diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp
index 29a40a9..2fc9206 100644
--- a/lib/SIL/IR/SILFunctionType.cpp
+++ b/lib/SIL/IR/SILFunctionType.cpp
@@ -537,6 +537,8 @@
         TC.getTypeLowering(pattern, tanType, TypeExpansionContext::minimal());
     ParameterConvention conv;
     switch (origResConv) {
+    case ResultConvention::Unowned:
+    case ResultConvention::UnownedInnerPointer:
     case ResultConvention::Owned:
     case ResultConvention::Autoreleased:
       if (tl.isAddressOnly()) {
@@ -546,10 +548,6 @@
                               : ParameterConvention::Direct_Guaranteed;
       }
       break;
-    case ResultConvention::Unowned:
-    case ResultConvention::UnownedInnerPointer:
-      conv = ParameterConvention::Direct_Unowned;
-      break;
     case ResultConvention::Indirect:
       conv = ParameterConvention::Indirect_In_Guaranteed;
       break;
diff --git a/lib/SIL/Utils/Dominance.cpp b/lib/SIL/Utils/Dominance.cpp
index 88e034c..ad91ee6 100644
--- a/lib/SIL/Utils/Dominance.cpp
+++ b/lib/SIL/Utils/Dominance.cpp
@@ -119,7 +119,7 @@
   //
   // Even though at the SIL level we have "one" return function, we can have
   // multiple exits provided by no-return functions.
-  auto *F = getRoots()[0]->getParent();
+  auto *F = (*root_begin())->getParent();
   PostDominanceInfo OtherDT(F);
 
   // And compare.
diff --git a/lib/SIL/Utils/OptimizationRemark.cpp b/lib/SIL/Utils/OptimizationRemark.cpp
index 6a778f0..9785273 100644
--- a/lib/SIL/Utils/OptimizationRemark.cpp
+++ b/lib/SIL/Utils/OptimizationRemark.cpp
@@ -182,59 +182,48 @@
   return SourceLoc();
 }
 
+static llvm::cl::opt<bool> IgnoreAlwaysInferForTesting(
+    "sil-opt-remark-ignore-always-infer", llvm::cl::Hidden,
+    llvm::cl::init(false),
+    llvm::cl::desc(
+        "Disables always infer source loc behavior for testing purposes"));
+
+// Attempt to infer a SourceLoc for \p i using heuristics specified by \p
+// inferBehavior.
+//
+// NOTE: We distinguish in between situations where we always must infer
+// (retain, release) and other situations where we are ok with original source
+// locs if we are not inlined (alloc_ref, alloc_stack).
 SourceLoc swift::OptRemark::inferOptRemarkSourceLoc(
     SILInstruction &i, SourceLocInferenceBehavior inferBehavior) {
-  // Do a quick check if we already have a valid loc and it isnt an inline
-  // loc. In such a case, just return. Otherwise, we try to infer using one of
-  // our heuristics below.
+  // If we are only supposed to infer in inline contexts, see if we have a valid
+  // loc and if that loc is an inlined call site.
   auto loc = i.getLoc();
-  if (loc.getSourceLoc().isValid()) {
-    // Before we do anything, if we do not have an inlined call site, just
-    // return our loc.
-    if (!i.getDebugScope() || !i.getDebugScope()->InlinedCallSite)
-      return loc.getSourceLoc();
-  }
+  if (loc.getSourceLoc().isValid() &&
+      !(bool(inferBehavior & SourceLocInferenceBehavior::AlwaysInfer) &&
+        !IgnoreAlwaysInferForTesting) &&
+      !(i.getDebugScope() && i.getDebugScope()->InlinedCallSite))
+    return loc.getSourceLoc();
 
-  // Otherwise, try to handle the individual behavior cases, returning loc at
-  // the end of each case (its invalid, so it will get ignored). If loc is not
-  // returned, we hit an assert at the end to make it easy to identify a case
-  // was missed.
-  switch (inferBehavior) {
-  case SourceLocInferenceBehavior::None:
-    return SourceLoc();
-  case SourceLocInferenceBehavior::ForwardScanOnly: {
+  if (bool(inferBehavior & SourceLocInferenceBehavior::ForwardScan)) {
     SourceLoc newLoc = inferOptRemarkSearchForwards(i);
     if (newLoc.isValid())
       return newLoc;
-    return SourceLoc();
   }
-  case SourceLocInferenceBehavior::BackwardScanOnly: {
+
+  if (bool(inferBehavior & SourceLocInferenceBehavior::BackwardScan)) {
     SourceLoc newLoc = inferOptRemarkSearchBackwards(i);
     if (newLoc.isValid())
       return newLoc;
-    return SourceLoc();
   }
-  case SourceLocInferenceBehavior::ForwardThenBackward: {
+
+  if (bool(inferBehavior & SourceLocInferenceBehavior::ForwardScan2nd)) {
     SourceLoc newLoc = inferOptRemarkSearchForwards(i);
     if (newLoc.isValid())
       return newLoc;
-    newLoc = inferOptRemarkSearchBackwards(i);
-    if (newLoc.isValid())
-      return newLoc;
-    return SourceLoc();
-  }
-  case SourceLocInferenceBehavior::BackwardThenForward: {
-    SourceLoc newLoc = inferOptRemarkSearchBackwards(i);
-    if (newLoc.isValid())
-      return newLoc;
-    newLoc = inferOptRemarkSearchForwards(i);
-    if (newLoc.isValid())
-      return newLoc;
-    return SourceLoc();
-  }
   }
 
-  llvm_unreachable("Covered switch isn't covered?!");
+  return SourceLoc();
 }
 
 template <typename RemarkT, typename... ArgTypes>
diff --git a/lib/SIL/Utils/OwnershipUtils.cpp b/lib/SIL/Utils/OwnershipUtils.cpp
index 8ece70a..7cd18ae 100644
--- a/lib/SIL/Utils/OwnershipUtils.cpp
+++ b/lib/SIL/Utils/OwnershipUtils.cpp
@@ -12,6 +12,7 @@
 
 #include "swift/SIL/OwnershipUtils.h"
 #include "swift/Basic/Defer.h"
+#include "swift/SIL/InstructionUtils.h"
 #include "swift/SIL/LinearLifetimeChecker.h"
 #include "swift/SIL/Projection.h"
 #include "swift/SIL/SILArgument.h"
@@ -266,6 +267,48 @@
   }
 }
 
+bool BorrowingOperand::getImplicitUses(
+    SmallVectorImpl<Operand *> &foundUses,
+    std::function<void(Operand *)> *errorFunction) const {
+  if (!areAnyUserResultsBorrowIntroducers()) {
+    visitEndScopeInstructions([&](Operand *op) { foundUses.push_back(op); });
+    return false;
+  }
+
+  // Ok, we have an instruction that introduces a new borrow scope and its
+  // result is that borrow scope. In such a case, we need to not just add the
+  // end scope instructions of this scoped operand, but also look through any
+  // guaranteed phis and add their end_borrow to this list as well.
+  SmallVector<BorrowingOperand, 8> worklist;
+  SmallPtrSet<Operand *, 8> visitedValue;
+  worklist.push_back(*this);
+  visitedValue.insert(op);
+  bool foundError = false;
+  while (!worklist.empty()) {
+    auto scopedOperand = worklist.pop_back_val();
+    scopedOperand.visitConsumingUsesOfBorrowIntroducingUserResults(
+        [&](Operand *op) {
+          if (auto subSub = BorrowingOperand::get(op)) {
+            if (!visitedValue.insert(op).second) {
+              if (errorFunction) {
+                (*errorFunction)(op);
+              }
+              foundError = true;
+              return;
+            }
+
+            worklist.push_back(*subSub);
+            visitedValue.insert(subSub->op);
+            return;
+          }
+
+          foundUses.push_back(op);
+        });
+  }
+
+  return foundError;
+}
+
 //===----------------------------------------------------------------------===//
 //                             Borrow Introducers
 //===----------------------------------------------------------------------===//
@@ -460,6 +503,113 @@
 }
 
 //===----------------------------------------------------------------------===//
+//                           InteriorPointerOperand
+//===----------------------------------------------------------------------===//
+
+bool InteriorPointerOperand::getImplicitUses(
+    SmallVectorImpl<Operand *> &foundUses,
+    std::function<void(Operand *)> *onError) {
+  SILValue projectedAddress = getProjectedAddress();
+  SmallVector<Operand *, 8> worklist(projectedAddress->getUses());
+
+  bool foundError = false;
+
+  while (!worklist.empty()) {
+    auto *op = worklist.pop_back_val();
+
+    // Skip type dependent operands.
+    if (op->isTypeDependent())
+      continue;
+
+    // Before we do anything, add this operand to our implicit regular user
+    // list.
+    foundUses.push_back(op);
+
+    // Then update the worklist with new things to find if we recognize this
+    // inst and then continue. If we fail, we emit an error at the bottom of the
+    // loop that we didn't recognize the user.
+    auto *user = op->getUser();
+
+    // First, eliminate "end point uses" that we just need to check liveness at
+    // and do not need to check transitive uses of.
+    if (isa<LoadInst>(user) || isa<CopyAddrInst>(user) ||
+        isIncidentalUse(user) || isa<StoreInst>(user) ||
+        isa<StoreBorrowInst>(user) || isa<PartialApplyInst>(user) ||
+        isa<DestroyAddrInst>(user) || isa<AssignInst>(user) ||
+        isa<AddressToPointerInst>(user) || isa<YieldInst>(user) ||
+        isa<LoadUnownedInst>(user) || isa<StoreUnownedInst>(user) ||
+        isa<EndApplyInst>(user) || isa<LoadWeakInst>(user) ||
+        isa<StoreWeakInst>(user) || isa<AssignByWrapperInst>(user) ||
+        isa<BeginUnpairedAccessInst>(user) ||
+        isa<EndUnpairedAccessInst>(user) || isa<WitnessMethodInst>(user) ||
+        isa<SwitchEnumAddrInst>(user) || isa<CheckedCastAddrBranchInst>(user) ||
+        isa<SelectEnumAddrInst>(user)) {
+      continue;
+    }
+
+    // Then handle users that we need to look at transitive uses of.
+    if (Projection::isAddressProjection(user) ||
+        isa<ProjectBlockStorageInst>(user) ||
+        isa<OpenExistentialAddrInst>(user) ||
+        isa<InitExistentialAddrInst>(user) || isa<BeginAccessInst>(user) ||
+        isa<TailAddrInst>(user) || isa<IndexAddrInst>(user)) {
+      for (SILValue r : user->getResults()) {
+        llvm::copy(r->getUses(), std::back_inserter(worklist));
+      }
+      continue;
+    }
+
+    if (auto *builtin = dyn_cast<BuiltinInst>(user)) {
+      if (auto kind = builtin->getBuiltinKind()) {
+        if (*kind == BuiltinValueKind::TSanInoutAccess) {
+          continue;
+        }
+      }
+    }
+
+    // If we have a load_borrow, add it's end scope to the liveness requirement.
+    if (auto *lbi = dyn_cast<LoadBorrowInst>(user)) {
+      transform(lbi->getEndBorrows(), std::back_inserter(foundUses),
+                [](EndBorrowInst *ebi) { return &ebi->getAllOperands()[0]; });
+      continue;
+    }
+
+    // TODO: Merge this into the full apply site code below.
+    if (auto *beginApply = dyn_cast<BeginApplyInst>(user)) {
+      // TODO: Just add this to implicit regular user list?
+      llvm::copy(beginApply->getTokenResult()->getUses(),
+                 std::back_inserter(foundUses));
+      continue;
+    }
+
+    if (auto fas = FullApplySite::isa(user)) {
+      continue;
+    }
+
+    if (auto *mdi = dyn_cast<MarkDependenceInst>(user)) {
+      // If this is the base, just treat it as a liveness use.
+      if (op->get() == mdi->getBase()) {
+        continue;
+      }
+
+      // If we are the value use, look through it.
+      llvm::copy(mdi->getValue()->getUses(), std::back_inserter(worklist));
+      continue;
+    }
+
+    // We were unable to recognize this user, so return true that we failed.
+    if (onError) {
+      (*onError)(op);
+    }
+    foundError = true;
+  }
+
+  // We were able to recognize all of the uses of the address, so return false
+  // that we did not find any errors.
+  return foundError;
+}
+
+//===----------------------------------------------------------------------===//
 //                          Owned Value Introducers
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/SIL/Verifier/LinearLifetimeChecker.cpp b/lib/SIL/Verifier/LinearLifetimeChecker.cpp
index ee5bdf8..ebc26a6 100644
--- a/lib/SIL/Verifier/LinearLifetimeChecker.cpp
+++ b/lib/SIL/Verifier/LinearLifetimeChecker.cpp
@@ -682,7 +682,6 @@
 bool LinearLifetimeChecker::usesNotContainedWithinLifetime(
     SILValue value, ArrayRef<Operand *> consumingUses,
     ArrayRef<Operand *> usesToTest) {
-
   auto errorBehavior = ErrorBehaviorKind(
       ErrorBehaviorKind::ReturnFalse |
       ErrorBehaviorKind::StoreNonConsumingUsesOutsideLifetime);
@@ -707,7 +706,13 @@
   assert(numFoundUses == uniqueUsers.size());
 #endif
 
-  // Return true if we /did/ found an error and when emitting that error, we
+  // If we found any error except for uses outside of our lifetime, bail.
+  if (error.getFoundLeak() || error.getFoundOverConsume() ||
+      error.getFoundUseAfterFree())
+    return false;
+
+  // Return true if we /did/ find an error and when emitting that error, we
   // found /all/ uses we were looking for.
-  return error.getFoundError() && numFoundUses == usesToTest.size();
+  return error.getFoundUseOutsideOfLifetime() &&
+         numFoundUses == usesToTest.size();
 }
diff --git a/lib/SIL/Verifier/SILOwnershipVerifier.cpp b/lib/SIL/Verifier/SILOwnershipVerifier.cpp
index f829349..8490e00 100644
--- a/lib/SIL/Verifier/SILOwnershipVerifier.cpp
+++ b/lib/SIL/Verifier/SILOwnershipVerifier.cpp
@@ -99,14 +99,6 @@
   /// is successful.
   SmallVector<Operand *, 16> regularUsers;
 
-  /// The list of implicit non lifetime ending users that we found. This
-  /// consists of instructions like end_borrow that end a scoped lifetime. We
-  /// must treat those as regular uses and ensure that our value is not
-  /// destroyed while that sub-scope is valid.
-  ///
-  /// TODO: Rename to SubBorrowScopeUsers?
-  SmallVector<Operand *, 4> implicitRegularUsers;
-
   /// The set of blocks that we have visited.
   SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks;
 
@@ -133,13 +125,10 @@
   bool isCompatibleDefUse(Operand *op, ValueOwnershipKind ownershipKind);
 
   bool gatherUsers(SmallVectorImpl<Operand *> &lifetimeEndingUsers,
-                   SmallVectorImpl<Operand *> &regularUsers,
-                   SmallVectorImpl<Operand *> &implicitRegularUsers);
+                   SmallVectorImpl<Operand *> &regularUsers);
 
-  bool
-  gatherNonGuaranteedUsers(SmallVectorImpl<Operand *> &lifetimeEndingUsers,
-                           SmallVectorImpl<Operand *> &regularUsers,
-                           SmallVectorImpl<Operand *> &implicitRegularUsers);
+  bool gatherNonGuaranteedUsers(SmallVectorImpl<Operand *> &lifetimeEndingUsers,
+                                SmallVectorImpl<Operand *> &regularUsers);
 
   bool checkValueWithoutLifetimeEndingUses();
 
@@ -152,12 +141,6 @@
   bool isSubobjectProjectionWithLifetimeEndingUses(
       SILValue value,
       const SmallVectorImpl<Operand *> &lifetimeEndingUsers) const;
-  bool discoverBorrowOperandImplicitRegularUsers(
-      const BorrowingOperand &initialScopedOperand,
-      SmallVectorImpl<Operand *> &implicitRegularUsers, bool isGuaranteed);
-  bool discoverInteriorPointerOperandImplicitRegularUsers(
-      const InteriorPointerOperand &interiorPointerOperand,
-      SmallVectorImpl<Operand *> &implicitRegularUsers);
 };
 
 } // namespace swift
@@ -175,7 +158,6 @@
   llvm::copy(lifetimeEndingUsers, std::back_inserter(allLifetimeEndingUsers));
   SmallVector<Operand *, 32> allRegularUsers;
   llvm::copy(regularUsers, std::back_inserter(allRegularUsers));
-  llvm::copy(implicitRegularUsers, std::back_inserter(allRegularUsers));
 
   LinearLifetimeChecker checker(visitedBlocks, deadEndBlocks);
   auto linearLifetimeResult = checker.checkValue(value, allLifetimeEndingUsers,
@@ -227,165 +209,9 @@
   return false;
 }
 
-/// Returns true if an error was found.
-bool SILValueOwnershipChecker::discoverBorrowOperandImplicitRegularUsers(
-    const BorrowingOperand &initialScopedOperand,
-    SmallVectorImpl<Operand *> &implicitRegularUsers, bool isGuaranteed) {
-  if (!initialScopedOperand.areAnyUserResultsBorrowIntroducers()) {
-    initialScopedOperand.visitEndScopeInstructions(
-        [&](Operand *op) { implicitRegularUsers.push_back(op); });
-    return false;
-  }
-
-  // Ok, we have an instruction that introduces a new borrow scope and its
-  // result is that borrow scope. In such a case, we need to not just add the
-  // end scope instructions of this scoped operand, but also look through any
-  // guaranteed phis and add their end_borrow to this list as well.
-  SmallVector<BorrowingOperand, 8> worklist;
-  SmallPtrSet<Operand *, 8> visitedValue;
-  worklist.push_back(initialScopedOperand);
-  visitedValue.insert(initialScopedOperand.op);
-  bool foundError = false;
-  while (!worklist.empty()) {
-    auto scopedOperand = worklist.pop_back_val();
-    scopedOperand.visitConsumingUsesOfBorrowIntroducingUserResults(
-        [&](Operand *op) {
-          if (auto subSub = BorrowingOperand::get(op)) {
-            if (!visitedValue.insert(op).second) {
-              errorBuilder.handleMalformedSIL([&] {
-                llvm::errs()
-                    << "Implicit Regular User Guaranteed Phi Cycle!\n"
-                    << "User: " << *op->getUser()
-                    << "Initial: " << initialScopedOperand << "\n";
-              });
-              foundError = true;
-              return;
-            }
-
-            worklist.push_back(*subSub);
-            visitedValue.insert(subSub->op);
-            return;
-          }
-
-          implicitRegularUsers.push_back(op);
-        });
-  }
-
-  return foundError;
-}
-
-bool SILValueOwnershipChecker::
-    discoverInteriorPointerOperandImplicitRegularUsers(
-        const InteriorPointerOperand &interiorPointerOperand,
-        SmallVectorImpl<Operand *> &implicitRegularUsers) {
-  SILValue projectedAddress = interiorPointerOperand.getProjectedAddress();
-  SmallVector<Operand *, 8> worklist(projectedAddress->getUses());
-
-  bool foundError = false;
-
-  while (!worklist.empty()) {
-    auto *op = worklist.pop_back_val();
-
-    // Skip type dependent operands.
-    if (op->isTypeDependent())
-      continue;
-
-    // Before we do anything, add this operand to our implicit regular user
-    // list.
-    implicitRegularUsers.push_back(op);
-
-    // Then update the worklist with new things to find if we recognize this
-    // inst and then continue. If we fail, we emit an error at the bottom of the
-    // loop that we didn't recognize the user.
-    auto *user = op->getUser();
-
-    // First, eliminate "end point uses" that we just need to check liveness at
-    // and do not need to check transitive uses of.
-    if (isa<LoadInst>(user) || isa<CopyAddrInst>(user) ||
-        isIncidentalUse(user) || isa<StoreInst>(user) ||
-        isa<StoreBorrowInst>(user) || isa<PartialApplyInst>(user) ||
-        isa<DestroyAddrInst>(user) || isa<AssignInst>(user) ||
-        isa<AddressToPointerInst>(user) || isa<YieldInst>(user) ||
-        isa<LoadUnownedInst>(user) || isa<StoreUnownedInst>(user) ||
-        isa<EndApplyInst>(user) || isa<LoadWeakInst>(user) ||
-        isa<StoreWeakInst>(user) || isa<AssignByWrapperInst>(user) ||
-        isa<BeginUnpairedAccessInst>(user) ||
-        isa<EndUnpairedAccessInst>(user) || isa<WitnessMethodInst>(user) ||
-        isa<SwitchEnumAddrInst>(user) || isa<CheckedCastAddrBranchInst>(user) ||
-        isa<SelectEnumAddrInst>(user)) {
-      continue;
-    }
-
-    // Then handle users that we need to look at transitive uses of.
-    if (Projection::isAddressProjection(user) ||
-        isa<ProjectBlockStorageInst>(user) ||
-        isa<OpenExistentialAddrInst>(user) ||
-        isa<InitExistentialAddrInst>(user) || isa<BeginAccessInst>(user) ||
-        isa<TailAddrInst>(user) || isa<IndexAddrInst>(user)) {
-      for (SILValue r : user->getResults()) {
-        llvm::copy(r->getUses(), std::back_inserter(worklist));
-      }
-      continue;
-    }
-
-    if (auto *builtin = dyn_cast<BuiltinInst>(user)) {
-      if (auto kind = builtin->getBuiltinKind()) {
-        if (*kind == BuiltinValueKind::TSanInoutAccess) {
-          continue;
-        }
-      }
-    }
-
-    // If we have a load_borrow, add it's end scope to the liveness requirement.
-    if (auto *lbi = dyn_cast<LoadBorrowInst>(user)) {
-      transform(lbi->getEndBorrows(), std::back_inserter(implicitRegularUsers),
-                [](EndBorrowInst *ebi) { return &ebi->getAllOperands()[0]; });
-      continue;
-    }
-
-    // TODO: Merge this into the full apply site code below.
-    if (auto *beginApply = dyn_cast<BeginApplyInst>(user)) {
-      // TODO: Just add this to implicit regular user list?
-      llvm::copy(beginApply->getTokenResult()->getUses(),
-                 std::back_inserter(implicitRegularUsers));
-      continue;
-    }
-
-    if (auto fas = FullApplySite::isa(user)) {
-      continue;
-    }
-
-    if (auto *mdi = dyn_cast<MarkDependenceInst>(user)) {
-      // If this is the base, just treat it as a liveness use.
-      if (op->get() == mdi->getBase()) {
-        continue;
-      }
-
-      // If we are the value use, look through it.
-      llvm::copy(mdi->getValue()->getUses(), std::back_inserter(worklist));
-      continue;
-    }
-
-    // We were unable to recognize this user, so return true that we failed.
-    errorBuilder.handleMalformedSIL([&] {
-      llvm::errs()
-          << "Could not recognize address user of interior pointer operand!\n"
-          << "Interior Pointer Operand: "
-          << *interiorPointerOperand.operand->getUser()
-          << "Address User: " << *op->getUser();
-    });
-    foundError = true;
-  }
-
-  // We were able to recognize all of the uses of the address, so return false
-  // that we did not find any errors.
-  return foundError;
-}
-
 bool SILValueOwnershipChecker::gatherNonGuaranteedUsers(
     SmallVectorImpl<Operand *> &lifetimeEndingUsers,
-    SmallVectorImpl<Operand *> &nonLifetimeEndingUsers,
-    SmallVectorImpl<Operand *> &implicitRegularUsers) {
+    SmallVectorImpl<Operand *> &nonLifetimeEndingUsers) {
   bool foundError = false;
 
   auto ownershipKind = value.getOwnershipKind();
@@ -442,8 +268,15 @@
     // initial end scope instructions without any further work.
     //
     // Maybe: Is borrow scope non-local?
-    foundError |= discoverBorrowOperandImplicitRegularUsers(
-        *initialScopedOperand, implicitRegularUsers, false);
+    std::function<void(Operand *)> error = [&](Operand *op) {
+      errorBuilder.handleMalformedSIL([&] {
+        llvm::errs() << "Implicit Regular User Guaranteed Phi Cycle!\n"
+                     << "User: " << *op->getUser()
+                     << "Initial: " << *initialScopedOperand << "\n";
+      });
+    };
+    foundError |=
+        initialScopedOperand->getImplicitUses(nonLifetimeEndingUsers, &error);
   }
 
   return foundError;
@@ -451,16 +284,15 @@
 
 bool SILValueOwnershipChecker::gatherUsers(
     SmallVectorImpl<Operand *> &lifetimeEndingUsers,
-    SmallVectorImpl<Operand *> &nonLifetimeEndingUsers,
-    SmallVectorImpl<Operand *> &implicitRegularUsers) {
+    SmallVectorImpl<Operand *> &nonLifetimeEndingUsers) {
 
   // See if Value is guaranteed. If we are guaranteed and not forwarding, then
   // we need to look through subobject uses for more uses. Otherwise, if we are
   // forwarding, we do not create any lifetime ending users/non lifetime ending
   // users since we verify against our base.
   if (value.getOwnershipKind() != ValueOwnershipKind::Guaranteed) {
-    return !gatherNonGuaranteedUsers(
-        lifetimeEndingUsers, nonLifetimeEndingUsers, implicitRegularUsers);
+    return !gatherNonGuaranteedUsers(lifetimeEndingUsers,
+                                     nonLifetimeEndingUsers);
   }
 
   // Ok, we have a value with guarantee ownership. Before we continue, check if
@@ -533,16 +365,32 @@
       if (auto scopedOperand = BorrowingOperand::get(op)) {
         assert(!scopedOperand->consumesGuaranteedValues());
 
-        foundError |= discoverBorrowOperandImplicitRegularUsers(
-            *scopedOperand, implicitRegularUsers, true);
+        std::function<void(Operand *)> onError = [&](Operand *op) {
+          errorBuilder.handleMalformedSIL([&] {
+            llvm::errs() << "Implicit Regular User Guaranteed Phi Cycle!\n"
+                         << "User: " << *op->getUser()
+                         << "Initial: " << *scopedOperand << "\n";
+          });
+        };
+        foundError |=
+            scopedOperand->getImplicitUses(nonLifetimeEndingUsers, &onError);
       }
 
       // Next see if our use is an interior pointer operand. If we have an
       // interior pointer, we need to add all of its address uses as "implicit
       // regular users" of our consumed value.
       if (auto interiorPointerOperand = InteriorPointerOperand::get(op)) {
-        foundError |= discoverInteriorPointerOperandImplicitRegularUsers(
-            *interiorPointerOperand, implicitRegularUsers);
+        std::function<void(Operand *)> onError = [&](Operand *op) {
+          errorBuilder.handleMalformedSIL([&] {
+            llvm::errs() << "Could not recognize address user of interior "
+                            "pointer operand!\n"
+                         << "Interior Pointer Operand: "
+                         << interiorPointerOperand->operand->getUser()
+                         << "Address User: " << *op->getUser();
+          });
+        };
+        foundError |= interiorPointerOperand->getImplicitUses(
+            nonLifetimeEndingUsers, &onError);
       }
 
       // Finally add the op to the non lifetime ending user list.
@@ -759,7 +607,7 @@
   // 1. Verify that none of the uses are in the same block. This would be an
   // overconsume so in this case we assert.
   // 2. Verify that the uses are compatible with our ownership convention.
-  if (!gatherUsers(lifetimeEndingUsers, regularUsers, implicitRegularUsers)) {
+  if (!gatherUsers(lifetimeEndingUsers, regularUsers)) {
     // Silently return false if this fails.
     //
     // If the user pass in a ErrorBehaviorKind that will assert, we
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index ecd8482..49433302 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -676,17 +676,56 @@
 
 void SILGenModule::visitFuncDecl(FuncDecl *fd) { emitFunction(fd); }
 
-static void emitDelayedFunction(SILGenModule &SGM,
-                                SILDeclRef constant,
-                                SILFunction *f) {
+void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
+
+  if (constant.isForeignToNativeThunk()) {
+    f->setThunk(IsThunk);
+    if (constant.asForeign().isClangGenerated())
+      f->setSerialized(IsSerializable);
+
+    auto loc = constant.getAsRegularLocation();
+    loc.markAutoGenerated();
+    auto *dc = loc.getAsDeclContext();
+    assert(dc);
+
+    preEmitFunction(constant, f, loc);
+    PrettyStackTraceSILFunction X("silgen emitForeignToNativeThunk", f);
+    SILGenFunction(*this, *f, dc).emitForeignToNativeThunk(constant);
+    postEmitFunction(constant, f);
+    return;
+  }
+
+  if (constant.isNativeToForeignThunk()) {
+    auto loc = constant.getAsRegularLocation();
+    loc.markAutoGenerated();
+    auto *dc = loc.getAsDeclContext();
+    assert(dc);
+
+    preEmitFunction(constant, f, loc);
+    PrettyStackTraceSILFunction X("silgen emitNativeToForeignThunk", f);
+    f->setBare(IsBare);
+    f->setThunk(IsThunk);
+    SILGenFunction(*this, *f, dc).emitNativeToForeignThunk(constant);
+    postEmitFunction(constant, f);
+    return;
+  }
+
   switch (constant.kind) {
   case SILDeclRef::Kind::Func: {
+    if (auto *ce = constant.getAbstractClosureExpr()) {
+      preEmitFunction(constant, f, ce);
+      PrettyStackTraceSILFunction X("silgen closureexpr", f);
+      SILGenFunction(*this, *f, ce).emitClosure(ce);
+      postEmitFunction(constant, f);
+      break;
+    }
+
     auto *fd = cast<FuncDecl>(constant.getDecl());
 
-    SGM.preEmitFunction(constant, fd, f, fd);
+    preEmitFunction(constant, f, fd);
     PrettyStackTraceSILFunction X("silgen emitFunction", f);
-    SILGenFunction(SGM, *f, fd).emitFunction(fd);
-    SGM.postEmitFunction(constant, f);
+    SILGenFunction(*this, *f, fd).emitFunction(fd);
+    postEmitFunction(constant, f);
     break;
   }
 
@@ -696,16 +735,16 @@
     if (decl->getDeclContext()->getSelfClassDecl() &&
         (decl->isDesignatedInit() ||
          decl->isObjC())) {
-      SGM.preEmitFunction(constant, decl, f, decl);
+      preEmitFunction(constant, f, decl);
       PrettyStackTraceSILFunction X("silgen emitConstructor", f);
-      SILGenFunction(SGM, *f, decl).emitClassConstructorAllocator(decl);
-      SGM.postEmitFunction(constant, f);
+      SILGenFunction(*this, *f, decl).emitClassConstructorAllocator(decl);
+      postEmitFunction(constant, f);
     } else {
-      SGM.preEmitFunction(constant, decl, f, decl);
+      preEmitFunction(constant, f, decl);
       PrettyStackTraceSILFunction X("silgen emitConstructor", f);
       f->createProfiler(decl, constant, ForDefinition);
-      SILGenFunction(SGM, *f, decl).emitValueConstructor(decl);
-      SGM.postEmitFunction(constant, f);
+      SILGenFunction(*this, *f, decl).emitValueConstructor(decl);
+      postEmitFunction(constant, f);
     }
     break;
   }
@@ -714,11 +753,11 @@
     auto *decl = cast<ConstructorDecl>(constant.getDecl());
     assert(decl->getDeclContext()->getSelfClassDecl());
 
-    SGM.preEmitFunction(constant, decl, f, decl);
+    preEmitFunction(constant, f, decl);
     PrettyStackTraceSILFunction X("silgen constructor initializer", f);
     f->createProfiler(decl, constant, ForDefinition);
-    SILGenFunction(SGM, *f, decl).emitClassConstructorInitializer(decl);
-    SGM.postEmitFunction(constant, f);
+    SILGenFunction(*this, *f, decl).emitClassConstructorInitializer(decl);
+    postEmitFunction(constant, f);
     break;
   }
 
@@ -731,22 +770,22 @@
     case DefaultArgumentKind::Normal: {
       auto arg = param->getTypeCheckedDefaultExpr();
       auto loc = RegularLocation::getAutoGeneratedLocation(arg);
-      SGM.preEmitFunction(constant, arg, f, loc);
+      preEmitFunction(constant, f, loc);
       PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
-      SILGenFunction SGF(SGM, *f, initDC);
+      SILGenFunction SGF(*this, *f, initDC);
       SGF.emitGeneratorFunction(constant, arg);
-      SGM.postEmitFunction(constant, f);
+      postEmitFunction(constant, f);
       break;
     }
 
     case DefaultArgumentKind::StoredProperty: {
       auto arg = param->getStoredProperty();
       auto loc = RegularLocation::getAutoGeneratedLocation(arg);
-      SGM.preEmitFunction(constant, arg, f, loc);
+      preEmitFunction(constant, f, loc);
       PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
-      SILGenFunction SGF(SGM, *f, initDC);
+      SILGenFunction SGF(*this, *f, initDC);
       SGF.emitGeneratorFunction(constant, arg);
-      SGM.postEmitFunction(constant, f);
+      postEmitFunction(constant, f);
       break;
     }
 
@@ -780,23 +819,23 @@
     }
 
     auto loc = RegularLocation::getAutoGeneratedLocation(init);
-    SGM.preEmitFunction(constant, init, f, loc);
+    preEmitFunction(constant, f, loc);
     PrettyStackTraceSILFunction X("silgen emitStoredPropertyInitialization", f);
     f->createProfiler(init, constant, ForDefinition);
-    SILGenFunction SGF(SGM, *f, initDC);
+    SILGenFunction SGF(*this, *f, initDC);
 
     // If this is a stored property initializer inside a type at global scope,
     // it may close over a global variable. If we're emitting top-level code,
     // then emit a "mark_function_escape" that lists the captured global
     // variables so that definite initialization can reason about this
     // escape point.
-    if (!var->getDeclContext()->isLocalContext() &&
-        SGM.TopLevelSGF && SGM.TopLevelSGF->B.hasValidInsertionPoint()) {
-      SGM.emitMarkFunctionEscapeForTopLevelCodeGlobals(var, captureInfo);
+    if (!var->getDeclContext()->isLocalContext() &&  TopLevelSGF &&
+        TopLevelSGF->B.hasValidInsertionPoint()) {
+      emitMarkFunctionEscapeForTopLevelCodeGlobals(var, captureInfo);
     }
 
     SGF.emitGeneratorFunction(constant, init, /*EmitProfilerIncrement=*/true);
-    SGM.postEmitFunction(constant, f);
+    postEmitFunction(constant, f);
     break;
   }
 
@@ -804,7 +843,7 @@
     auto *var = cast<VarDecl>(constant.getDecl());
 
     auto loc = RegularLocation::getAutoGeneratedLocation(var);
-    SGM.preEmitFunction(constant, var, f, loc);
+    preEmitFunction(constant, f, loc);
     PrettyStackTraceSILFunction X(
         "silgen emitPropertyWrapperBackingInitializer", f);
     auto wrapperInfo = var->getPropertyWrapperBackingPropertyInfo();
@@ -812,26 +851,26 @@
     f->createProfiler(wrapperInfo.initializeFromOriginal, constant,
                       ForDefinition);
     auto varDC = var->getInnermostDeclContext();
-    SILGenFunction SGF(SGM, *f, varDC);
+    SILGenFunction SGF(*this, *f, varDC);
     SGF.emitGeneratorFunction(constant, wrapperInfo.initializeFromOriginal);
-    SGM.postEmitFunction(constant, f);
+    postEmitFunction(constant, f);
     break;
   }
 
   case SILDeclRef::Kind::GlobalAccessor: {
     auto *global = cast<VarDecl>(constant.getDecl());
-    auto found = SGM.delayedGlobals.find(global);
-    assert(found != SGM.delayedGlobals.end());
+    auto found = delayedGlobals.find(global);
+    assert(found != delayedGlobals.end());
 
     auto *onceToken = found->second.first;
     auto *onceFunc = found->second.second;
 
     auto loc = RegularLocation::getAutoGeneratedLocation(global);
-    SGM.preEmitFunction(constant, global, f, loc);
+    preEmitFunction(constant, f, loc);
     PrettyStackTraceSILFunction X("silgen emitGlobalAccessor", f);
-    SILGenFunction(SGM, *f, global->getDeclContext())
+    SILGenFunction(*this, *f, global->getDeclContext())
       .emitGlobalAccessor(global, onceToken, onceFunc);
-    SGM.postEmitFunction(constant, f);
+    postEmitFunction(constant, f);
     break;
   }
 
@@ -839,19 +878,63 @@
     auto *decl = cast<EnumElementDecl>(constant.getDecl());
 
     auto loc = RegularLocation::getAutoGeneratedLocation(decl);
-    SGM.preEmitFunction(constant, decl, f, loc);
+    preEmitFunction(constant, f, loc);
     PrettyStackTraceSILFunction X("silgen enum constructor", f);
-    SILGenFunction(SGM, *f, decl->getDeclContext()).emitEnumConstructor(decl);
-    SGM.postEmitFunction(constant, f);
+    SILGenFunction(*this, *f, decl->getDeclContext()).emitEnumConstructor(decl);
+    postEmitFunction(constant, f);
     break;
   }
 
-  case SILDeclRef::Kind::Destroyer:
-  case SILDeclRef::Kind::Deallocator:
-  case SILDeclRef::Kind::IVarInitializer:
-  case SILDeclRef::Kind::IVarDestroyer:
-    llvm_unreachable("Cannot emit as a delayed function");
-    break;
+  case SILDeclRef::Kind::Destroyer: {
+    auto *dd = cast<DestructorDecl>(constant.getDecl());
+    preEmitFunction(constant, f, dd);
+    PrettyStackTraceSILFunction X("silgen emitDestroyingDestructor", f);
+    SILGenFunction(*this, *f, dd).emitDestroyingDestructor(dd);
+    postEmitFunction(constant, f);
+    return;
+  }
+
+  case SILDeclRef::Kind::Deallocator: {
+    auto *dd = cast<DestructorDecl>(constant.getDecl());
+    auto *cd = cast<ClassDecl>(dd->getDeclContext());
+
+    if (usesObjCAllocator(cd)) {
+      preEmitFunction(constant, f, dd);
+      PrettyStackTraceSILFunction X("silgen emitDestructor -dealloc", f);
+      f->createProfiler(dd, constant, ForDefinition);
+      SILGenFunction(*this, *f, dd).emitObjCDestructor(constant);
+      postEmitFunction(constant, f);
+      return;
+    }
+
+    auto loc = RegularLocation::getAutoGeneratedLocation(dd);
+    preEmitFunction(constant, f, loc);
+    PrettyStackTraceSILFunction X("silgen emitDeallocatingDestructor", f);
+    f->createProfiler(dd, constant, ForDefinition);
+    SILGenFunction(*this, *f, dd).emitDeallocatingDestructor(dd);
+    postEmitFunction(constant, f);
+    return;
+  }
+
+  case SILDeclRef::Kind::IVarInitializer: {
+    auto *cd = cast<ClassDecl>(constant.getDecl());
+    auto loc = RegularLocation::getAutoGeneratedLocation(cd);
+    preEmitFunction(constant, f, loc);
+    PrettyStackTraceSILFunction X("silgen emitDestructor ivar initializer", f);
+    SILGenFunction(*this, *f, cd).emitIVarInitializer(constant);
+    postEmitFunction(constant, f);
+    return;
+  }
+
+  case SILDeclRef::Kind::IVarDestroyer: {
+    auto *cd = cast<ClassDecl>(constant.getDecl());
+    auto loc = RegularLocation::getAutoGeneratedLocation(cd);
+    preEmitFunction(constant, f, loc);
+    PrettyStackTraceSILFunction X("silgen emitDestructor ivar destroyer", f);
+    SILGenFunction(*this, *f, cd).emitIVarDestroyer(constant);
+    postEmitFunction(constant, f);
+    return;
+  }
   }
 }
 
@@ -889,22 +972,11 @@
     return;
   }
 
-  emitDelayedFunction(SGM, constant, f);
+  SGM.emitFunctionDefinition(constant, f);
 }
 
-void SILGenModule::preEmitFunction(SILDeclRef constant,
-                              llvm::PointerUnion<ValueDecl *,
-                                                 Expr *> astNode,
-                                   SILFunction *F,
+void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
                                    SILLocation Loc) {
-  // By default, use the astNode to create the location.
-  if (Loc.isNull()) {
-    if (auto *decl = astNode.get<ValueDecl *>())
-      Loc = RegularLocation(decl);
-    else
-      Loc = RegularLocation(astNode.get<Expr *>());
-  }
-
   assert(F->empty() && "already emitted function?!");
 
   if (F->getLoweredFunctionType()->isPolymorphic())
@@ -918,14 +990,12 @@
              llvm::dbgs() << " : ";
              F->getLoweredType().print(llvm::dbgs());
              llvm::dbgs() << '\n';
-             if (astNode) {
-               if (auto *decl = astNode.dyn_cast<ValueDecl *>()) {
-                 decl->dump(llvm::dbgs());
-               } else {
-                 astNode.get<Expr *>()->dump(llvm::dbgs());
-                 llvm::dbgs() << "\n";
-               }
+             if (auto *decl = Loc.getAsASTNode<ValueDecl>()) {
+               decl->dump(llvm::dbgs());
                llvm::dbgs() << '\n';
+             } else if (auto *expr = Loc.getAsASTNode<Expr>()) {
+               expr->dump(llvm::dbgs());
+               llvm::dbgs() << "\n";
              });
 }
 
@@ -1178,10 +1248,8 @@
   // initializer of the containing type.
   if (!f->isExternalDeclaration())
     return f;
-  preEmitFunction(constant, ce, f, ce);
-  PrettyStackTraceSILFunction X("silgen closureexpr", f);
-  SILGenFunction(*this, *f, ce).emitClosure(ce);
-  postEmitFunction(constant, f);
+
+  emitFunctionDefinition(constant, f);
   return f;
 }
 
@@ -1232,12 +1300,7 @@
   // Destructors are a necessary part of class metadata, so can't be delayed.
   if (dd->hasBody()) {
     SILDeclRef dealloc(dd, SILDeclRef::Kind::Deallocator);
-    SILFunction *f = getFunction(dealloc, ForDefinition);
-    preEmitFunction(dealloc, dd, f, dd);
-    PrettyStackTraceSILFunction X("silgen emitDestructor -dealloc", f);
-    f->createProfiler(dd, dealloc, ForDefinition);
-    SILGenFunction(*this, *f, dd).emitObjCDestructor(dealloc);
-    postEmitFunction(dealloc, f);
+    emitFunctionDefinition(dealloc, getFunction(dealloc, ForDefinition));
   }
 
   // Emit the Objective-C -dealloc entry point if it has
@@ -1249,24 +1312,16 @@
   if (requiresIVarInitialization(*this, cd)) {
     auto ivarInitializer = SILDeclRef(cd, SILDeclRef::Kind::IVarInitializer)
       .asForeign();
-    SILFunction *f = getFunction(ivarInitializer, ForDefinition);
-    auto loc = RegularLocation::getAutoGeneratedLocation(dd);
-    preEmitFunction(ivarInitializer, dd, f, loc);
-    PrettyStackTraceSILFunction X("silgen emitDestructor ivar initializer", f);
-    SILGenFunction(*this, *f, cd).emitIVarInitializer(ivarInitializer);
-    postEmitFunction(ivarInitializer, f);
+    emitFunctionDefinition(ivarInitializer,
+                           getFunction(ivarInitializer, ForDefinition));
   }
 
   // Emit the ivar destroyer, if needed.
   if (hasNonTrivialIVars(cd)) {
     auto ivarDestroyer = SILDeclRef(cd, SILDeclRef::Kind::IVarDestroyer)
       .asForeign();
-    SILFunction *f = getFunction(ivarDestroyer, ForDefinition);
-    auto loc = RegularLocation::getAutoGeneratedLocation(dd);
-    preEmitFunction(ivarDestroyer, dd, f, loc);
-    PrettyStackTraceSILFunction X("silgen emitDestructor ivar destroyer", f);
-    SILGenFunction(*this, *f, cd).emitIVarDestroyer(ivarDestroyer);
-    postEmitFunction(ivarDestroyer, f);
+    emitFunctionDefinition(ivarDestroyer,
+                           getFunction(ivarDestroyer, ForDefinition));
   }
 }
 
@@ -1276,12 +1331,8 @@
   // Emit the ivar destroyer, if needed.
   if (requiresIVarDestroyer(cd)) {
     SILDeclRef ivarDestroyer(cd, SILDeclRef::Kind::IVarDestroyer);
-    SILFunction *f = getFunction(ivarDestroyer, ForDefinition);
-    auto loc = RegularLocation::getAutoGeneratedLocation(dd);
-    preEmitFunction(ivarDestroyer, dd, f, loc);
-    PrettyStackTraceSILFunction X("silgen emitDestructor ivar destroyer", f);
-    SILGenFunction(*this, *f, dd).emitIVarDestroyer(ivarDestroyer);
-    postEmitFunction(ivarDestroyer, f);
+    emitFunctionDefinition(ivarDestroyer,
+                           getFunction(ivarDestroyer, ForDefinition));
   }
 
   // If the class would use the Objective-C allocator, only emit -dealloc.
@@ -1294,24 +1345,14 @@
   // Destructors are a necessary part of class metadata, so can't be delayed.
   if (dd->hasBody()) {
     SILDeclRef destroyer(dd, SILDeclRef::Kind::Destroyer);
-    SILFunction *f = getFunction(destroyer, ForDefinition);
-    RegularLocation loc(dd);
-    preEmitFunction(destroyer, dd, f, loc);
-    PrettyStackTraceSILFunction X("silgen emitDestroyingDestructor", f);
-    SILGenFunction(*this, *f, dd).emitDestroyingDestructor(dd);
-    postEmitFunction(destroyer, f);
+    emitFunctionDefinition(destroyer, getFunction(destroyer, ForDefinition));
   }
 
   // Emit the deallocating destructor.
   {
     SILDeclRef deallocator(dd, SILDeclRef::Kind::Deallocator);
-    SILFunction *f = getFunction(deallocator, ForDefinition);
-    auto loc = RegularLocation::getAutoGeneratedLocation(dd);
-    preEmitFunction(deallocator, dd, f, loc);
-    PrettyStackTraceSILFunction X("silgen emitDeallocatingDestructor", f);
-    f->createProfiler(dd, deallocator, ForDefinition);
-    SILGenFunction(*this, *f, dd).emitDeallocatingDestructor(dd);
-    postEmitFunction(deallocator, f);
+    emitFunctionDefinition(deallocator,
+                           getFunction(deallocator, ForDefinition));
   }
 }
 
@@ -1404,14 +1445,7 @@
     return;
 
   // ObjC entry points are always externally usable, so can't be delay-emitted.
-
-  SILFunction *f = getFunction(thunk, ForDefinition);
-  preEmitFunction(thunk, method, f, method);
-  PrettyStackTraceSILFunction X("silgen emitObjCMethodThunk", f);
-  f->setBare(IsBare);
-  f->setThunk(IsThunk);
-  SILGenFunction(*this, *f, method).emitNativeToForeignThunk(thunk);
-  postEmitFunction(thunk, f);
+  emitNativeToForeignThunk(thunk);
 }
 
 void SILGenModule::emitObjCPropertyMethodThunks(AbstractStorageDecl *prop) {
@@ -1427,18 +1461,9 @@
   if (hasFunction(getterRef))
     return;
 
-  auto thunkBodyLoc = RegularLocation::getAutoGeneratedLocation(prop);
   // ObjC entry points are always externally usable, so emitting can't be
   // delayed.
-  {
-    SILFunction *f = getFunction(getterRef, ForDefinition);
-    preEmitFunction(getterRef, prop, f, thunkBodyLoc);
-    PrettyStackTraceSILFunction X("silgen objc property getter thunk", f);
-    f->setBare(IsBare);
-    f->setThunk(IsThunk);
-    SILGenFunction(*this, *f, getter).emitNativeToForeignThunk(getterRef);
-    postEmitFunction(getterRef, f);
-  }
+  emitNativeToForeignThunk(getterRef);
 
   if (!prop->isSettable(prop->getDeclContext()))
     return;
@@ -1446,14 +1471,7 @@
   // FIXME: Add proper location.
   auto *setter = prop->getOpaqueAccessor(AccessorKind::Set);
   auto setterRef = SILDeclRef(setter, SILDeclRef::Kind::Func).asForeign();
-
-  SILFunction *f = getFunction(setterRef, ForDefinition);
-  preEmitFunction(setterRef, prop, f, thunkBodyLoc);
-  PrettyStackTraceSILFunction X("silgen objc property setter thunk", f);
-  f->setBare(IsBare);
-  f->setThunk(IsThunk);
-  SILGenFunction(*this, *f, setter).emitNativeToForeignThunk(setterRef);
-  postEmitFunction(setterRef, f);
+  emitNativeToForeignThunk(setterRef);
 }
 
 void SILGenModule::emitObjCConstructorThunk(ConstructorDecl *constructor) {
@@ -1465,15 +1483,7 @@
     return;
   // ObjC entry points are always externally usable, so emitting can't be
   // delayed.
-
-  SILFunction *f = getFunction(thunk, ForDefinition);
-  auto loc = RegularLocation::getAutoGeneratedLocation(constructor);
-  preEmitFunction(thunk, constructor, f, loc);
-  PrettyStackTraceSILFunction X("silgen objc constructor thunk", f);
-  f->setBare(IsBare);
-  f->setThunk(IsThunk);
-  SILGenFunction(*this, *f, constructor).emitNativeToForeignThunk(thunk);
-  postEmitFunction(thunk, f);
+  emitNativeToForeignThunk(thunk);
 }
 
 void SILGenModule::emitObjCDestructorThunk(DestructorDecl *destructor) {
@@ -1483,14 +1493,8 @@
   // Don't emit the thunk if it already exists.
   if (hasFunction(thunk))
     return;
-  SILFunction *f = getFunction(thunk, ForDefinition);
-  auto loc = RegularLocation::getAutoGeneratedLocation(destructor);
-  preEmitFunction(thunk, destructor, f, loc);
-  PrettyStackTraceSILFunction X("silgen objc destructor thunk", f);
-  f->setBare(IsBare);
-  f->setThunk(IsThunk);
-  SILGenFunction(*this, *f, destructor).emitNativeToForeignThunk(thunk);
-  postEmitFunction(thunk, f);
+
+  emitNativeToForeignThunk(thunk);
 }
 
 void SILGenModule::visitPatternBindingDecl(PatternBindingDecl *pd) {
@@ -1889,6 +1893,12 @@
       SGM.visit(D);
     }
 
+    for (Decl *D : sf->getHoistedDecls()) {
+      FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
+                                      "SILgen-decl", D);
+      SGM.visit(D);
+    }
+
     for (TypeDecl *TD : sf->LocalTypeDecls) {
       FrontendStatsTracer StatsTracer(SGM.getASTContext().Stats,
                                       "SILgen-tydecl", TD);
@@ -1910,8 +1920,8 @@
            || !SGM.pendingConformances.empty()) {
       while (!SGM.forcedFunctions.empty()) {
         auto &front = SGM.forcedFunctions.front();
-        emitDelayedFunction(SGM, front,
-                            SGM.getEmittedFunction(front, ForDefinition));
+        SGM.emitFunctionDefinition(
+            front, SGM.getEmittedFunction(front, ForDefinition));
         SGM.forcedFunctions.pop_front();
       }
       while (!SGM.pendingConformances.empty()) {
diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h
index 5e69eed..7670897 100644
--- a/lib/SILGen/SILGen.h
+++ b/lib/SILGen/SILGen.h
@@ -270,7 +270,10 @@
   /// curried functions, curried entry point Functions are also generated and
   /// added to the current SILModule.
   void emitFunction(FuncDecl *fd);
-  
+
+  /// Emits the function definition for a given SILDeclRef.
+  void emitFunctionDefinition(SILDeclRef constant, SILFunction *f);
+
   /// Generates code for the given closure expression and adds the
   /// SILFunction to the current SILModule under the name SILDeclRef(ce).
   SILFunction *emitClosure(AbstractClosureExpr *ce);
@@ -302,11 +305,7 @@
   /// Emits a thunk from a Swift function to the native Swift convention.
   void emitNativeToForeignThunk(SILDeclRef thunk);
 
-  void preEmitFunction(SILDeclRef constant,
-                       llvm::PointerUnion<ValueDecl *,
-                                          Expr *> astNode,
-                       SILFunction *F,
-                       SILLocation L);
+  void preEmitFunction(SILDeclRef constant, SILFunction *F, SILLocation L);
   void postEmitFunction(SILDeclRef constant, SILFunction *F);
   
   /// Add a global variable to the SILModule.
diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp
index 9854969..0f30f1c 100644
--- a/lib/SILGen/SILGenStmt.cpp
+++ b/lib/SILGen/SILGenStmt.cpp
@@ -346,7 +346,13 @@
     } else if (auto *E = ESD.dyn_cast<Expr*>()) {
       SGF.emitIgnoredExpr(E);
     } else {
-      SGF.visit(ESD.get<Decl*>());
+      auto *D = ESD.get<Decl*>();
+
+      // Hoisted declarations are emitted at the top level by emitSourceFile().
+      if (D->isHoisted())
+        continue;
+
+      SGF.visit(D);
     }
   }
 }
diff --git a/lib/SILGen/SILGenThunk.cpp b/lib/SILGen/SILGenThunk.cpp
index 8fd44de..e2c65ef 100644
--- a/lib/SILGen/SILGenThunk.cpp
+++ b/lib/SILGen/SILGenThunk.cpp
@@ -90,32 +90,14 @@
 
 void SILGenModule::emitForeignToNativeThunk(SILDeclRef thunk) {
   // Thunks are always emitted by need, so don't need delayed emission.
-  assert(!thunk.isForeign && "foreign-to-native thunks only");
-  SILFunction *f = getFunction(thunk, ForDefinition);
-  f->setThunk(IsThunk);
-  if (thunk.asForeign().isClangGenerated())
-    f->setSerialized(IsSerializable);
-  preEmitFunction(thunk, thunk.getDecl(), f, thunk.getDecl());
-  PrettyStackTraceSILFunction X("silgen emitForeignToNativeThunk", f);
-  SILGenFunction(*this, *f, SwiftModule).emitForeignToNativeThunk(thunk);
-  postEmitFunction(thunk, f);
+  assert(thunk.isForeignToNativeThunk() && "foreign-to-native thunks only");
+  emitFunctionDefinition(thunk, getFunction(thunk, ForDefinition));
 }
 
 void SILGenModule::emitNativeToForeignThunk(SILDeclRef thunk) {
   // Thunks are always emitted by need, so don't need delayed emission.
-  assert(thunk.isForeign && "native-to-foreign thunks only");
-  
-  SILFunction *f = getFunction(thunk, ForDefinition);
-  if (thunk.hasDecl())
-    preEmitFunction(thunk, thunk.getDecl(), f, thunk.getDecl());
-  else
-    preEmitFunction(thunk, thunk.getAbstractClosureExpr(), f,
-                    thunk.getAbstractClosureExpr());
-  PrettyStackTraceSILFunction X("silgen emitNativeToForeignThunk", f);
-  f->setBare(IsBare);
-  f->setThunk(IsThunk);
-  SILGenFunction(*this, *f, SwiftModule).emitNativeToForeignThunk(thunk);
-  postEmitFunction(thunk, f);
+  assert(thunk.isNativeToForeignThunk() && "native-to-foreign thunks only");
+  emitFunctionDefinition(thunk, getFunction(thunk, ForDefinition));
 }
 
 SILValue
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index 83f2de2..d30a740 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -1038,7 +1038,7 @@
 
     // Build a vtable if this is a class.
     if (auto theClass = dyn_cast<ClassDecl>(theType)) {
-      for (Decl *member : theClass->getEmittedMembers())
+      for (Decl *member : theClass->getSemanticMembers())
         visit(member);
 
       SILGenVTable genVTable(SGM, theClass);
diff --git a/lib/SILOptimizer/ARC/ARCBBState.cpp b/lib/SILOptimizer/ARC/ARCBBState.cpp
index 0b2b0f3..63ddaef 100644
--- a/lib/SILOptimizer/ARC/ARCBBState.cpp
+++ b/lib/SILOptimizer/ARC/ARCBBState.cpp
@@ -137,6 +137,34 @@
   PtrToTopDownState = PredBBState.PtrToTopDownState;
 }
 
+void ARCBBState::dumpBottomUpState() {
+  for (auto state : getBottomupStates()) {
+    if (!state.hasValue())
+      continue;
+    auto elem = state.getValue();
+    if (!elem.first)
+      continue;
+    llvm::dbgs() << "SILValue: ";
+    elem.first->dump();
+    llvm::dbgs() << "RefCountState: ";
+    elem.second.dump();
+  }
+}
+
+void ARCBBState::dumpTopDownState() {
+  for (auto state : getTopDownStates()) {
+    if (!state.hasValue())
+      continue;
+    auto elem = state.getValue();
+    if (!elem.first)
+      continue;
+    llvm::dbgs() << "SILValue: ";
+    elem.first->dump();
+    llvm::dbgs() << "RefCountState: ";
+    elem.second.dump();
+  }
+}
+
 //===----------------------------------------------------------------------===//
 //                               ARCBBStateInfo
 //===----------------------------------------------------------------------===//
diff --git a/lib/SILOptimizer/ARC/ARCBBState.h b/lib/SILOptimizer/ARC/ARCBBState.h
index 286c1fc..e7d3abe 100644
--- a/lib/SILOptimizer/ARC/ARCBBState.h
+++ b/lib/SILOptimizer/ARC/ARCBBState.h
@@ -137,6 +137,9 @@
   /// BB. Used to create an initial state before we merge in other
   /// predecessors. This is currently a stub.
   void initPredTopDown(ARCBBState &PredBB);
+
+  void dumpBottomUpState();
+  void dumpTopDownState();
 };
 
 class ARCSequenceDataflowEvaluator::ARCBBStateInfoHandle {
diff --git a/lib/SILOptimizer/ARC/ARCRegionState.cpp b/lib/SILOptimizer/ARC/ARCRegionState.cpp
index 0f60f59..c076b0e 100644
--- a/lib/SILOptimizer/ARC/ARCRegionState.cpp
+++ b/lib/SILOptimizer/ARC/ARCRegionState.cpp
@@ -156,13 +156,21 @@
 // Bottom Up Dataflow
 //
 
-static bool processBlockBottomUpInsts(
-    ARCRegionState &State, SILBasicBlock &BB,
-    BottomUpDataflowRCStateVisitor<ARCRegionState> &DataflowVisitor,
-    AliasAnalysis *AA, ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
+bool ARCRegionState::processBlockBottomUp(
+    const LoopRegion *R, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
+    EpilogueARCFunctionInfo *EAFI, LoopRegionFunctionInfo *LRFI,
+    bool FreezeOwnedArgEpilogueReleases,
+    BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
+    ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
+  LLVM_DEBUG(llvm::dbgs() << ">>>> Bottom Up!\n");
 
-  auto II = State.summarizedinterestinginsts_rbegin();
-  auto IE = State.summarizedinterestinginsts_rend();
+  SILBasicBlock &BB = *R->getBlock();
+  BottomUpDataflowRCStateVisitor<ARCRegionState> DataflowVisitor(
+      RCIA, EAFI, *this, FreezeOwnedArgEpilogueReleases, IncToDecStateMap,
+      SetFactory);
+
+  auto II = summarizedinterestinginsts_rbegin();
+  auto IE = summarizedinterestinginsts_rend();
 
   // If we do not have any interesting instructions, bail and return false since
   // we can not have any nested instructions.
@@ -196,9 +204,15 @@
     // that the instruction "visits".
     SILValue Op = Result.RCIdentity;
 
+    std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched =
+        [&IncToDecStateMap](SILInstruction *Inst) {
+          assert(isa<StrongRetainInst>(Inst) || isa<RetainValueInst>(Inst));
+          return IncToDecStateMap.find(Inst) != IncToDecStateMap.end();
+        };
+
     // For all other (reference counted value, ref count state) we are
     // tracking...
-    for (auto &OtherState : State.getBottomupStates()) {
+    for (auto &OtherState : getBottomupStates()) {
       // If the other state's value is blotted, skip it.
       if (!OtherState.hasValue())
         continue;
@@ -208,33 +222,15 @@
       if (Op && OtherState->first == Op)
         continue;
 
-      OtherState->second.updateForSameLoopInst(I, SetFactory, AA);
+      OtherState->second.updateForSameLoopInst(I, AA);
+      OtherState->second.checkAndResetKnownSafety(
+          I, OtherState->first, checkIfRefCountInstIsMatched, RCIA, AA);
     }
   }
 
   return NestingDetected;
 }
 
-bool ARCRegionState::processBlockBottomUp(
-    const LoopRegion *R, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
-    EpilogueARCFunctionInfo *EAFI, LoopRegionFunctionInfo *LRFI,
-    bool FreezeOwnedArgEpilogueReleases,
-    BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
-  LLVM_DEBUG(llvm::dbgs() << ">>>> Bottom Up!\n");
-
-  SILBasicBlock &BB = *R->getBlock();
-  BottomUpDataflowRCStateVisitor<ARCRegionState> DataflowVisitor(
-      RCIA, EAFI, *this, FreezeOwnedArgEpilogueReleases, IncToDecStateMap,
-      SetFactory);
-
-  // Visit each arc relevant instruction I in BB visited in reverse...
-  bool NestingDetected =
-      processBlockBottomUpInsts(*this, BB, DataflowVisitor, AA, SetFactory);
-
-  return NestingDetected;
-}
-
 // Returns true if any of the non-local successors of the region are leaking
 // blocks. We currently do not handle early exits, but do handle trapping
 // blocks. Returns false if otherwise
@@ -257,8 +253,9 @@
 
 bool ARCRegionState::processLoopBottomUp(
     const LoopRegion *R, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI,
+    RCIdentityFunctionInfo *RCIA,
     llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
+    llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts) {
   ARCRegionState *State = RegionStateInfo[R];
 
   // If we find that we have non-leaking early exits, clear state
@@ -268,14 +265,23 @@
     return false;
   }
 
+  std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched =
+      [&UnmatchedRefCountInsts](SILInstruction *Inst) {
+        assert(isa<StrongRetainInst>(Inst) || isa<RetainValueInst>(Inst));
+        return UnmatchedRefCountInsts.find(Inst) == UnmatchedRefCountInsts.end();
+      };
+
   // For each state that we are currently tracking, apply our summarized
   // instructions to it.
   for (auto &OtherState : getBottomupStates()) {
     if (!OtherState.hasValue())
       continue;
 
-    for (auto *I : State->getSummarizedInterestingInsts())
-      OtherState->second.updateForDifferentLoopInst(I, SetFactory, AA);
+    for (auto *I : State->getSummarizedInterestingInsts()) {
+      OtherState->second.updateForDifferentLoopInst(I, AA);
+      OtherState->second.checkAndResetKnownSafety(
+          I, OtherState->first, checkIfRefCountInstIsMatched, RCIA, AA);
+    }
   }
 
   return false;
@@ -285,6 +291,7 @@
     AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
     EpilogueARCFunctionInfo *EAFI, LoopRegionFunctionInfo *LRFI,
     bool FreezeOwnedArgEpilogueReleases,
+    llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
     BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
     llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
     ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
@@ -293,7 +300,8 @@
   // We only process basic blocks for now. This ensures that we always propagate
   // the empty set from loops.
   if (!R->isBlock())
-    return processLoopBottomUp(R, AA, LRFI, RegionStateInfo, SetFactory);
+    return processLoopBottomUp(R, AA, LRFI, RCIA, RegionStateInfo,
+                               UnmatchedRefCountInsts);
 
   return processBlockBottomUp(R, AA, RCIA, EAFI, LRFI, FreezeOwnedArgEpilogueReleases,
                               IncToDecStateMap, SetFactory);
@@ -349,6 +357,12 @@
     // that the instruction "visits".
     SILValue Op = Result.RCIdentity;
 
+    std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched =
+        [&DecToIncStateMap](SILInstruction *Inst) {
+          assert(isa<StrongReleaseInst>(Inst) || isa<ReleaseValueInst>(Inst));
+          return DecToIncStateMap.find(Inst) != DecToIncStateMap.end();
+        };
+
     // For all other [(SILValue, TopDownState)] we are tracking...
     for (auto &OtherState : getTopDownStates()) {
       // If the other state's value is blotted, skip it.
@@ -361,7 +375,9 @@
       if (Op && OtherState->first == Op)
         continue;
 
-      OtherState->second.updateForSameLoopInst(I, SetFactory, AA);
+      OtherState->second.updateForSameLoopInst(I, AA);
+      OtherState->second.checkAndResetKnownSafety(
+          I, OtherState->first, checkIfRefCountInstIsMatched, RCIA, AA);
     }
   }
 
@@ -370,8 +386,8 @@
 
 bool ARCRegionState::processLoopTopDown(
     const LoopRegion *R, ARCRegionState *State, AliasAnalysis *AA,
-    LoopRegionFunctionInfo *LRFI,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
+    LoopRegionFunctionInfo *LRFI, RCIdentityFunctionInfo *RCIA,
+    llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts) {
 
   assert(R->isLoop() && "We assume we are processing a loop");
 
@@ -387,14 +403,23 @@
   assert(PredRegion->isBlock() && "Expected the predecessor region to be a "
                                   "block");
 
+  std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched =
+      [&UnmatchedRefCountInsts](SILInstruction *Inst) {
+        assert(isa<StrongReleaseInst>(Inst) || isa<ReleaseValueInst>(Inst));
+        return UnmatchedRefCountInsts.find(Inst) == UnmatchedRefCountInsts.end();
+      };
+
   // For each state that we are currently tracking, apply our summarized
   // instructions to it.
   for (auto &OtherState : getTopDownStates()) {
     if (!OtherState.hasValue())
       continue;
 
-    for (auto *I : State->getSummarizedInterestingInsts())
-      OtherState->second.updateForDifferentLoopInst(I, SetFactory, AA);
+    for (auto *I : State->getSummarizedInterestingInsts()) {
+      OtherState->second.updateForDifferentLoopInst(I, AA);
+      OtherState->second.checkAndResetKnownSafety(
+          I, OtherState->first, checkIfRefCountInstIsMatched, RCIA, AA);
+    }
   }
 
   return false;
@@ -403,6 +428,7 @@
 bool ARCRegionState::processTopDown(
     AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
     LoopRegionFunctionInfo *LRFI,
+    llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
     BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap,
     llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
     ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
@@ -411,7 +437,8 @@
   // We only process basic blocks for now. This ensures that we always propagate
   // the empty set from loops.
   if (!R->isBlock())
-    return processLoopTopDown(R, RegionStateInfo[R], AA, LRFI, SetFactory);
+    return processLoopTopDown(R, RegionStateInfo[R], AA, LRFI, RCIA,
+                              UnmatchedRefCountInsts);
 
   return processBlockTopDown(*R->getBlock(), AA, RCIA, DecToIncStateMap,
                              SetFactory);
diff --git a/lib/SILOptimizer/ARC/ARCRegionState.h b/lib/SILOptimizer/ARC/ARCRegionState.h
index 6facbb7..c55af46 100644
--- a/lib/SILOptimizer/ARC/ARCRegionState.h
+++ b/lib/SILOptimizer/ARC/ARCRegionState.h
@@ -188,6 +188,7 @@
   bool processTopDown(
       AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
       LoopRegionFunctionInfo *LRFI,
+      llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
       BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap,
       llvm::DenseMap<const LoopRegion *, ARCRegionState *> &LoopRegionState,
       ImmutablePointerSetFactory<SILInstruction> &SetFactory);
@@ -200,6 +201,7 @@
       AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
       EpilogueARCFunctionInfo *EAFI, LoopRegionFunctionInfo *LRFI,
       bool FreezeOwnedArgEpilogueReleases,
+      llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
       BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
       llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
       ImmutablePointerSetFactory<SILInstruction> &SetFactory);
@@ -219,9 +221,6 @@
   void removeInterestingInst(SILInstruction *I);
 
 private:
-  void processBlockBottomUpPredTerminators(
-      const LoopRegion *R, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI,
-      ImmutablePointerSetFactory<SILInstruction> &SetFactory);
   bool processBlockBottomUp(
       const LoopRegion *R, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
       EpilogueARCFunctionInfo *EAFI,
@@ -230,17 +229,18 @@
       ImmutablePointerSetFactory<SILInstruction> &SetFactory);
   bool processLoopBottomUp(
       const LoopRegion *R, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI,
+      RCIdentityFunctionInfo *RCIA,
       llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
-      ImmutablePointerSetFactory<SILInstruction> &SetFactory);
+      llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts);
 
   bool processBlockTopDown(
       SILBasicBlock &BB, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
       BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap,
       ImmutablePointerSetFactory<SILInstruction> &SetFactory);
-  bool
-  processLoopTopDown(const LoopRegion *R, ARCRegionState *State,
-                     AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI,
-                     ImmutablePointerSetFactory<SILInstruction> &SetFactory);
+  bool processLoopTopDown(
+      const LoopRegion *R, ARCRegionState *State, AliasAnalysis *AA,
+      LoopRegionFunctionInfo *LRFI, RCIdentityFunctionInfo *RCIA,
+      llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts);
 
   void summarizeLoop(
       const LoopRegion *R, LoopRegionFunctionInfo *LRFI,
diff --git a/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp b/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp
index f628be8..827b59d 100644
--- a/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp
+++ b/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp
@@ -156,6 +156,7 @@
     }
 
     MadeChange |= MatchedPair;
+    Evaluator.saveMatchingInfo(Region);
     Evaluator.clearLoopState(Region);
     Context.DecToIncStateMap.clear();
     Context.IncToDecStateMap.clear();
diff --git a/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp
index 5d08062..1e85107 100644
--- a/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp
+++ b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp
@@ -76,6 +76,12 @@
     }
   }
 
+  std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched =
+      [&DecToIncStateMap = DecToIncStateMap](SILInstruction *Inst) {
+        assert(isa<StrongReleaseInst>(Inst) || isa<ReleaseValueInst>(Inst));
+        return DecToIncStateMap.find(Inst) != DecToIncStateMap.end();
+      };
+
   // For each instruction I in BB...
   for (auto &I : BB) {
 
@@ -94,7 +100,7 @@
 
     // This SILValue may be null if we were unable to find a specific RCIdentity
     // that the instruction "visits".
-    SILValue Op = Result.RCIdentity;
+    SILValue CurrentRC = Result.RCIdentity;
 
     // For all other [(SILValue, TopDownState)] we are tracking...
     for (auto &OtherState : BBState.getTopDownStates()) {
@@ -105,10 +111,12 @@
       // If we visited an increment or decrement successfully (and thus Op is
       // set), if this is the state for this operand, skip it. We already
       // processed it.
-      if (Op && OtherState->first == Op)
+      if (CurrentRC && OtherState->first == CurrentRC)
         continue;
 
-      OtherState->second.updateForSameLoopInst(&I, SetFactory, AA);
+      OtherState->second.updateForSameLoopInst(&I, AA);
+      OtherState->second.checkAndResetKnownSafety(
+          &I, OtherState->first, checkIfRefCountInstIsMatched, RCIA, AA);
     }
   }
 
@@ -221,6 +229,12 @@
       RCIA, EAFI, BBState, FreezeOwnedArgEpilogueReleases, IncToDecStateMap,
       SetFactory);
 
+  std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched =
+      [&IncToDecStateMap = IncToDecStateMap](SILInstruction *Inst) {
+        assert(isa<StrongRetainInst>(Inst) || isa<RetainValueInst>(Inst));
+        return IncToDecStateMap.find(Inst) != IncToDecStateMap.end();
+      };
+
   auto II = BB.rbegin();
   if (!isARCSignificantTerminator(&cast<TermInst>(*II))) {
     II++;
@@ -246,7 +260,7 @@
 
     // This SILValue may be null if we were unable to find a specific RCIdentity
     // that the instruction "visits".
-    SILValue Op = Result.RCIdentity;
+    SILValue CurrentRC = Result.RCIdentity;
 
     // For all other (reference counted value, ref count state) we are
     // tracking...
@@ -257,10 +271,12 @@
 
       // If this is the state associated with the instruction that we are
       // currently visiting, bail.
-      if (Op && OtherState->first == Op)
+      if (CurrentRC && OtherState->first == CurrentRC)
         continue;
 
-      OtherState->second.updateForSameLoopInst(&I, SetFactory, AA);
+      OtherState->second.updateForSameLoopInst(&I, AA);
+      OtherState->second.checkAndResetKnownSafety(
+          &I, OtherState->first, checkIfRefCountInstIsMatched, RCIA, AA);
     }
   }
 
@@ -363,9 +379,36 @@
 bool ARCSequenceDataflowEvaluator::run(bool FreezeOwnedReleases) {
   bool NestingDetected = processBottomUp(FreezeOwnedReleases);
   NestingDetected |= processTopDown();
+
+  LLVM_DEBUG(
+      llvm::dbgs() << "*** Bottom-Up and Top-Down analysis results ***\n");
+  LLVM_DEBUG(dumpDataflowResults());
+
   return NestingDetected;
 }
 
+void ARCSequenceDataflowEvaluator::dumpDataflowResults() {
+  llvm::dbgs() << "IncToDecStateMap:\n";
+  for (auto it : IncToDecStateMap) {
+    if (!it.hasValue())
+      continue;
+    auto instAndState = it.getValue();
+    llvm::dbgs() << "Increment: ";
+    instAndState.first->dump();
+    instAndState.second.dump();
+  }
+
+  llvm::dbgs() << "DecToIncStateMap:\n";
+  for (auto it : DecToIncStateMap) {
+    if (!it.hasValue())
+      continue;
+    auto instAndState = it.getValue();
+    llvm::dbgs() << "Decrement: ";
+    instAndState.first->dump();
+    instAndState.second.dump();
+  }
+}
+
 // We put the destructor here so we don't need to expose the type of
 // BBStateInfo to the outside world.
 ARCSequenceDataflowEvaluator::~ARCSequenceDataflowEvaluator() = default;
diff --git a/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.h b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.h
index bf9f828..615a755 100644
--- a/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.h
+++ b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.h
@@ -108,6 +108,8 @@
 
   llvm::Optional<ARCBBStateInfoHandle> getBottomUpBBState(SILBasicBlock *BB);
   llvm::Optional<ARCBBStateInfoHandle> getTopDownBBState(SILBasicBlock *BB);
+
+  void dumpDataflowResults();
 };
 
 } // end swift namespace
diff --git a/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.cpp b/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.cpp
index 46715dd..108af5d 100644
--- a/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.cpp
+++ b/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.cpp
@@ -110,7 +110,8 @@
 
     // Then perform the dataflow.
     NestingDetected |= SubregionData.processTopDown(
-        AA, RCFI, LRFI, DecToIncStateMap, RegionStateInfo, SetFactory);
+        AA, RCFI, LRFI, UnmatchedRefCountInsts, DecToIncStateMap,
+        RegionStateInfo, SetFactory);
   }
 
   return NestingDetected;
@@ -214,8 +215,9 @@
 
     // Then perform the region optimization.
     NestingDetected |= SubregionData.processBottomUp(
-        AA, RCFI, EAFI, LRFI, FreezeOwnedArgEpilogueReleases, IncToDecStateMap,
-        RegionStateInfo, SetFactory);
+        AA, RCFI, EAFI, LRFI, FreezeOwnedArgEpilogueReleases,
+        UnmatchedRefCountInsts, IncToDecStateMap, RegionStateInfo,
+        SetFactory);
   }
 
   return NestingDetected;
@@ -252,13 +254,39 @@
 bool LoopARCSequenceDataflowEvaluator::runOnLoop(
     const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases,
     bool RecomputePostDomReleases) {
+  LLVM_DEBUG(llvm::dbgs() << "Run on region:\n");
+  LLVM_DEBUG(R->dump(true));
   bool NestingDetected = processLoopBottomUp(R, FreezeOwnedArgEpilogueReleases);
   NestingDetected |= processLoopTopDown(R);
+  LLVM_DEBUG(
+      llvm::dbgs() << "*** Bottom-Up and Top-Down analysis results ***\n");
+  LLVM_DEBUG(dumpDataflowResults());
   return NestingDetected;
 }
 
-void LoopARCSequenceDataflowEvaluator::summarizeLoop(
-    const LoopRegion *R) {
+void LoopARCSequenceDataflowEvaluator::dumpDataflowResults() {
+  llvm::dbgs() << "IncToDecStateMap:\n";
+  for (auto it : IncToDecStateMap) {
+    if (!it.hasValue())
+      continue;
+    auto instAndState = it.getValue();
+    llvm::dbgs() << "Increment: ";
+    instAndState.first->dump();
+    instAndState.second.dump();
+  }
+
+  llvm::dbgs() << "DecToIncStateMap:\n";
+  for (auto it : DecToIncStateMap) {
+    if (!it.hasValue())
+      continue;
+    auto instAndState = it.getValue();
+    llvm::dbgs() << "Decrement: ";
+    instAndState.first->dump();
+    instAndState.second.dump();
+  }
+}
+
+void LoopARCSequenceDataflowEvaluator::summarizeLoop(const LoopRegion *R) {
   RegionStateInfo[R]->summarize(LRFI, RegionStateInfo);
 }
 
@@ -287,3 +315,34 @@
   auto *Region = LRFI->getRegion(I->getParent());
   RegionStateInfo[Region]->removeInterestingInst(I);
 }
+
+// Compute if a RefCountInst was unmatched and populate in the persistent
+// UnmatchedRefCountInsts.
+// This can be done by looking up the RefCountInst in IncToDecStateMap or
+// DecToIncStateMap. If the StrongIncrement was matched to a StrongDecrement,
+// it will be found in IncToDecStateMap. If the StrongDecrement was matched to
+// a StrongIncrement, it will be found in DecToIncStateMap.
+void LoopARCSequenceDataflowEvaluator::saveMatchingInfo(const LoopRegion *R) {
+  if (R->isFunction())
+    return;
+  for (unsigned SubregionID : R->getSubregions()) {
+    auto *Subregion = LRFI->getRegion(SubregionID);
+    if (!Subregion->isBlock())
+      continue;
+    auto *RegionState = RegionStateInfo[Subregion];
+    for (auto Inst : RegionState->getSummarizedInterestingInsts()) {
+      if (isa<StrongRetainInst>(Inst) || isa<RetainValueInst>(Inst)) {
+        // unmatched if not found in IncToDecStateMap
+        if (IncToDecStateMap.find(Inst) == IncToDecStateMap.end())
+          UnmatchedRefCountInsts.insert(Inst);
+        continue;
+      }
+      if (isa<StrongReleaseInst>(Inst) || isa<ReleaseValueInst>(Inst)) {
+        // unmatched if not found in DecToIncStateMap
+        if (DecToIncStateMap.find(Inst) == DecToIncStateMap.end())
+          UnmatchedRefCountInsts.insert(Inst);
+        continue;
+      }
+    }
+  }
+}
diff --git a/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.h b/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.h
index 027e587..09f8613 100644
--- a/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.h
+++ b/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.h
@@ -72,6 +72,9 @@
   /// Stashed information for each region.
   llvm::DenseMap<const LoopRegion *, ARCRegionState *> RegionStateInfo;
 
+  /// Set of unmatched RefCountInsts
+  llvm::DenseSet<SILInstruction *> UnmatchedRefCountInsts;
+
 public:
   LoopARCSequenceDataflowEvaluator(
       SILFunction &F, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI,
@@ -108,6 +111,10 @@
   /// Remove \p I from the interesting instruction list of its parent block.
   void removeInterestingInst(SILInstruction *I);
 
+  /// Compute if a RefCountInst was unmatched and populate the persistent
+  /// UnmatchedRefCountInsts set.
+  void saveMatchingInfo(const LoopRegion *R);
+
   /// Clear the folding node set of the set factory we have stored internally.
   void clearSetFactory() {
     SetFactory.clear();
@@ -134,6 +141,8 @@
   bool processLoopTopDown(const LoopRegion *R);
   bool processLoopBottomUp(const LoopRegion *R,
                            bool FreezeOwnedArgEpilogueReleases);
+
+  void dumpDataflowResults();
 };
 
 } // end swift namespace
diff --git a/lib/SILOptimizer/ARC/RCStateTransition.h b/lib/SILOptimizer/ARC/RCStateTransition.h
index 65829ff..7789cb9 100644
--- a/lib/SILOptimizer/ARC/RCStateTransition.h
+++ b/lib/SILOptimizer/ARC/RCStateTransition.h
@@ -126,7 +126,6 @@
   /// Returns a Range of Mutators. Asserts if this transition is not a mutator
   /// transition.
   mutator_range getMutators() const {
-    assert(isMutator() && "This should never be called given mutators");
     return {Mutators->begin(), Mutators->end()};
   }
 
diff --git a/lib/SILOptimizer/ARC/RefCountState.cpp b/lib/SILOptimizer/ARC/RefCountState.cpp
index 7633739..1ffba9f 100644
--- a/lib/SILOptimizer/ARC/RefCountState.cpp
+++ b/lib/SILOptimizer/ARC/RefCountState.cpp
@@ -118,7 +118,7 @@
 
   // We will not remove mutators if we have a might be decremented value that
   // is not known safe.
-  return LatState != LatticeState::MightBeDecremented || isKnownSafe();
+  return isCodeMotionSafe() || isKnownSafe();
 }
 
 /// Uninitialize the current state.
@@ -195,9 +195,7 @@
 
 /// Given the current lattice state, if we have seen a use, advance the
 /// lattice state. Return true if we do so and false otherwise.
-bool BottomUpRefCountState::handleUser(
-    SILValue RCIdentity,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+bool BottomUpRefCountState::handleUser() {
   assert(valueCanBeUsedGivenLatticeState() &&
          "Must be able to be used at this point of the lattice.");
 
@@ -233,9 +231,7 @@
 
 /// Given the current lattice state, if we have seen a use, advance the
 /// lattice state. Return true if we do so and false otherwise.
-bool BottomUpRefCountState::handleGuaranteedUser(
-    SILValue RCIdentity,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+bool BottomUpRefCountState::handleGuaranteedUser() {
   assert(valueCanBeGuaranteedUsedGivenLatticeState() &&
          "Must be able to be used at this point of the lattice.");
 
@@ -270,14 +266,12 @@
   if (!Transition.matchingInst(RefCountInst))
     return false;
 
-  return handleRefCountInstMatch(RefCountInst);
+  return handleRefCountInstMatch();
 }
 
 /// We have a matching ref count inst. Return true if we advance the sequence
 /// and false otherwise.
-bool
-BottomUpRefCountState::
-handleRefCountInstMatch(SILInstruction *RefCountInst) {
+bool BottomUpRefCountState::handleRefCountInstMatch() {
   // Otherwise modify the state appropriately in preparation for removing the
   // increment, decrement pair.
   switch (LatState) {
@@ -340,8 +334,7 @@
 // the value we are tracking. If so advance the state's sequence appropriately
 // and return true. Otherwise return false.
 bool BottomUpRefCountState::handlePotentialGuaranteedUser(
-    SILInstruction *PotentialGuaranteedUser,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+    SILInstruction *PotentialGuaranteedUser, AliasAnalysis *AA) {
   // If we are not tracking a ref count, just return false.
   if (!isTrackingRefCount())
     return false;
@@ -375,7 +368,7 @@
       FoundNonARCUser = true;
 
   // Otherwise, update the ref count state given the guaranteed user.
-  return handleGuaranteedUser(getRCRoot(), SetFactory, AA);
+  return handleGuaranteedUser();
 }
 
 /// Check if PotentialDecrement can decrement the reference count associated
@@ -408,9 +401,8 @@
 // Check if PotentialUser could be a use of the reference counted value that
 // requires user to be alive. If so advance the state's sequence
 // appropriately and return true. Otherwise return false.
-bool BottomUpRefCountState::handlePotentialUser(
-    SILInstruction *PotentialUser,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+bool BottomUpRefCountState::handlePotentialUser(SILInstruction *PotentialUser,
+                                                AliasAnalysis *AA) {
 
   // If we are not tracking a ref count, just return false.
   if (!isTrackingRefCount())
@@ -434,12 +426,11 @@
     if (mustUseValue(PotentialUser, getRCRoot(), AA))
       FoundNonARCUser = true;
 
-  return handleUser(getRCRoot(), SetFactory, AA);
+  return handleUser();
 }
 
-void BottomUpRefCountState::updateForSameLoopInst(
-    SILInstruction *I,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+void BottomUpRefCountState::updateForSameLoopInst(SILInstruction *I,
+                                                  AliasAnalysis *AA) {
   // If this state is not tracking anything, there is nothing to update.
   if (!isTrackingRefCount())
     return;
@@ -448,7 +439,7 @@
   // instruction in a way that requires us to guarantee the lifetime of the
   // pointer up to this point. This has the effect of performing a use and a
   // decrement.
-  if (handlePotentialGuaranteedUser(I, SetFactory, AA)) {
+  if (handlePotentialGuaranteedUser(I, AA)) {
     LLVM_DEBUG(llvm::dbgs() << "    Found Potential Guaranteed Use:\n        "
                             << getRCRoot());
     return;
@@ -465,15 +456,45 @@
 
   // Otherwise check if the reference counted value we are tracking
   // could be used by the given instruction.
-  if (!handlePotentialUser(I, SetFactory, AA))
+  if (!handlePotentialUser(I, AA))
     return;
   LLVM_DEBUG(llvm::dbgs() << "    Found Potential Use:\n        "
                           << getRCRoot());
 }
 
-void BottomUpRefCountState::updateForDifferentLoopInst(
-    SILInstruction *I,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+// Remove "KnownSafe" on the BottomUpRefCountState. If we find another unmatched
+// retain instruction with a different aliasing RCIdentity or the same
+// RCIdentity in the child region in the loop case.
+void BottomUpRefCountState::checkAndResetKnownSafety(
+    SILInstruction *I, SILValue VisitedRC,
+    std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched,
+    RCIdentityFunctionInfo *RCIA, AliasAnalysis *AA) {
+  assert(VisitedRC);
+  // If the RefCountState was not marked "KnownSafe", there is nothing to do.
+  if (!isKnownSafe())
+    return;
+  assert(Transition.getKind() == RCStateTransitionKind::StrongDecrement);
+  // We only care about retain instructions that can potentially pair with a
+  // previously visited release.
+  if (!(isa<StrongRetainInst>(I) || isa<RetainValueInst>(I)))
+    return;
+  SILValue VisitingRC = RCIA->getRCIdentityRoot(I->getOperand(0));
+  assert(VisitingRC);
+  // If the visiting retain instruction was not already pair with a release
+  // instruction, return.
+  if (checkIfRefCountInstIsMatched(I))
+    return;
+  // If the VisitingRC and VisitedRC do not alias, they cannot be incorrectly
+  // paired.
+  if (AA->isNoAlias(VisitingRC, VisitedRC))
+    return;
+  LLVM_DEBUG(llvm::dbgs() << "Clearing KnownSafe for: ");
+  LLVM_DEBUG(VisitedRC->dump());
+  clearKnownSafe();
+}
+
+void BottomUpRefCountState::updateForDifferentLoopInst(SILInstruction *I,
+                                                       AliasAnalysis *AA) {
   // If we are not tracking anything, bail.
   if (!isTrackingRefCount())
     return;
@@ -483,7 +504,7 @@
         mayDecrementRefCount(I, getRCRoot(), AA)) {
       LLVM_DEBUG(llvm::dbgs() << "    Found potential guaranteed use:\n        "
                               << getRCRoot());
-      handleGuaranteedUser(getRCRoot(), SetFactory, AA);
+      handleGuaranteedUser();
       return;
     }
   }
@@ -491,7 +512,7 @@
   // We can just handle potential users normally, since if we handle the user we
   // already saw a decrement implying that we will treat this like a guaranteed
   // use.
-  if (!handlePotentialUser(I, SetFactory, AA))
+  if (!handlePotentialUser(I, AA))
     return;
   LLVM_DEBUG(llvm::dbgs() << "    Found Potential Use:\n        "
                           << getRCRoot());
@@ -585,9 +606,7 @@
 
 /// If advance the state's sequence appropriately for a decrement. If we do
 /// advance return true. Otherwise return false.
-bool TopDownRefCountState::handleDecrement(
-    SILInstruction *PotentialDecrement,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
+bool TopDownRefCountState::handleDecrement() {
   switch (LatState) {
   case LatticeState::Incremented:
     LatState = LatticeState::MightBeDecremented;
@@ -618,9 +637,7 @@
 
 /// Given the current lattice state, if we have seen a use, advance the
 /// lattice state. Return true if we do so and false otherwise.
-bool TopDownRefCountState::handleUser(SILInstruction *PotentialUser,
-                                      SILValue RCIdentity,
-                                      AliasAnalysis *AA) {
+bool TopDownRefCountState::handleUser() {
   assert(valueCanBeUsedGivenLatticeState() &&
          "Must be able to be used at this point of the lattice.");
 
@@ -657,10 +674,7 @@
 
 /// Given the current lattice state, if we have seen a use, advance the
 /// lattice state. Return true if we do so and false otherwise.
-bool TopDownRefCountState::handleGuaranteedUser(
-    SILInstruction *PotentialGuaranteedUser,
-    SILValue RCIdentity, ImmutablePointerSetFactory<SILInstruction> &SetFactory,
-    AliasAnalysis *AA) {
+bool TopDownRefCountState::handleGuaranteedUser() {
   assert(valueCanBeGuaranteedUsedGivenLatticeState() &&
          "Must be able to be used at this point of the lattice.");
   // Advance the sequence...
@@ -694,13 +708,12 @@
   if (!Transition.matchingInst(RefCountInst))
     return false;
 
-  return handleRefCountInstMatch(RefCountInst);
+  return handleRefCountInstMatch();
 }
 
 /// We have a matching ref count inst. Return true if we advance the sequence
 /// and false otherwise.
-bool TopDownRefCountState::
-handleRefCountInstMatch(SILInstruction *RefCountInst) {
+bool TopDownRefCountState::handleRefCountInstMatch() {
   // Otherwise modify the state appropriately in preparation for removing the
   // increment, decrement pair.
   switch (LatState) {
@@ -762,8 +775,7 @@
 // the value we are tracking. If so advance the state's sequence appropriately
 // and return true. Otherwise return false.
 bool TopDownRefCountState::handlePotentialGuaranteedUser(
-    SILInstruction *PotentialGuaranteedUser,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+    SILInstruction *PotentialGuaranteedUser, AliasAnalysis *AA) {
   // If we are not tracking a ref count, just return false.
   if (!isTrackingRefCount())
     return false;
@@ -789,16 +801,14 @@
    }
 
   // Otherwise, update our step given that we have a potential decrement.
-  return handleGuaranteedUser(PotentialGuaranteedUser, getRCRoot(),
-                              SetFactory, AA);
+   return handleGuaranteedUser();
 }
 
 // Check if PotentialDecrement can decrement the reference count associated with
 // the value we are tracking. If so advance the state's sequence appropriately
 // and return true. Otherwise return false.
 bool TopDownRefCountState::handlePotentialDecrement(
-    SILInstruction *PotentialDecrement,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+    SILInstruction *PotentialDecrement, AliasAnalysis *AA) {
   // If we are not tracking a ref count, just return false.
   if (!isTrackingRefCount())
     return false;
@@ -817,7 +827,7 @@
     return false;
 
   // Otherwise, update our state given the potential decrement.
-  return handleDecrement(PotentialDecrement, SetFactory);
+  return handleDecrement();
 }
 
 // Check if PotentialUser could be a use of the reference counted value that
@@ -840,12 +850,11 @@
   if (!mayHaveSymmetricInterference(PotentialUser, getRCRoot(), AA))
     return false;
 
-  return handleUser(PotentialUser, getRCRoot(), AA);
+  return handleUser();
 }
 
-void TopDownRefCountState::updateForSameLoopInst(
-    SILInstruction *I, 
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+void TopDownRefCountState::updateForSameLoopInst(SILInstruction *I,
+                                                 AliasAnalysis *AA) {
   // If we are not tracking anything, bail.
   if (!isTrackingRefCount())
     return;
@@ -854,7 +863,7 @@
   // instruction in a way that requires us to guarantee the lifetime of the
   // pointer up to this point. This has the effect of performing a use and a
   // decrement.
-  if (handlePotentialGuaranteedUser(I, SetFactory, AA)) {
+  if (handlePotentialGuaranteedUser(I, AA)) {
     LLVM_DEBUG(llvm::dbgs() << "    Found Potential Guaranteed Use:\n        "
                             << getRCRoot());
     return;
@@ -863,7 +872,7 @@
   // Check if the instruction we are visiting could potentially decrement
   // the reference counted value we are tracking in a manner that could
   // cause us to change states. If we do change states continue...
-  if (handlePotentialDecrement(I, SetFactory, AA)) {
+  if (handlePotentialDecrement(I, AA)) {
     LLVM_DEBUG(llvm::dbgs() << "    Found Potential Decrement:\n        "
                             << getRCRoot());
     return;
@@ -877,9 +886,39 @@
                           << getRCRoot());
 }
 
-void TopDownRefCountState::updateForDifferentLoopInst(
-    SILInstruction *I,
-    ImmutablePointerSetFactory<SILInstruction> &SetFactory, AliasAnalysis *AA) {
+// Remove "KnownSafe" on the TopDownRefCountState. If we find another unmatched
+// release instruction with a different aliasing RCIdentity or the same
+// RCIdentity in the child region in the loop case.
+void TopDownRefCountState::checkAndResetKnownSafety(
+    SILInstruction *I, SILValue VisitedRC,
+    std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched,
+    RCIdentityFunctionInfo *RCIA, AliasAnalysis *AA) {
+  assert(VisitedRC);
+  // If the RefCountState was not marked "KnownSafe", there is nothing to do.
+  if (!isKnownSafe())
+    return;
+  assert(Transition.getKind() == RCStateTransitionKind::StrongIncrement);
+  // We only care about release instructions that can potentially pair with a
+  // previously visited retain.
+  if (!(isa<StrongReleaseInst>(I) || isa<ReleaseValueInst>(I)))
+    return;
+  SILValue VisitingRC = RCIA->getRCIdentityRoot(I->getOperand(0));
+  assert(VisitingRC);
+  // If the visiting release instruction was already pair with a retain
+  // instruction, return.
+  if (checkIfRefCountInstIsMatched(I))
+    return;
+  // If the VisitingRC and VisitedRC do not alias, they cannot be incorrectly
+  // paired.
+  if (AA->isNoAlias(VisitingRC, VisitedRC))
+    return;
+  LLVM_DEBUG(llvm::dbgs() << "Clearing KnownSafe for: ");
+  LLVM_DEBUG(VisitedRC->dump());
+  clearKnownSafe();
+}
+
+void TopDownRefCountState::updateForDifferentLoopInst(SILInstruction *I,
+                                                      AliasAnalysis *AA) {
   // If we are not tracking anything, bail.
   if (!isTrackingRefCount())
     return;
@@ -888,7 +927,7 @@
     if (mayGuaranteedUseValue(I, getRCRoot(), AA) ||
         mayDecrementRefCount(I, getRCRoot(), AA)) {
       LLVM_DEBUG(llvm::dbgs() << "    Found potential guaranteed use!\n");
-      handleGuaranteedUser(I, getRCRoot(), SetFactory, AA);
+      handleGuaranteedUser();
       return;
     }
   }
@@ -903,6 +942,27 @@
 //                             Printing Utilities
 //===----------------------------------------------------------------------===//
 
+void BottomUpRefCountState::dump() {
+  llvm::dbgs() << LatState << " "
+               << (isKnownSafe() ? "KnownSafe" : "NotKnownSafe") << " "
+               << (isCodeMotionSafe() ? "CodeMotionSafe" : "NotCodeMotionSafe")
+               << "\n";
+  llvm::dbgs() << "Matching Instructions:\n";
+  for (auto it : getInstructions()) {
+    it->dump();
+  }
+}
+void TopDownRefCountState::dump() {
+  llvm::dbgs() << LatState << " "
+               << (isKnownSafe() ? "KnownSafe" : "NotKnownSafe") << " "
+               << (isCodeMotionSafe() ? "CodeMotionSafe" : "NotCodeMotionSafe")
+               << "\n";
+  llvm::dbgs() << "Matching Instructions:\n";
+  for (auto it : getInstructions()) {
+    it->dump();
+  }
+}
+
 namespace llvm {
 
 raw_ostream &operator<<(raw_ostream &OS,
@@ -938,5 +998,4 @@
 
   llvm_unreachable("Unhandled LatticeState in switch.");
 }
-
 } // end namespace llvm
diff --git a/lib/SILOptimizer/ARC/RefCountState.h b/lib/SILOptimizer/ARC/RefCountState.h
index c234ce0..bc9e2e4 100644
--- a/lib/SILOptimizer/ARC/RefCountState.h
+++ b/lib/SILOptimizer/ARC/RefCountState.h
@@ -14,12 +14,13 @@
 #define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_REFCOUNTSTATE_H
 
 #include "RCStateTransition.h"
-#include "swift/Basic/type_traits.h"
+#include "swift/Basic/BlotMapVector.h"
 #include "swift/Basic/ImmutablePointerSet.h"
-#include "swift/SIL/SILInstruction.h"
+#include "swift/Basic/type_traits.h"
+#include "swift/SIL/InstructionUtils.h"
 #include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILBasicBlock.h"
-#include "swift/SIL/InstructionUtils.h"
+#include "swift/SIL/SILInstruction.h"
 #include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
 #include "swift/SILOptimizer/Analysis/EpilogueARCAnalysis.h"
 #include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
@@ -134,6 +135,8 @@
   void updateKnownSafe(bool NewValue) {
     KnownSafe |= NewValue;
   }
+
+  void clearKnownSafe() { KnownSafe = false; }
 };
 
 //===----------------------------------------------------------------------===//
@@ -188,8 +191,14 @@
   /// Update this reference count's state given the instruction \p I.
   void
   updateForSameLoopInst(SILInstruction *I,
-                        ImmutablePointerSetFactory<SILInstruction> &SetFactory,
                         AliasAnalysis *AA);
+  /// Remove "KnownSafe" on the BottomUpRefCountState, if we find a retain
+  /// instruction with another RCIdentity can pair with the previously visited
+  /// retain instruction.
+  void checkAndResetKnownSafety(
+      SILInstruction *I, SILValue VisitedRC,
+      std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched,
+      RCIdentityFunctionInfo *RCIA, AliasAnalysis *AA);
 
   /// Update this reference count's state given the instruction \p I.
   //
@@ -198,7 +207,6 @@
   /// guaranteed used. We treat any uses as regular uses.
   void updateForDifferentLoopInst(
       SILInstruction *I,
-      ImmutablePointerSetFactory<SILInstruction> &SetFactory,
       AliasAnalysis *AA);
 
   /// Attempt to merge \p Other into this ref count state. Return true if we
@@ -212,6 +220,8 @@
   /// Uninitialize the current state.
   void clear();
 
+  void dump();
+
 private:
   /// Return true if we *might* remove this instruction.
   ///
@@ -241,16 +251,13 @@
 
   /// Given the current lattice state, if we have seen a use, advance the
   /// lattice state. Return true if we do so and false otherwise.
-  bool handleUser(SILValue RCIdentity,
-                  ImmutablePointerSetFactory<SILInstruction> &SetFactory,
-                  AliasAnalysis *AA);
+  bool handleUser();
 
   /// Check if PotentialUser could be a use of the reference counted value that
   /// requires user to be alive. If so advance the state's sequence
   /// appropriately and return true. Otherwise return false.
   bool
   handlePotentialUser(SILInstruction *PotentialUser,
-                      ImmutablePointerSetFactory<SILInstruction> &SetFactory,
                       AliasAnalysis *AA);
 
   /// Returns true if given the current lattice state, do we care if the value
@@ -259,22 +266,18 @@
 
   /// Given the current lattice state, if we have seen a use, advance the
   /// lattice state. Return true if we do so and false otherwise.
-  bool
-  handleGuaranteedUser(SILValue RCIdentity,
-                       ImmutablePointerSetFactory<SILInstruction> &SetFactory,
-                       AliasAnalysis *AA);
+  bool handleGuaranteedUser();
 
   /// Check if PotentialGuaranteedUser can use the reference count associated
   /// with the value we are tracking. If so advance the state's sequence
   /// appropriately and return true. Otherwise return false.
   bool handlePotentialGuaranteedUser(
       SILInstruction *User,
-      ImmutablePointerSetFactory<SILInstruction> &SetFactory,
       AliasAnalysis *AA);
 
   /// We have a matching ref count inst. Return true if we advance the sequence
   /// and false otherwise.
-  bool handleRefCountInstMatch(SILInstruction *RefCountInst);
+  bool handleRefCountInstMatch();
 };
 
 //===----------------------------------------------------------------------===//
@@ -333,8 +336,14 @@
   /// Update this reference count's state given the instruction \p I.
   void
   updateForSameLoopInst(SILInstruction *I,
-                        ImmutablePointerSetFactory<SILInstruction> &SetFactory,
                         AliasAnalysis *AA);
+  /// Remove "KnownSafe" on the TopDownRefCountState, if we find a retain
+  /// instruction with another RCIdentity can pair with the previously visited
+  /// retain instruction.
+  void checkAndResetKnownSafety(
+      SILInstruction *I, SILValue VisitedRC,
+      std::function<bool(SILInstruction *)> checkIfRefCountInstIsMatched,
+      RCIdentityFunctionInfo *RCIA, AliasAnalysis *AA);
 
   /// Update this reference count's state given the instruction \p I.
   ///
@@ -343,7 +352,6 @@
   /// guaranteed used. We treat any uses as regular uses.
   void updateForDifferentLoopInst(
       SILInstruction *I,
-      ImmutablePointerSetFactory<SILInstruction> &SetFactory,
       AliasAnalysis *AA);
 
   /// Returns true if the passed in ref count inst matches the ref count inst
@@ -354,6 +362,8 @@
   /// succeed and false otherwise.
   bool merge(const TopDownRefCountState &Other);
 
+  void dump();
+
 private:
   /// Can we guarantee that the given reference counted value has been modified?
   bool isRefCountStateModified() const;
@@ -364,15 +374,13 @@
 
   /// If advance the state's sequence appropriately for a decrement. If we do
   /// advance return true. Otherwise return false.
-  bool handleDecrement(SILInstruction *PotentialDecrement,
-                       ImmutablePointerSetFactory<SILInstruction> &SetFactory);
+  bool handleDecrement();
 
   /// Check if PotentialDecrement can decrement the reference count associated
   /// with the value we are tracking. If so advance the state's sequence
   /// appropriately and return true. Otherwise return false.
   bool handlePotentialDecrement(
       SILInstruction *PotentialDecrement,
-      ImmutablePointerSetFactory<SILInstruction> &SetFactory,
       AliasAnalysis *AA);
 
   /// Returns true if given the current lattice state, do we care if the value
@@ -381,8 +389,7 @@
 
   /// Given the current lattice state, if we have seen a use, advance the
   /// lattice state. Return true if we do so and false otherwise.
-  bool handleUser(SILInstruction *PotentialUser,
-                  SILValue RCIdentity, AliasAnalysis *AA);
+  bool handleUser();
 
   /// Check if PotentialUser could be a use of the reference counted value that
   /// requires user to be alive. If so advance the state's sequence
@@ -395,23 +402,18 @@
 
   /// Given the current lattice state, if we have seen a use, advance the
   /// lattice state. Return true if we do so and false otherwise.
-  bool
-  handleGuaranteedUser(SILInstruction *PotentialGuaranteedUser,
-                       SILValue RCIdentity,
-                       ImmutablePointerSetFactory<SILInstruction> &SetFactory,
-                       AliasAnalysis *AA);
+  bool handleGuaranteedUser();
 
   /// Check if PotentialGuaranteedUser can use the reference count associated
   /// with the value we are tracking. If so advance the state's sequence
   /// appropriately and return true. Otherwise return false.
   bool handlePotentialGuaranteedUser(
       SILInstruction *PotentialGuaranteedUser,
-      ImmutablePointerSetFactory<SILInstruction> &SetFactory,
       AliasAnalysis *AA);
 
   /// We have a matching ref count inst. Return true if we advance the sequence
   /// and false otherwise.
-  bool handleRefCountInstMatch(SILInstruction *RefCountInst);
+  bool handleRefCountInstMatch();
 };
 
 // These static asserts are here for performance reasons.
diff --git a/lib/SILOptimizer/Analysis/DifferentiableActivityAnalysis.cpp b/lib/SILOptimizer/Analysis/DifferentiableActivityAnalysis.cpp
index 3d1da0a..884f544 100644
--- a/lib/SILOptimizer/Analysis/DifferentiableActivityAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/DifferentiableActivityAnalysis.cpp
@@ -557,6 +557,8 @@
     for (auto &inst : bb)
       for (auto res : inst.getResults())
         dump(res, indices, s);
-    s << '\n';
+    if (std::next(bb.getIterator()) != fn.end())
+      s << '\n';
   }
+  s << "End activity info for " << fn.getName() << " at " << indices << "\n\n";
 }
diff --git a/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp b/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp
index 7a04927..e9e07a1 100644
--- a/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp
@@ -522,13 +522,18 @@
 /// We only use the instruction analysis here.
 void RCIdentityFunctionInfo::getRCUses(SILValue InputValue,
                                        llvm::SmallVectorImpl<Operand *> &Uses) {
+  return visitRCUses(InputValue,
+                     [&](Operand *op) { return Uses.push_back(op); });
+}
 
+void RCIdentityFunctionInfo::visitRCUses(
+    SILValue InputValue, function_ref<void(Operand *)> Visitor) {
   // Add V to the worklist.
-  llvm::SmallVector<SILValue, 8> Worklist;
+  SmallVector<SILValue, 8> Worklist;
   Worklist.push_back(InputValue);
 
   // A set used to ensure we only visit uses once.
-  llvm::SmallPtrSet<Operand *, 8> VisitedOps;
+  SmallPtrSet<Operand *, 8> VisitedOps;
 
   // Then until we finish the worklist...
   while (!Worklist.empty()) {
@@ -564,7 +569,7 @@
       }
 
       // Otherwise, stop searching and report this RC operand.
-      Uses.push_back(Op);
+      Visitor(Op);
     }
   }
 }
diff --git a/lib/SILOptimizer/Differentiation/JVPCloner.cpp b/lib/SILOptimizer/Differentiation/JVPCloner.cpp
index 2586e5a..86c587e 100644
--- a/lib/SILOptimizer/Differentiation/JVPCloner.cpp
+++ b/lib/SILOptimizer/Differentiation/JVPCloner.cpp
@@ -134,19 +134,6 @@
   // General utilities
   //--------------------------------------------------------------------------//
 
-  SILBasicBlock::iterator getNextDifferentialLocalAllocationInsertionPoint() {
-    // If there are no local allocations, insert at the beginning of the tangent
-    // entry.
-    if (differentialLocalAllocations.empty())
-      return getDifferential().getEntryBlock()->begin();
-    // Otherwise, insert before the last local allocation. Inserting before
-    // rather than after ensures that allocation and zero initialization
-    // instructions are grouped together.
-    auto lastLocalAlloc = differentialLocalAllocations.back();
-    auto it = lastLocalAlloc->getDefiningInstruction()->getIterator();
-    return it;
-  }
-
   /// Get the lowered SIL type of the given AST type.
   SILType getLoweredType(Type type) {
     auto jvpGenSig = jvp->getLoweredFunctionType()->getSubstGenericSignature();
@@ -309,6 +296,8 @@
   // Tangent buffer mapping
   //--------------------------------------------------------------------------//
 
+  /// Sets the tangent buffer for the original buffer. Asserts that the
+  /// original buffer does not already have a tangent buffer.
   void setTangentBuffer(SILBasicBlock *origBB, SILValue originalBuffer,
                         SILValue tangentBuffer) {
     assert(originalBuffer->getType().isAddress());
@@ -318,13 +307,14 @@
     (void)insertion;
   }
 
+  /// Returns the tangent buffer for the original buffer. Asserts that the
+  /// original buffer has a tangent buffer.
   SILValue &getTangentBuffer(SILBasicBlock *origBB, SILValue originalBuffer) {
     assert(originalBuffer->getType().isAddress());
     assert(originalBuffer->getFunction() == original);
-    auto insertion =
-        bufferMap.try_emplace({origBB, originalBuffer}, SILValue());
-    assert(!insertion.second && "Tangent buffer should already exist");
-    return insertion.first->getSecond();
+    auto it = bufferMap.find({origBB, originalBuffer});
+    assert(it != bufferMap.end() && "Tangent buffer should already exist");
+    return it->getSecond();
   }
 
   //--------------------------------------------------------------------------//
@@ -446,9 +436,21 @@
   // If an `apply` has active results or active inout parameters, replace it
   // with an `apply` of its JVP.
   void visitApplyInst(ApplyInst *ai) {
+    bool shouldDifferentiate =
+        differentialInfo.shouldDifferentiateApplySite(ai);
+    // If the function has no active arguments or results, zero-initialize the
+    // tangent buffers of the active indirect results.
+    if (!shouldDifferentiate) {
+      for (auto indResult : ai->getIndirectSILResults())
+        if (activityInfo.isActive(indResult, getIndices())) {
+          auto &tanBuf = getTangentBuffer(ai->getParent(), indResult);
+          emitZeroIndirect(tanBuf->getType().getASTType(), tanBuf,
+                           tanBuf.getLoc());
+        }
+    }
     // If the function should not be differentiated or its the array literal
     // initialization intrinsic, just do standard cloning.
-    if (!differentialInfo.shouldDifferentiateApplySite(ai) ||
+    if (!shouldDifferentiate ||
         ArraySemanticsCall(ai, semantics::ARRAY_UNINITIALIZED_INTRINSIC)) {
       LLVM_DEBUG(getADDebugStream() << "No active results:\n" << *ai << '\n');
       TypeSubstCloner::visitApplyInst(ai);
@@ -789,7 +791,7 @@
     auto &diffBuilder = getDifferentialBuilder();
     auto loc = dvi->getLoc();
     auto tanVal = materializeTangent(getTangentValue(dvi->getOperand()), loc);
-    diffBuilder.emitDestroyValue(loc, tanVal);
+    diffBuilder.emitDestroyValueOperation(loc, tanVal);
   }
 
   CLONE_AND_EMIT_TANGENT(CopyValue, cvi) {
@@ -804,7 +806,20 @@
   /// Handle `load` instruction.
   ///   Original: y = load x
   ///    Tangent: tan[y] = load tan[x]
-  CLONE_AND_EMIT_TANGENT(Load, li) {
+  void visitLoadInst(LoadInst *li) {
+    TypeSubstCloner::visitLoadInst(li);
+    // If an active buffer is loaded with take to a non-active value, destroy
+    // the active buffer's tangent buffer.
+    if (!differentialInfo.shouldDifferentiateInstruction(li)) {
+      auto isTake =
+          (li->getOwnershipQualifier() == LoadOwnershipQualifier::Take);
+      if (isTake && activityInfo.isActive(li->getOperand(), getIndices())) {
+        auto &tanBuf = getTangentBuffer(li->getParent(), li->getOperand());
+        getDifferentialBuilder().emitDestroyOperation(tanBuf.getLoc(), tanBuf);
+      }
+      return;
+    }
+    // Otherwise, do standard differential cloning.
     auto &diffBuilder = getDifferentialBuilder();
     auto *bb = li->getParent();
     auto loc = li->getLoc();
@@ -829,7 +844,19 @@
   /// Handle `store` instruction in the differential.
   ///   Original: store x to y
   ///     Tangent: store tan[x] to tan[y]
-  CLONE_AND_EMIT_TANGENT(Store, si) {
+  void visitStoreInst(StoreInst *si) {
+    TypeSubstCloner::visitStoreInst(si);
+    // If a non-active value is stored into an active buffer, zero-initialize
+    // the active buffer's tangent buffer.
+    if (!differentialInfo.shouldDifferentiateInstruction(si)) {
+      if (activityInfo.isActive(si->getDest(), getIndices())) {
+        auto &tanBufDest = getTangentBuffer(si->getParent(), si->getDest());
+        emitZeroIndirect(tanBufDest->getType().getASTType(), tanBufDest,
+                         tanBufDest.getLoc());
+      }
+      return;
+    }
+    // Otherwise, do standard differential cloning.
     auto &diffBuilder = getDifferentialBuilder();
     auto loc = si->getLoc();
     auto tanValSrc = materializeTangent(getTangentValue(si->getSrc()), loc);
@@ -841,7 +868,19 @@
   /// Handle `store_borrow` instruction in the differential.
   ///   Original: store_borrow x to y
   ///    Tangent: store_borrow tan[x] to tan[y]
-  CLONE_AND_EMIT_TANGENT(StoreBorrow, sbi) {
+  void visitStoreBorrowInst(StoreBorrowInst *sbi) {
+    TypeSubstCloner::visitStoreBorrowInst(sbi);
+    // If a non-active value is stored into an active buffer, zero-initialize
+    // the active buffer's tangent buffer.
+    if (!differentialInfo.shouldDifferentiateInstruction(sbi)) {
+      if (activityInfo.isActive(sbi->getDest(), getIndices())) {
+        auto &tanBufDest = getTangentBuffer(sbi->getParent(), sbi->getDest());
+        emitZeroIndirect(tanBufDest->getType().getASTType(), tanBufDest,
+                         tanBufDest.getLoc());
+      }
+      return;
+    }
+    // Otherwise, do standard differential cloning.
     auto &diffBuilder = getDifferentialBuilder();
     auto loc = sbi->getLoc();
     auto tanValSrc = materializeTangent(getTangentValue(sbi->getSrc()), loc);
@@ -852,13 +891,32 @@
   /// Handle `copy_addr` instruction.
   ///   Original: copy_addr x to y
   ///    Tangent: copy_addr tan[x] to tan[y]
-  CLONE_AND_EMIT_TANGENT(CopyAddr, cai) {
+  void visitCopyAddrInst(CopyAddrInst *cai) {
+    TypeSubstCloner::visitCopyAddrInst(cai);
+    // If a non-active buffer is copied into an active buffer, zero-initialize
+    // the destination buffer's tangent buffer.
+    // If an active buffer is copied with take into a non-active buffer, destroy
+    // the source buffer's tangent buffer.
+    if (!differentialInfo.shouldDifferentiateInstruction(cai)) {
+      if (activityInfo.isActive(cai->getDest(), getIndices())) {
+        auto &tanBufDest = getTangentBuffer(cai->getParent(), cai->getDest());
+        emitZeroIndirect(tanBufDest->getType().getASTType(), tanBufDest,
+                         tanBufDest.getLoc());
+      }
+      if (cai->isTakeOfSrc() &&
+          activityInfo.isActive(cai->getSrc(), getIndices())) {
+        auto &tanBufSrc = getTangentBuffer(cai->getParent(), cai->getSrc());
+        getDifferentialBuilder().emitDestroyOperation(tanBufSrc.getLoc(),
+                                                      tanBufSrc);
+      }
+      return;
+    }
+    // Otherwise, do standard differential cloning.
     auto diffBuilder = getDifferentialBuilder();
     auto loc = cai->getLoc();
     auto *bb = cai->getParent();
     auto &tanSrc = getTangentBuffer(bb, cai->getSrc());
     auto tanDest = getTangentBuffer(bb, cai->getDest());
-
     diffBuilder.createCopyAddr(loc, tanSrc, tanDest, cai->isTakeOfSrc(),
                                cai->isInitializationOfDest());
   }
@@ -918,8 +976,8 @@
     auto &diffBuilder = getDifferentialBuilder();
     auto *bb = eai->getParent();
     auto loc = eai->getLoc();
-    auto tanSrc = getTangentBuffer(bb, eai->getOperand());
-    diffBuilder.createEndAccess(loc, tanSrc, eai->isAborting());
+    auto tanOperand = getTangentBuffer(bb, eai->getOperand());
+    diffBuilder.createEndAccess(loc, tanOperand, eai->isAborting());
   }
 
   /// Handle `alloc_stack` instruction.
@@ -930,7 +988,7 @@
     auto *mappedAllocStackInst = diffBuilder.createAllocStack(
         asi->getLoc(), getRemappedTangentType(asi->getElementType()),
         asi->getVarInfo());
-    bufferMap.try_emplace({asi->getParent(), asi}, mappedAllocStackInst);
+    setTangentBuffer(asi->getParent(), asi, mappedAllocStackInst);
   }
 
   /// Handle `dealloc_stack` instruction.
@@ -1062,16 +1120,15 @@
     auto tanType = getRemappedTangentType(tei->getType());
     auto tanSource =
         materializeTangent(getTangentValue(tei->getOperand()), loc);
-    SILValue tanBuf;
-    // If the tangent buffer of the source does not have a tuple type, then
+    // If the tangent value of the source does not have a tuple type, then
     // it must represent a "single element tuple type". Use it directly.
     if (!tanSource->getType().is<TupleType>()) {
       setTangentValue(tei->getParent(), tei,
                       makeConcreteTangentValue(tanSource));
     } else {
-      tanBuf =
+      auto tanElt =
           diffBuilder.createTupleExtract(loc, tanSource, tanIndex, tanType);
-      bufferMap.try_emplace({tei->getParent(), tei}, tanBuf);
+      setTangentValue(tei->getParent(), tei, makeConcreteTangentValue(tanElt));
     }
   }
 
@@ -1100,7 +1157,7 @@
       tanBuf = diffBuilder.createTupleElementAddr(teai->getLoc(), tanSource,
                                                   tanIndex, tanType);
     }
-    bufferMap.try_emplace({teai->getParent(), teai}, tanBuf);
+    setTangentBuffer(teai->getParent(), teai, tanBuf);
   }
 
   /// Handle `destructure_tuple` instruction.
@@ -1282,9 +1339,8 @@
     // Collect original results.
     SmallVector<SILValue, 2> originalResults;
     collectAllDirectResultsInTypeOrder(*original, originalResults);
-    // Collect differential return elements.
+    // Collect differential direct results.
     SmallVector<SILValue, 8> retElts;
-    // for (auto origResult : originalResults) {
     for (auto i : range(originalResults.size())) {
       auto origResult = originalResults[i];
       if (!getIndices().results->contains(i))
@@ -1401,7 +1457,10 @@
 void JVPCloner::Implementation::prepareForDifferentialGeneration() {
   // Create differential blocks and arguments.
   auto &differential = getDifferential();
+  auto diffLoc = differential.getLocation();
   auto *origEntry = original->getEntryBlock();
+  auto origFnTy = original->getLoweredFunctionType();
+
   for (auto &origBB : *original) {
     auto *diffBB = differential.createBasicBlock();
     diffBBMap.insert({&origBB, diffBB});
@@ -1482,21 +1541,51 @@
                << " as the tangent of original result " << *origArg);
   }
 
-  // Initialize tangent mapping for indirect results.
-  auto origIndResults = original->getIndirectResults();
+  // Initialize tangent mapping for original indirect results and non-wrt
+  // `inout` parameters. The tangent buffers of these address values are
+  // differential indirect results.
+
+  // Collect original results.
+  SmallVector<SILValue, 2> originalResults;
+  collectAllFormalResultsInTypeOrder(*original, originalResults);
+
+  // Iterate over differentiability results.
+  differentialBuilder.setInsertionPoint(differential.getEntryBlock());
   auto diffIndResults = differential.getIndirectResults();
-#ifndef NDEBUG
-  unsigned numNonWrtInoutParameters = llvm::count_if(
-    range(original->getLoweredFunctionType()->getNumParameters()),
-    [&] (unsigned i) {
-      auto &paramInfo = original->getLoweredFunctionType()->getParameters()[i];
-      return paramInfo.isIndirectInOut() && !getIndices().parameters->contains(i);
-    });
-#endif
-  assert(origIndResults.size() + numNonWrtInoutParameters == diffIndResults.size());
-  for (auto &origBB : *original)
-    for (auto i : indices(origIndResults))
-      setTangentBuffer(&origBB, origIndResults[i], diffIndResults[i]);
+  unsigned differentialIndirectResultIndex = 0;
+  for (auto resultIndex : getIndices().results->getIndices()) {
+    auto origResult = originalResults[resultIndex];
+    // Handle original formal indirect result.
+    if (resultIndex < origFnTy->getNumResults()) {
+      // Skip original direct results.
+      if (origResult->getType().isObject())
+        continue;
+      auto diffIndResult = diffIndResults[differentialIndirectResultIndex++];
+      setTangentBuffer(origEntry, origResult, diffIndResult);
+      // If original indirect result is non-varied, zero-initialize its tangent
+      // buffer.
+      if (!activityInfo.isVaried(origResult, getIndices().parameters))
+        emitZeroIndirect(diffIndResult->getType().getASTType(),
+                         diffIndResult, diffLoc);
+      continue;
+    }
+    // Handle original non-wrt `inout` parameter.
+    // Only original *non-wrt* `inout` parameters have corresponding
+    // differential indirect results.
+    auto inoutParamIndex = resultIndex - origFnTy->getNumResults();
+    auto inoutParamIt = std::next(
+        origFnTy->getIndirectMutatingParameters().begin(), inoutParamIndex);
+    auto paramIndex =
+        std::distance(origFnTy->getParameters().begin(), &*inoutParamIt);
+    if (getIndices().parameters->contains(paramIndex))
+      continue;
+    auto diffIndResult = diffIndResults[differentialIndirectResultIndex++];
+    setTangentBuffer(origEntry, origResult, diffIndResult);
+    // Original `inout` parameters are initialized, so their tangent buffers
+    // must also be initialized.
+    emitZeroIndirect(diffIndResult->getType().getASTType(),
+                     diffIndResult, diffLoc);
+  }
 }
 
 /*static*/ SILFunction *JVPCloner::Implementation::createEmptyDifferential(
@@ -1526,7 +1615,6 @@
   auto origParams = origTy->getParameters();
   auto indices = witness->getSILAutoDiffIndices();
 
-
   for (auto resultIndex : indices.results->getIndices()) {
     if (resultIndex < origTy->getNumResults()) {
       // Handle formal original result.
@@ -1539,17 +1627,16 @@
                             ->getType()
                             ->getCanonicalType(witnessCanGenSig),
                         origResult.getConvention()));
-    }
-    else {
+    } else {
       // Handle original `inout` parameter.
       auto inoutParamIndex = resultIndex - origTy->getNumResults();
       auto inoutParamIt = std::next(
           origTy->getIndirectMutatingParameters().begin(), inoutParamIndex);
       auto paramIndex =
           std::distance(origTy->getParameters().begin(), &*inoutParamIt);
-      // If the original `inout` parameter is a differentiability parameter, then
-      // it already has a corresponding differential parameter. Skip adding a
-      // corresponding differential result.
+      // If the original `inout` parameter is a differentiability parameter,
+      // then it already has a corresponding differential parameter. Do not add
+      // a corresponding differential result.
       if (indices.parameters->contains(paramIndex))
         continue;
       auto inoutParam = origTy->getParameters()[paramIndex];
diff --git a/lib/SILOptimizer/Differentiation/LinearMapInfo.cpp b/lib/SILOptimizer/Differentiation/LinearMapInfo.cpp
index 4582c20..8fe0323 100644
--- a/lib/SILOptimizer/Differentiation/LinearMapInfo.cpp
+++ b/lib/SILOptimizer/Differentiation/LinearMapInfo.cpp
@@ -141,8 +141,6 @@
   if (genericSig)
     branchingTraceDecl->setGenericSignature(genericSig);
   computeAccessLevel(branchingTraceDecl, original->getEffectiveSymbolLinkage());
-  branchingTraceDecl->getInterfaceType();
-  assert(branchingTraceDecl->hasInterfaceType());
   file.addTopLevelDecl(branchingTraceDecl);
   // Add basic block enum cases.
   for (auto *predBB : originalBB->getPredecessorBlocks()) {
@@ -165,7 +163,6 @@
         /*IdentifierLoc*/ loc, DeclName(astCtx.getIdentifier(bbId)), paramList,
         loc, /*RawValueExpr*/ nullptr, branchingTraceDecl);
     enumEltDecl->setImplicit();
-    enumEltDecl->getInterfaceType();
     auto *enumCaseDecl = EnumCaseDecl::create(
         /*CaseLoc*/ loc, {enumEltDecl}, branchingTraceDecl);
     enumCaseDecl->setImplicit();
@@ -207,8 +204,6 @@
   if (genericSig)
     linearMapStruct->setGenericSignature(genericSig);
   computeAccessLevel(linearMapStruct, original->getEffectiveSymbolLinkage());
-  linearMapStruct->getInterfaceType();
-  assert(linearMapStruct->hasInterfaceType());
   file.addTopLevelDecl(linearMapStruct);
   return linearMapStruct;
 }
@@ -460,7 +455,8 @@
 /// 3. The instruction has both an active result (direct or indirect) and an
 ///    active argument.
 bool LinearMapInfo::shouldDifferentiateApplySite(FullApplySite applySite) {
-  // Function applications with an inout argument should be differentiated.
+  // Function applications with an active inout argument should be
+  // differentiated.
   for (auto inoutArg : applySite.getInoutArguments())
     if (activityInfo.isActive(inoutArg, indices))
       return true;
diff --git a/lib/SILOptimizer/Differentiation/PullbackCloner.cpp b/lib/SILOptimizer/Differentiation/PullbackCloner.cpp
index 7b0c3c6..d018f27 100644
--- a/lib/SILOptimizer/Differentiation/PullbackCloner.cpp
+++ b/lib/SILOptimizer/Differentiation/PullbackCloner.cpp
@@ -562,7 +562,7 @@
   ///
   /// This method first tries to find an existing entry in the adjoint buffer
   /// mapping. If no entry exists, creates a zero adjoint buffer.
-  SILValue &getAdjointBuffer(SILBasicBlock *origBB, SILValue originalValue) {
+  SILValue getAdjointBuffer(SILBasicBlock *origBB, SILValue originalValue) {
     assert(getTangentValueCategory(originalValue) == SILValueCategory::Address);
     assert(originalValue->getFunction() == &getOriginal());
     auto insertion = bufferMap.try_emplace({origBB, originalValue}, SILValue());
@@ -1011,28 +1011,68 @@
     auto *bb = si->getParent();
     auto loc = si->getLoc();
     auto *structDecl = si->getStructDecl();
-    auto av = getAdjointValue(bb, si);
-    switch (av.getKind()) {
-    case AdjointValueKind::Zero:
-      for (auto *field : structDecl->getStoredProperties()) {
-        auto fv = si->getFieldValue(field);
-        addAdjointValue(
-            bb, fv, makeZeroAdjointValue(getRemappedTangentType(fv->getType())),
-            loc);
+    switch (getTangentValueCategory(si)) {
+    case SILValueCategory::Object: {
+      auto av = getAdjointValue(bb, si);
+      switch (av.getKind()) {
+      case AdjointValueKind::Zero: {
+        for (auto *field : structDecl->getStoredProperties()) {
+          auto fv = si->getFieldValue(field);
+          addAdjointValue(
+              bb, fv,
+              makeZeroAdjointValue(getRemappedTangentType(fv->getType())), loc);
+        }
+        break;
       }
-      break;
-    case AdjointValueKind::Concrete: {
-      auto adjStruct = materializeAdjointDirect(std::move(av), loc);
-      auto *dti = builder.createDestructureStruct(si->getLoc(), adjStruct);
+      case AdjointValueKind::Concrete: {
+        auto adjStruct = materializeAdjointDirect(std::move(av), loc);
+        auto *dti = builder.createDestructureStruct(si->getLoc(), adjStruct);
 
-      // Find the struct `TangentVector` type.
-      auto structTy = remapType(si->getType()).getASTType();
+        // Find the struct `TangentVector` type.
+        auto structTy = remapType(si->getType()).getASTType();
 #ifndef NDEBUG
-      auto tangentVectorTy = getTangentSpace(structTy)->getCanonicalType();
-      assert(!getTypeLowering(tangentVectorTy).isAddressOnly());
-      assert(tangentVectorTy->getStructOrBoundGenericStruct());
+        auto tangentVectorTy = getTangentSpace(structTy)->getCanonicalType();
+        assert(!getTypeLowering(tangentVectorTy).isAddressOnly());
+        assert(tangentVectorTy->getStructOrBoundGenericStruct());
 #endif
 
+        // Accumulate adjoints for the fields of the `struct` operand.
+        unsigned fieldIndex = 0;
+        for (auto it = structDecl->getStoredProperties().begin();
+             it != structDecl->getStoredProperties().end();
+             ++it, ++fieldIndex) {
+          VarDecl *field = *it;
+          if (field->getAttrs().hasAttribute<NoDerivativeAttr>())
+            continue;
+          // Find the corresponding field in the tangent space.
+          auto *tanField = getTangentStoredProperty(
+              getContext(), field, structTy, loc, getInvoker());
+          if (!tanField) {
+            errorOccurred = true;
+            return;
+          }
+          auto tanElt = dti->getResult(fieldIndex);
+          addAdjointValue(bb, si->getFieldValue(field),
+                          makeConcreteAdjointValue(tanElt), si->getLoc());
+        }
+        break;
+      }
+      case AdjointValueKind::Aggregate: {
+        // Note: All user-called initializations go through the calls to the
+        // initializer, and synthesized initializers only have one level of
+        // struct formation which will not result into any aggregate adjoint
+        // valeus.
+        llvm_unreachable(
+            "Aggregate adjoint values should not occur for `struct` "
+            "instructions");
+      }
+      }
+      break;
+    }
+    case SILValueCategory::Address: {
+      auto adjBuf = getAdjointBuffer(bb, si);
+      // Find the struct `TangentVector` type.
+      auto structTy = remapType(si->getType()).getASTType();
       // Accumulate adjoints for the fields of the `struct` operand.
       unsigned fieldIndex = 0;
       for (auto it = structDecl->getStoredProperties().begin();
@@ -1047,19 +1087,25 @@
           errorOccurred = true;
           return;
         }
-        auto tanElt = dti->getResult(fieldIndex);
-        addAdjointValue(bb, si->getFieldValue(field),
-                        makeConcreteAdjointValue(tanElt), si->getLoc());
+        auto *adjFieldBuf =
+            builder.createStructElementAddr(loc, adjBuf, tanField);
+        auto fieldValue = si->getFieldValue(field);
+        switch (getTangentValueCategory(fieldValue)) {
+        case SILValueCategory::Object: {
+          auto adjField = builder.emitLoadValueOperation(
+              loc, adjFieldBuf, LoadOwnershipQualifier::Copy);
+          recordTemporary(adjField);
+          addAdjointValue(bb, fieldValue, makeConcreteAdjointValue(adjField),
+                          loc);
+          break;
+        }
+        case SILValueCategory::Address: {
+          addToAdjointBuffer(bb, fieldValue, adjFieldBuf, loc);
+          break;
+        }
+        }
       }
-      break;
-    }
-    case AdjointValueKind::Aggregate: {
-      // Note: All user-called initializations go through the calls to the
-      // initializer, and synthesized initializers only have one level of struct
-      // formation which will not result into any aggregate adjoint valeus.
-      llvm_unreachable("Aggregate adjoint values should not occur for `struct` "
-                       "instructions");
-    }
+    } break;
     }
   }
 
@@ -1071,41 +1117,75 @@
   void visitStructExtractInst(StructExtractInst *sei) {
     auto *bb = sei->getParent();
     auto loc = getValidLocation(sei);
-    auto structTy = remapType(sei->getOperand()->getType()).getASTType();
-    auto tangentVectorTy = getTangentSpace(structTy)->getCanonicalType();
-    assert(!getTypeLowering(tangentVectorTy).isAddressOnly());
-    auto tangentVectorSILTy = SILType::getPrimitiveObjectType(tangentVectorTy);
-    auto *tangentVectorDecl = tangentVectorTy->getStructOrBoundGenericStruct();
-    assert(tangentVectorDecl);
     // Find the corresponding field in the tangent space.
+    auto structTy = remapType(sei->getOperand()->getType()).getASTType();
     auto *tanField =
         getTangentStoredProperty(getContext(), sei, structTy, getInvoker());
-    assert(tanField && "Invalid projections should have been diagnosed");
-    // Accumulate adjoint for the `struct_extract` operand.
-    auto av = getAdjointValue(bb, sei);
-    switch (av.getKind()) {
-    case AdjointValueKind::Zero:
-      addAdjointValue(bb, sei->getOperand(),
-                      makeZeroAdjointValue(tangentVectorSILTy), loc);
-      break;
-    case AdjointValueKind::Concrete:
-    case AdjointValueKind::Aggregate: {
-      SmallVector<AdjointValue, 8> eltVals;
-      for (auto *field : tangentVectorDecl->getStoredProperties()) {
-        if (field == tanField) {
-          eltVals.push_back(av);
-        } else {
-          auto substMap = tangentVectorTy->getMemberSubstitutionMap(
-              field->getModuleContext(), field);
-          auto fieldTy = field->getType().subst(substMap);
-          auto fieldSILTy = getTypeLowering(fieldTy).getLoweredType();
-          assert(fieldSILTy.isObject());
-          eltVals.push_back(makeZeroAdjointValue(fieldSILTy));
+    // Check the `struct_extract` operand's value tangent category.
+    switch (getTangentValueCategory(sei->getOperand())) {
+    case SILValueCategory::Object: {
+      auto tangentVectorTy = getTangentSpace(structTy)->getCanonicalType();
+      auto *tangentVectorDecl =
+          tangentVectorTy->getStructOrBoundGenericStruct();
+      assert(tangentVectorDecl);
+      auto tangentVectorSILTy =
+          SILType::getPrimitiveObjectType(tangentVectorTy);
+      assert(tanField && "Invalid projections should have been diagnosed");
+      // Accumulate adjoint for the `struct_extract` operand.
+      auto av = getAdjointValue(bb, sei);
+      switch (av.getKind()) {
+      case AdjointValueKind::Zero:
+        addAdjointValue(bb, sei->getOperand(),
+                        makeZeroAdjointValue(tangentVectorSILTy), loc);
+        break;
+      case AdjointValueKind::Concrete:
+      case AdjointValueKind::Aggregate: {
+        SmallVector<AdjointValue, 8> eltVals;
+        for (auto *field : tangentVectorDecl->getStoredProperties()) {
+          if (field == tanField) {
+            eltVals.push_back(av);
+          } else {
+            auto substMap = tangentVectorTy->getMemberSubstitutionMap(
+                field->getModuleContext(), field);
+            auto fieldTy = field->getType().subst(substMap);
+            auto fieldSILTy = getTypeLowering(fieldTy).getLoweredType();
+            assert(fieldSILTy.isObject());
+            eltVals.push_back(makeZeroAdjointValue(fieldSILTy));
+          }
         }
+        addAdjointValue(bb, sei->getOperand(),
+                        makeAggregateAdjointValue(tangentVectorSILTy, eltVals),
+                        loc);
       }
-      addAdjointValue(bb, sei->getOperand(),
-                      makeAggregateAdjointValue(tangentVectorSILTy, eltVals),
-                      loc);
+      }
+      break;
+    }
+    case SILValueCategory::Address: {
+      auto adjBase = getAdjointBuffer(bb, sei->getOperand());
+      auto *adjBaseElt =
+          builder.createStructElementAddr(loc, adjBase, tanField);
+      // Check the `struct_extract`'s value tangent category.
+      switch (getTangentValueCategory(sei)) {
+      case SILValueCategory::Object: {
+        auto adjElt = getAdjointValue(bb, sei);
+        auto concreteAdjElt = materializeAdjointDirect(adjElt, loc);
+        auto concreteAdjEltCopy =
+            builder.emitCopyValueOperation(loc, concreteAdjElt);
+        auto *alloc = builder.createAllocStack(loc, adjElt.getType());
+        builder.emitStoreValueOperation(loc, concreteAdjEltCopy, alloc,
+                                        StoreOwnershipQualifier::Init);
+        accumulateIndirect(adjBaseElt, alloc, loc);
+        builder.createDestroyAddr(loc, alloc);
+        builder.createDeallocStack(loc, alloc);
+        break;
+      }
+      case SILValueCategory::Address: {
+        auto adjElt = getAdjointBuffer(bb, sei);
+        accumulateIndirect(adjBaseElt, adjElt, loc);
+        break;
+      }
+      }
+      break;
     }
     }
   }
@@ -1171,53 +1251,74 @@
   ///                         excluding non-differentiable elements
   void visitTupleInst(TupleInst *ti) {
     auto *bb = ti->getParent();
-    auto av = getAdjointValue(bb, ti);
-    switch (av.getKind()) {
-    case AdjointValueKind::Zero:
-      for (auto elt : ti->getElements()) {
-        if (!getTangentSpace(elt->getType().getASTType()))
-          continue;
-        addAdjointValue(
-            bb, elt,
-            makeZeroAdjointValue(getRemappedTangentType(elt->getType())),
-            ti->getLoc());
+    auto loc = ti->getLoc();
+    switch (getTangentValueCategory(ti)) {
+    case SILValueCategory::Object: {
+      auto av = getAdjointValue(bb, ti);
+      switch (av.getKind()) {
+      case AdjointValueKind::Zero:
+        for (auto elt : ti->getElements()) {
+          if (!getTangentSpace(elt->getType().getASTType()))
+            continue;
+          addAdjointValue(
+              bb, elt,
+              makeZeroAdjointValue(getRemappedTangentType(elt->getType())),
+              loc);
+        }
+        break;
+      case AdjointValueKind::Concrete: {
+        auto adjVal = av.getConcreteValue();
+        auto adjValCopy = builder.emitCopyValueOperation(loc, adjVal);
+        SmallVector<SILValue, 4> adjElts;
+        if (!adjVal->getType().getAs<TupleType>()) {
+          recordTemporary(adjValCopy);
+          adjElts.push_back(adjValCopy);
+        } else {
+          auto *dti = builder.createDestructureTuple(loc, adjValCopy);
+          for (auto adjElt : dti->getResults())
+            recordTemporary(adjElt);
+          adjElts.append(dti->getResults().begin(), dti->getResults().end());
+        }
+        // Accumulate adjoints for `tuple` operands, skipping the
+        // non-`Differentiable` ones.
+        unsigned adjIndex = 0;
+        for (auto i : range(ti->getNumOperands())) {
+          if (!getTangentSpace(ti->getOperand(i)->getType().getASTType()))
+            continue;
+          auto adjElt = adjElts[adjIndex++];
+          addAdjointValue(bb, ti->getOperand(i),
+                          makeConcreteAdjointValue(adjElt), loc);
+        }
+        break;
       }
-      break;
-    case AdjointValueKind::Concrete: {
-      auto adjVal = av.getConcreteValue();
-      unsigned adjIdx = 0;
-      auto adjValCopy = builder.emitCopyValueOperation(ti->getLoc(), adjVal);
-      SmallVector<SILValue, 4> adjElts;
-      if (!adjVal->getType().getAs<TupleType>()) {
-        recordTemporary(adjValCopy);
-        adjElts.push_back(adjValCopy);
-      } else {
-        auto *dti = builder.createDestructureTuple(ti->getLoc(), adjValCopy);
-        for (auto adjElt : dti->getResults())
-          recordTemporary(adjElt);
-        adjElts.append(dti->getResults().begin(), dti->getResults().end());
-      }
-      // Accumulate adjoints for `tuple` operands, skipping the
-      // non-differentiable ones.
-      for (auto i : range(ti->getNumOperands())) {
-        if (!getTangentSpace(ti->getOperand(i)->getType().getASTType()))
-          continue;
-        auto adjElt = adjElts[adjIdx++];
-        addAdjointValue(bb, ti->getOperand(i), makeConcreteAdjointValue(adjElt),
-                        ti->getLoc());
+      case AdjointValueKind::Aggregate:
+        unsigned adjIndex = 0;
+        for (auto i : range(ti->getElements().size())) {
+          if (!getTangentSpace(ti->getElement(i)->getType().getASTType()))
+            continue;
+          addAdjointValue(bb, ti->getElement(i),
+                          av.getAggregateElement(adjIndex++), loc);
+        }
+        break;
       }
       break;
     }
-    case AdjointValueKind::Aggregate:
-      unsigned adjIdx = 0;
-      for (auto i : range(ti->getElements().size())) {
-        if (!getTangentSpace(ti->getElement(i)->getType().getASTType()))
+    case SILValueCategory::Address: {
+      auto adjBuf = getAdjointBuffer(bb, ti);
+      // Accumulate adjoints for `tuple` operands, skipping the
+      // non-`Differentiable` ones.
+      unsigned adjIndex = 0;
+      for (auto i : range(ti->getNumOperands())) {
+        if (!getTangentSpace(ti->getOperand(i)->getType().getASTType()))
           continue;
-        addAdjointValue(bb, ti->getElement(i), av.getAggregateElement(adjIdx++),
-                        ti->getLoc());
+        auto adjBufElt =
+            builder.createTupleElementAddr(loc, adjBuf, adjIndex++);
+        auto adjElt = getAdjointBuffer(bb, ti->getOperand(i));
+        accumulateIndirect(adjElt, adjBufElt, loc);
       }
       break;
     }
+    }
   }
 
   /// Handle `tuple_extract` instruction.
@@ -1276,26 +1377,58 @@
   ///             adj[x].n += adj[yn]
   void visitDestructureTupleInst(DestructureTupleInst *dti) {
     auto *bb = dti->getParent();
+    auto loc = dti->getLoc();
     auto tupleTanTy = getRemappedTangentType(dti->getOperand()->getType());
-    SmallVector<AdjointValue, 8> adjValues;
-    for (auto origElt : dti->getResults()) {
-      if (!getTangentSpace(remapType(origElt->getType()).getASTType()))
-        continue;
-      adjValues.push_back(getAdjointValue(bb, origElt));
+    // Check the `destructure_tuple` operand's value tangent category.
+    switch (getTangentValueCategory(dti->getOperand())) {
+    case SILValueCategory::Object: {
+      SmallVector<AdjointValue, 8> adjValues;
+      for (auto origElt : dti->getResults()) {
+        // Skip non-`Differentiable` tuple elements.
+        if (!getTangentSpace(remapType(origElt->getType()).getASTType()))
+          continue;
+        adjValues.push_back(getAdjointValue(bb, origElt));
+      }
+      // Handle tuple tangent type.
+      // Add adjoints for every tuple element that has a tangent space.
+      if (tupleTanTy.is<TupleType>()) {
+        assert(adjValues.size() > 1);
+        addAdjointValue(bb, dti->getOperand(),
+                        makeAggregateAdjointValue(tupleTanTy, adjValues), loc);
+      }
+      // Handle non-tuple tangent type.
+      // Add adjoint for the single tuple element that has a tangent space.
+      else {
+        assert(adjValues.size() == 1);
+        addAdjointValue(bb, dti->getOperand(), adjValues.front(), loc);
+      }
+      break;
     }
-    // Handle tuple tangent type.
-    // Add adjoints for every tuple element that has a tangent space.
-    if (tupleTanTy.is<TupleType>()) {
-      assert(adjValues.size() > 1);
-      addAdjointValue(bb, dti->getOperand(),
-                      makeAggregateAdjointValue(tupleTanTy, adjValues),
-                      dti->getLoc());
+    case SILValueCategory::Address: {
+      auto adjBuf = getAdjointBuffer(bb, dti->getOperand());
+      unsigned adjIndex = 0;
+      for (auto origElt : dti->getResults()) {
+        // Skip non-`Differentiable` tuple elements.
+        if (!getTangentSpace(remapType(origElt->getType()).getASTType()))
+          continue;
+        // Handle tuple tangent type.
+        // Add adjoints for every tuple element that has a tangent space.
+        if (tupleTanTy.is<TupleType>()) {
+          auto adjEltBuf = getAdjointBuffer(bb, origElt);
+          auto adjBufElt =
+              builder.createTupleElementAddr(loc, adjBuf, adjIndex);
+          accumulateIndirect(adjBufElt, adjEltBuf, loc);
+        }
+        // Handle non-tuple tangent type.
+        // Add adjoint for the single tuple element that has a tangent space.
+        else {
+          auto adjEltBuf = getAdjointBuffer(bb, origElt);
+          addToAdjointBuffer(bb, dti->getOperand(), adjEltBuf, loc);
+        }
+        ++adjIndex;
+      }
+      break;
     }
-    // Handle non-tuple tangent type.
-    // Add adjoint for the single tuple element that has a tangent space.
-    else {
-      assert(adjValues.size() == 1);
-      addAdjointValue(bb, dti->getOperand(), adjValues.front(), dti->getLoc());
     }
   }
 
@@ -1337,7 +1470,7 @@
   ///    Adjoint: adj[x] += load adj[y]; adj[y] = 0
   void visitStoreOperation(SILBasicBlock *bb, SILLocation loc, SILValue origSrc,
                            SILValue origDest) {
-    auto &adjBuf = getAdjointBuffer(bb, origDest);
+    auto adjBuf = getAdjointBuffer(bb, origDest);
     switch (getTangentValueCategory(origSrc)) {
     case SILValueCategory::Object: {
       auto adjVal = builder.emitLoadValueOperation(
@@ -1369,7 +1502,7 @@
   ///    Adjoint: adj[x] += adj[y]; adj[y] = 0
   void visitCopyAddrInst(CopyAddrInst *cai) {
     auto *bb = cai->getParent();
-    auto &adjDest = getAdjointBuffer(bb, cai->getDest());
+    auto adjDest = getAdjointBuffer(bb, cai->getDest());
     auto destType = remapType(adjDest->getType());
     addToAdjointBuffer(bb, cai->getSrc(), adjDest, cai->getLoc());
     builder.emitDestroyAddrAndFold(cai->getLoc(), adjDest);
@@ -1388,7 +1521,7 @@
       break;
     }
     case SILValueCategory::Address: {
-      auto &adjDest = getAdjointBuffer(bb, cvi);
+      auto adjDest = getAdjointBuffer(bb, cvi);
       auto destType = remapType(adjDest->getType());
       addToAdjointBuffer(bb, cvi->getOperand(), adjDest, cvi->getLoc());
       builder.emitDestroyAddrAndFold(cvi->getLoc(), adjDest);
@@ -1410,7 +1543,7 @@
       break;
     }
     case SILValueCategory::Address: {
-      auto &adjDest = getAdjointBuffer(bb, bbi);
+      auto adjDest = getAdjointBuffer(bb, bbi);
       auto destType = remapType(adjDest->getType());
       addToAdjointBuffer(bb, bbi->getOperand(), adjDest, bbi->getLoc());
       builder.emitDestroyAddrAndFold(bbi->getLoc(), adjDest);
@@ -1449,8 +1582,8 @@
   void visitUnconditionalCheckedCastAddrInst(
       UnconditionalCheckedCastAddrInst *uccai) {
     auto *bb = uccai->getParent();
-    auto &adjDest = getAdjointBuffer(bb, uccai->getDest());
-    auto &adjSrc = getAdjointBuffer(bb, uccai->getSrc());
+    auto adjDest = getAdjointBuffer(bb, uccai->getDest());
+    auto adjSrc = getAdjointBuffer(bb, uccai->getSrc());
     auto destType = remapType(adjDest->getType());
     auto castBuf = builder.createAllocStack(uccai->getLoc(), adjSrc->getType());
     builder.createUnconditionalCheckedCastAddr(
@@ -1479,7 +1612,7 @@
       break;
     }
     case SILValueCategory::Address: {
-      auto &adjDest = getAdjointBuffer(bb, urci);
+      auto adjDest = getAdjointBuffer(bb, urci);
       auto destType = remapType(adjDest->getType());
       addToAdjointBuffer(bb, urci->getOperand(), adjDest, urci->getLoc());
       builder.emitDestroyAddrAndFold(urci->getLoc(), adjDest);
@@ -1506,7 +1639,7 @@
       break;
     }
     case SILValueCategory::Address: {
-      auto &adjDest = getAdjointBuffer(bb, ui);
+      auto adjDest = getAdjointBuffer(bb, ui);
       auto destType = remapType(adjDest->getType());
       addToAdjointBuffer(bb, ui->getOperand(), adjDest, ui->getLoc());
       builder.emitDestroyAddrAndFold(ui->getLoc(), adjDest);
diff --git a/lib/SILOptimizer/Differentiation/Thunk.cpp b/lib/SILOptimizer/Differentiation/Thunk.cpp
index 820805f..a59dc09 100644
--- a/lib/SILOptimizer/Differentiation/Thunk.cpp
+++ b/lib/SILOptimizer/Differentiation/Thunk.cpp
@@ -249,6 +249,58 @@
       fn->getASTContext());
 }
 
+/// Forward function arguments, handling ownership convention mismatches.
+/// Adapted from `forwardFunctionArguments` in SILGenPoly.cpp.
+///
+/// Forwarded arguments are appended to `forwardedArgs`.
+///
+/// Local allocations are appended to `localAllocations`. They need to be
+/// deallocated via `dealloc_stack`.
+///
+/// Local values requiring cleanup are appended to `valuesToCleanup`.
+static void forwardFunctionArgumentsConvertingOwnership(
+    SILBuilder &builder, SILLocation loc, CanSILFunctionType fromTy,
+    CanSILFunctionType toTy, ArrayRef<SILArgument *> originalArgs,
+    SmallVectorImpl<SILValue> &forwardedArgs,
+    SmallVectorImpl<AllocStackInst *> &localAllocations,
+    SmallVectorImpl<SILValue> &valuesToCleanup) {
+  auto fromParameters = fromTy->getParameters();
+  auto toParameters = toTy->getParameters();
+  assert(fromParameters.size() == toParameters.size());
+  assert(fromParameters.size() == originalArgs.size());
+  for (auto index : indices(originalArgs)) {
+    auto &arg = originalArgs[index];
+    auto fromParam = fromParameters[index];
+    auto toParam = toParameters[index];
+    // To convert guaranteed argument to be owned, create a copy.
+    if (fromParam.isConsumed() && !toParam.isConsumed()) {
+      // If the argument has an object type, create a `copy_value`.
+      if (arg->getType().isObject()) {
+        auto argCopy = builder.emitCopyValueOperation(loc, arg);
+        forwardedArgs.push_back(argCopy);
+        continue;
+      }
+      // If the argument has an address type, create a local allocation and
+      // `copy_addr` its contents to the local allocation.
+      auto *alloc = builder.createAllocStack(loc, arg->getType());
+      builder.createCopyAddr(loc, arg, alloc, IsNotTake, IsInitialization);
+      localAllocations.push_back(alloc);
+      forwardedArgs.push_back(alloc);
+      continue;
+    }
+    // To convert owned argument to be guaranteed, borrow the argument.
+    if (fromParam.isGuaranteed() && !toParam.isGuaranteed()) {
+      auto bbi = builder.emitBeginBorrowOperation(loc, arg);
+      forwardedArgs.push_back(bbi);
+      valuesToCleanup.push_back(bbi);
+      valuesToCleanup.push_back(arg);
+      continue;
+    }
+    // Otherwise, simply forward the argument.
+    forwardedArgs.push_back(arg);
+  }
+}
+
 SILFunction *getOrCreateReabstractionThunk(SILOptFunctionBuilder &fb,
                                            SILModule &module, SILLocation loc,
                                            SILFunction *caller,
@@ -274,18 +326,13 @@
       thunkType, fromInterfaceType, toInterfaceType, Type(),
       module.getSwiftModule());
 
-  // FIXME(TF-989): Mark reabstraction thunks as transparent. This requires
-  // generating ossa reabstraction thunks so that they can be inlined during
-  // mandatory inlining when `-enable-strip-ownership-after-serialization` is
-  // true and ownership model eliminator is not run after differentiation.
   auto *thunk = fb.getOrCreateSharedFunction(
-      loc, name, thunkDeclType, IsBare, IsNotTransparent, IsSerialized,
+      loc, name, thunkDeclType, IsBare, IsTransparent, IsSerialized,
       ProfileCounter(), IsReabstractionThunk, IsNotDynamic);
   if (!thunk->empty())
     return thunk;
 
   thunk->setGenericEnvironment(genericEnv);
-  thunk->setOwnershipEliminated();
   auto *entry = thunk->createBasicBlock();
   SILBuilder builder(entry);
   createEntryArguments(thunk);
@@ -294,13 +341,21 @@
   SILFunctionConventions toConv(toType, module);
   assert(toConv.useLoweredAddresses());
 
-  auto *fnArg = thunk->getArgumentsWithoutIndirectResults().back();
+  // Forward thunk arguments, handling ownership convention mismatches.
+  SmallVector<SILValue, 4> forwardedArgs;
+  for (auto indRes : thunk->getIndirectResults())
+    forwardedArgs.push_back(indRes);
+  SmallVector<AllocStackInst *, 4> localAllocations;
+  SmallVector<SILValue, 4> valuesToCleanup;
+  forwardFunctionArgumentsConvertingOwnership(
+      builder, loc, fromType, toType,
+      thunk->getArgumentsWithoutIndirectResults().drop_back(), forwardedArgs,
+      localAllocations, valuesToCleanup);
 
   SmallVector<SILValue, 4> arguments;
-  auto toArgIter = thunk->getArguments().begin();
+  auto toArgIter = forwardedArgs.begin();
   auto useNextArgument = [&]() { arguments.push_back(*toArgIter++); };
 
-  SmallVector<AllocStackInst *, 4> localAllocations;
   auto createAllocStack = [&](SILType type) {
     auto *alloc = builder.createAllocStack(loc, type);
     localAllocations.push_back(alloc);
@@ -350,21 +405,25 @@
       if (!paramTy.hasArchetype())
         paramTy = thunk->mapTypeIntoContext(paramTy);
       assert(paramTy.isAddress());
-      auto *toArg = *toArgIter++;
+      auto toArg = *toArgIter++;
       auto *buf = createAllocStack(toArg->getType());
-      builder.createStore(loc, toArg, buf,
-                          StoreOwnershipQualifier::Unqualified);
+      toArg = builder.emitCopyValueOperation(loc, toArg);
+      builder.emitStoreValueOperation(loc, toArg, buf,
+                                      StoreOwnershipQualifier::Init);
+      valuesToCleanup.push_back(buf);
       arguments.push_back(buf);
       continue;
     }
     // Convert direct parameter to indirect parameter.
     assert(toParam.isFormalIndirect());
-    auto *toArg = *toArgIter++;
-    auto *load =
-        builder.createLoad(loc, toArg, LoadOwnershipQualifier::Unqualified);
+    auto toArg = *toArgIter++;
+    auto load = builder.emitLoadBorrowOperation(loc, toArg);
+    if (isa<LoadBorrowInst>(load))
+      valuesToCleanup.push_back(load);
     arguments.push_back(load);
   }
 
+  auto *fnArg = thunk->getArgumentsWithoutIndirectResults().back();
   auto *apply = builder.createApply(loc, fnArg, SubstitutionMap(), arguments,
                                     /*isNonThrowing*/ false);
 
@@ -413,8 +472,8 @@
     // Load direct results from indirect results.
     if (fromRes.isFormalIndirect()) {
       auto indRes = *fromIndResultsIter++;
-      auto *load =
-          builder.createLoad(loc, indRes, LoadOwnershipQualifier::Unqualified);
+      auto load = builder.emitLoadValueOperation(loc, indRes,
+                                                 LoadOwnershipQualifier::Take);
       results.push_back(load);
       continue;
     }
@@ -426,11 +485,28 @@
     assert(resultTy.isAddress());
 #endif
     auto indRes = *toIndResultsIter++;
-    builder.createStore(loc, *fromDirResultsIter++, indRes,
-                        StoreOwnershipQualifier::Unqualified);
+    auto dirRes = *fromDirResultsIter++;
+    builder.emitStoreValueOperation(loc, dirRes, indRes,
+                                    StoreOwnershipQualifier::Init);
   }
   auto retVal = joinElements(results, builder, loc);
 
+  // Clean up local values.
+  // Guaranteed values need an `end_borrow`.
+  // Owned values need to be destroyed.
+  for (auto arg : valuesToCleanup) {
+    switch (arg.getOwnershipKind()) {
+    case ValueOwnershipKind::Guaranteed:
+      builder.emitEndBorrowOperation(loc, arg);
+      break;
+    case ValueOwnershipKind::Owned:
+    case ValueOwnershipKind::Unowned:
+    case ValueOwnershipKind::None:
+      builder.emitDestroyOperation(loc, arg);
+      break;
+    }
+  }
+
   // Deallocate local allocations.
   for (auto *alloc : llvm::reverse(localAllocations))
     builder.createDeallocStack(loc, alloc);
@@ -549,11 +625,11 @@
       auto *buf = builder.createAllocStack(loc, zeroSILObjType);
       localAllocations.push_back(buf);
       emitZeroIntoBuffer(builder, zeroType, buf, loc);
-      if (zeroSILType.isAddress())
+      if (zeroSILType.isAddress()) {
         arguments.push_back(buf);
-      else {
-        auto *arg =
-            builder.createLoad(loc, buf, LoadOwnershipQualifier::Unqualified);
+      } else {
+        auto arg = builder.emitLoadValueOperation(loc, buf,
+                                                  LoadOwnershipQualifier::Take);
         arguments.push_back(arg);
       }
       break;
@@ -810,8 +886,6 @@
   if (!thunk->empty())
     return {thunk, interfaceSubs};
 
-  // TODO(TF-1206): Enable ownership in all differentiation thunks.
-  thunk->setOwnershipEliminated();
   thunk->setGenericEnvironment(genericEnv);
   auto *entry = thunk->createBasicBlock();
   SILBuilder builder(entry);
diff --git a/lib/SILOptimizer/Differentiation/VJPCloner.cpp b/lib/SILOptimizer/Differentiation/VJPCloner.cpp
index f58db20..d28fb85 100644
--- a/lib/SILOptimizer/Differentiation/VJPCloner.cpp
+++ b/lib/SILOptimizer/Differentiation/VJPCloner.cpp
@@ -755,6 +755,8 @@
         pattern, tanType, TypeExpansionContext::minimal());
     ParameterConvention conv;
     switch (origResConv) {
+    case ResultConvention::Unowned:
+    case ResultConvention::UnownedInnerPointer:
     case ResultConvention::Owned:
     case ResultConvention::Autoreleased:
       if (tl.isAddressOnly()) {
@@ -764,10 +766,6 @@
                               : ParameterConvention::Direct_Guaranteed;
       }
       break;
-    case ResultConvention::Unowned:
-    case ResultConvention::UnownedInnerPointer:
-      conv = ParameterConvention::Direct_Unowned;
-      break;
     case ResultConvention::Indirect:
       conv = ParameterConvention::Indirect_In_Guaranteed;
       break;
diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp
index 1c34038..9c9e7bf 100644
--- a/lib/SILOptimizer/IPO/GlobalOpt.cpp
+++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp
@@ -301,7 +301,7 @@
 
   if (LoopCheckedFunctions.insert(F).second) {
     for (auto I = scc_begin(F); !I.isAtEnd(); ++I) {
-      if (I.hasLoop())
+      if (I.hasCycle())
         for (SILBasicBlock *BB : *I)
           LoopBlocks.insert(BB);
     }
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h
index 66a878c..1cea674 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h
@@ -176,6 +176,11 @@
            MemoryInst->isDerivedClassSelfOnly();
   }
 
+  /// True if this memory object is the 'self' of a root class init method.
+  bool isRootClassSelf() const {
+    return isClassInitSelf() && MemoryInst->isRootSelf();
+  }
+
   /// True if this memory object is the 'self' of a non-root class init method.
   bool isNonRootClassSelf() const {
     return isClassInitSelf() && !MemoryInst->isRootSelf();
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index ab7a60c..14a6328 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -1072,7 +1072,13 @@
     // it for later.   Once we've collected all of the conditional init/assigns,
     // we can insert a single control variable for the memory object for the
     // whole function.
-    if (!Use.onlyTouchesTrivialElements(TheMemory))
+    //
+    // For root class initializers, we must keep track of initializations of
+    // trivial stored properties also, since we need to know when the object
+    // has been fully initialized when deciding if a strong_release should
+    // lower to a partial_dealloc_ref.
+    if (TheMemory.isRootClassSelf() ||
+        !Use.onlyTouchesTrivialElements(TheMemory))
       HasConditionalInitAssign = true;
     return;
   }
@@ -2186,12 +2192,12 @@
 }
 
 /// Test a bit in the control variable at the current insertion point.
-static SILValue testControlVariable(SILLocation Loc,
-                                    unsigned Elt,
-                                    SILValue ControlVariableAddr,
-                                    Identifier &ShiftRightFn,
-                                    Identifier &TruncateFn,
-                                    SILBuilder &B) {
+static SILValue testControlVariableBit(SILLocation Loc,
+                                       unsigned Elt,
+                                       SILValue ControlVariableAddr,
+                                       Identifier &ShiftRightFn,
+                                       Identifier &TruncateFn,
+                                       SILBuilder &B) {
   SILValue ControlVariable =
         B.createLoad(Loc, ControlVariableAddr, LoadOwnershipQualifier::Trivial);
 
@@ -2224,6 +2230,32 @@
                          {}, CondVal);
 }
 
+/// Test if all bits in the control variable are set at the current
+/// insertion point.
+static SILValue testAllControlVariableBits(SILLocation Loc,
+                                           SILValue ControlVariableAddr,
+                                           Identifier &CmpEqFn,
+                                           SILBuilder &B) {
+  SILValue ControlVariable =
+        B.createLoad(Loc, ControlVariableAddr, LoadOwnershipQualifier::Trivial);
+
+  SILValue CondVal = ControlVariable;
+  CanBuiltinIntegerType IVType = CondVal->getType().castTo<BuiltinIntegerType>();
+
+  if (IVType->getFixedWidth() == 1)
+    return CondVal;
+
+  SILValue AllBitsSet = B.createIntegerLiteral(Loc, CondVal->getType(), -1);
+  if (!CmpEqFn.get())
+    CmpEqFn = getBinaryFunction("cmp_eq", CondVal->getType(),
+                                B.getASTContext());
+  SILValue Args[] = { CondVal, AllBitsSet };
+
+  return B.createBuiltin(Loc, CmpEqFn,
+                         SILType::getBuiltinIntegerType(1, B.getASTContext()),
+                         {}, Args);
+}
+
 /// handleConditionalInitAssign - This memory object has some stores
 /// into (some element of) it that is either an init or an assign based on the
 /// control flow path through the function, or have a destroy event that happens
@@ -2285,7 +2317,13 @@
     // If this ambiguous store is only of trivial types, then we don't need to
     // do anything special.  We don't even need keep the init bit for the
     // element precise.
-    if (Use.onlyTouchesTrivialElements(TheMemory))
+    //
+    // For root class initializers, we must keep track of initializations of
+    // trivial stored properties also, since we need to know when the object
+    // has been fully initialized when deciding if a strong_release should
+    // lower to a partial_dealloc_ref.
+    if (!TheMemory.isRootClassSelf() &&
+        Use.onlyTouchesTrivialElements(TheMemory))
       continue;
     
     B.setInsertionPoint(Use.Inst);
@@ -2324,9 +2362,9 @@
     // initialization.
     for (unsigned Elt = Use.FirstElement, e = Elt+Use.NumElements;
          Elt != e; ++Elt) {
-      auto CondVal = testControlVariable(Loc, Elt, ControlVariableAddr,
-                                         ShiftRightFn, TruncateFn,
-                                         B);
+      auto CondVal = testControlVariableBit(Loc, Elt, ControlVariableAddr,
+                                            ShiftRightFn, TruncateFn,
+                                            B);
       
       SILBasicBlock *TrueBB, *FalseBB, *ContBB;
       InsertCFGDiamond(CondVal, Loc, B,
@@ -2395,7 +2433,7 @@
 void LifetimeChecker::
 handleConditionalDestroys(SILValue ControlVariableAddr) {
   SILBuilderWithScope B(TheMemory.getUninitializedValue());
-  Identifier ShiftRightFn, TruncateFn;
+  Identifier ShiftRightFn, TruncateFn, CmpEqFn;
 
   unsigned NumMemoryElements = TheMemory.getNumElements();
 
@@ -2465,9 +2503,9 @@
 
       // Insert a load of the liveness bitmask and split the CFG into a diamond
       // right before the destroy_addr, if we haven't already loaded it.
-      auto CondVal = testControlVariable(Loc, Elt, ControlVariableAddr,
-                                         ShiftRightFn, TruncateFn,
-                                         B);
+      auto CondVal = testControlVariableBit(Loc, Elt, ControlVariableAddr,
+                                            ShiftRightFn, TruncateFn,
+                                            B);
 
       SILBasicBlock *ReleaseBlock, *DeallocBlock, *ContBlock;
 
@@ -2486,11 +2524,11 @@
   // depending on if the self box was initialized or not.
   auto emitReleaseOfSelfWhenNotConsumed = [&](SILLocation Loc,
                                               SILInstruction *Release) {
-    auto CondVal = testControlVariable(Loc, SelfInitializedElt,
-                                       ControlVariableAddr,
-                                       ShiftRightFn,
-                                       TruncateFn,
-                                       B);
+    auto CondVal = testControlVariableBit(Loc, SelfInitializedElt,
+                                          ControlVariableAddr,
+                                          ShiftRightFn,
+                                          TruncateFn,
+                                          B);
 
     SILBasicBlock *ReleaseBlock, *ConsumedBlock, *ContBlock;
 
@@ -2522,12 +2560,50 @@
     // Just conditionally destroy each memory element, and for classes,
     // also free the partially initialized object.
     if (!TheMemory.isNonRootClassSelf()) {
-      destroyMemoryElements(Loc, Availability);
-      processUninitializedRelease(Release, false, B.getInsertionPoint());
+      assert(!Availability.isAllYes() &&
+             "Should not end up here if fully initialized");
 
-      // The original strong_release or destroy_addr instruction is
-      // always dead at this point.
-      deleteDeadRelease(CDElt.ReleaseID);
+      // For root class initializers, we check if all proeprties were
+      // dynamically initialized, and if so, treat this as a release of
+      // an initialized 'self', instead of tearing down the fields
+      // one by one and deallocating memory.
+      //
+      // This is required for correctness, since the condition that
+      // allows 'self' to escape is that all stored properties were
+      // initialized. So we cannot deallocate the memory if 'self' may
+      // have escaped.
+      //
+      // This also means the deinitializer will run if all stored
+      // properties were initialized.
+      if (TheMemory.isClassInitSelf() &&
+          Availability.hasAny(DIKind::Partial)) {
+        auto CondVal = testAllControlVariableBits(Loc, ControlVariableAddr,
+                                                  CmpEqFn, B);
+
+        SILBasicBlock *ReleaseBlock, *DeallocBlock, *ContBlock;
+
+        InsertCFGDiamond(CondVal, Loc, B,
+                         ReleaseBlock, DeallocBlock, ContBlock);
+
+        // If true, self was fully initialized and must be released.
+        B.setInsertionPoint(ReleaseBlock->begin());
+        B.setCurrentDebugScope(ReleaseBlock->begin()->getDebugScope());
+        Release->moveBefore(&*B.getInsertionPoint());
+
+        // If false, self is uninitialized and must be freed.
+        B.setInsertionPoint(DeallocBlock->begin());
+        B.setCurrentDebugScope(DeallocBlock->begin()->getDebugScope());
+        destroyMemoryElements(Loc, Availability);
+        processUninitializedRelease(Release, false, B.getInsertionPoint());
+      } else {
+        destroyMemoryElements(Loc, Availability);
+        processUninitializedRelease(Release, false, B.getInsertionPoint());
+
+        // The original strong_release or destroy_addr instruction is
+        // always dead at this point.
+        deleteDeadRelease(CDElt.ReleaseID);
+      }
+
       continue;
     }
 
@@ -2573,11 +2649,11 @@
         // self.init or super.init may or may not have been called.
         // We have not yet stored 'self' into the box.
 
-        auto CondVal = testControlVariable(Loc, SuperInitElt,
-                                           ControlVariableAddr,
-                                           ShiftRightFn,
-                                           TruncateFn,
-                                           B);
+        auto CondVal = testControlVariableBit(Loc, SuperInitElt,
+                                              ControlVariableAddr,
+                                              ShiftRightFn,
+                                              TruncateFn,
+                                              B);
 
         SILBasicBlock *ConsumedBlock, *DeallocBlock, *ContBlock;
 
@@ -2607,11 +2683,11 @@
         // self.init or super.init may or may not have been called.
         // We may or may have stored 'self' into the box.
 
-        auto CondVal = testControlVariable(Loc, SuperInitElt,
-                                           ControlVariableAddr,
-                                           ShiftRightFn,
-                                           TruncateFn,
-                                           B);
+        auto CondVal = testControlVariableBit(Loc, SuperInitElt,
+                                              ControlVariableAddr,
+                                              ShiftRightFn,
+                                              TruncateFn,
+                                              B);
 
         SILBasicBlock *LiveBlock, *DeallocBlock, *ContBlock;
 
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index fd5d3a0..4774b9f 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -806,6 +806,8 @@
       // BuilderContext before rewriting any uses of the ConcreteType.
       OpenedArchetypesTracker.addOpenedArchetypeDef(
           cast<ArchetypeType>(CEI.ConcreteType), CEI.ConcreteTypeDef);
+    } else if (auto *I = CEI.ConcreteValue->getDefiningInstruction()) {
+      OpenedArchetypesTracker.registerUsedOpenedArchetypes(I);
     }
   }
 }
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp
index c499356..4321485 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp
@@ -554,7 +554,8 @@
   // Be careful with open archetypes, because they cannot be moved before
   // their definitions.
   if (IEI && !OEI &&
-      !IEI->getLoweredConcreteType().isOpenedExistential()) {
+      !IEI->getLoweredConcreteType().hasOpenedExistential()) {
+    assert(!IEI->getLoweredConcreteType().isOpenedExistential());
     auto *ConcAlloc = Builder.createAllocStack(
         AS->getLoc(), IEI->getLoweredConcreteType(), AS->getVarInfo());
     IEI->replaceAllUsesWith(ConcAlloc);
diff --git a/lib/SILOptimizer/SemanticARC/BorrowScopeOpts.cpp b/lib/SILOptimizer/SemanticARC/BorrowScopeOpts.cpp
new file mode 100644
index 0000000..600c6f4
--- /dev/null
+++ b/lib/SILOptimizer/SemanticARC/BorrowScopeOpts.cpp
@@ -0,0 +1,58 @@
+//===--- BorrowScopeOpts.cpp ----------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+///
+/// Optimizations that attempt to simplify and or eliminate borrow scopes. Today
+/// we only eliminate scopes, but we could also eliminate redundant scopes by
+/// converting struct_extract operations to use destructure operations.
+///
+//===----------------------------------------------------------------------===//
+
+#include "SemanticARCOptVisitor.h"
+
+using namespace swift;
+using namespace swift::semanticarc;
+
+bool SemanticARCOptVisitor::visitBeginBorrowInst(BeginBorrowInst *bbi) {
+  auto kind = bbi->getOperand().getOwnershipKind();
+  SmallVector<EndBorrowInst *, 16> endBorrows;
+  for (auto *op : bbi->getUses()) {
+    if (!op->isConsumingUse()) {
+      // Make sure that this operand can accept our arguments kind.
+      auto map = op->getOwnershipKindMap();
+      if (map.canAcceptKind(kind))
+        continue;
+      return false;
+    }
+
+    // Otherwise, this borrow is being consumed. See if our consuming inst is an
+    // end_borrow. If it isn't, then return false, this scope is
+    // needed. Otherwise, add the end_borrow to our list of end borrows.
+    auto *ebi = dyn_cast<EndBorrowInst>(op->getUser());
+    if (!ebi) {
+      return false;
+    }
+    endBorrows.push_back(ebi);
+  }
+
+  // At this point, we know that the begin_borrow's operand can be
+  // used as an argument to all non-end borrow uses. Eliminate the
+  // begin borrow and end borrows.
+  while (!endBorrows.empty()) {
+    auto *ebi = endBorrows.pop_back_val();
+    eraseInstruction(ebi);
+  }
+
+  eraseAndRAUWSingleValueInstruction(bbi, bbi->getOperand());
+  return true;
+}
diff --git a/lib/SILOptimizer/SemanticARC/CMakeLists.txt b/lib/SILOptimizer/SemanticARC/CMakeLists.txt
index 91b9e10..24d12d7 100644
--- a/lib/SILOptimizer/SemanticARC/CMakeLists.txt
+++ b/lib/SILOptimizer/SemanticARC/CMakeLists.txt
@@ -1,3 +1,7 @@
 target_sources(swiftSILOptimizer PRIVATE
   SemanticARCOpts.cpp
-  OwnershipLiveRange.cpp)
+  OwnershipLiveRange.cpp
+  LoadCopyToLoadBorrowOpt.cpp
+  BorrowScopeOpts.cpp
+  CopyValueOpts.cpp
+  OwnedToGuaranteedPhiOpt.cpp)
diff --git a/lib/SILOptimizer/SemanticARC/CopyValueOpts.cpp b/lib/SILOptimizer/SemanticARC/CopyValueOpts.cpp
new file mode 100644
index 0000000..4d2ba91
--- /dev/null
+++ b/lib/SILOptimizer/SemanticARC/CopyValueOpts.cpp
@@ -0,0 +1,478 @@
+//===--- CopyValueOpts.cpp ------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+///
+/// Contains optimizations that eliminate redundant copy values.
+///
+//===----------------------------------------------------------------------===//
+
+#include "OwnershipPhiOperand.h"
+#include "SemanticARCOptVisitor.h"
+
+using namespace swift;
+using namespace swift::semanticarc;
+
+//===----------------------------------------------------------------------===//
+//                     Guaranteed Copy Value Optimization
+//===----------------------------------------------------------------------===//
+
+// Eliminate a copy of a borrowed value, if:
+//
+// 1. All of the copies users do not consume the copy (and thus can accept a
+//    borrowed value instead).
+// 2. The copies's non-destroy_value users are strictly contained within the
+//    scope of the borrowed value.
+//
+// Example:
+//
+//   %0 = @guaranteed (argument or instruction)
+//   %1 = copy_value %0
+//   apply %f(%1) : $@convention(thin) (@guaranteed ...) ...
+//   other_non_consuming_use %1
+//   destroy_value %1
+//   end_borrow %0 (if an instruction)
+//
+// =>
+//
+//   %0 = @guaranteed (argument or instruction)
+//   apply %f(%0) : $@convention(thin) (@guaranteed ...) ...
+//   other_non_consuming_use %0
+//   end_borrow %0 (if an instruction)
+//
+// NOTE: This means that the destroy_value technically can be after the
+// end_borrow. In practice, this will not be the case but we use this to avoid
+// having to reason about the ordering of the end_borrow and destroy_value.
+//
+// NOTE: Today we only perform this for guaranteed parameters since this enables
+// us to avoid doing the linear lifetime check to make sure that all destroys
+// are within the borrow scope.
+//
+// TODO: This needs a better name.
+bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(
+    CopyValueInst *cvi) {
+  // For now, do not run this optimization. This is just to be careful.
+  if (onlyGuaranteedOpts)
+    return false;
+
+  SmallVector<BorrowedValue, 4> borrowScopeIntroducers;
+
+  // Find all borrow introducers for our copy operand. If we are unable to find
+  // all of the reproducers (due to pattern matching failure), conservatively
+  // return false. We can not optimize.
+  //
+  // NOTE: We can get multiple introducers if our copy_value's operand
+  // value runs through a phi or an aggregate forming instruction.
+  if (!getAllBorrowIntroducingValues(cvi->getOperand(), borrowScopeIntroducers))
+    return false;
+
+  // Then go over all of our uses and see if the value returned by our copy
+  // value forms a dead live range or a live range that would be dead if it was
+  // not consumed by phi nodes. If we do not have such a live range, there must
+  // be some consuming use that we either do not understand is /actually/
+  // forwarding or a user that truly represents a necessary consume of the value
+  // (e.x. storing into memory).
+  OwnershipLiveRange lr(cvi);
+  auto hasUnknownConsumingUseState =
+      lr.hasUnknownConsumingUse(assumingAtFixedPoint);
+  if (hasUnknownConsumingUseState ==
+      OwnershipLiveRange::HasConsumingUse_t::Yes) {
+    return false;
+  }
+
+  // Next check if we do not have any destroys of our copy_value and are
+  // processing a local borrow scope. In such a case, due to the way we ignore
+  // dead end blocks, we may eliminate the copy_value, creating a use of the
+  // borrowed value after the end_borrow. To avoid this, in such cases we
+  // bail. In contrast, a non-local borrow scope does not have any end scope
+  // instructions, implying we can avoid this hazard and still optimize in such
+  // a case.
+  //
+  // DISCUSSION: Consider the following SIL:
+  //
+  // ```
+  //   %1 = begin_borrow %0 : $KlassPair                            (1)
+  //   %2 = struct_extract %1 : $KlassPair, #KlassPair.firstKlass
+  //   %3 = copy_value %2 : $Klass
+  //   ...
+  //   end_borrow %1 : $LintCommand                                 (2)
+  //   cond_br ..., bb1, bb2
+  //
+  //   ...
+  //
+  //   bbN:
+  //     // Never return type implies dead end block.
+  //     apply %f(%3) : $@convention(thin) (@guaranteed Klass) -> Never (3)
+  //     unreachable
+  // ```
+  //
+  // For simplicity, note that if bbN post-dominates %3, given that when we
+  // compute linear lifetime errors we ignore dead end blocks, we would not
+  // register that the copy_values only use is outside of the begin_borrow
+  // region defined by (1), (2) and thus would eliminate the copy. This would
+  // result in %2 being used by %f, causing the linear lifetime checker to
+  // error.
+  //
+  // Naively one may assume that the solution to this is to just check if %3 has
+  // /any/ destroy_values at all and if it doesn't have any reachable
+  // destroy_values, then we are in this case. But is this correct in
+  // general. We prove this below:
+  //
+  // The only paths along which the copy_value can not be destroyed or consumed
+  // is along paths to dead end blocks. Trivially, we know that such a dead end
+  // block, can not be reachable from the end_borrow since by their nature dead
+  // end blocks end in unreachables.
+  //
+  // So we know that we can only run into this bug if we have a dead end block
+  // reachable from the end_borrow, meaning that the bug can not occur if we
+  // branch before the end_borrow since in that case, the borrow scope would
+  // last over the dead end block's no return meaning that we will not use the
+  // borrowed value after its lifetime is ended by the end_borrow.
+  //
+  // With that in hand, we note again that if we have exactly one consumed,
+  // destroy_value /after/ the end_borrow we will not optimize here. This means
+  // that this bug can only occur if the copy_value is only post-dominated by
+  // dead end blocks that use the value in a non-consuming way.
+  //
+  // TODO: There may be some way of sinking this into the loop below.
+  bool haveAnyLocalScopes =
+      llvm::any_of(borrowScopeIntroducers, [](BorrowedValue borrowScope) {
+        return borrowScope.isLocalScope();
+      });
+
+  auto destroys = lr.getDestroyingUses();
+  if (destroys.empty() && haveAnyLocalScopes) {
+    return false;
+  }
+
+  // If we reached this point, then we know that all of our users can accept a
+  // guaranteed value and our owned value is destroyed only by a set of
+  // destroy_values. Check if:
+  //
+  // 1. All of our destroys are joint post-dominated by our end borrow scope
+  //    set. If they do not, then the copy_value is lifetime extending the
+  //    guaranteed value, we can not eliminate it.
+  //
+  // 2. If all of our destroy_values are dead end. In such a case, the linear
+  //    lifetime checker will not perform any checks since it assumes that dead
+  //    end destroys can be ignored. Since we are going to end the program
+  //    anyways, we want to be conservative here and optimize only if we do not
+  //    need to insert an end_borrow since all of our borrow introducers are
+  //    non-local scopes.
+  {
+    bool foundNonDeadEnd = false;
+    for (auto *d : destroys) {
+      foundNonDeadEnd |= !getDeadEndBlocks().isDeadEnd(d->getParentBlock());
+    }
+    if (!foundNonDeadEnd && haveAnyLocalScopes)
+      return false;
+    SmallVector<Operand *, 8> scratchSpace;
+    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
+    if (llvm::any_of(borrowScopeIntroducers, [&](BorrowedValue borrowScope) {
+          return !borrowScope.areUsesWithinScope(lr.getAllConsumingUses(),
+                                                 scratchSpace, visitedBlocks,
+                                                 getDeadEndBlocks());
+        })) {
+      return false;
+    }
+  }
+
+  // Otherwise, we know that our copy_value/destroy_values are all completely
+  // within the guaranteed value scope. So we /could/ optimize it. Now check if
+  // we were truly dead or if we are dead if we can eliminate phi arg uses. If
+  // we need to handle the phi arg uses, we bail. After we reach a fixed point,
+  // we will try to eliminate this value then if we can find a complete set of
+  // all incoming values to our phi argument.
+  if (hasUnknownConsumingUseState ==
+      OwnershipLiveRange::HasConsumingUse_t::YesButAllPhiArgs) {
+    auto opPhi = *OwnershipPhiOperand::get(lr.getSingleUnknownConsumingUse());
+    SmallVector<Operand *, 8> scratchSpace;
+    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
+
+    bool canOptimizePhi = opPhi.visitResults([&](SILValue value) {
+      SWIFT_DEFER {
+        scratchSpace.clear();
+        visitedBlocks.clear();
+      };
+
+      OwnershipLiveRange phiArgLR(value);
+      if (bool(phiArgLR.hasUnknownConsumingUse())) {
+        return false;
+      }
+
+      if (llvm::any_of(borrowScopeIntroducers, [&](BorrowedValue borrowScope) {
+            return !borrowScope.areUsesWithinScope(
+                phiArgLR.getAllConsumingUses(), scratchSpace, visitedBlocks,
+                getDeadEndBlocks());
+          })) {
+        return false;
+      }
+
+      return true;
+    });
+
+    if (canOptimizePhi) {
+      opPhi.visitResults([&](SILValue value) {
+        joinedOwnedIntroducerToConsumedOperands.insert(value,
+                                                       opPhi.getOperand());
+        return true;
+      });
+    }
+
+    return false;
+  }
+
+  // Otherwise, our copy must truly not be needed, o RAUW and convert to
+  // guaranteed!
+  std::move(lr).convertToGuaranteedAndRAUW(cvi->getOperand(), getCallbacks());
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
+//                       Trivial Live Range Elimination
+//===----------------------------------------------------------------------===//
+
+/// If cvi only has destroy value users, then cvi is a dead live range. Lets
+/// eliminate all such dead live ranges.
+bool SemanticARCOptVisitor::eliminateDeadLiveRangeCopyValue(
+    CopyValueInst *cvi) {
+  // This is a cheap optimization generally.
+
+  // See if we are lucky and have a simple case.
+  if (auto *op = cvi->getSingleUse()) {
+    if (auto *dvi = dyn_cast<DestroyValueInst>(op->getUser())) {
+      eraseInstruction(dvi);
+      eraseInstructionAndAddOperandsToWorklist(cvi);
+      return true;
+    }
+  }
+
+  // If all of our copy_value users are destroy_value, zap all of the
+  // instructions. We begin by performing that check and gathering up our
+  // destroy_value.
+  SmallVector<DestroyValueInst *, 16> destroys;
+  if (!all_of(cvi->getUses(), [&](Operand *op) {
+        auto *dvi = dyn_cast<DestroyValueInst>(op->getUser());
+        if (!dvi)
+          return false;
+
+        // Stash dvi in destroys so we can easily eliminate it later.
+        destroys.push_back(dvi);
+        return true;
+      })) {
+    return false;
+  }
+
+  // Now that we have a truly dead live range copy value, eliminate it!
+  while (!destroys.empty()) {
+    eraseInstruction(destroys.pop_back_val());
+  }
+  eraseInstructionAndAddOperandsToWorklist(cvi);
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
+//                             Live Range Joining
+//===----------------------------------------------------------------------===//
+
+// Handle simple checking where we do not need to form live ranges and visit a
+// bunch of instructions.
+static bool canSafelyJoinSimpleRange(SILValue cviOperand,
+                                     DestroyValueInst *cviOperandDestroy,
+                                     CopyValueInst *cvi) {
+  // We only handle cases where our copy_value has a single consuming use that
+  // is not a forwarding use. We need to use the LiveRange functionality to
+  // guarantee correctness in the presence of forwarding uses.
+  //
+  // NOTE: This use may be any type of consuming use and may not be a
+  // destroy_value.
+  auto *cviConsumer = cvi->getSingleConsumingUse();
+  if (!cviConsumer || isOwnedForwardingInstruction(cviConsumer->getUser())) {
+    return false;
+  }
+
+  // Ok, we may be able to eliminate this. The main thing we need to be careful
+  // of here is that if the destroy_value is /after/ the consuming use of the
+  // operand of copy_value, we may have normal uses of the copy_value's operand
+  // that would become use-after-frees since we would be shrinking the lifetime
+  // of the object potentially. Consider the following SIL:
+  //
+  //   %0 = ...
+  //   %1 = copy_value %0
+  //   apply %cviConsumer(%1)
+  //   apply %guaranteedUser(%0)
+  //   destroy_value %0
+  //
+  // Easily, if we were to eliminate the copy_value, destroy_value, the object's
+  // lifetime could potentially be shrunk before guaranteedUser is executed,
+  // causing guaranteedUser to be a use-after-free.
+  //
+  // As an extra wrinkle, until all interior pointer constructs (e.x.:
+  // project_box) are guaranteed to be guaranted by a begin_borrow, we can not
+  // in general safely shrink lifetimes. So even if we think we can prove that
+  // all non-consuming uses of %0 are before apply %cviConsumer, we may miss
+  // implicit uses that are not guarded yet by a begin_borrow, resulting in
+  // use-after-frees.
+  //
+  // With that in mind, we only handle cases today where we can prove that
+  // destroy_value is strictly before the consuming use of the operand. This
+  // guarantees that we are not shrinking the lifetime of the underlying object.
+  //
+  // First we handle the simple case: where the cviConsumer is a return inst. In
+  // such a case, we know for sure that cviConsumer post-dominates the
+  // destroy_value.
+  auto cviConsumerIter = cviConsumer->getUser()->getIterator();
+  if (isa<ReturnInst>(cviConsumerIter)) {
+    return true;
+  }
+
+  // Then see if our cviConsumer is in the same block as a return inst and the
+  // destroy_value is not. In that case, we know that the cviConsumer must
+  // post-dominate the destroy_value.
+  auto *cviConsumingBlock = cviConsumerIter->getParent();
+  if (isa<ReturnInst>(cviConsumingBlock->getTerminator()) &&
+      cviConsumingBlock != cviOperandDestroy->getParent()) {
+    return true;
+  }
+
+  // Otherwise, we only support joining live ranges where the cvi and the cvi's
+  // operand's destroy are in the same block with the destroy_value of cvi
+  // operand needing to be strictly after the copy_value. This analysis can be
+  // made significantly stronger by using LiveRanges, but this is simple for
+  // now.
+  auto cviOperandDestroyIter = cviOperandDestroy->getIterator();
+  if (cviConsumingBlock != cviOperandDestroyIter->getParent()) {
+    return false;
+  }
+
+  // TODO: This should really be llvm::find, but for some reason, the templates
+  // do not match up given the current state of the iterators. This impl works
+  // in a pinch though.
+  return llvm::any_of(
+      llvm::make_range(cviOperandDestroyIter,
+                       cviOperandDestroyIter->getParent()->end()),
+      [&](const SILInstruction &val) { return &*cviConsumerIter == &val; });
+}
+
+// # The Problem We Are Solving
+//
+// The main idea here is that we are trying to eliminate the simplest, easiest
+// form of live range joining. Consider the following SIL:
+//
+//   ```
+//   %cviOperand = ...                // @owned value
+//   %cvi = copy_value %cviOperand    // copy of @owned value
+//   ...
+//   destroy_value %cviOperandDestroy // destruction of @owned value
+//   ...
+//   apply %consumingUser(%cvi)       // destruction of copy of @owned value
+//   ```
+//
+// We want to reduce reference count traffic by eliminating the middle
+// copy/destroy yielding:
+//
+//   ```
+//   %cviOperand = ...                // @owned value
+//   // *eliminated copy_value*
+//   ...
+//   // *eliminated destroy_value*
+//   ...
+//   apply %consumingUser(%cviOperand)       // destruction of copy of @owned
+//   value
+//   ```
+//
+// # Safety
+//
+// In order to do this safely, we need to take the union of the two objects
+// lifetimes since we are only joining lifetimes. This ensures that we can rely
+// on SILGen's correctness on inserting safe lifetimes. To keep this simple
+// today we only optimize if the destroy_value and consuming user are in the
+// same block and the consuming user is later in the block than the
+// destroy_value.
+//
+// DISCUSSION: The reason why we do not shrink lifetimes today is that all
+// interior pointers (e.x. project_box) are properly guarded by
+// begin_borrow. Because of that we can not shrink lifetimes and instead rely on
+// SILGen's correctness.
+bool SemanticARCOptVisitor::tryJoiningCopyValueLiveRangeWithOperand(
+    CopyValueInst *cvi) {
+  // First do a quick check if our operand is owned. If it is not owned, we can
+  // not join live ranges.
+  SILValue operand = cvi->getOperand();
+  if (operand.getOwnershipKind() != ValueOwnershipKind::Owned) {
+    return false;
+  }
+
+  // Then check if our operand has a single destroy_value. If it does and that
+  // destroy_value is strictly before the consumer of our copy_value in the same
+  // block as the consumer of said copy_value then we can always join the live
+  // ranges.
+  //
+  // Example:
+  //
+  //   ```
+  //   %1 = copy_value %0
+  //   ...
+  //   destroy_value %0
+  //   apply %consumingUser(%1)
+  //   ```
+  // ->
+  //
+  //   ```
+  //   apply %consumingUser(%0)
+  //   ```
+  //
+  // DISCUSSION: We need to ensure that the consuming use of the copy_value is
+  // strictly after the destroy_value to ensure that we do not shrink the live
+  // range of the operand if the operand has any normal uses beyond our copy
+  // value. Otherwise, we could have normal uses /after/ the consuming use of
+  // our copy_value.
+  if (auto *dvi = operand->getSingleConsumingUserOfType<DestroyValueInst>()) {
+    if (canSafelyJoinSimpleRange(operand, dvi, cvi)) {
+      eraseInstruction(dvi);
+      eraseAndRAUWSingleValueInstruction(cvi, operand);
+      return true;
+    }
+  }
+
+  // Otherwise, we couldn't handle this case, so return false.
+  //
+  // NOTE: We would generally do a more complex analysis here to handle the more
+  // general case. That would most likely /not/ be a guaranteed optimization
+  // until we investigate/measure.
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+//                            Top Level Entrypoint
+//===----------------------------------------------------------------------===//
+
+bool SemanticARCOptVisitor::visitCopyValueInst(CopyValueInst *cvi) {
+  // If our copy value inst has only destroy_value users, it is a dead live
+  // range. Try to eliminate them.
+  if (eliminateDeadLiveRangeCopyValue(cvi)) {
+    return true;
+  }
+
+  // Then see if copy_value operand's lifetime ends after our copy_value via a
+  // destroy_value. If so, we can join their lifetimes.
+  if (tryJoiningCopyValueLiveRangeWithOperand(cvi)) {
+    return true;
+  }
+
+  // Then try to perform the guaranteed copy value optimization.
+  if (performGuaranteedCopyValueOptimization(cvi)) {
+    return true;
+  }
+
+  return false;
+}
diff --git a/lib/SILOptimizer/SemanticARC/LoadCopyToLoadBorrowOpt.cpp b/lib/SILOptimizer/SemanticARC/LoadCopyToLoadBorrowOpt.cpp
new file mode 100644
index 0000000..2ea47e4
--- /dev/null
+++ b/lib/SILOptimizer/SemanticARC/LoadCopyToLoadBorrowOpt.cpp
@@ -0,0 +1,491 @@
+//===--- LoadCopyToLoadBorrowOpt.cpp --------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+///
+/// Defines the main optimization that converts load [copy] -> load_borrow if we
+/// can prove that the +1 is not actually needed and the memory loaded from is
+/// never written to while the load [copy]'s object value is being used.
+///
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "sil-semantic-arc-opts"
+
+#include "OwnershipLiveRange.h"
+#include "SemanticARCOptVisitor.h"
+#include "swift/SIL/LinearLifetimeChecker.h"
+#include "swift/SIL/MemAccessUtils.h"
+#include "swift/SIL/OwnershipUtils.h"
+#include "swift/SIL/Projection.h"
+#include "swift/SIL/SILInstruction.h"
+#include "swift/SIL/SILValue.h"
+#include "swift/SILOptimizer/Utils/ValueLifetime.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace swift;
+using namespace swift::semanticarc;
+
+//===----------------------------------------------------------------------===//
+//                        Well Behaved Write Analysis
+//===----------------------------------------------------------------------===//
+
+/// Returns true if we were able to ascertain that either the initialValue has
+/// no write uses or all of the write uses were writes that we could understand.
+bool swift::semanticarc::constructCacheValue(
+    SILValue initialValue,
+    SmallVectorImpl<Operand *> &wellBehavedWriteAccumulator) {
+  SmallVector<Operand *, 8> worklist(initialValue->getUses());
+
+  while (!worklist.empty()) {
+    auto *op = worklist.pop_back_val();
+    SILInstruction *user = op->getUser();
+
+    if (Projection::isAddressProjection(user) ||
+        isa<ProjectBlockStorageInst>(user)) {
+      for (SILValue r : user->getResults()) {
+        llvm::copy(r->getUses(), std::back_inserter(worklist));
+      }
+      continue;
+    }
+
+    if (auto *oeai = dyn_cast<OpenExistentialAddrInst>(user)) {
+      // Mutable access!
+      if (oeai->getAccessKind() != OpenedExistentialAccess::Immutable) {
+        wellBehavedWriteAccumulator.push_back(op);
+      }
+
+      //  Otherwise, look through it and continue.
+      llvm::copy(oeai->getUses(), std::back_inserter(worklist));
+      continue;
+    }
+
+    if (auto *si = dyn_cast<StoreInst>(user)) {
+      // We must be the dest since addresses can not be stored.
+      assert(si->getDest() == op->get());
+      wellBehavedWriteAccumulator.push_back(op);
+      continue;
+    }
+
+    // Add any destroy_addrs to the resultAccumulator.
+    if (isa<DestroyAddrInst>(user)) {
+      wellBehavedWriteAccumulator.push_back(op);
+      continue;
+    }
+
+    // load_borrow and incidental uses are fine as well.
+    if (isa<LoadBorrowInst>(user) || isIncidentalUse(user)) {
+      continue;
+    }
+
+    // Look through begin_access and mark them/their end_borrow as users.
+    if (auto *bai = dyn_cast<BeginAccessInst>(user)) {
+      // If we do not have a read, mark this as a write. Also, insert our
+      // end_access as well.
+      if (bai->getAccessKind() != SILAccessKind::Read) {
+        wellBehavedWriteAccumulator.push_back(op);
+        transform(bai->getUsersOfType<EndAccessInst>(),
+                  std::back_inserter(wellBehavedWriteAccumulator),
+                  [](EndAccessInst *eai) { return &eai->getAllOperands()[0]; });
+      }
+
+      // And then add the users to the worklist and continue.
+      llvm::copy(bai->getUses(), std::back_inserter(worklist));
+      continue;
+    }
+
+    // If we have a load, we just need to mark the load [take] as a write.
+    if (auto *li = dyn_cast<LoadInst>(user)) {
+      if (li->getOwnershipQualifier() == LoadOwnershipQualifier::Take) {
+        wellBehavedWriteAccumulator.push_back(op);
+      }
+      continue;
+    }
+
+    // If we have a FullApplySite, we need to do per convention/inst logic.
+    if (auto fas = FullApplySite::isa(user)) {
+      // Begin by seeing if we have an in_guaranteed use. If we do, we are done.
+      if (fas.getArgumentConvention(*op) ==
+          SILArgumentConvention::Indirect_In_Guaranteed) {
+        continue;
+      }
+
+      // Then see if we have an apply site that is not a coroutine apply
+      // site. In such a case, without further analysis, we can treat it like an
+      // instantaneous write and validate that it doesn't overlap with our load
+      // [copy].
+      if (!fas.beginsCoroutineEvaluation() &&
+          fas.getArgumentConvention(*op).isInoutConvention()) {
+        wellBehavedWriteAccumulator.push_back(op);
+        continue;
+      }
+
+      // Otherwise, be conservative and return that we had a write that we did
+      // not understand.
+      LLVM_DEBUG(llvm::dbgs()
+                 << "Function: " << user->getFunction()->getName() << "\n");
+      LLVM_DEBUG(llvm::dbgs() << "Value: " << op->get());
+      LLVM_DEBUG(llvm::dbgs() << "Unhandled apply site!: " << *user);
+
+      return false;
+    }
+
+    // Copy addr that read are just loads.
+    if (auto *cai = dyn_cast<CopyAddrInst>(user)) {
+      // If our value is the destination, this is a write.
+      if (cai->getDest() == op->get()) {
+        wellBehavedWriteAccumulator.push_back(op);
+        continue;
+      }
+
+      // Ok, so we are Src by process of elimination. Make sure we are not being
+      // taken.
+      if (cai->isTakeOfSrc()) {
+        wellBehavedWriteAccumulator.push_back(op);
+        continue;
+      }
+
+      // Otherwise, we are safe and can continue.
+      continue;
+    }
+
+    // If we did not recognize the user, just return conservatively that it was
+    // written to in a way we did not understand.
+    LLVM_DEBUG(llvm::dbgs()
+               << "Function: " << user->getFunction()->getName() << "\n");
+    LLVM_DEBUG(llvm::dbgs() << "Value: " << op->get());
+    LLVM_DEBUG(llvm::dbgs() << "Unknown instruction!: " << *user);
+    return false;
+  }
+
+  // Ok, we finished our worklist and this address is not being written to.
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
+//                              Memory Analysis
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+/// A class that computes in a flow insensitive way if we can prove that our
+/// storage is either never written to, or is initialized exactly once and never
+/// written to again. In both cases, we can convert load [copy] -> load_borrow
+/// safely.
+class StorageGuaranteesLoadVisitor
+    : public AccessUseDefChainVisitor<StorageGuaranteesLoadVisitor> {
+  // The outer SemanticARCOptVisitor.
+  SemanticARCOptVisitor &ARCOpt;
+
+  // The live range of the original load.
+  const OwnershipLiveRange &liveRange;
+
+  // The current address being visited.
+  SILValue currentAddress;
+
+  Optional<bool> isWritten;
+
+public:
+  StorageGuaranteesLoadVisitor(SemanticARCOptVisitor &arcOpt, LoadInst *load,
+                               const OwnershipLiveRange &liveRange)
+      : ARCOpt(arcOpt), liveRange(liveRange),
+        currentAddress(load->getOperand()) {}
+
+  void answer(bool written) {
+    currentAddress = nullptr;
+    isWritten = written;
+  }
+
+  void next(SILValue address) { currentAddress = address; }
+
+  void visitNestedAccess(BeginAccessInst *access) {
+    // First see if we have read/modify. If we do not, just look through the
+    // nested access.
+    switch (access->getAccessKind()) {
+    case SILAccessKind::Init:
+    case SILAccessKind::Deinit:
+      return next(access->getOperand());
+    case SILAccessKind::Read:
+    case SILAccessKind::Modify:
+      break;
+    }
+
+    // Next check if our live range is completely in the begin/end access
+    // scope. If so, we may be able to use a load_borrow here!
+    SmallVector<Operand *, 8> endScopeUses;
+    transform(access->getEndAccesses(), std::back_inserter(endScopeUses),
+              [](EndAccessInst *eai) { return &eai->getAllOperands()[0]; });
+    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
+    LinearLifetimeChecker checker(visitedBlocks, ARCOpt.getDeadEndBlocks());
+    if (!checker.validateLifetime(access, endScopeUses,
+                                  liveRange.getAllConsumingUses())) {
+      // If we fail the linear lifetime check, then just recur:
+      return next(access->getOperand());
+    }
+
+    // Otherwise, if we have read, then we are done!
+    if (access->getAccessKind() == SILAccessKind::Read) {
+      return answer(false);
+    }
+
+    // If we have a modify, check if our value is /ever/ written to. If it is
+    // never actually written to, then we convert to a load_borrow.
+    auto result = ARCOpt.addressToExhaustiveWriteListCache.get(access);
+    if (!result.hasValue()) {
+      return answer(true);
+    }
+
+    if (result.getValue().empty()) {
+      return answer(false);
+    }
+
+    return answer(true);
+  }
+
+  void visitArgumentAccess(SILFunctionArgument *arg) {
+    // If this load_copy is from an indirect in_guaranteed argument, then we
+    // know for sure that it will never be written to.
+    if (arg->hasConvention(SILArgumentConvention::Indirect_In_Guaranteed)) {
+      return answer(false);
+    }
+
+    // If we have an inout parameter that isn't ever actually written to, return
+    // false.
+    if (arg->getKnownParameterInfo().isIndirectMutating()) {
+      auto wellBehavedWrites =
+          ARCOpt.addressToExhaustiveWriteListCache.get(arg);
+      if (!wellBehavedWrites.hasValue()) {
+        return answer(true);
+      }
+
+      // No writes.
+      if (wellBehavedWrites->empty()) {
+        return answer(false);
+      }
+
+      // Ok, we have some writes. See if any of them are within our live
+      // range. If any are, we definitely can not promote to load_borrow.
+      SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
+      SmallVector<BeginAccessInst *, 16> foundBeginAccess;
+      LinearLifetimeChecker checker(visitedBlocks, ARCOpt.getDeadEndBlocks());
+      SILValue introducerValue = liveRange.getIntroducer().value;
+      if (!checker.usesNotContainedWithinLifetime(introducerValue,
+                                                  liveRange.getDestroyingUses(),
+                                                  *wellBehavedWrites)) {
+        return answer(true);
+      }
+
+      // Finally, check if our live range is strictly contained within any of
+      // our scoped writes.
+      SmallVector<Operand *, 16> endAccessList;
+      for (Operand *use : *wellBehavedWrites) {
+        auto *bai = dyn_cast<BeginAccessInst>(use->getUser());
+        if (!bai) {
+          continue;
+        }
+
+        endAccessList.clear();
+        llvm::transform(
+            bai->getUsersOfType<EndAccessInst>(),
+            std::back_inserter(endAccessList),
+            [](EndAccessInst *eai) { return &eai->getAllOperands()[0]; });
+        visitedBlocks.clear();
+
+        // We know that our live range is based on a load [copy], so we know
+        // that our value must have a defining inst.
+        auto *definingInst =
+            cast<LoadInst>(introducerValue->getDefiningInstruction());
+
+        // Then if our defining inst is not in our bai, endAccessList region, we
+        // know that the two ranges must be disjoint, so continue.
+        if (!checker.validateLifetime(bai, endAccessList,
+                                      &definingInst->getAllOperands()[0])) {
+          continue;
+        }
+
+        // Otherwise, we do have an overlap, return true.
+        return answer(true);
+      }
+
+      // Otherwise, there isn't an overlap, so we don't write to it.
+      return answer(false);
+    }
+
+    // TODO: This should be extended:
+    //
+    // 1. We should be able to analyze in arguments and see if they are only
+    //    ever destroyed at the end of the function. In such a case, we may be
+    //    able to also to promote load [copy] from such args to load_borrow.
+    return answer(true);
+  }
+
+  void visitGlobalAccess(SILValue global) {
+    return answer(!AccessedStorage(global, AccessedStorage::Global)
+                       .isLetAccess(&ARCOpt.F));
+  }
+
+  void visitClassAccess(RefElementAddrInst *field) {
+    currentAddress = nullptr;
+
+    // We know a let property won't be written to if the base object is
+    // guaranteed for the duration of the access.
+    // For non-let properties conservatively assume they may be written to.
+    if (!field->getField()->isLet()) {
+      return answer(true);
+    }
+
+    // The lifetime of the `let` is guaranteed if it's dominated by the
+    // guarantee on the base. See if we can find a single borrow introducer for
+    // this object. If we could not find a single such borrow introducer, assume
+    // that our property is conservatively written to.
+    SILValue baseObject = field->getOperand();
+    auto value = getSingleBorrowIntroducingValue(baseObject);
+    if (!value) {
+      return answer(true);
+    }
+
+    // Ok, we have a single borrow introducing value. First do a quick check if
+    // we have a non-local scope that is a function argument. In such a case, we
+    // know statically that our let can not be written to in the current
+    // function. To be conservative, assume that all other non-local scopes
+    // write to memory.
+    if (!value->isLocalScope()) {
+      if (value->kind == BorrowedValueKind::SILFunctionArgument) {
+        return answer(false);
+      }
+
+      // TODO: Once we model Coroutine results as non-local scopes, we should be
+      // able to return false here for them as well.
+      return answer(true);
+    }
+
+    // TODO: This is disabled temporarily for guaranteed phi args just for
+    // staging purposes. Thus be conservative and assume true in these cases.
+    if (value->kind == BorrowedValueKind::Phi) {
+      return answer(true);
+    }
+
+    // Ok, we now know that we have a local scope whose lifetime we need to
+    // analyze. With that in mind, gather up the lifetime ending uses of our
+    // borrow scope introducing value and then use the linear lifetime checker
+    // to check whether the copied value is dominated by the lifetime of the
+    // borrow it's based on.
+    SmallVector<Operand *, 4> endScopeInsts;
+    value->visitLocalScopeEndingUses(
+        [&](Operand *use) { endScopeInsts.push_back(use); });
+
+    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
+    LinearLifetimeChecker checker(visitedBlocks, ARCOpt.getDeadEndBlocks());
+
+    // Returns true on success. So we invert.
+    bool foundError = !checker.validateLifetime(
+        baseObject, endScopeInsts, liveRange.getAllConsumingUses());
+    return answer(foundError);
+  }
+
+  // TODO: Handle other access kinds?
+  void visitBase(SILValue base, AccessedStorage::Kind kind) {
+    return answer(true);
+  }
+
+  void visitNonAccess(SILValue addr) { return answer(true); }
+
+  void visitCast(SingleValueInstruction *cast, Operand *parentAddr) {
+    return next(parentAddr->get());
+  }
+
+  void visitPathComponent(SingleValueInstruction *projectedAddr,
+                          Operand *parentAddr) {
+    return next(parentAddr->get());
+  }
+
+  void visitPhi(SILPhiArgument *phi) {
+    // We shouldn't have address phis in OSSA SIL, so we don't need to recur
+    // through the predecessors here.
+    return answer(true);
+  }
+
+  /// See if we have an alloc_stack that is only written to once by an
+  /// initializing instruction.
+  void visitStackAccess(AllocStackInst *stack) {
+    SmallVector<Operand *, 8> destroyAddrOperands;
+    bool initialAnswer = isSingleInitAllocStack(stack, destroyAddrOperands);
+    if (!initialAnswer)
+      return answer(true);
+
+    // Then make sure that all of our load [copy] uses are within the
+    // destroy_addr.
+    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
+    LinearLifetimeChecker checker(visitedBlocks, ARCOpt.getDeadEndBlocks());
+    // Returns true on success. So we invert.
+    bool foundError = !checker.validateLifetime(
+        stack, destroyAddrOperands /*consuming users*/,
+        liveRange.getAllConsumingUses() /*non consuming users*/);
+    return answer(foundError);
+  }
+
+  bool doIt() {
+    while (currentAddress) {
+      visit(currentAddress);
+    }
+    return *isWritten;
+  }
+};
+
+} // namespace
+
+bool SemanticARCOptVisitor::isWrittenTo(LoadInst *load,
+                                        const OwnershipLiveRange &lr) {
+  StorageGuaranteesLoadVisitor visitor(*this, load, lr);
+  return visitor.doIt();
+}
+
+//===----------------------------------------------------------------------===//
+//                            Top Level Entrypoint
+//===----------------------------------------------------------------------===//
+
+// Convert a load [copy] from unique storage [read] that has all uses that can
+// accept a guaranteed parameter to a load_borrow.
+bool SemanticARCOptVisitor::visitLoadInst(LoadInst *li) {
+  // This optimization can use more complex analysis. We should do some
+  // experiments before enabling this by default as a guaranteed optimization.
+  if (onlyGuaranteedOpts)
+    return false;
+
+  if (li->getOwnershipQualifier() != LoadOwnershipQualifier::Copy)
+    return false;
+
+  // Ok, we have our load [copy]. Make sure its value is truly a dead live range
+  // implying it is only ever consumed by destroy_value instructions. If it is
+  // consumed, we need to pass off a +1 value, so bail.
+  //
+  // FIXME: We should consider if it is worth promoting a load [copy]
+  // -> load_borrow if we can put a copy_value on a cold path and thus
+  // eliminate RR traffic on a hot path.
+  OwnershipLiveRange lr(li);
+  if (bool(lr.hasUnknownConsumingUse()))
+    return false;
+
+  // Then check if our address is ever written to. If it is, then we cannot use
+  // the load_borrow because the stored value may be released during the loaded
+  // value's live range.
+  if (isWrittenTo(li, lr))
+    return false;
+
+  // Ok, we can perform our optimization. Convert the load [copy] into a
+  // load_borrow.
+  auto *lbi =
+      SILBuilderWithScope(li).createLoadBorrow(li->getLoc(), li->getOperand());
+
+  lr.insertEndBorrowsAtDestroys(lbi, getDeadEndBlocks(), lifetimeFrontier);
+  std::move(lr).convertToGuaranteedAndRAUW(lbi, getCallbacks());
+  return true;
+}
diff --git a/lib/SILOptimizer/SemanticARC/OwnedToGuaranteedPhiOpt.cpp b/lib/SILOptimizer/SemanticARC/OwnedToGuaranteedPhiOpt.cpp
new file mode 100644
index 0000000..b2740a0
--- /dev/null
+++ b/lib/SILOptimizer/SemanticARC/OwnedToGuaranteedPhiOpt.cpp
@@ -0,0 +1,257 @@
+//===--- OwnedToGuaranteedPhiOpt.cpp --------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+///
+/// Late optimization that eliminates webs of owned phi nodes.
+///
+//===----------------------------------------------------------------------===//
+
+#include "OwnershipPhiOperand.h"
+#include "SemanticARCOptVisitor.h"
+
+using namespace swift;
+using namespace swift::semanticarc;
+
+static bool canEliminatePhi(
+    SemanticARCOptVisitor::FrozenMultiMapRange optimizableIntroducerRange,
+    ArrayRef<OwnershipPhiOperand> incomingValueOperandList,
+    SmallVectorImpl<OwnedValueIntroducer> &ownedValueIntroducerAccumulator) {
+  for (auto incomingValueOperand : incomingValueOperandList) {
+    SILValue incomingValue = incomingValueOperand.getValue();
+
+    // Before we do anything, see if we have an incoming value with trivial
+    // ownership. This can occur in the case where we are working with enums due
+    // to trivial non-payloaded cases. Skip that.
+    if (incomingValue.getOwnershipKind() == ValueOwnershipKind::None) {
+      continue;
+    }
+
+    // Then see if this is an introducer that we actually saw as able to be
+    // optimized if we could flip this joined live range.
+    //
+    // NOTE: If this linear search is too slow, we can change the multimap to
+    // sort the mapped to list by pointer instead of insertion order. In such a
+    // case, we could then bisect.
+    if (llvm::find(optimizableIntroducerRange,
+                   incomingValueOperand.getOperand()) ==
+        optimizableIntroducerRange.end()) {
+      return false;
+    }
+
+    // Now that we know it is an owned value that we saw before, check for
+    // introducers of the owned value which are the copies that we may be able
+    // to eliminate. Since we do not look through joined live ranges, we must
+    // only have a single introducer. So look for that one and if not, bail.
+    auto singleIntroducer = getSingleOwnedValueIntroducer(incomingValue);
+    if (!singleIntroducer.hasValue()) {
+      return false;
+    }
+
+    // Then make sure that our owned value introducer is able to be converted to
+    // guaranteed and that we found it to have a LiveRange that we could have
+    // eliminated /if/ we were to get rid of this phi.
+    if (!singleIntroducer->isConvertableToGuaranteed()) {
+      return false;
+    }
+
+    // Otherwise, add the introducer to our result array.
+    ownedValueIntroducerAccumulator.push_back(*singleIntroducer);
+  }
+
+#ifndef NDEBUG
+  // Other parts of the pass ensure that we only add values to the list if their
+  // owned value introducer is not used by multiple live ranges. That being
+  // said, lets assert that.
+  {
+    SmallVector<OwnedValueIntroducer, 32> uniqueCheck;
+    llvm::copy(ownedValueIntroducerAccumulator,
+               std::back_inserter(uniqueCheck));
+    sortUnique(uniqueCheck);
+    assert(
+        uniqueCheck.size() == ownedValueIntroducerAccumulator.size() &&
+        "multiple joined live range operands are from the same live range?!");
+  }
+#endif
+
+  return true;
+}
+
+static bool getIncomingJoinedLiveRangeOperands(
+    SILValue joinedLiveRange,
+    SmallVectorImpl<OwnershipPhiOperand> &resultingOperands) {
+  if (auto *phi = dyn_cast<SILPhiArgument>(joinedLiveRange)) {
+    return phi->visitIncomingPhiOperands([&](Operand *op) {
+      if (auto phiOp = OwnershipPhiOperand::get(op)) {
+        resultingOperands.push_back(*phiOp);
+        return true;
+      }
+      return false;
+    });
+  }
+
+  if (auto *svi = dyn_cast<SingleValueInstruction>(joinedLiveRange)) {
+    return llvm::all_of(svi->getAllOperands(), [&](const Operand &op) {
+      // skip type dependent operands.
+      if (op.isTypeDependent())
+        return true;
+
+      auto phiOp = OwnershipPhiOperand::get(&op);
+      if (!phiOp)
+        return false;
+      resultingOperands.push_back(*phiOp);
+      return true;
+    });
+  }
+
+  llvm_unreachable("Unhandled joined live range?!");
+}
+
+//===----------------------------------------------------------------------===//
+//                            Top Level Entrypoint
+//===----------------------------------------------------------------------===//
+
+bool SemanticARCOptVisitor::performPostPeepholeOwnedArgElimination() {
+  bool madeChange = false;
+
+  // First freeze our multi-map so we can use it for map queries. Also, setup a
+  // defer of the reset so we do not forget to reset the map when we are done.
+  joinedOwnedIntroducerToConsumedOperands.setFrozen();
+  SWIFT_DEFER { joinedOwnedIntroducerToConsumedOperands.reset(); };
+
+  // Now for each phi argument that we have in our multi-map...
+  SmallVector<OwnershipPhiOperand, 4> incomingValueOperandList;
+  SmallVector<OwnedValueIntroducer, 4> ownedValueIntroducers;
+  for (auto pair : joinedOwnedIntroducerToConsumedOperands.getRange()) {
+    SWIFT_DEFER {
+      incomingValueOperandList.clear();
+      ownedValueIntroducers.clear();
+    };
+
+    // First compute the LiveRange for ownershipPhi value. For simplicity, we
+    // only handle cases now where the result does not have any additional
+    // ownershipPhi uses.
+    SILValue joinedIntroducer = pair.first;
+    OwnershipLiveRange joinedLiveRange(joinedIntroducer);
+    if (bool(joinedLiveRange.hasUnknownConsumingUse())) {
+      continue;
+    }
+
+    // Ok, we know that our phi argument /could/ be converted to guaranteed if
+    // our incoming values are able to be converted to guaranteed. Now for each
+    // incoming value, compute the incoming values ownership roots and see if
+    // all of the ownership roots are in our owned incoming value array.
+    if (!getIncomingJoinedLiveRangeOperands(joinedIntroducer,
+                                            incomingValueOperandList)) {
+      continue;
+    }
+
+    // Grab our list of introducer values paired with this SILArgument. See if
+    // all of these introducer values were ones that /could/ have been
+    // eliminated if it was not for the given phi. If all of them are, we can
+    // optimize!
+    {
+      auto rawFoundOptimizableIntroducerArray = pair.second;
+      if (!canEliminatePhi(rawFoundOptimizableIntroducerArray,
+                           incomingValueOperandList, ownedValueIntroducers)) {
+        continue;
+      }
+    }
+
+    // Ok, at this point we know that we can eliminate this phi. First go
+    // through the list of incomingValueOperandList and stash the value/set the
+    // operand's stored value to undef. We will hook them back up later.
+    SmallVector<SILValue, 8> originalIncomingValues;
+    for (auto &incomingValueOperand : incomingValueOperandList) {
+      originalIncomingValues.push_back(incomingValueOperand.getValue());
+      incomingValueOperand.markUndef();
+    }
+
+    // Then go through all of our owned value introducers, compute their live
+    // ranges, and eliminate them. We know it is safe to remove them from our
+    // previous proofs.
+    //
+    // NOTE: If our introducer is a copy_value that is one of our
+    // originalIncomingValues, we need to update the originalIncomingValue array
+    // with that value since we are going to delete the copy_value here. This
+    // creates a complication since we want to binary_search on
+    // originalIncomingValues to detect this same condition! So, we create a
+    // list of updates that we apply after we no longer need to perform
+    // binary_search, but before we start RAUWing things.
+    SmallVector<std::pair<SILValue, unsigned>, 8> incomingValueUpdates;
+    for (auto introducer : ownedValueIntroducers) {
+      SILValue v = introducer.value;
+      OwnershipLiveRange lr(v);
+
+      // For now, we only handle copy_value for simplicity.
+      //
+      // TODO: Add support for load [copy].
+      if (introducer.kind == OwnedValueIntroducerKind::Copy) {
+        auto *cvi = cast<CopyValueInst>(v);
+        // Before we convert from owned to guaranteed, we need to first see if
+        // cvi is one of our originalIncomingValues. If so, we need to set
+        // originalIncomingValues to be cvi->getOperand(). Otherwise, weirdness
+        // results since we are deleting one of our stashed values.
+        auto iter = find(originalIncomingValues, cvi);
+        if (iter != originalIncomingValues.end()) {
+          // We use an auxillary array here so we can continue to bisect on
+          // original incoming values. Once we are done processing here, we will
+          // not need that property anymore.
+          unsigned updateOffset =
+              std::distance(originalIncomingValues.begin(), iter);
+          incomingValueUpdates.emplace_back(cvi->getOperand(), updateOffset);
+        }
+        std::move(lr).convertToGuaranteedAndRAUW(cvi->getOperand(),
+                                                 getCallbacks());
+        continue;
+      }
+      llvm_unreachable("Unhandled optimizable introducer!");
+    }
+
+    // Now go through and update our original incoming value array now that we
+    // do not need it to be sorted for bisection purposes.
+    while (!incomingValueUpdates.empty()) {
+      auto pair = incomingValueUpdates.pop_back_val();
+      originalIncomingValues[pair.second] = pair.first;
+    }
+
+    // Then convert the phi's live range to be guaranteed.
+    std::move(joinedLiveRange)
+        .convertJoinedLiveRangePhiToGuaranteed(
+            getDeadEndBlocks(), lifetimeFrontier, getCallbacks());
+
+    // Now if our phi operand consumes/forwards its guaranteed input, insert a
+    // begin_borrow along the incoming value edges. We have to do this after
+    // converting the incoming values to be guaranteed to avoid tripping
+    // SILBuilder checks around simple ownership invariants (namely that def/use
+    // line up) when creating instructions.
+    assert(incomingValueOperandList.size() == originalIncomingValues.size());
+    while (!incomingValueOperandList.empty()) {
+      auto incomingValueOperand = incomingValueOperandList.pop_back_val();
+      SILValue originalValue = originalIncomingValues.pop_back_val();
+      if (incomingValueOperand.isGuaranteedConsuming() &&
+          originalValue.getOwnershipKind() != ValueOwnershipKind::None) {
+        auto loc = RegularLocation::getAutoGeneratedLocation();
+        SILBuilderWithScope builder(incomingValueOperand.getInst());
+        originalValue = builder.createBeginBorrow(loc, originalValue);
+      }
+      incomingValueOperand.getOperand()->set(originalValue);
+    }
+
+    madeChange = true;
+    if (VerifyAfterTransform) {
+      F.verify();
+    }
+  }
+
+  return madeChange;
+}
diff --git a/lib/SILOptimizer/SemanticARC/SemanticARCOptVisitor.h b/lib/SILOptimizer/SemanticARC/SemanticARCOptVisitor.h
new file mode 100644
index 0000000..038ca71
--- /dev/null
+++ b/lib/SILOptimizer/SemanticARC/SemanticARCOptVisitor.h
@@ -0,0 +1,256 @@
+//===--- SemanticARCOptVisitor.h ------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_SILOPTIMIZER_SEMANTICARC_SEMANTICARCOPTVISITOR_H
+#define SWIFT_SILOPTIMIZER_SEMANTICARC_SEMANTICARCOPTVISITOR_H
+
+#include "OwnershipLiveRange.h"
+
+#include "swift/Basic/BlotSetVector.h"
+#include "swift/Basic/FrozenMultiMap.h"
+#include "swift/Basic/MultiMapCache.h"
+#include "swift/SIL/BasicBlockUtils.h"
+#include "swift/SIL/OwnershipUtils.h"
+#include "swift/SIL/SILVisitor.h"
+#include "swift/SILOptimizer/Utils/InstOptUtils.h"
+#include "swift/SILOptimizer/Utils/ValueLifetime.h"
+
+namespace swift {
+namespace semanticarc {
+
+extern bool VerifyAfterTransform;
+
+bool constructCacheValue(
+    SILValue initialValue,
+    SmallVectorImpl<Operand *> &wellBehavedWriteAccumulator);
+
+/// A visitor that optimizes ownership instructions and eliminates any trivially
+/// dead code that results after optimization. It uses an internal worklist that
+/// is initialized on construction with targets to avoid iterator invalidation
+/// issues. Rather than revisit the entire CFG like SILCombine and other
+/// visitors do, we maintain a visitedSinceLastMutation list to ensure that we
+/// revisit all interesting instructions in between mutations.
+struct LLVM_LIBRARY_VISIBILITY SemanticARCOptVisitor
+    : SILInstructionVisitor<SemanticARCOptVisitor, bool> {
+  /// Our main worklist. We use this after an initial run through.
+  SmallBlotSetVector<SILValue, 32> worklist;
+
+  /// A set of values that we have visited since the last mutation. We use this
+  /// to ensure that we do not visit values twice without mutating.
+  ///
+  /// This is specifically to ensure that we do not go into an infinite loop
+  /// when visiting phi nodes.
+  SmallBlotSetVector<SILValue, 16> visitedSinceLastMutation;
+
+  SILFunction &F;
+  Optional<DeadEndBlocks> TheDeadEndBlocks;
+  ValueLifetimeAnalysis::Frontier lifetimeFrontier;
+  SmallMultiMapCache<SILValue, Operand *> addressToExhaustiveWriteListCache;
+
+  /// Are we assuming that we reached a fix point and are re-processing to
+  /// prepare to use the phiToIncomingValueMultiMap.
+  bool assumingAtFixedPoint = false;
+
+  /// A map from a value that acts as a "joined owned introducer" in the def-use
+  /// graph.
+  ///
+  /// A "joined owned introducer" is a value with owned ownership whose
+  /// ownership is derived from multiple non-trivial owned operands of a related
+  /// instruction. Some examples are phi arguments, tuples, structs. Naturally,
+  /// all of these instructions must be non-unary instructions and only have
+  /// this property if they have multiple operands that are non-trivial.
+  ///
+  /// In such a case, we can not just treat them like normal forwarding concepts
+  /// since we can only eliminate optimize such a value if we are able to reason
+  /// about all of its operands together jointly. This is not amenable to a
+  /// small peephole analysis.
+  ///
+  /// Instead, as we perform the peephole analysis, using the multimap, we map
+  /// each joined owned value introducer to the set of its @owned operands that
+  /// we thought we could convert to guaranteed only if we could do the same to
+  /// the joined owned value introducer. Then once we finish performing
+  /// peepholes, we iterate through the map and see if any of our joined phi
+  /// ranges had all of their operand's marked with this property by iterating
+  /// over the multimap. Since we are dealing with owned values and we know that
+  /// our LiveRange can not see through joined live ranges, we know that we
+  /// should only be able to have a single owned value introducer for each
+  /// consumed operand.
+  FrozenMultiMap<SILValue, Operand *> joinedOwnedIntroducerToConsumedOperands;
+
+  /// If set to true, then we should only run cheap optimizations that do not
+  /// build up data structures or analyze code in depth.
+  ///
+  /// As an example, we do not do load [copy] optimizations here since they
+  /// generally involve more complex analysis, but simple peepholes of
+  /// copy_values we /do/ allow.
+  bool onlyGuaranteedOpts;
+
+  using FrozenMultiMapRange =
+      decltype(joinedOwnedIntroducerToConsumedOperands)::PairToSecondEltRange;
+
+  explicit SemanticARCOptVisitor(SILFunction &F, bool onlyGuaranteedOpts)
+      : F(F), addressToExhaustiveWriteListCache(constructCacheValue),
+        onlyGuaranteedOpts(onlyGuaranteedOpts) {}
+
+  DeadEndBlocks &getDeadEndBlocks() {
+    if (!TheDeadEndBlocks)
+      TheDeadEndBlocks.emplace(&F);
+    return *TheDeadEndBlocks;
+  }
+
+  /// Given a single value instruction, RAUW it with newValue, add newValue to
+  /// the worklist, and then call eraseInstruction on i.
+  void eraseAndRAUWSingleValueInstruction(SingleValueInstruction *i,
+                                          SILValue newValue) {
+    worklist.insert(newValue);
+    for (auto *use : i->getUses()) {
+      for (SILValue result : use->getUser()->getResults()) {
+        worklist.insert(result);
+      }
+    }
+    i->replaceAllUsesWith(newValue);
+    eraseInstructionAndAddOperandsToWorklist(i);
+  }
+
+  /// Add all operands of i to the worklist and then call eraseInstruction on
+  /// i. Assumes that the instruction doesnt have users.
+  void eraseInstructionAndAddOperandsToWorklist(SILInstruction *i) {
+    // Then copy all operands into the worklist for future processing.
+    for (SILValue v : i->getOperandValues()) {
+      worklist.insert(v);
+    }
+    eraseInstruction(i);
+  }
+
+  /// Pop values off of visitedSinceLastMutation, adding .some values to the
+  /// worklist.
+  void drainVisitedSinceLastMutationIntoWorklist() {
+    while (!visitedSinceLastMutation.empty()) {
+      Optional<SILValue> nextValue = visitedSinceLastMutation.pop_back_val();
+      if (!nextValue.hasValue()) {
+        continue;
+      }
+      worklist.insert(*nextValue);
+    }
+  }
+
+  /// Remove all results of the given instruction from the worklist and then
+  /// erase the instruction. Assumes that the instruction does not have any
+  /// users left.
+  void eraseInstruction(SILInstruction *i) {
+    // Remove all SILValues of the instruction from the worklist and then erase
+    // the instruction.
+    for (SILValue result : i->getResults()) {
+      worklist.erase(result);
+      visitedSinceLastMutation.erase(result);
+    }
+    i->eraseFromParent();
+
+    // Add everything else from visitedSinceLastMutation to the worklist.
+    drainVisitedSinceLastMutationIntoWorklist();
+  }
+
+  InstModCallbacks getCallbacks() {
+    return InstModCallbacks(
+        [this](SILInstruction *inst) { eraseInstruction(inst); },
+        [](SILInstruction *) {}, [](SILValue, SILValue) {},
+        [this](SingleValueInstruction *i, SILValue value) {
+          eraseAndRAUWSingleValueInstruction(i, value);
+        });
+  }
+
+  /// The default visitor.
+  bool visitSILInstruction(SILInstruction *i) {
+    assert(!isGuaranteedForwardingInst(i) &&
+           "Should have forwarding visitor for all ownership forwarding "
+           "instructions");
+    return false;
+  }
+
+  bool visitCopyValueInst(CopyValueInst *cvi);
+  bool visitBeginBorrowInst(BeginBorrowInst *bbi);
+  bool visitLoadInst(LoadInst *li);
+  static bool shouldVisitInst(SILInstruction *i) {
+    switch (i->getKind()) {
+    default:
+      return false;
+    case SILInstructionKind::CopyValueInst:
+    case SILInstructionKind::BeginBorrowInst:
+    case SILInstructionKind::LoadInst:
+      return true;
+    }
+  }
+
+#define FORWARDING_INST(NAME)                                                  \
+  bool visit##NAME##Inst(NAME##Inst *cls) {                                    \
+    for (SILValue v : cls->getResults()) {                                     \
+      worklist.insert(v);                                                      \
+    }                                                                          \
+    return false;                                                              \
+  }
+  FORWARDING_INST(Tuple)
+  FORWARDING_INST(Struct)
+  FORWARDING_INST(Enum)
+  FORWARDING_INST(OpenExistentialRef)
+  FORWARDING_INST(Upcast)
+  FORWARDING_INST(UncheckedRefCast)
+  FORWARDING_INST(ConvertFunction)
+  FORWARDING_INST(RefToBridgeObject)
+  FORWARDING_INST(BridgeObjectToRef)
+  FORWARDING_INST(UnconditionalCheckedCast)
+  FORWARDING_INST(UncheckedEnumData)
+  FORWARDING_INST(MarkUninitialized)
+  FORWARDING_INST(SelectEnum)
+  FORWARDING_INST(DestructureStruct)
+  FORWARDING_INST(DestructureTuple)
+  FORWARDING_INST(TupleExtract)
+  FORWARDING_INST(StructExtract)
+  FORWARDING_INST(OpenExistentialValue)
+  FORWARDING_INST(OpenExistentialBoxValue)
+  FORWARDING_INST(MarkDependence)
+  FORWARDING_INST(InitExistentialRef)
+  FORWARDING_INST(DifferentiableFunction)
+  FORWARDING_INST(LinearFunction)
+  FORWARDING_INST(DifferentiableFunctionExtract)
+  FORWARDING_INST(LinearFunctionExtract)
+#undef FORWARDING_INST
+
+#define FORWARDING_TERM(NAME)                                                  \
+  bool visit##NAME##Inst(NAME##Inst *cls) {                                    \
+    for (auto succValues : cls->getSuccessorBlockArgumentLists()) {            \
+      for (SILValue v : succValues) {                                          \
+        worklist.insert(v);                                                    \
+      }                                                                        \
+    }                                                                          \
+    return false;                                                              \
+  }
+
+  FORWARDING_TERM(SwitchEnum)
+  FORWARDING_TERM(CheckedCastBranch)
+  FORWARDING_TERM(Branch)
+#undef FORWARDING_TERM
+
+  bool isWrittenTo(LoadInst *li, const OwnershipLiveRange &lr);
+
+  bool processWorklist();
+  bool optimize();
+
+  bool performGuaranteedCopyValueOptimization(CopyValueInst *cvi);
+  bool eliminateDeadLiveRangeCopyValue(CopyValueInst *cvi);
+  bool tryJoiningCopyValueLiveRangeWithOperand(CopyValueInst *cvi);
+  bool performPostPeepholeOwnedArgElimination();
+};
+
+} // namespace semanticarc
+} // namespace swift
+
+#endif // SWIFT_SILOPTIMIZER_SEMANTICARC_SEMANTICARCOPTVISITOR_H
diff --git a/lib/SILOptimizer/SemanticARC/SemanticARCOpts.cpp b/lib/SILOptimizer/SemanticARC/SemanticARCOpts.cpp
index 383ec14..ba60b34 100644
--- a/lib/SILOptimizer/SemanticARC/SemanticARCOpts.cpp
+++ b/lib/SILOptimizer/SemanticARC/SemanticARCOpts.cpp
@@ -14,8 +14,9 @@
 
 #include "swift/Basic/LLVM.h"
 
-#include "OwnershipPhiOperand.h"
 #include "OwnershipLiveRange.h"
+#include "OwnershipPhiOperand.h"
+#include "SemanticARCOptVisitor.h"
 
 #include "swift/Basic/BlotSetVector.h"
 #include "swift/Basic/FrozenMultiMap.h"
@@ -45,598 +46,14 @@
 using namespace swift::semanticarc;
 
 //===----------------------------------------------------------------------===//
-//                        Address Written To Analysis
-//===----------------------------------------------------------------------===//
-
-/// Returns true if we were able to ascertain that either the initialValue has
-/// no write uses or all of the write uses were writes that we could understand.
-static bool
-constructCacheValue(SILValue initialValue,
-                    SmallVectorImpl<Operand *> &wellBehavedWriteAccumulator) {
-  SmallVector<Operand *, 8> worklist(initialValue->getUses());
-
-  while (!worklist.empty()) {
-    auto *op = worklist.pop_back_val();
-    SILInstruction *user = op->getUser();
-
-    if (Projection::isAddressProjection(user) ||
-        isa<ProjectBlockStorageInst>(user)) {
-      for (SILValue r : user->getResults()) {
-        llvm::copy(r->getUses(), std::back_inserter(worklist));
-      }
-      continue;
-    }
-
-    if (auto *oeai = dyn_cast<OpenExistentialAddrInst>(user)) {
-      // Mutable access!
-      if (oeai->getAccessKind() != OpenedExistentialAccess::Immutable) {
-        wellBehavedWriteAccumulator.push_back(op);
-      }
-
-      //  Otherwise, look through it and continue.
-      llvm::copy(oeai->getUses(), std::back_inserter(worklist));
-      continue;
-    }
-
-    if (auto *si = dyn_cast<StoreInst>(user)) {
-      // We must be the dest since addresses can not be stored.
-      assert(si->getDest() == op->get());
-      wellBehavedWriteAccumulator.push_back(op);
-      continue;
-    }
-
-    // Add any destroy_addrs to the resultAccumulator.
-    if (isa<DestroyAddrInst>(user)) {
-      wellBehavedWriteAccumulator.push_back(op);
-      continue;
-    }
-
-    // load_borrow and incidental uses are fine as well.
-    if (isa<LoadBorrowInst>(user) || isIncidentalUse(user)) {
-      continue;
-    }
-
-    // Look through begin_access and mark them/their end_borrow as users.
-    if (auto *bai = dyn_cast<BeginAccessInst>(user)) {
-      // If we do not have a read, mark this as a write. Also, insert our
-      // end_access as well.
-      if (bai->getAccessKind() != SILAccessKind::Read) {
-        wellBehavedWriteAccumulator.push_back(op);
-        transform(bai->getUsersOfType<EndAccessInst>(),
-                  std::back_inserter(wellBehavedWriteAccumulator),
-                  [](EndAccessInst *eai) { return &eai->getAllOperands()[0]; });
-      }
-
-      // And then add the users to the worklist and continue.
-      llvm::copy(bai->getUses(), std::back_inserter(worklist));
-      continue;
-    }
-
-    // If we have a load, we just need to mark the load [take] as a write.
-    if (auto *li = dyn_cast<LoadInst>(user)) {
-      if (li->getOwnershipQualifier() == LoadOwnershipQualifier::Take) {
-        wellBehavedWriteAccumulator.push_back(op);
-      }
-      continue;
-    }
-
-    // If we have a FullApplySite, we need to do per convention/inst logic.
-    if (auto fas = FullApplySite::isa(user)) {
-      // Begin by seeing if we have an in_guaranteed use. If we do, we are done.
-      if (fas.getArgumentConvention(*op) ==
-          SILArgumentConvention::Indirect_In_Guaranteed) {
-        continue;
-      }
-
-      // Then see if we have an apply site that is not a coroutine apply
-      // site. In such a case, without further analysis, we can treat it like an
-      // instantaneous write and validate that it doesn't overlap with our load
-      // [copy].
-      if (!fas.beginsCoroutineEvaluation() &&
-          fas.getArgumentConvention(*op).isInoutConvention()) {
-        wellBehavedWriteAccumulator.push_back(op);
-        continue;
-      }
-
-      // Otherwise, be conservative and return that we had a write that we did
-      // not understand.
-      LLVM_DEBUG(llvm::dbgs()
-                 << "Function: " << user->getFunction()->getName() << "\n");
-      LLVM_DEBUG(llvm::dbgs() << "Value: " << op->get());
-      LLVM_DEBUG(llvm::dbgs() << "Unhandled apply site!: " << *user);
-
-      return false;
-    }
-
-    // Copy addr that read are just loads.
-    if (auto *cai = dyn_cast<CopyAddrInst>(user)) {
-      // If our value is the destination, this is a write.
-      if (cai->getDest() == op->get()) {
-        wellBehavedWriteAccumulator.push_back(op);
-        continue;
-      }
-
-      // Ok, so we are Src by process of elimination. Make sure we are not being
-      // taken.
-      if (cai->isTakeOfSrc()) {
-        wellBehavedWriteAccumulator.push_back(op);
-        continue;
-      }
-
-      // Otherwise, we are safe and can continue.
-      continue;
-    }
-
-    // If we did not recognize the user, just return conservatively that it was
-    // written to in a way we did not understand.
-    LLVM_DEBUG(llvm::dbgs()
-               << "Function: " << user->getFunction()->getName() << "\n");
-    LLVM_DEBUG(llvm::dbgs() << "Value: " << op->get());
-    LLVM_DEBUG(llvm::dbgs() << "Unknown instruction!: " << *user);
-    return false;
-  }
-
-  // Ok, we finished our worklist and this address is not being written to.
-  return true;
-}
-
-//===----------------------------------------------------------------------===//
 //                               Implementation
 //===----------------------------------------------------------------------===//
 
-namespace {
+bool swift::semanticarc::VerifyAfterTransform;
 
-/// A visitor that optimizes ownership instructions and eliminates any trivially
-/// dead code that results after optimization. It uses an internal worklist that
-/// is initialized on construction with targets to avoid iterator invalidation
-/// issues. Rather than revisit the entire CFG like SILCombine and other
-/// visitors do, we maintain a visitedSinceLastMutation list to ensure that we
-/// revisit all interesting instructions in between mutations.
-struct SemanticARCOptVisitor
-    : SILInstructionVisitor<SemanticARCOptVisitor, bool> {
-  /// Our main worklist. We use this after an initial run through.
-  SmallBlotSetVector<SILValue, 32> worklist;
-
-  /// A set of values that we have visited since the last mutation. We use this
-  /// to ensure that we do not visit values twice without mutating.
-  ///
-  /// This is specifically to ensure that we do not go into an infinite loop
-  /// when visiting phi nodes.
-  SmallBlotSetVector<SILValue, 16> visitedSinceLastMutation;
-
-  SILFunction &F;
-  Optional<DeadEndBlocks> TheDeadEndBlocks;
-  ValueLifetimeAnalysis::Frontier lifetimeFrontier;
-  SmallMultiMapCache<SILValue, Operand *> addressToExhaustiveWriteListCache;
-
-  /// Are we assuming that we reached a fix point and are re-processing to
-  /// prepare to use the phiToIncomingValueMultiMap.
-  bool assumingAtFixedPoint = false;
-
-  /// A map from a value that acts as a "joined owned introducer" in the def-use
-  /// graph.
-  ///
-  /// A "joined owned introducer" is a value with owned ownership whose
-  /// ownership is derived from multiple non-trivial owned operands of a related
-  /// instruction. Some examples are phi arguments, tuples, structs. Naturally,
-  /// all of these instructions must be non-unary instructions and only have
-  /// this property if they have multiple operands that are non-trivial.
-  ///
-  /// In such a case, we can not just treat them like normal forwarding concepts
-  /// since we can only eliminate optimize such a value if we are able to reason
-  /// about all of its operands together jointly. This is not amenable to a
-  /// small peephole analysis.
-  ///
-  /// Instead, as we perform the peephole analysis, using the multimap, we map
-  /// each joined owned value introducer to the set of its @owned operands that
-  /// we thought we could convert to guaranteed only if we could do the same to
-  /// the joined owned value introducer. Then once we finish performing
-  /// peepholes, we iterate through the map and see if any of our joined phi
-  /// ranges had all of their operand's marked with this property by iterating
-  /// over the multimap. Since we are dealing with owned values and we know that
-  /// our LiveRange can not see through joined live ranges, we know that we
-  /// should only be able to have a single owned value introducer for each
-  /// consumed operand.
-  FrozenMultiMap<SILValue, Operand *> joinedOwnedIntroducerToConsumedOperands;
-
-  /// If set to true, then we should only run cheap optimizations that do not
-  /// build up data structures or analyze code in depth.
-  ///
-  /// As an example, we do not do load [copy] optimizations here since they
-  /// generally involve more complex analysis, but simple peepholes of
-  /// copy_values we /do/ allow.
-  bool onlyGuaranteedOpts;
-
-  using FrozenMultiMapRange =
-      decltype(joinedOwnedIntroducerToConsumedOperands)::PairToSecondEltRange;
-
-  explicit SemanticARCOptVisitor(SILFunction &F, bool onlyGuaranteedOpts)
-      : F(F), addressToExhaustiveWriteListCache(constructCacheValue),
-        onlyGuaranteedOpts(onlyGuaranteedOpts) {}
-
-  DeadEndBlocks &getDeadEndBlocks() {
-    if (!TheDeadEndBlocks)
-      TheDeadEndBlocks.emplace(&F);
-    return *TheDeadEndBlocks;
-  }
-
-  /// Given a single value instruction, RAUW it with newValue, add newValue to
-  /// the worklist, and then call eraseInstruction on i.
-  void eraseAndRAUWSingleValueInstruction(SingleValueInstruction *i, SILValue newValue) {
-    worklist.insert(newValue);
-    for (auto *use : i->getUses()) {
-      for (SILValue result : use->getUser()->getResults()) {
-        worklist.insert(result);
-      }
-    }
-    i->replaceAllUsesWith(newValue);
-    eraseInstructionAndAddOperandsToWorklist(i);
-  }
-
-  /// Add all operands of i to the worklist and then call eraseInstruction on
-  /// i. Assumes that the instruction doesnt have users.
-  void eraseInstructionAndAddOperandsToWorklist(SILInstruction *i) {
-    // Then copy all operands into the worklist for future processing.
-    for (SILValue v : i->getOperandValues()) {
-      worklist.insert(v);
-    }
-    eraseInstruction(i);
-  }
-
-  /// Pop values off of visitedSinceLastMutation, adding .some values to the
-  /// worklist.
-  void drainVisitedSinceLastMutationIntoWorklist() {
-    while (!visitedSinceLastMutation.empty()) {
-      Optional<SILValue> nextValue = visitedSinceLastMutation.pop_back_val();
-      if (!nextValue.hasValue()) {
-        continue;
-      }
-      worklist.insert(*nextValue);
-    }
-  }
-
-  /// Remove all results of the given instruction from the worklist and then
-  /// erase the instruction. Assumes that the instruction does not have any
-  /// users left.
-  void eraseInstruction(SILInstruction *i) {
-    // Remove all SILValues of the instruction from the worklist and then erase
-    // the instruction.
-    for (SILValue result : i->getResults()) {
-      worklist.erase(result);
-      visitedSinceLastMutation.erase(result);
-    }
-    i->eraseFromParent();
-
-    // Add everything else from visitedSinceLastMutation to the worklist.
-    drainVisitedSinceLastMutationIntoWorklist();
-  }
-
-  InstModCallbacks getCallbacks() {
-    return InstModCallbacks(
-        [this](SILInstruction *inst) { eraseInstruction(inst); },
-        [](SILInstruction *) {}, [](SILValue, SILValue) {},
-        [this](SingleValueInstruction *i, SILValue value) {
-          eraseAndRAUWSingleValueInstruction(i, value);
-        });
-  }
-
-  /// The default visitor.
-  bool visitSILInstruction(SILInstruction *i) {
-    assert(!isGuaranteedForwardingInst(i) &&
-           "Should have forwarding visitor for all ownership forwarding "
-           "instructions");
-    return false;
-  }
-
-  bool visitCopyValueInst(CopyValueInst *cvi);
-  bool visitBeginBorrowInst(BeginBorrowInst *bbi);
-  bool visitLoadInst(LoadInst *li);
-  static bool shouldVisitInst(SILInstruction *i) {
-    switch (i->getKind()) {
-    default:
-      return false;
-    case SILInstructionKind::CopyValueInst:
-    case SILInstructionKind::BeginBorrowInst:
-    case SILInstructionKind::LoadInst:
-      return true;
-    }
-  }
-
-#define FORWARDING_INST(NAME)                                                  \
-  bool visit##NAME##Inst(NAME##Inst *cls) {                                    \
-    for (SILValue v : cls->getResults()) {                                     \
-      worklist.insert(v);                                                      \
-    }                                                                          \
-    return false;                                                              \
-  }
-  FORWARDING_INST(Tuple)
-  FORWARDING_INST(Struct)
-  FORWARDING_INST(Enum)
-  FORWARDING_INST(OpenExistentialRef)
-  FORWARDING_INST(Upcast)
-  FORWARDING_INST(UncheckedRefCast)
-  FORWARDING_INST(ConvertFunction)
-  FORWARDING_INST(RefToBridgeObject)
-  FORWARDING_INST(BridgeObjectToRef)
-  FORWARDING_INST(UnconditionalCheckedCast)
-  FORWARDING_INST(UncheckedEnumData)
-  FORWARDING_INST(MarkUninitialized)
-  FORWARDING_INST(SelectEnum)
-  FORWARDING_INST(DestructureStruct)
-  FORWARDING_INST(DestructureTuple)
-  FORWARDING_INST(TupleExtract)
-  FORWARDING_INST(StructExtract)
-  FORWARDING_INST(OpenExistentialValue)
-  FORWARDING_INST(OpenExistentialBoxValue)
-  FORWARDING_INST(MarkDependence)
-  FORWARDING_INST(InitExistentialRef)
-  FORWARDING_INST(DifferentiableFunction)
-  FORWARDING_INST(LinearFunction)
-  FORWARDING_INST(DifferentiableFunctionExtract)
-  FORWARDING_INST(LinearFunctionExtract)
-#undef FORWARDING_INST
-
-#define FORWARDING_TERM(NAME)                                                  \
-  bool visit##NAME##Inst(NAME##Inst *cls) {                                    \
-    for (auto succValues : cls->getSuccessorBlockArgumentLists()) {            \
-      for (SILValue v : succValues) {                                          \
-        worklist.insert(v);                                                    \
-      }                                                                        \
-    }                                                                          \
-    return false;                                                              \
-  }
-
-  FORWARDING_TERM(SwitchEnum)
-  FORWARDING_TERM(CheckedCastBranch)
-  FORWARDING_TERM(Branch)
-#undef FORWARDING_TERM
-
-  bool isWrittenTo(LoadInst *li, const OwnershipLiveRange &lr);
-
-  bool processWorklist();
-  bool optimize();
-
-  bool performGuaranteedCopyValueOptimization(CopyValueInst *cvi);
-  bool eliminateDeadLiveRangeCopyValue(CopyValueInst *cvi);
-  bool tryJoiningCopyValueLiveRangeWithOperand(CopyValueInst *cvi);
-  bool performPostPeepholeOwnedArgElimination();
-};
-
-} // end anonymous namespace
-
-static llvm::cl::opt<bool>
-    VerifyAfterTransform("sil-semantic-arc-opts-verify-after-transform",
-                         llvm::cl::init(false), llvm::cl::Hidden);
-
-static bool canEliminatePhi(
-    SemanticARCOptVisitor::FrozenMultiMapRange optimizableIntroducerRange,
-    ArrayRef<OwnershipPhiOperand> incomingValueOperandList,
-    SmallVectorImpl<OwnedValueIntroducer> &ownedValueIntroducerAccumulator) {
-  for (auto incomingValueOperand : incomingValueOperandList) {
-    SILValue incomingValue = incomingValueOperand.getValue();
-
-    // Before we do anything, see if we have an incoming value with trivial
-    // ownership. This can occur in the case where we are working with enums due
-    // to trivial non-payloaded cases. Skip that.
-    if (incomingValue.getOwnershipKind() == ValueOwnershipKind::None) {
-      continue;
-    }
-
-    // Then see if this is an introducer that we actually saw as able to be
-    // optimized if we could flip this joined live range.
-    //
-    // NOTE: If this linear search is too slow, we can change the multimap to
-    // sort the mapped to list by pointer instead of insertion order. In such a
-    // case, we could then bisect.
-    if (llvm::find(optimizableIntroducerRange,
-                   incomingValueOperand.getOperand()) ==
-        optimizableIntroducerRange.end()) {
-      return false;
-    }
-
-    // Now that we know it is an owned value that we saw before, check for
-    // introducers of the owned value which are the copies that we may be able
-    // to eliminate. Since we do not look through joined live ranges, we must
-    // only have a single introducer. So look for that one and if not, bail.
-    auto singleIntroducer = getSingleOwnedValueIntroducer(incomingValue);
-    if (!singleIntroducer.hasValue()) {
-      return false;
-    }
-
-    // Then make sure that our owned value introducer is able to be converted to
-    // guaranteed and that we found it to have a LiveRange that we could have
-    // eliminated /if/ we were to get rid of this phi.
-    if (!singleIntroducer->isConvertableToGuaranteed()) {
-      return false;
-    }
-
-    // Otherwise, add the introducer to our result array.
-    ownedValueIntroducerAccumulator.push_back(*singleIntroducer);
-  }
-
-#ifndef NDEBUG
-  // Other parts of the pass ensure that we only add values to the list if their
-  // owned value introducer is not used by multiple live ranges. That being
-  // said, lets assert that.
-  {
-    SmallVector<OwnedValueIntroducer, 32> uniqueCheck;
-    llvm::copy(ownedValueIntroducerAccumulator,
-               std::back_inserter(uniqueCheck));
-    sortUnique(uniqueCheck);
-    assert(
-        uniqueCheck.size() == ownedValueIntroducerAccumulator.size() &&
-        "multiple joined live range operands are from the same live range?!");
-  }
-#endif
-
-  return true;
-}
-
-static bool getIncomingJoinedLiveRangeOperands(
-    SILValue joinedLiveRange,
-    SmallVectorImpl<OwnershipPhiOperand> &resultingOperands) {
-  if (auto *phi = dyn_cast<SILPhiArgument>(joinedLiveRange)) {
-    return phi->visitIncomingPhiOperands([&](Operand *op) {
-      if (auto phiOp = OwnershipPhiOperand::get(op)) {
-        resultingOperands.push_back(*phiOp);
-        return true;
-      }
-      return false;
-    });
-  }
-
-  if (auto *svi = dyn_cast<SingleValueInstruction>(joinedLiveRange)) {
-    return llvm::all_of(svi->getAllOperands(), [&](const Operand &op) {
-      // skip type dependent operands.
-      if (op.isTypeDependent())
-        return true;
-
-      auto phiOp = OwnershipPhiOperand::get(&op);
-      if (!phiOp)
-        return false;
-      resultingOperands.push_back(*phiOp);
-      return true;
-    });
-  }
-
-  llvm_unreachable("Unhandled joined live range?!");
-}
-
-bool SemanticARCOptVisitor::performPostPeepholeOwnedArgElimination() {
-  bool madeChange = false;
-
-  // First freeze our multi-map so we can use it for map queries. Also, setup a
-  // defer of the reset so we do not forget to reset the map when we are done.
-  joinedOwnedIntroducerToConsumedOperands.setFrozen();
-  SWIFT_DEFER { joinedOwnedIntroducerToConsumedOperands.reset(); };
-
-  // Now for each phi argument that we have in our multi-map...
-  SmallVector<OwnershipPhiOperand, 4> incomingValueOperandList;
-  SmallVector<OwnedValueIntroducer, 4> ownedValueIntroducers;
-  for (auto pair : joinedOwnedIntroducerToConsumedOperands.getRange()) {
-    SWIFT_DEFER {
-      incomingValueOperandList.clear();
-      ownedValueIntroducers.clear();
-    };
-
-    // First compute the LiveRange for ownershipPhi value. For simplicity, we
-    // only handle cases now where the result does not have any additional
-    // ownershipPhi uses.
-    SILValue joinedIntroducer = pair.first;
-    OwnershipLiveRange joinedLiveRange(joinedIntroducer);
-    if (bool(joinedLiveRange.hasUnknownConsumingUse())) {
-      continue;
-    }
-
-    // Ok, we know that our phi argument /could/ be converted to guaranteed if
-    // our incoming values are able to be converted to guaranteed. Now for each
-    // incoming value, compute the incoming values ownership roots and see if
-    // all of the ownership roots are in our owned incoming value array.
-    if (!getIncomingJoinedLiveRangeOperands(joinedIntroducer,
-                                            incomingValueOperandList)) {
-      continue;
-    }
-
-    // Grab our list of introducer values paired with this SILArgument. See if
-    // all of these introducer values were ones that /could/ have been
-    // eliminated if it was not for the given phi. If all of them are, we can
-    // optimize!
-    {
-      auto rawFoundOptimizableIntroducerArray = pair.second;
-      if (!canEliminatePhi(rawFoundOptimizableIntroducerArray,
-                           incomingValueOperandList, ownedValueIntroducers)) {
-        continue;
-      }
-    }
-
-    // Ok, at this point we know that we can eliminate this phi. First go
-    // through the list of incomingValueOperandList and stash the value/set the
-    // operand's stored value to undef. We will hook them back up later.
-    SmallVector<SILValue, 8> originalIncomingValues;
-    for (auto &incomingValueOperand : incomingValueOperandList) {
-      originalIncomingValues.push_back(incomingValueOperand.getValue());
-      incomingValueOperand.markUndef();
-    }
-
-    // Then go through all of our owned value introducers, compute their live
-    // ranges, and eliminate them. We know it is safe to remove them from our
-    // previous proofs.
-    //
-    // NOTE: If our introducer is a copy_value that is one of our
-    // originalIncomingValues, we need to update the originalIncomingValue array
-    // with that value since we are going to delete the copy_value here. This
-    // creates a complication since we want to binary_search on
-    // originalIncomingValues to detect this same condition! So, we create a
-    // list of updates that we apply after we no longer need to perform
-    // binary_search, but before we start RAUWing things.
-    SmallVector<std::pair<SILValue, unsigned>, 8> incomingValueUpdates;
-    for (auto introducer : ownedValueIntroducers) {
-      SILValue v = introducer.value;
-      OwnershipLiveRange lr(v);
-
-      // For now, we only handle copy_value for simplicity.
-      //
-      // TODO: Add support for load [copy].
-      if (introducer.kind == OwnedValueIntroducerKind::Copy) {
-        auto *cvi = cast<CopyValueInst>(v);
-        // Before we convert from owned to guaranteed, we need to first see if
-        // cvi is one of our originalIncomingValues. If so, we need to set
-        // originalIncomingValues to be cvi->getOperand(). Otherwise, weirdness
-        // results since we are deleting one of our stashed values.
-        auto iter = find(originalIncomingValues, cvi);
-        if (iter != originalIncomingValues.end()) {
-          // We use an auxillary array here so we can continue to bisect on
-          // original incoming values. Once we are done processing here, we will
-          // not need that property anymore.
-          unsigned updateOffset =
-              std::distance(originalIncomingValues.begin(), iter);
-          incomingValueUpdates.emplace_back(cvi->getOperand(), updateOffset);
-        }
-        std::move(lr).convertToGuaranteedAndRAUW(cvi->getOperand(),
-                                                 getCallbacks());
-        continue;
-      }
-      llvm_unreachable("Unhandled optimizable introducer!");
-    }
-
-    // Now go through and update our original incoming value array now that we
-    // do not need it to be sorted for bisection purposes.
-    while (!incomingValueUpdates.empty()) {
-      auto pair = incomingValueUpdates.pop_back_val();
-      originalIncomingValues[pair.second] = pair.first;
-    }
-
-    // Then convert the phi's live range to be guaranteed.
-    std::move(joinedLiveRange)
-        .convertJoinedLiveRangePhiToGuaranteed(
-            getDeadEndBlocks(), lifetimeFrontier, getCallbacks());
-
-    // Now if our phi operand consumes/forwards its guaranteed input, insert a
-    // begin_borrow along the incoming value edges. We have to do this after
-    // converting the incoming values to be guaranteed to avoid tripping
-    // SILBuilder checks around simple ownership invariants (namely that def/use
-    // line up) when creating instructions.
-    assert(incomingValueOperandList.size() == originalIncomingValues.size());
-    while (!incomingValueOperandList.empty()) {
-      auto incomingValueOperand = incomingValueOperandList.pop_back_val();
-      SILValue originalValue = originalIncomingValues.pop_back_val();
-      if (incomingValueOperand.isGuaranteedConsuming() &&
-          originalValue.getOwnershipKind() != ValueOwnershipKind::None) {
-        auto loc = RegularLocation::getAutoGeneratedLocation();
-        SILBuilderWithScope builder(incomingValueOperand.getInst());
-        originalValue = builder.createBeginBorrow(loc, originalValue);
-      }
-      incomingValueOperand.getOperand()->set(originalValue);
-    }
-
-    madeChange = true;
-    if (VerifyAfterTransform) {
-      F.verify();
-    }
-  }
-
-  return madeChange;
-}
+static llvm::cl::opt<bool, true> VerifyAfterTransformOption(
+    "sil-semantic-arc-opts-verify-after-transform", llvm::cl::Hidden,
+    llvm::cl::location(VerifyAfterTransform), llvm::cl::init(false));
 
 bool SemanticARCOptVisitor::optimize() {
   bool madeChange = false;
@@ -732,803 +149,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-//                     Redundant Borrow Scope Elimination
-//===----------------------------------------------------------------------===//
-
-bool SemanticARCOptVisitor::visitBeginBorrowInst(BeginBorrowInst *bbi) {
-  auto kind = bbi->getOperand().getOwnershipKind();
-  SmallVector<EndBorrowInst *, 16> endBorrows;
-  for (auto *op : bbi->getUses()) {
-    if (!op->isConsumingUse()) {
-      // Make sure that this operand can accept our arguments kind.
-      auto map = op->getOwnershipKindMap();
-      if (map.canAcceptKind(kind))
-        continue;
-      return false;
-    }
-
-    // Otherwise, this borrow is being consumed. See if our consuming inst is an
-    // end_borrow. If it isn't, then return false, this scope is
-    // needed. Otherwise, add the end_borrow to our list of end borrows.
-    auto *ebi = dyn_cast<EndBorrowInst>(op->getUser());
-    if (!ebi) {
-      return false;
-    }
-    endBorrows.push_back(ebi);
-  }
-
-  // At this point, we know that the begin_borrow's operand can be
-  // used as an argument to all non-end borrow uses. Eliminate the
-  // begin borrow and end borrows.
-  while (!endBorrows.empty()) {
-    auto *ebi = endBorrows.pop_back_val();
-    eraseInstruction(ebi);
-  }
-
-  eraseAndRAUWSingleValueInstruction(bbi, bbi->getOperand());
-  return true;
-}
-
-//===----------------------------------------------------------------------===//
-//                    CopyValue Optimizations Elimination
-//===----------------------------------------------------------------------===//
-
-// Eliminate a copy of a borrowed value, if:
-//
-// 1. All of the copies users do not consume the copy (and thus can accept a
-//    borrowed value instead).
-// 2. The copies's non-destroy_value users are strictly contained within the
-//    scope of the borrowed value.
-//
-// Example:
-//
-//   %0 = @guaranteed (argument or instruction)
-//   %1 = copy_value %0
-//   apply %f(%1) : $@convention(thin) (@guaranteed ...) ...
-//   other_non_consuming_use %1
-//   destroy_value %1
-//   end_borrow %0 (if an instruction)
-//
-// =>
-//
-//   %0 = @guaranteed (argument or instruction)
-//   apply %f(%0) : $@convention(thin) (@guaranteed ...) ...
-//   other_non_consuming_use %0
-//   end_borrow %0 (if an instruction)
-//
-// NOTE: This means that the destroy_value technically can be after the
-// end_borrow. In practice, this will not be the case but we use this to avoid
-// having to reason about the ordering of the end_borrow and destroy_value.
-//
-// NOTE: Today we only perform this for guaranteed parameters since this enables
-// us to avoid doing the linear lifetime check to make sure that all destroys
-// are within the borrow scope.
-//
-// TODO: This needs a better name.
-bool SemanticARCOptVisitor::performGuaranteedCopyValueOptimization(
-    CopyValueInst *cvi) {
-  // For now, do not run this optimization. This is just to be careful.
-  if (onlyGuaranteedOpts)
-    return false;
-
-  SmallVector<BorrowedValue, 4> borrowScopeIntroducers;
-
-  // Find all borrow introducers for our copy operand. If we are unable to find
-  // all of the reproducers (due to pattern matching failure), conservatively
-  // return false. We can not optimize.
-  //
-  // NOTE: We can get multiple introducers if our copy_value's operand
-  // value runs through a phi or an aggregate forming instruction.
-  if (!getAllBorrowIntroducingValues(cvi->getOperand(), borrowScopeIntroducers))
-    return false;
-
-  // Then go over all of our uses and see if the value returned by our copy
-  // value forms a dead live range or a live range that would be dead if it was
-  // not consumed by phi nodes. If we do not have such a live range, there must
-  // be some consuming use that we either do not understand is /actually/
-  // forwarding or a user that truly represents a necessary consume of the value
-  // (e.x. storing into memory).
-  OwnershipLiveRange lr(cvi);
-  auto hasUnknownConsumingUseState =
-      lr.hasUnknownConsumingUse(assumingAtFixedPoint);
-  if (hasUnknownConsumingUseState ==
-      OwnershipLiveRange::HasConsumingUse_t::Yes) {
-    return false;
-  }
-
-  // Next check if we do not have any destroys of our copy_value and are
-  // processing a local borrow scope. In such a case, due to the way we ignore
-  // dead end blocks, we may eliminate the copy_value, creating a use of the
-  // borrowed value after the end_borrow. To avoid this, in such cases we
-  // bail. In contrast, a non-local borrow scope does not have any end scope
-  // instructions, implying we can avoid this hazard and still optimize in such
-  // a case.
-  //
-  // DISCUSSION: Consider the following SIL:
-  //
-  // ```
-  //   %1 = begin_borrow %0 : $KlassPair                            (1)
-  //   %2 = struct_extract %1 : $KlassPair, #KlassPair.firstKlass
-  //   %3 = copy_value %2 : $Klass
-  //   ...
-  //   end_borrow %1 : $LintCommand                                 (2)
-  //   cond_br ..., bb1, bb2
-  //
-  //   ...
-  //
-  //   bbN:
-  //     // Never return type implies dead end block.
-  //     apply %f(%3) : $@convention(thin) (@guaranteed Klass) -> Never (3)
-  //     unreachable
-  // ```
-  //
-  // For simplicity, note that if bbN post-dominates %3, given that when we
-  // compute linear lifetime errors we ignore dead end blocks, we would not
-  // register that the copy_values only use is outside of the begin_borrow
-  // region defined by (1), (2) and thus would eliminate the copy. This would
-  // result in %2 being used by %f, causing the linear lifetime checker to
-  // error.
-  //
-  // Naively one may assume that the solution to this is to just check if %3 has
-  // /any/ destroy_values at all and if it doesn't have any reachable
-  // destroy_values, then we are in this case. But is this correct in
-  // general. We prove this below:
-  //
-  // The only paths along which the copy_value can not be destroyed or consumed
-  // is along paths to dead end blocks. Trivially, we know that such a dead end
-  // block, can not be reachable from the end_borrow since by their nature dead
-  // end blocks end in unreachables.
-  //
-  // So we know that we can only run into this bug if we have a dead end block
-  // reachable from the end_borrow, meaning that the bug can not occur if we
-  // branch before the end_borrow since in that case, the borrow scope would
-  // last over the dead end block's no return meaning that we will not use the
-  // borrowed value after its lifetime is ended by the end_borrow.
-  //
-  // With that in hand, we note again that if we have exactly one consumed,
-  // destroy_value /after/ the end_borrow we will not optimize here. This means
-  // that this bug can only occur if the copy_value is only post-dominated by
-  // dead end blocks that use the value in a non-consuming way.
-  //
-  // TODO: There may be some way of sinking this into the loop below.
-  bool haveAnyLocalScopes =
-      llvm::any_of(borrowScopeIntroducers, [](BorrowedValue borrowScope) {
-        return borrowScope.isLocalScope();
-      });
-
-  auto destroys = lr.getDestroyingUses();
-  if (destroys.empty() && haveAnyLocalScopes) {
-    return false;
-  }
-
-  // If we reached this point, then we know that all of our users can accept a
-  // guaranteed value and our owned value is destroyed only by a set of
-  // destroy_values. Check if:
-  //
-  // 1. All of our destroys are joint post-dominated by our end borrow scope
-  //    set. If they do not, then the copy_value is lifetime extending the
-  //    guaranteed value, we can not eliminate it.
-  //
-  // 2. If all of our destroy_values are dead end. In such a case, the linear
-  //    lifetime checker will not perform any checks since it assumes that dead
-  //    end destroys can be ignored. Since we are going to end the program
-  //    anyways, we want to be conservative here and optimize only if we do not
-  //    need to insert an end_borrow since all of our borrow introducers are
-  //    non-local scopes.
-  {
-    bool foundNonDeadEnd = false;
-    for (auto *d : destroys) {
-      foundNonDeadEnd |= !getDeadEndBlocks().isDeadEnd(d->getParentBlock());
-    }
-    if (!foundNonDeadEnd && haveAnyLocalScopes)
-      return false;
-    SmallVector<Operand *, 8> scratchSpace;
-    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
-    if (llvm::any_of(borrowScopeIntroducers, [&](BorrowedValue borrowScope) {
-          return !borrowScope.areUsesWithinScope(lr.getAllConsumingUses(),
-                                                 scratchSpace, visitedBlocks,
-                                                 getDeadEndBlocks());
-        })) {
-      return false;
-    }
-  }
-
-  // Otherwise, we know that our copy_value/destroy_values are all completely
-  // within the guaranteed value scope. So we /could/ optimize it. Now check if
-  // we were truly dead or if we are dead if we can eliminate phi arg uses. If
-  // we need to handle the phi arg uses, we bail. After we reach a fixed point,
-  // we will try to eliminate this value then if we can find a complete set of
-  // all incoming values to our phi argument.
-  if (hasUnknownConsumingUseState ==
-      OwnershipLiveRange::HasConsumingUse_t::YesButAllPhiArgs) {
-    auto opPhi = *OwnershipPhiOperand::get(lr.getSingleUnknownConsumingUse());
-    SmallVector<Operand *, 8> scratchSpace;
-    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
-
-    bool canOptimizePhi = opPhi.visitResults([&](SILValue value) {
-      SWIFT_DEFER {
-        scratchSpace.clear();
-        visitedBlocks.clear();
-      };
-
-      OwnershipLiveRange phiArgLR(value);
-      if (bool(phiArgLR.hasUnknownConsumingUse())) {
-        return false;
-      }
-
-      if (llvm::any_of(borrowScopeIntroducers, [&](BorrowedValue borrowScope) {
-            return !borrowScope.areUsesWithinScope(
-                phiArgLR.getAllConsumingUses(), scratchSpace, visitedBlocks,
-                getDeadEndBlocks());
-          })) {
-        return false;
-      }
-
-      return true;
-    });
-
-    if (canOptimizePhi) {
-      opPhi.visitResults([&](SILValue value) {
-        joinedOwnedIntroducerToConsumedOperands.insert(value,
-                                                       opPhi.getOperand());
-        return true;
-      });
-    }
-
-    return false;
-  }
-
-  // Otherwise, our copy must truly not be needed, o RAUW and convert to
-  // guaranteed!
-  std::move(lr).convertToGuaranteedAndRAUW(cvi->getOperand(), getCallbacks());
-  return true;
-}
-
-/// If cvi only has destroy value users, then cvi is a dead live range. Lets
-/// eliminate all such dead live ranges.
-bool SemanticARCOptVisitor::eliminateDeadLiveRangeCopyValue(
-    CopyValueInst *cvi) {
-  // This is a cheap optimization generally.
-
-  // See if we are lucky and have a simple case.
-  if (auto *op = cvi->getSingleUse()) {
-    if (auto *dvi = dyn_cast<DestroyValueInst>(op->getUser())) {
-      eraseInstruction(dvi);
-      eraseInstructionAndAddOperandsToWorklist(cvi);
-      return true;
-    }
-  }
-
-  // If all of our copy_value users are destroy_value, zap all of the
-  // instructions. We begin by performing that check and gathering up our
-  // destroy_value.
-  SmallVector<DestroyValueInst *, 16> destroys;
-  if (!all_of(cvi->getUses(), [&](Operand *op) {
-        auto *dvi = dyn_cast<DestroyValueInst>(op->getUser());
-        if (!dvi)
-          return false;
-
-        // Stash dvi in destroys so we can easily eliminate it later.
-        destroys.push_back(dvi);
-        return true;
-      })) {
-    return false;
-  }
-
-  // Now that we have a truly dead live range copy value, eliminate it!
-  while (!destroys.empty()) {
-    eraseInstruction(destroys.pop_back_val());
-  }
-  eraseInstructionAndAddOperandsToWorklist(cvi);
-  return true;
-}
-
-// Handle simple checking where we do not need to form live ranges and visit a
-// bunch of instructions.
-static bool canSafelyJoinSimpleRange(SILValue cviOperand,
-                                     DestroyValueInst *cviOperandDestroy,
-                                     CopyValueInst *cvi) {
-  // We only handle cases where our copy_value has a single consuming use that
-  // is not a forwarding use. We need to use the LiveRange functionality to
-  // guarantee correctness in the presence of forwarding uses.
-  //
-  // NOTE: This use may be any type of consuming use and may not be a
-  // destroy_value.
-  auto *cviConsumer = cvi->getSingleConsumingUse();
-  if (!cviConsumer || isOwnedForwardingInstruction(cviConsumer->getUser())) {
-    return false;
-  }
-
-  // Ok, we may be able to eliminate this. The main thing we need to be careful
-  // of here is that if the destroy_value is /after/ the consuming use of the
-  // operand of copy_value, we may have normal uses of the copy_value's operand
-  // that would become use-after-frees since we would be shrinking the lifetime
-  // of the object potentially. Consider the following SIL:
-  //
-  //   %0 = ...
-  //   %1 = copy_value %0
-  //   apply %cviConsumer(%1)
-  //   apply %guaranteedUser(%0)
-  //   destroy_value %0
-  //
-  // Easily, if we were to eliminate the copy_value, destroy_value, the object's
-  // lifetime could potentially be shrunk before guaranteedUser is executed,
-  // causing guaranteedUser to be a use-after-free.
-  //
-  // As an extra wrinkle, until all interior pointer constructs (e.x.:
-  // project_box) are guaranteed to be guaranted by a begin_borrow, we can not
-  // in general safely shrink lifetimes. So even if we think we can prove that
-  // all non-consuming uses of %0 are before apply %cviConsumer, we may miss
-  // implicit uses that are not guarded yet by a begin_borrow, resulting in
-  // use-after-frees.
-  //
-  // With that in mind, we only handle cases today where we can prove that
-  // destroy_value is strictly before the consuming use of the operand. This
-  // guarantees that we are not shrinking the lifetime of the underlying object.
-  //
-  // First we handle the simple case: where the cviConsumer is a return inst. In
-  // such a case, we know for sure that cviConsumer post-dominates the
-  // destroy_value.
-  auto cviConsumerIter = cviConsumer->getUser()->getIterator();
-  if (isa<ReturnInst>(cviConsumerIter)) {
-    return true;
-  }
-
-  // Then see if our cviConsumer is in the same block as a return inst and the
-  // destroy_value is not. In that case, we know that the cviConsumer must
-  // post-dominate the destroy_value.
-  auto *cviConsumingBlock = cviConsumerIter->getParent();
-  if (isa<ReturnInst>(cviConsumingBlock->getTerminator()) &&
-      cviConsumingBlock != cviOperandDestroy->getParent()) {
-    return true;
-  }
-
-  // Otherwise, we only support joining live ranges where the cvi and the cvi's
-  // operand's destroy are in the same block with the destroy_value of cvi
-  // operand needing to be strictly after the copy_value. This analysis can be
-  // made significantly stronger by using LiveRanges, but this is simple for
-  // now.
-  auto cviOperandDestroyIter = cviOperandDestroy->getIterator();
-  if (cviConsumingBlock != cviOperandDestroyIter->getParent()) {
-    return false;
-  }
-
-  // TODO: This should really be llvm::find, but for some reason, the templates
-  // do not match up given the current state of the iterators. This impl works
-  // in a pinch though.
-  return llvm::any_of(
-      llvm::make_range(cviOperandDestroyIter,
-                       cviOperandDestroyIter->getParent()->end()),
-      [&](const SILInstruction &val) { return &*cviConsumerIter == &val; });
-}
-
-// # The Problem We Are Solving
-//
-// The main idea here is that we are trying to eliminate the simplest, easiest
-// form of live range joining. Consider the following SIL:
-//
-//   ```
-//   %cviOperand = ...                // @owned value
-//   %cvi = copy_value %cviOperand    // copy of @owned value
-//   ...
-//   destroy_value %cviOperandDestroy // destruction of @owned value
-//   ...
-//   apply %consumingUser(%cvi)       // destruction of copy of @owned value
-//   ```
-//
-// We want to reduce reference count traffic by eliminating the middle
-// copy/destroy yielding:
-//
-//   ```
-//   %cviOperand = ...                // @owned value
-//   // *eliminated copy_value*
-//   ...
-//   // *eliminated destroy_value*
-//   ...
-//   apply %consumingUser(%cviOperand)       // destruction of copy of @owned
-//   value
-//   ```
-//
-// # Safety
-//
-// In order to do this safely, we need to take the union of the two objects
-// lifetimes since we are only joining lifetimes. This ensures that we can rely
-// on SILGen's correctness on inserting safe lifetimes. To keep this simple
-// today we only optimize if the destroy_value and consuming user are in the
-// same block and the consuming user is later in the block than the
-// destroy_value.
-//
-// DISCUSSION: The reason why we do not shrink lifetimes today is that all
-// interior pointers (e.x. project_box) are properly guarded by
-// begin_borrow. Because of that we can not shrink lifetimes and instead rely on
-// SILGen's correctness.
-bool SemanticARCOptVisitor::tryJoiningCopyValueLiveRangeWithOperand(
-    CopyValueInst *cvi) {
-  // First do a quick check if our operand is owned. If it is not owned, we can
-  // not join live ranges.
-  SILValue operand = cvi->getOperand();
-  if (operand.getOwnershipKind() != ValueOwnershipKind::Owned) {
-    return false;
-  }
-
-  // Then check if our operand has a single destroy_value. If it does and that
-  // destroy_value is strictly before the consumer of our copy_value in the same
-  // block as the consumer of said copy_value then we can always join the live
-  // ranges.
-  //
-  // Example:
-  //
-  //   ```
-  //   %1 = copy_value %0
-  //   ...
-  //   destroy_value %0
-  //   apply %consumingUser(%1)
-  //   ```
-  // ->
-  //
-  //   ```
-  //   apply %consumingUser(%0)
-  //   ```
-  //
-  // DISCUSSION: We need to ensure that the consuming use of the copy_value is
-  // strictly after the destroy_value to ensure that we do not shrink the live
-  // range of the operand if the operand has any normal uses beyond our copy
-  // value. Otherwise, we could have normal uses /after/ the consuming use of
-  // our copy_value.
-  if (auto *dvi = operand->getSingleConsumingUserOfType<DestroyValueInst>()) {
-    if (canSafelyJoinSimpleRange(operand, dvi, cvi)) {
-      eraseInstruction(dvi);
-      eraseAndRAUWSingleValueInstruction(cvi, operand);
-      return true;
-    }
-  }
-
-  // Otherwise, we couldn't handle this case, so return false.
-  //
-  // NOTE: We would generally do a more complex analysis here to handle the more
-  // general case. That would most likely /not/ be a guaranteed optimization
-  // until we investigate/measure.
-  return false;
-}
-
-bool SemanticARCOptVisitor::visitCopyValueInst(CopyValueInst *cvi) {
-  // If our copy value inst has only destroy_value users, it is a dead live
-  // range. Try to eliminate them.
-  if (eliminateDeadLiveRangeCopyValue(cvi)) {
-    return true;
-  }
-
-  // Then see if copy_value operand's lifetime ends after our copy_value via a
-  // destroy_value. If so, we can join their lifetimes.
-  if (tryJoiningCopyValueLiveRangeWithOperand(cvi)) {
-    return true;
-  }
-
-  // Then try to perform the guaranteed copy value optimization.
-  if (performGuaranteedCopyValueOptimization(cvi)) {
-    return true;
-  }
-
-  return false;
-}
-
-//===----------------------------------------------------------------------===//
-//                         load [copy] Optimizations
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-/// A class that computes in a flow insensitive way if we can prove that our
-/// storage is either never written to, or is initialized exactly once and never
-/// written to again. In both cases, we can convert load [copy] -> load_borrow
-/// safely.
-class StorageGuaranteesLoadVisitor
-    : public AccessUseDefChainVisitor<StorageGuaranteesLoadVisitor> {
-  // The outer SemanticARCOptVisitor.
-  SemanticARCOptVisitor &ARCOpt;
-
-  // The live range of the original load.
-  const OwnershipLiveRange &liveRange;
-
-  // The current address being visited.
-  SILValue currentAddress;
-
-  Optional<bool> isWritten;
-
-public:
-  StorageGuaranteesLoadVisitor(SemanticARCOptVisitor &arcOpt, LoadInst *load,
-                               const OwnershipLiveRange &liveRange)
-      : ARCOpt(arcOpt), liveRange(liveRange),
-        currentAddress(load->getOperand()) {}
-
-  void answer(bool written) {
-    currentAddress = nullptr;
-    isWritten = written;
-  }
-
-  void next(SILValue address) { currentAddress = address; }
-
-  void visitNestedAccess(BeginAccessInst *access) {
-    // First see if we have read/modify. If we do not, just look through the
-    // nested access.
-    switch (access->getAccessKind()) {
-    case SILAccessKind::Init:
-    case SILAccessKind::Deinit:
-      return next(access->getOperand());
-    case SILAccessKind::Read:
-    case SILAccessKind::Modify:
-      break;
-    }
-
-    // Next check if our live range is completely in the begin/end access
-    // scope. If so, we may be able to use a load_borrow here!
-    SmallVector<Operand *, 8> endScopeUses;
-    transform(access->getEndAccesses(), std::back_inserter(endScopeUses),
-              [](EndAccessInst *eai) { return &eai->getAllOperands()[0]; });
-    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
-    LinearLifetimeChecker checker(visitedBlocks, ARCOpt.getDeadEndBlocks());
-    if (!checker.validateLifetime(access, endScopeUses,
-                                  liveRange.getAllConsumingUses())) {
-      // If we fail the linear lifetime check, then just recur:
-      return next(access->getOperand());
-    }
-
-    // Otherwise, if we have read, then we are done!
-    if (access->getAccessKind() == SILAccessKind::Read) {
-      return answer(false);
-    }
-
-    // If we have a modify, check if our value is /ever/ written to. If it is
-    // never actually written to, then we convert to a load_borrow.
-    auto result = ARCOpt.addressToExhaustiveWriteListCache.get(access);
-    if (!result.hasValue()) {
-      return answer(true);
-    }
-
-    if (result.getValue().empty()) {
-      return answer(false);
-    }
-
-    return answer(true);
-  }
-
-  void visitArgumentAccess(SILFunctionArgument *arg) {
-    // If this load_copy is from an indirect in_guaranteed argument, then we
-    // know for sure that it will never be written to.
-    if (arg->hasConvention(SILArgumentConvention::Indirect_In_Guaranteed)) {
-      return answer(false);
-    }
-
-    // If we have an inout parameter that isn't ever actually written to, return
-    // false.
-    if (arg->getKnownParameterInfo().isIndirectMutating()) {
-      auto wellBehavedWrites =
-          ARCOpt.addressToExhaustiveWriteListCache.get(arg);
-      if (!wellBehavedWrites.hasValue()) {
-        return answer(true);
-      }
-
-      // No writes.
-      if (wellBehavedWrites->empty()) {
-        return answer(false);
-      }
-
-      // Ok, we have some writes. See if any of them are within our live
-      // range. If any are, we definitely can not promote to load_borrow.
-      SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
-      SmallVector<BeginAccessInst *, 16> foundBeginAccess;
-      LinearLifetimeChecker checker(visitedBlocks, ARCOpt.getDeadEndBlocks());
-      SILValue introducerValue = liveRange.getIntroducer().value;
-      if (!checker.usesNotContainedWithinLifetime(introducerValue,
-                                                  liveRange.getDestroyingUses(),
-                                                  *wellBehavedWrites)) {
-        return answer(true);
-      }
-
-      // Finally, check if our live range is strictly contained within any of
-      // our scoped writes.
-      SmallVector<Operand *, 16> endAccessList;
-      for (Operand *use : *wellBehavedWrites) {
-        auto *bai = dyn_cast<BeginAccessInst>(use->getUser());
-        if (!bai) {
-          continue;
-        }
-
-        endAccessList.clear();
-        llvm::transform(
-            bai->getUsersOfType<EndAccessInst>(),
-            std::back_inserter(endAccessList),
-            [](EndAccessInst *eai) { return &eai->getAllOperands()[0]; });
-        visitedBlocks.clear();
-
-        // We know that our live range is based on a load [copy], so we know
-        // that our value must have a defining inst.
-        auto *definingInst =
-            cast<LoadInst>(introducerValue->getDefiningInstruction());
-
-        // Then if our defining inst is not in our bai, endAccessList region, we
-        // know that the two ranges must be disjoint, so continue.
-        if (!checker.validateLifetime(bai, endAccessList,
-                                      &definingInst->getAllOperands()[0])) {
-          continue;
-        }
-
-        // Otherwise, we do have an overlap, return true.
-        return answer(true);
-      }
-
-      // Otherwise, there isn't an overlap, so we don't write to it.
-      return answer(false);
-    }
-
-    // TODO: This should be extended:
-    //
-    // 1. We should be able to analyze in arguments and see if they are only
-    //    ever destroyed at the end of the function. In such a case, we may be
-    //    able to also to promote load [copy] from such args to load_borrow.
-    return answer(true);
-  }
-
-  void visitGlobalAccess(SILValue global) {
-    return answer(!AccessedStorage(global, AccessedStorage::Global)
-                       .isLetAccess(&ARCOpt.F));
-  }
-
-  void visitClassAccess(RefElementAddrInst *field) {
-    currentAddress = nullptr;
-
-    // We know a let property won't be written to if the base object is
-    // guaranteed for the duration of the access.
-    // For non-let properties conservatively assume they may be written to.
-    if (!field->getField()->isLet()) {
-      return answer(true);
-    }
-
-    // The lifetime of the `let` is guaranteed if it's dominated by the
-    // guarantee on the base. See if we can find a single borrow introducer for
-    // this object. If we could not find a single such borrow introducer, assume
-    // that our property is conservatively written to.
-    SILValue baseObject = field->getOperand();
-    auto value = getSingleBorrowIntroducingValue(baseObject);
-    if (!value) {
-      return answer(true);
-    }
-
-    // Ok, we have a single borrow introducing value. First do a quick check if
-    // we have a non-local scope that is a function argument. In such a case, we
-    // know statically that our let can not be written to in the current
-    // function. To be conservative, assume that all other non-local scopes
-    // write to memory.
-    if (!value->isLocalScope()) {
-      if (value->kind == BorrowedValueKind::SILFunctionArgument) {
-        return answer(false);
-      }
-
-      // TODO: Once we model Coroutine results as non-local scopes, we should be
-      // able to return false here for them as well.
-      return answer(true);
-    }
-
-    // TODO: This is disabled temporarily for guaranteed phi args just for
-    // staging purposes. Thus be conservative and assume true in these cases.
-    if (value->kind == BorrowedValueKind::Phi) {
-      return answer(true);
-    }
-
-    // Ok, we now know that we have a local scope whose lifetime we need to
-    // analyze. With that in mind, gather up the lifetime ending uses of our
-    // borrow scope introducing value and then use the linear lifetime checker
-    // to check whether the copied value is dominated by the lifetime of the
-    // borrow it's based on.
-    SmallVector<Operand *, 4> endScopeInsts;
-    value->visitLocalScopeEndingUses(
-        [&](Operand *use) { endScopeInsts.push_back(use); });
-
-    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
-    LinearLifetimeChecker checker(visitedBlocks, ARCOpt.getDeadEndBlocks());
-
-    // Returns true on success. So we invert.
-    bool foundError = !checker.validateLifetime(
-        baseObject, endScopeInsts, liveRange.getAllConsumingUses());
-    return answer(foundError);
-  }
-
-  // TODO: Handle other access kinds?
-  void visitBase(SILValue base, AccessedStorage::Kind kind) {
-    return answer(true);
-  }
-
-  void visitNonAccess(SILValue addr) { return answer(true); }
-
-  void visitCast(SingleValueInstruction *cast, Operand *parentAddr) {
-    return next(parentAddr->get());
-  }
-
-  void visitPathComponent(SingleValueInstruction *projectedAddr,
-                          Operand *parentAddr) {
-    return next(parentAddr->get());
-  }
-
-  void visitPhi(SILPhiArgument *phi) {
-    // We shouldn't have address phis in OSSA SIL, so we don't need to recur
-    // through the predecessors here.
-    return answer(true);
-  }
-
-  /// See if we have an alloc_stack that is only written to once by an
-  /// initializing instruction.
-  void visitStackAccess(AllocStackInst *stack) {
-    SmallVector<Operand *, 8> destroyAddrOperands;
-    bool initialAnswer = isSingleInitAllocStack(stack, destroyAddrOperands);
-    if (!initialAnswer)
-      return answer(true);
-
-    // Then make sure that all of our load [copy] uses are within the
-    // destroy_addr.
-    SmallPtrSet<SILBasicBlock *, 4> visitedBlocks;
-    LinearLifetimeChecker checker(visitedBlocks, ARCOpt.getDeadEndBlocks());
-    // Returns true on success. So we invert.
-    bool foundError = !checker.validateLifetime(
-        stack, destroyAddrOperands /*consuming users*/,
-        liveRange.getAllConsumingUses() /*non consuming users*/);
-    return answer(foundError);
-  }
-
-  bool doIt() {
-    while (currentAddress) {
-      visit(currentAddress);
-    }
-    return *isWritten;
-  }
-};
-
-} // namespace
-
-bool SemanticARCOptVisitor::isWrittenTo(LoadInst *load,
-                                        const OwnershipLiveRange &lr) {
-  StorageGuaranteesLoadVisitor visitor(*this, load, lr);
-  return visitor.doIt();
-}
-
-// Convert a load [copy] from unique storage [read] that has all uses that can
-// accept a guaranteed parameter to a load_borrow.
-bool SemanticARCOptVisitor::visitLoadInst(LoadInst *li) {
-  // This optimization can use more complex analysis. We should do some
-  // experiments before enabling this by default as a guaranteed optimization.
-  if (onlyGuaranteedOpts)
-    return false;
-
-  if (li->getOwnershipQualifier() != LoadOwnershipQualifier::Copy)
-    return false;
-
-  // Ok, we have our load [copy]. Make sure its value is truly a dead live range
-  // implying it is only ever consumed by destroy_value instructions. If it is
-  // consumed, we need to pass off a +1 value, so bail.
-  //
-  // FIXME: We should consider if it is worth promoting a load [copy]
-  // -> load_borrow if we can put a copy_value on a cold path and thus
-  // eliminate RR traffic on a hot path.
-  OwnershipLiveRange lr(li);
-  if (bool(lr.hasUnknownConsumingUse()))
-    return false;
-
-  // Then check if our address is ever written to. If it is, then we cannot use
-  // the load_borrow because the stored value may be released during the loaded
-  // value's live range.
-  if (isWrittenTo(li, lr))
-    return false;
-
-  // Ok, we can perform our optimization. Convert the load [copy] into a
-  // load_borrow.
-  auto *lbi =
-      SILBuilderWithScope(li).createLoadBorrow(li->getLoc(), li->getOperand());
-
-  lr.insertEndBorrowsAtDestroys(lbi, getDeadEndBlocks(), lifetimeFrontier);
-  std::move(lr).convertToGuaranteedAndRAUW(lbi, getCallbacks());
-  return true;
-}
-
-//===----------------------------------------------------------------------===//
 //                            Top Level Entrypoint
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
index ef4777e..88e4ed0 100644
--- a/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
+++ b/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
@@ -1020,7 +1020,7 @@
   info.id = 0;
   for (auto sccIt = scc_begin(F); !sccIt.isAtEnd(); ++sccIt) {
     ++info.id;
-    info.hasLoop = sccIt.hasLoop();
+    info.hasLoop = sccIt.hasCycle();
     for (auto *bb : *sccIt) {
       blockToSCCMap.insert(std::make_pair(bb, info));
     }
diff --git a/lib/SILOptimizer/Transforms/CSE.cpp b/lib/SILOptimizer/Transforms/CSE.cpp
index f62fa49..1e1f6bb 100644
--- a/lib/SILOptimizer/Transforms/CSE.cpp
+++ b/lib/SILOptimizer/Transforms/CSE.cpp
@@ -831,6 +831,14 @@
       !callee->isLazyPropertyGetter())
     return false;
 
+  // Only handle classes, but not structs.
+  // Lazy property getters of structs have an indirect inout self parameter.
+  // We don't know if the whole struct is overwritten between two getter calls.
+  // In such a case, the lazy property could be reset to an Optional.none.
+  // TODO: We could check this case with AliasAnalysis.
+  if (ai->getArgument(0)->getType().isAddress())
+    return false;
+
   // Check if the first block has a switch_enum of an Optional.
   // We don't handle getters of generic types, which have a switch_enum_addr.
   // This will be obsolete with opaque values anyway.
diff --git a/lib/SILOptimizer/Transforms/OptRemarkGenerator.cpp b/lib/SILOptimizer/Transforms/OptRemarkGenerator.cpp
index 987c36e..b1e98ba 100644
--- a/lib/SILOptimizer/Transforms/OptRemarkGenerator.cpp
+++ b/lib/SILOptimizer/Transforms/OptRemarkGenerator.cpp
@@ -41,6 +41,15 @@
         "Emit opt remarks even on implicit and autogenerated functions"),
     llvm::cl::init(false));
 
+static llvm::cl::opt<bool> DecllessDebugValueUseSILDebugInfo(
+    "optremarkgen-declless-debugvalue-use-sildebugvar-info", llvm::cl::Hidden,
+    llvm::cl::desc(
+        "If a debug_value does not have a decl, infer a value with a name from "
+        "that info that has a loc set to the loc of the debug_value "
+        "instruction itself. This is for testing purposes so it is easier to "
+        "write SIL test cases for this pass"),
+    llvm::cl::init(false));
+
 //===----------------------------------------------------------------------===//
 //                           Value To Decl Inferrer
 //===----------------------------------------------------------------------===//
@@ -53,6 +62,7 @@
 
   RCIdentityFunctionInfo &rcfi;
   SmallVector<std::pair<SILType, Projection>, 32> accessPath;
+  SmallVector<Operand *, 32> rcIdenticalSecondaryUseSearch;
 
   ValueToDeclInferrer(RCIdentityFunctionInfo &rcfi) : rcfi(rcfi) {}
 
@@ -61,20 +71,74 @@
   bool infer(ArgumentKeyKind keyKind, SILValue value,
              SmallVectorImpl<Argument> &resultingInferredDecls);
 
-  /// Print out a note to \p stream that beings at decl and then consumes the
-  /// accessPath we computed for decl producing a segmented access path, e.x.:
-  /// "of 'x.lhs.ivar'".
-  void printNote(llvm::raw_string_ostream &stream, const ValueDecl *decl);
+  /// Print out a note to \p stream that beings at decl and then if
+  /// useProjectionPath is set to true iterates the accessPath we computed for
+  /// decl producing a segmented access path, e.x.: "of 'x.lhs.ivar'".
+  ///
+  /// The reason why one may not want to emit a projection path note here is if
+  /// one found an debug_value on a value that is rc-identical to the actual
+  /// value associated with the current projection path. Consider the following
+  /// SIL:
+  ///
+  ///    struct KlassPair {
+  ///      var lhs: Klass
+  ///      var rhs: Klass
+  ///    }
+  ///
+  ///    struct StateWithOwningPointer {
+  ///      var state: TrivialState
+  ///      var owningPtr: Klass
+  ///    }
+  ///
+  ///    sil @theFunction : $@convention(thin) () -> () {
+  ///    bb0:
+  ///      %0 = apply %getKlassPair() : $@convention(thin) () -> @owned KlassPair
+  ///      // This debug_value's name can be combined...
+  ///      debug_value %0 : $KlassPair, name "myPair"
+  ///      // ... with the access path from the struct_extract here...
+  ///      %1 = struct_extract %0 : $KlassPair, #KlassPair.lhs
+  ///      // ... to emit a nice diagnostic that 'myPair.lhs' is being retained.
+  ///      strong_retain %1 : $Klass
+  ///
+  ///      // In contrast in this case, we rely on looking through rc-identity
+  ///      // uses to find the debug_value. In this case, the source info
+  ///      // associated with the debug_value (%2) is no longer associated with
+  ///      // the underlying access path we have been tracking upwards (%1 is in
+  ///      // our access path list). Instead, we know that the debug_value is
+  ///      // rc-identical to whatever value we were originally tracking up (%1)
+  ///      // and thus the correct identifier to use is the direct name of the
+  ///      // identifier alone since that source identifier must be some value
+  ///      // in the source that by itself is rc-identical to whatever is being
+  ///      // manipulated.
+  ///      //
+  ///      // The reason why we must do this is due to the behavior of the late
+  ///      // optimizer and how it forms these patterns in the code.
+  ///      %0a = apply %getStateWithOwningPointer() : $@convention(thin) () -> @owned StateWithOwningPointer
+  ///      %1 = struct_extract %0a : $StateWithOwningPointer, #StateWithOwningPointer.owningPtr
+  ///      strong_retain %1 : $Klass
+  ///      %2 = struct $Array(%0 : $Builtin.NativeObject, ...)
+  ///      debug_value %2 : $Array, ...
+  ///    }
+  void printNote(llvm::raw_string_ostream &stream, StringRef name,
+                 bool shouldPrintAccessPath = true);
+
+  /// Convenience overload that calls:
+  ///
+  ///   printNote(stream, decl->getBaseName().userFacingName(), shouldPrintAccessPath).
+  void printNote(llvm::raw_string_ostream &stream, const ValueDecl *decl,
+                 bool shouldPrintAccessPath = true) {
+    printNote(stream, decl->getBaseName().userFacingName(),
+              shouldPrintAccessPath);
+  }
+
+  /// Print out non-destructively the current access path we have found to
+  /// stream.
+  void printAccessPath(llvm::raw_string_ostream &stream);
 };
 
 } // anonymous namespace
 
-void ValueToDeclInferrer::printNote(llvm::raw_string_ostream &stream,
-                                    const ValueDecl *decl) {
-  assert(decl &&
-         "We assume for now that this is always called with a non-null decl");
-  stream << "of '" << decl->getBaseName();
-
+void ValueToDeclInferrer::printAccessPath(llvm::raw_string_ostream &stream) {
   for (auto &pair : accessPath) {
     auto baseType = pair.first;
     auto &proj = pair.second;
@@ -111,8 +175,14 @@
 
     llvm_unreachable("Covered switch is not covered?!");
   }
+}
 
-  accessPath.clear();
+void ValueToDeclInferrer::printNote(llvm::raw_string_ostream &stream,
+                                    StringRef name,
+                                    bool shouldPrintAccessPath) {
+  stream << "of '" << name;
+  if (shouldPrintAccessPath)
+    printAccessPath(stream);
   stream << "'";
 }
 
@@ -145,6 +215,12 @@
 bool ValueToDeclInferrer::infer(
     ArgumentKeyKind keyKind, SILValue value,
     SmallVectorImpl<Argument> &resultingInferredDecls) {
+  // Clear the stored access path at end of scope.
+  SWIFT_DEFER {
+    accessPath.clear();
+  };
+  SmallPtrSet<SILInstruction *, 8> visitedDebugValueInsts;
+
   // This is a linear IR traversal using a 'falling while loop'. That means
   // every time through the loop we are trying to handle a case before we hit
   // the bottom of the while loop where we always return true (since we did not
@@ -216,40 +292,77 @@
       }
     }
 
-    // Then visit our users and see if we can find a debug_value that provides
-    // us with a decl we can use to construct an argument.
+    // Then visit our users (ignoring rc identical transformations) and see if
+    // we can find a debug_value that provides us with a decl we can use to
+    // construct an argument.
+    //
+    // The reason why we do this is that sometimes we reform a struct from its
+    // constituant parts and then construct the debug_value from that. For
+    // instance, if we FSOed.
     bool foundDeclFromUse = false;
-    for (auto *use : value->getUses()) {
+    rcfi.visitRCUses(value, [&](Operand *use) {
       // Skip type dependent uses.
       if (use->isTypeDependent())
-        continue;
+        return;
 
-      if (auto *dvi = dyn_cast<DebugValueInst>(use->getUser())) {
-        // Check if our debug_value has a decl and was not inlined into the
-        // current function.
-        if (hasNonInlinedDebugScope(dvi)) {
-          if (auto *decl = dvi->getDecl()) {
-            std::string msg;
-            {
-              llvm::raw_string_ostream stream(msg);
-              printNote(stream, decl);
-            }
-            resultingInferredDecls.push_back(
-                Argument({keyKind, "InferredValue"}, std::move(msg), decl));
-            foundDeclFromUse = true;
-          }
+      // Then see if we have a debug_value that is associated with a non-inlined
+      // debug scope. Such an instruction is an instruction that is from the
+      // current function.
+      auto *dvi = dyn_cast<DebugValueInst>(use->getUser());
+      if (!dvi || !hasNonInlinedDebugScope(dvi))
+        return;
+
+      // See if we have already inferred this debug_value as a potential source
+      // for this instruction. In such a case, just return.
+      if (!visitedDebugValueInsts.insert(dvi).second)
+        return;
+
+      if (auto *decl = dvi->getDecl()) {
+        std::string msg;
+        {
+          llvm::raw_string_ostream stream(msg);
+          // If we are not a top level use, we must be a rc-identical transitive
+          // use. In such a case, we just print out the rc identical value
+          // without a projection path. This is because we now have a better
+          // name and the name is rc-identical to whatever was at the end of the
+          // projection path but is not at the end of that projection path.
+          printNote(stream, decl,
+                    use->get() == value /*print projection path*/);
         }
+        resultingInferredDecls.emplace_back(
+            OptRemark::ArgumentKey{keyKind, "InferredValue"}, std::move(msg),
+            decl);
+        foundDeclFromUse = true;
+        return;
       }
-    }
-    if (foundDeclFromUse)
-      return true;
 
-    // At this point, we could not infer any argument. See if we can look
-    // through loads.
-    //
-    // TODO: Add GEPs to construct a ProjectionPath.
+      // If we did not have a decl, see if we were asked for testing
+      // purposes to use SILDebugInfo to create a placeholder inferred
+      // value.
+      if (!DecllessDebugValueUseSILDebugInfo)
+        return;
 
-    // Finally, see if we can look through a load...
+      auto varInfo = dvi->getVarInfo();
+      if (!varInfo)
+        return;
+
+      auto name = varInfo->Name;
+      if (name.empty())
+        return;
+
+      std::string msg;
+      {
+        llvm::raw_string_ostream stream(msg);
+        printNote(stream, name, use->get() == value /*print projection path*/);
+      }
+      resultingInferredDecls.push_back(
+          Argument({keyKind, "InferredValue"}, std::move(msg), dvi->getLoc()));
+      foundDeclFromUse = true;
+    });
+
+    // At this point, we could not infer any argument. See if we can look up the
+    // def-use graph and come up with a good location after looking through
+    // loads and projections.
     if (auto *li = dyn_cast<LoadInst>(value)) {
       value = stripAccessMarkers(li->getOperand());
       continue;
@@ -266,8 +379,9 @@
     // TODO: We could emit at this point a msg for temporary allocations.
 
     // If we reached this point, we finished falling through the loop and return
-    // true.
-    return true;
+    // if we found any decls from uses. We always process everything so we /can/
+    // potentially emit multiple diagnostics.
+    return foundDeclFromUse;
   }
 }
 
@@ -311,10 +425,11 @@
     (void)foundArgs;
 
     // Retains begin a lifetime scope so we infer scan forward.
-    auto remark = RemarkMissed("memory", *sri,
-                               SourceLocInferenceBehavior::ForwardScanOnly)
-                  << "retain of type '"
-                  << NV("ValueType", sri->getOperand()->getType()) << "'";
+    auto remark =
+        RemarkMissed("memory", *sri,
+                     SourceLocInferenceBehavior::ForwardScanAlwaysInfer)
+        << "retain of type '" << NV("ValueType", sri->getOperand()->getType())
+        << "'";
     for (auto arg : inferredArgs) {
       remark << arg;
     }
@@ -332,10 +447,11 @@
                                                sri->getOperand(), inferredArgs);
     (void)foundArgs;
 
-    auto remark = RemarkMissed("memory", *sri,
-                               SourceLocInferenceBehavior::BackwardScanOnly)
-                  << "release of type '"
-                  << NV("ValueType", sri->getOperand()->getType()) << "'";
+    auto remark =
+        RemarkMissed("memory", *sri,
+                     SourceLocInferenceBehavior::BackwardScanAlwaysInfer)
+        << "release of type '" << NV("ValueType", sri->getOperand()->getType())
+        << "'";
     for (auto arg : inferredArgs) {
       remark << arg;
     }
@@ -352,10 +468,11 @@
                                                rvi->getOperand(), inferredArgs);
     (void)foundArgs;
     // Retains begin a lifetime scope, so we infer scan forwards.
-    auto remark = RemarkMissed("memory", *rvi,
-                               SourceLocInferenceBehavior::ForwardScanOnly)
-                  << "retain of type '"
-                  << NV("ValueType", rvi->getOperand()->getType()) << "'";
+    auto remark =
+        RemarkMissed("memory", *rvi,
+                     SourceLocInferenceBehavior::ForwardScanAlwaysInfer)
+        << "retain of type '" << NV("ValueType", rvi->getOperand()->getType())
+        << "'";
     for (auto arg : inferredArgs) {
       remark << arg;
     }
@@ -373,10 +490,11 @@
     (void)foundArgs;
 
     // Releases end a lifetime scope so we infer scan backward.
-    auto remark = RemarkMissed("memory", *rvi,
-                               SourceLocInferenceBehavior::BackwardScanOnly)
-                  << "release of type '"
-                  << NV("ValueType", rvi->getOperand()->getType()) << "'";
+    auto remark =
+        RemarkMissed("memory", *rvi,
+                     SourceLocInferenceBehavior::BackwardScanAlwaysInfer)
+        << "release of type '" << NV("ValueType", rvi->getOperand()->getType())
+        << "'";
     for (auto arg : inferredArgs) {
       remark << arg;
     }
@@ -394,8 +512,7 @@
           valueToDeclInferrer.infer(ArgumentKeyKind::Note, ari, inferredArgs);
       (void)foundArgs;
       auto resultRemark =
-          RemarkPassed("memory", *ari,
-                       SourceLocInferenceBehavior::ForwardScanOnly)
+          RemarkPassed("memory", *ari, SourceLocInferenceBehavior::ForwardScan)
           << "stack allocated ref of type '" << NV("ValueType", ari->getType())
           << "'";
       for (auto &arg : inferredArgs)
@@ -412,8 +529,7 @@
     (void)foundArgs;
 
     auto resultRemark =
-        RemarkMissed("memory", *ari,
-                     SourceLocInferenceBehavior::ForwardScanOnly)
+        RemarkMissed("memory", *ari, SourceLocInferenceBehavior::ForwardScan)
         << "heap allocated ref of type '" << NV("ValueType", ari->getType())
         << "'";
     for (auto &arg : inferredArgs)
@@ -432,8 +548,7 @@
     (void)foundArgs;
 
     auto resultRemark =
-        RemarkMissed("memory", *abi,
-                     SourceLocInferenceBehavior::ForwardScanOnly)
+        RemarkMissed("memory", *abi, SourceLocInferenceBehavior::ForwardScan)
         << "heap allocated box of type '" << NV("ValueType", abi->getType())
         << "'";
     for (auto &arg : inferredArgs)
diff --git a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
index e07553e..ce3a00e 100644
--- a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
+++ b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
@@ -559,6 +559,15 @@
   return false;
 }
 
+static bool isInlineAlwaysCallSite(SILFunction *Callee) {
+  if (Callee->isTransparent())
+    return true;
+  if (Callee->getInlineStrategy() == AlwaysInline)
+    if (!Callee->getModule().getOptions().IgnoreAlwaysInline)
+      return true;
+  return false;
+}
+
 /// Checks if a given generic apply should be inlined unconditionally, i.e.
 /// without any complex analysis using e.g. a cost model.
 /// It returns true if a function should be inlined.
@@ -585,7 +594,7 @@
 
   // Always inline generic functions which are marked as
   // AlwaysInline or transparent.
-  if (Callee->getInlineStrategy() == AlwaysInline || Callee->isTransparent())
+  if (isInlineAlwaysCallSite(Callee))
     return true;
 
   // If all substitutions are concrete, then there is no need to perform the
@@ -632,7 +641,7 @@
 
   SILFunction *Callee = AI.getReferencedFunctionOrNull();
 
-  if (Callee->getInlineStrategy() == AlwaysInline || Callee->isTransparent()) {
+  if (isInlineAlwaysCallSite(Callee)) {
     LLVM_DEBUG(dumpCaller(AI.getFunction());
                llvm::dbgs() << "    always-inline decision "
                             << Callee->getName() << '\n');
@@ -655,7 +664,7 @@
     return false;
   }
 
-  if (Callee->getInlineStrategy() == AlwaysInline || Callee->isTransparent()) {
+  if (isInlineAlwaysCallSite(Callee)) {
     LLVM_DEBUG(dumpCaller(AI.getFunction());
                llvm::dbgs() << "    always-inline decision "
                             << Callee->getName() << '\n');
@@ -717,10 +726,6 @@
   }
 }
 
-static bool isInlineAlwaysCallSite(SILFunction *Callee) {
-  return Callee->getInlineStrategy() == AlwaysInline || Callee->isTransparent();
-}
-
 static void
 calculateBBWeights(SILFunction *Caller, DominanceInfo *DT,
                    llvm::DenseMap<SILBasicBlock *, uint64_t> &BBToWeightMap) {
diff --git a/lib/SILOptimizer/Transforms/PruneVTables.cpp b/lib/SILOptimizer/Transforms/PruneVTables.cpp
index 1854390..f1c37c8 100644
--- a/lib/SILOptimizer/Transforms/PruneVTables.cpp
+++ b/lib/SILOptimizer/Transforms/PruneVTables.cpp
@@ -27,10 +27,16 @@
 
 namespace {
 class PruneVTables : public SILModuleTransform {
-  void runOnVTable(SILModule *M,
-                   SILVTable *vtable) {
+  void runOnVTable(SILModule *M, SILVTable *vtable) {
     LLVM_DEBUG(llvm::dbgs() << "PruneVTables inspecting table:\n";
                vtable->print(llvm::dbgs()));
+    if (!M->isWholeModule() &&
+        vtable->getClass()->getEffectiveAccess() >= AccessLevel::FilePrivate) {
+      LLVM_DEBUG(llvm::dbgs() << "Ignoring visible table: ";
+                 vtable->print(llvm::dbgs()));
+      return;
+    }
+
     for (auto &entry : vtable->getMutableEntries()) {
       
       // We don't need to worry about entries that are overridden,
diff --git a/lib/SILOptimizer/Transforms/StringOptimization.cpp b/lib/SILOptimizer/Transforms/StringOptimization.cpp
index aa737a2..10c5cfd 100644
--- a/lib/SILOptimizer/Transforms/StringOptimization.cpp
+++ b/lib/SILOptimizer/Transforms/StringOptimization.cpp
@@ -198,7 +198,7 @@
   // Replace lhs.append(rhs) with "lhs = lhs + rhs" if both lhs and rhs are
   // constant.
   if (lhsString.isConstant() && rhsString.isConstant()) {
-    std::string concat = lhsString.str;
+    std::string concat = lhsString.str.str();
     concat += rhsString.str;
     if (ApplyInst *stringInit = createStringInit(concat, appendCall)) {
       replaceAppendWith(appendCall, stringInit);
@@ -235,7 +235,7 @@
 
   // Replace lhs + rhs with "lhs + rhs" if both lhs and rhs are constant.
   if (lhsString.isConstant() && rhsString.isConstant()) {
-    std::string concat = lhsString.str;
+    std::string concat = lhsString.str.str();
     concat += rhsString.str;
     if (ApplyInst *stringInit = createStringInit(concat, concatCall)) {
       concatCall->replaceAllUsesWith(stringInit);
diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp
index c1c5da4..3a15d56 100644
--- a/lib/SILOptimizer/Utils/CastOptimizer.cpp
+++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp
@@ -918,25 +918,32 @@
       return nullptr;
     }
 
-    // For CopyOnSuccess casts, we could insert an explicit copy here, but this
-    // case does not happen in practice.
-    //
     // Both TakeOnSuccess and TakeAlways can be reduced to an
     // UnconditionalCheckedCast, since the failure path is irrelevant.
+    AllocStackInst *copiedSrc = nullptr;
     switch (Inst->getConsumptionKind()) {
     case CastConsumptionKind::BorrowAlways:
       llvm_unreachable("checked_cast_addr_br never has BorrowAlways");
     case CastConsumptionKind::CopyOnSuccess:
-      return nullptr;
+      if (!Src->getType().isTrivial(*BB->getParent())) {
+        copiedSrc = Builder.createAllocStack(Loc, Src->getType());
+        Builder.createCopyAddr(Loc, Src, copiedSrc, IsNotTake, IsInitialization);
+        Src = copiedSrc;
+      }
+      break;
     case CastConsumptionKind::TakeAlways:
     case CastConsumptionKind::TakeOnSuccess:
       break;
     }
 
-    if (!emitSuccessfulIndirectUnconditionalCast(Builder, Loc, dynamicCast)) {
-      // No optimization was possible.
-      return nullptr;
-    }
+    bool result = emitSuccessfulIndirectUnconditionalCast(
+      Builder, Builder.getModule().getSwiftModule(), Loc, Src,
+      Inst->getSourceFormalType(), Dest, Inst->getTargetFormalType(), Inst);
+    (void)result;
+    assert(result && "emit cannot fail for an checked_cast_addr_br");
+
+    if (copiedSrc)
+      Builder.createDeallocStack(Loc, copiedSrc);
     eraseInstAction(Inst);
   }
   SILInstruction *NewI = &BB->back();
diff --git a/lib/SILOptimizer/Utils/Existential.cpp b/lib/SILOptimizer/Utils/Existential.cpp
index 9092171..3aa840b 100644
--- a/lib/SILOptimizer/Utils/Existential.cpp
+++ b/lib/SILOptimizer/Utils/Existential.cpp
@@ -433,3 +433,40 @@
   }
   CEI->isConcreteValueCopied |= OAI.isOpenedValueCopied;
 }
+
+void LLVM_ATTRIBUTE_USED OpenedArchetypeInfo::dump() const {
+  if (!isValid()) {
+    llvm::dbgs() << "invalid OpenedArchetypeInfo\n";
+    return;
+  }
+  llvm::dbgs() << "OpendArchetype: ";
+  OpenedArchetype->dump(llvm::dbgs());
+  llvm::dbgs() << "OpendArchetypeValue: ";
+  OpenedArchetypeValue->dump();
+  llvm::dbgs() << (isOpenedValueCopied ? "copied " : "") << "ExistentialValue: ";
+  ExistentialValue->dump();
+}
+
+void LLVM_ATTRIBUTE_USED ConcreteExistentialInfo::dump() const {
+  llvm::dbgs() << "ExistentialType: ";
+  ExistentialType->dump(llvm::dbgs());
+  llvm::dbgs() << "ConcreteType: ";
+  ConcreteType->dump(llvm::dbgs());
+  llvm::dbgs() << (isConcreteValueCopied ? "copied " : "") << "ConcreteValue: ";
+  ConcreteValue->dump();
+  if (ConcreteTypeDef) {
+    llvm::dbgs() << "ConcreteTypeDef: ";
+    ConcreteTypeDef->dump();
+  }
+  ExistentialSubs.dump(llvm::dbgs());
+  llvm::dbgs() << '\n';
+}
+
+void LLVM_ATTRIBUTE_USED ConcreteOpenedExistentialInfo::dump() const {
+  OAI.dump();
+  if (CEI) {
+    CEI->dump();
+  } else {
+    llvm::dbgs() << "no ConcreteExistentialInfo\n";
+  }
+}
diff --git a/lib/SILOptimizer/Utils/InstOptUtils.cpp b/lib/SILOptimizer/Utils/InstOptUtils.cpp
index 312c15d..19ce863 100644
--- a/lib/SILOptimizer/Utils/InstOptUtils.cpp
+++ b/lib/SILOptimizer/Utils/InstOptUtils.cpp
@@ -48,6 +48,27 @@
     llvm::cl::desc(
       "Keep calls to swift_willThrow, even if the throw is optimized away"));
 
+// Defined here to avoid repeatedly paying the price of template instantiation.
+const std::function<void(SILInstruction *)>
+    InstModCallbacks::defaultDeleteInst
+        = [](SILInstruction *inst) {
+          inst->eraseFromParent();
+        };
+const std::function<void(SILInstruction *)>
+    InstModCallbacks::defaultCreatedNewInst
+        = [](SILInstruction *) {};
+const std::function<void(SILValue, SILValue)>
+    InstModCallbacks::defaultReplaceValueUsesWith
+        = [](SILValue oldValue, SILValue newValue) {
+          oldValue->replaceAllUsesWith(newValue);
+        };
+const std::function<void(SingleValueInstruction *, SILValue)>
+    InstModCallbacks::defaultEraseAndRAUWSingleValueInst
+        = [](SingleValueInstruction *i, SILValue newValue) {
+          i->replaceAllUsesWith(newValue);
+          i->eraseFromParent();
+        };
+
 /// Creates an increment on \p Ptr before insertion point \p InsertPt that
 /// creates a strong_retain if \p Ptr has reference semantics itself or a
 /// retain_value if \p Ptr is a non-trivial value without reference-semantics.
diff --git a/lib/Sema/BuilderTransform.cpp b/lib/Sema/BuilderTransform.cpp
index c4a1dd0..4ae60b1 100644
--- a/lib/Sema/BuilderTransform.cpp
+++ b/lib/Sema/BuilderTransform.cpp
@@ -145,32 +145,8 @@
       return known->second;
     }
 
-    bool found = false;
-    SmallVector<ValueDecl *, 4> foundDecls;
-    dc->lookupQualified(
-        builderType, DeclNameRef(fnName),
-        NL_QualifiedDefault | NL_ProtocolMembers, foundDecls);
-    for (auto decl : foundDecls) {
-      if (auto func = dyn_cast<FuncDecl>(decl)) {
-        // Function must be static.
-        if (!func->isStatic())
-          continue;
-
-        // Function must have the right argument labels, if provided.
-        if (!argLabels.empty()) {
-          auto funcLabels = func->getName().getArgumentNames();
-          if (argLabels.size() > funcLabels.size() ||
-              funcLabels.slice(0, argLabels.size()) != argLabels)
-            continue;
-        }
-
-        // Okay, it's a good-enough match.
-        found = true;
-        break;
-      }
-    }
-
-    return supportedOps[fnName] = found;
+    return supportedOps[fnName] = TypeChecker::typeSupportsBuilderOp(
+               builderType, dc, fnName, argLabels);
   }
 
   /// Build an implicit variable in this context.
@@ -1655,6 +1631,13 @@
   assert(builder && "Bad function builder type");
   assert(builder->getAttrs().hasAttribute<FunctionBuilderAttr>());
 
+  if (InvalidFunctionBuilderBodies.count(fn)) {
+    (void)recordFix(
+        IgnoreInvalidFunctionBuilderBody::duringConstraintGeneration(
+            *this, getConstraintLocator(fn.getBody())));
+    return getTypeMatchSuccess();
+  }
+
   // Pre-check the body: pre-check any expressions in it and look
   // for return statements.
   auto request =
@@ -1669,7 +1652,7 @@
     if (!shouldAttemptFixes())
       return getTypeMatchFailure(locator);
 
-    if (recordFix(IgnoreInvalidFunctionBuilderBody::create(
+    if (recordFix(IgnoreInvalidFunctionBuilderBody::duringPreCheck(
             *this, getConstraintLocator(fn.getBody()))))
       return getTypeMatchFailure(locator);
 
@@ -1711,9 +1694,25 @@
   BuilderClosureVisitor visitor(getASTContext(), this, dc, builderType,
                                 bodyResultType);
 
-  auto applied = visitor.apply(fn.getBody());
-  if (!applied)
-    return getTypeMatchFailure(locator);
+  Optional<AppliedBuilderTransform> applied = None;
+  {
+    DiagnosticTransaction transaction(dc->getASTContext().Diags);
+
+    applied = visitor.apply(fn.getBody());
+    if (!applied)
+      return getTypeMatchFailure(locator);
+
+    if (transaction.hasErrors()) {
+      InvalidFunctionBuilderBodies.insert(fn);
+
+      if (recordFix(
+              IgnoreInvalidFunctionBuilderBody::duringConstraintGeneration(
+                  *this, getConstraintLocator(fn.getBody()))))
+        return getTypeMatchFailure(locator);
+
+      return getTypeMatchSuccess();
+    }
+  }
 
   Type transformedType = getType(applied->returnExpr);
   assert(transformedType && "Missing type");
@@ -1800,7 +1799,7 @@
 
       HasError |= ConstraintSystem::preCheckExpression(
           E, DC, /*replaceInvalidRefsWithErrors=*/false);
-      HasError |= transaction.hasDiagnostics();
+      HasError |= transaction.hasErrors();
 
       if (SuppressDiagnostics)
         transaction.abort();
@@ -1851,3 +1850,37 @@
   (void)precheck.run();
   return precheck.getReturnStmts();
 }
+
+bool TypeChecker::typeSupportsBuilderOp(
+    Type builderType, DeclContext *dc, Identifier fnName,
+    ArrayRef<Identifier> argLabels, SmallVectorImpl<ValueDecl *> *allResults) {
+  bool foundMatch = false;
+  SmallVector<ValueDecl *, 4> foundDecls;
+  dc->lookupQualified(
+      builderType, DeclNameRef(fnName),
+      NL_QualifiedDefault | NL_ProtocolMembers, foundDecls);
+  for (auto decl : foundDecls) {
+    if (auto func = dyn_cast<FuncDecl>(decl)) {
+      // Function must be static.
+      if (!func->isStatic())
+        continue;
+
+      // Function must have the right argument labels, if provided.
+      if (!argLabels.empty()) {
+        auto funcLabels = func->getName().getArgumentNames();
+        if (argLabels.size() > funcLabels.size() ||
+            funcLabels.slice(0, argLabels.size()) != argLabels)
+          continue;
+      }
+
+      foundMatch = true;
+      break;
+    }
+  }
+
+  if (allResults)
+    allResults->append(foundDecls.begin(), foundDecls.end());
+
+  return foundMatch;
+}
+
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 762a493..97dd019 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -3790,17 +3790,14 @@
       };
 
       // There's nothing special to do if the operand isn't optional
-      // and we don't need any bridging.
-      if (srcOptionals.empty()) {
+      // (or is insufficiently optional) and we don't need any bridging.
+      if (srcOptionals.empty()
+          || (srcOptionals.size() < destOptionals.size() - destExtraOptionals)) {
         Expr *result = buildInnerOperation(subExpr, finalResultType);
         if (!result) return nullptr;
         return addFinalOptionalInjections(result);
       }
 
-      // The result type (without the final optional) is a subtype of
-      // the operand type, so it will never have a higher depth.
-      assert(destOptionals.size() - destExtraOptionals <= srcOptionals.size());
-
       // The outermost N levels of optionals on the operand must all
       // be present or the cast fails.  The innermost M levels of
       // optionals on the operand are reflected in the requested
@@ -5572,7 +5569,7 @@
     SmallVector<LocatorPathElt, 4> path;
     auto anchor = locator.getLocatorParts(path);
     if (!path.empty() && path.back().is<LocatorPathElt::ApplyArgument>() &&
-        (anchor.isExpr(ExprKind::Call) || anchor.isExpr(ExprKind::Subscript))) {
+        !anchor.isExpr(ExprKind::UnresolvedDot)) {
       auto locatorPtr = cs.getConstraintLocator(locator);
       assert(solution.trailingClosureMatchingChoices.count(locatorPtr) == 1);
       trailingClosureMatching = solution.trailingClosureMatchingChoices.find(
@@ -8412,6 +8409,15 @@
   return ProtocolConformanceRef::forInvalid();
 }
 
+bool Solution::hasType(ASTNode node) const {
+  auto result = nodeTypes.find(node);
+  if (result != nodeTypes.end())
+    return true;
+
+  auto &cs = getConstraintSystem();
+  return cs.hasType(node);
+}
+
 Type Solution::getType(ASTNode node) const {
   auto result = nodeTypes.find(node);
   if (result != nodeTypes.end())
diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp
index 5f324d7..7db71f6 100644
--- a/lib/Sema/CSBindings.cpp
+++ b/lib/Sema/CSBindings.cpp
@@ -360,6 +360,14 @@
     if (locator->isLastElement<LocatorPathElt::MemberRefBase>())
       PotentiallyIncomplete = true;
 
+    // Delay resolution of the code completion expression until
+    // the very end to give it a chance to be bound to some
+    // contextual type even if it's a hole.
+    if (locator->directlyAt<CodeCompletionExpr>()) {
+      FullyBound = true;
+      PotentiallyIncomplete = true;
+    }
+
     addPotentialBinding(PotentialBinding::forHole(TypeVar, locator));
   }
 
@@ -768,6 +776,24 @@
       return None;
   }
 
+  // If subtyping is allowed and this is a result of an implicit member chain,
+  // let's delay binding it to an optional until its object type resolved too or
+  // it has been determined that there is no possibility to resolve it. Otherwise
+  // we might end up missing solutions since it's allowed to implicitly unwrap
+  // base type of the chain but it can't be done early - type variable
+  // representing chain's result type has a different l-valueness comparing
+  // to generic parameter of the optional.
+  if (kind == AllowedBindingKind::Subtypes) {
+    auto *locator = typeVar->getImpl().getLocator();
+    if (locator &&
+        locator->isLastElement<LocatorPathElt::UnresolvedMemberChainResult>()) {
+      auto objectType = type->getOptionalObjectType();
+      if (objectType && objectType->isTypeVariableOrMember()) {
+        result.PotentiallyIncomplete = true;
+      }
+    }
+  }
+
   if (type->is<InOutType>() && !typeVar->getImpl().canBindToInOut())
     type = LValueType::get(type->getInOutObjectType());
   if (type->is<LValueType>() && !typeVar->getImpl().canBindToLValue())
diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp
index 6562cc3..fe04b9a 100644
--- a/lib/Sema/CSDiagnostics.cpp
+++ b/lib/Sema/CSDiagnostics.cpp
@@ -165,7 +165,7 @@
 bool FailureDiagnostic::conformsToKnownProtocol(
     Type type, KnownProtocolKind protocol) const {
   auto &cs = getConstraintSystem();
-  return constraints::conformsToKnownProtocol(cs, type, protocol);
+  return constraints::conformsToKnownProtocol(cs.DC, type, protocol);
 }
 
 Type RequirementFailure::getOwnerType() const {
@@ -643,7 +643,7 @@
 
 void GenericArgumentsMismatchFailure::emitNoteForMismatch(int position) {
   auto *locator = getLocator();
-  // Since there could be implicit conversions assoicated with argument
+  // Since there could be implicit conversions associated with argument
   // to parameter conversions, let's use parameter type as a source of
   // generic parameter information.
   auto paramSourceTy =
@@ -1047,6 +1047,8 @@
     if (componentPathElt->getIndex() == 0) {
       if (auto rootType = keyPathExpr->getRootType()) {
         return rootType->getSourceRange();
+      } else {
+        return keyPathExpr->getComponents().front().getLoc();
       }
     } else {
       auto componentIdx = componentPathElt->getIndex() - 1;
@@ -3169,7 +3171,7 @@
 }
 
 bool ExtraneousPropertyWrapperUnwrapFailure::diagnoseAsError() {
-  auto newPrefix = usingStorageWrapper() ? "$" : "_";
+  auto newPrefix = usingProjection() ? "$" : "_";
 
   if (auto *member = getReferencedMember()) {
     emitDiagnostic(diag::incorrect_property_wrapper_reference_member,
diff --git a/lib/Sema/CSDiagnostics.h b/lib/Sema/CSDiagnostics.h
index 956c917..980a8a5 100644
--- a/lib/Sema/CSDiagnostics.h
+++ b/lib/Sema/CSDiagnostics.h
@@ -974,20 +974,20 @@
 
 class PropertyWrapperReferenceFailure : public ContextualFailure {
   VarDecl *Property;
-  bool UsingStorageWrapper;
+  bool UsingProjection;
 
 public:
   PropertyWrapperReferenceFailure(const Solution &solution, VarDecl *property,
-                                  bool usingStorageWrapper, Type base,
+                                  bool usingProjection, Type base,
                                   Type wrapper, ConstraintLocator *locator)
       : ContextualFailure(solution, base, wrapper, locator), Property(property),
-        UsingStorageWrapper(usingStorageWrapper) {}
+        UsingProjection(usingProjection) {}
 
   VarDecl *getProperty() const { return Property; }
 
   Identifier getPropertyName() const { return Property->getName(); }
 
-  bool usingStorageWrapper() const { return UsingStorageWrapper; }
+  bool usingProjection() const { return UsingProjection; }
 
   ValueDecl *getReferencedMember() const {
     auto *locator = getLocator();
diff --git a/lib/Sema/CSFix.cpp b/lib/Sema/CSFix.cpp
index 80cc9fc..9808f8d 100644
--- a/lib/Sema/CSFix.cpp
+++ b/lib/Sema/CSFix.cpp
@@ -534,22 +534,22 @@
 
 bool UsePropertyWrapper::diagnose(const Solution &solution, bool asNote) const {
   ExtraneousPropertyWrapperUnwrapFailure failure(
-      solution, Wrapped, UsingStorageWrapper, Base, Wrapper, getLocator());
+      solution, Wrapped, UsingProjection, Base, Wrapper, getLocator());
   return failure.diagnose(asNote);
 }
 
 UsePropertyWrapper *UsePropertyWrapper::create(ConstraintSystem &cs,
                                                VarDecl *wrapped,
-                                               bool usingStorageWrapper,
+                                               bool usingProjection,
                                                Type base, Type wrapper,
                                                ConstraintLocator *locator) {
   return new (cs.getAllocator()) UsePropertyWrapper(
-      cs, wrapped, usingStorageWrapper, base, wrapper, locator);
+      cs, wrapped, usingProjection, base, wrapper, locator);
 }
 
 bool UseWrappedValue::diagnose(const Solution &solution, bool asNote) const {
   MissingPropertyWrapperUnwrapFailure failure(solution, PropertyWrapper,
-                                              usingStorageWrapper(), Base,
+                                              usingProjection(), Base,
                                               Wrapper, getLocator());
   return failure.diagnose(asNote);
 }
@@ -1554,6 +1554,14 @@
 
 bool IgnoreInvalidFunctionBuilderBody::diagnose(const Solution &solution,
                                                 bool asNote) const {
+  switch (Phase) {
+  // Handled below
+  case ErrorInPhase::PreCheck:
+    break;
+  case ErrorInPhase::ConstraintGeneration:
+    return true; // Already diagnosed by `matchFunctionBuilder`.
+  }
+
   auto *S = getAnchor().get<Stmt *>();
 
   class PreCheckWalker : public ASTWalker {
@@ -1580,7 +1588,7 @@
     }
 
     bool diagnosed() const {
-      return Transaction.hasDiagnostics();
+      return Transaction.hasErrors();
     }
   };
 
@@ -1590,8 +1598,8 @@
   return walker.diagnosed();
 }
 
-IgnoreInvalidFunctionBuilderBody *
-IgnoreInvalidFunctionBuilderBody::create(ConstraintSystem &cs,
-                                         ConstraintLocator *locator) {
-  return new (cs.getAllocator()) IgnoreInvalidFunctionBuilderBody(cs, locator);
+IgnoreInvalidFunctionBuilderBody *IgnoreInvalidFunctionBuilderBody::create(
+    ConstraintSystem &cs, ErrorInPhase phase, ConstraintLocator *locator) {
+  return new (cs.getAllocator())
+      IgnoreInvalidFunctionBuilderBody(cs, phase, locator);
 }
diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h
index 7bcaf50..acf8123 100644
--- a/lib/Sema/CSFix.h
+++ b/lib/Sema/CSFix.h
@@ -799,15 +799,15 @@
 
 class UsePropertyWrapper final : public ConstraintFix {
   VarDecl *Wrapped;
-  bool UsingStorageWrapper;
+  bool UsingProjection;
   Type Base;
   Type Wrapper;
 
   UsePropertyWrapper(ConstraintSystem &cs, VarDecl *wrapped,
-                     bool usingStorageWrapper, Type base, Type wrapper,
+                     bool usingProjection, Type base, Type wrapper,
                      ConstraintLocator *locator)
       : ConstraintFix(cs, FixKind::UsePropertyWrapper, locator),
-        Wrapped(wrapped), UsingStorageWrapper(usingStorageWrapper), Base(base),
+        Wrapped(wrapped), UsingProjection(usingProjection), Base(base),
         Wrapper(wrapper) {}
 
 public:
@@ -822,7 +822,7 @@
   }
 
   static UsePropertyWrapper *create(ConstraintSystem &cs, VarDecl *wrapped,
-                                    bool usingStorageWrapper, Type base,
+                                    bool usingProjection, Type base,
                                     Type wrapper, ConstraintLocator *locator);
 };
 
@@ -836,7 +836,7 @@
       : ConstraintFix(cs, FixKind::UseWrappedValue, locator),
         PropertyWrapper(propertyWrapper), Base(base), Wrapper(wrapper) {}
 
-  bool usingStorageWrapper() const {
+  bool usingProjection() const {
     auto nameStr = PropertyWrapper->getName().str();
     return !nameStr.startswith("_");
   }
@@ -1984,9 +1984,17 @@
 };
 
 class IgnoreInvalidFunctionBuilderBody final : public ConstraintFix {
-  IgnoreInvalidFunctionBuilderBody(ConstraintSystem &cs,
+  enum class ErrorInPhase {
+    PreCheck,
+    ConstraintGeneration,
+  };
+
+  ErrorInPhase Phase;
+
+  IgnoreInvalidFunctionBuilderBody(ConstraintSystem &cs, ErrorInPhase phase,
                                    ConstraintLocator *locator)
-      : ConstraintFix(cs, FixKind::IgnoreInvalidFunctionBuilderBody, locator) {}
+      : ConstraintFix(cs, FixKind::IgnoreInvalidFunctionBuilderBody, locator),
+        Phase(phase) {}
 
 public:
   std::string getName() const override {
@@ -1999,8 +2007,19 @@
     return diagnose(*commonFixes.front().first);
   }
 
-  static IgnoreInvalidFunctionBuilderBody *create(ConstraintSystem &cs,
-                                                  ConstraintLocator *locator);
+  static IgnoreInvalidFunctionBuilderBody *
+  duringPreCheck(ConstraintSystem &cs, ConstraintLocator *locator) {
+    return create(cs, ErrorInPhase::PreCheck, locator);
+  }
+
+  static IgnoreInvalidFunctionBuilderBody *
+  duringConstraintGeneration(ConstraintSystem &cs, ConstraintLocator *locator) {
+    return create(cs, ErrorInPhase::ConstraintGeneration, locator);
+  }
+
+private:
+  static IgnoreInvalidFunctionBuilderBody *
+  create(ConstraintSystem &cs, ErrorInPhase phase, ConstraintLocator *locator);
 };
 
 } // end namespace constraints
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 496052c..342891f 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1009,23 +1009,9 @@
     virtual Type visitCodeCompletionExpr(CodeCompletionExpr *E) {
       CS.Options |= ConstraintSystemFlags::SuppressDiagnostics;
       auto locator = CS.getConstraintLocator(E);
-      auto ty = CS.createTypeVariable(locator,
-                                      TVO_CanBindToLValue |
-                                      TVO_CanBindToNoEscape);
-
-      // Defaults to the type of the base expression if we have a base
-      // expression.
-      // FIXME: This is just to keep the old behavior where `foo(base.<HERE>)`
-      // the argument is type checked to the type of the 'base'. Ideally, code
-      // completion expression should be defauled to 'UnresolvedType'
-      // regardless of the existence of the base expression. But the constraint
-      // system is simply not ready for that.
-      if (auto base = E->getBase()) {
-        CS.addConstraint(ConstraintKind::Defaultable, ty, CS.getType(base),
-                         locator);
-      }
-      
-      return ty;
+      return CS.createTypeVariable(locator, TVO_CanBindToLValue |
+                                                TVO_CanBindToNoEscape |
+                                                TVO_CanBindToHole);
     }
 
     Type visitNilLiteralExpr(NilLiteralExpr *expr) {
@@ -1328,17 +1314,11 @@
 
     Type
     resolveTypeReferenceInExpression(TypeRepr *repr, TypeResolverContext resCtx,
-                                     OpenUnboundGenericTypeFn unboundTyOpener) {
-      if (!unboundTyOpener) {
-        unboundTyOpener = [](auto unboundTy) {
-          // FIXME: Don't let unbound generic types escape type resolution.
-          // For now, just return the unbound generic type.
-          return unboundTy;
-        };
-      }
-      const auto result =
-          TypeResolution::forContextual(CS.DC, resCtx, unboundTyOpener)
-              .resolveType(repr);
+                                     const ConstraintLocatorBuilder &locator) {
+      // Introduce type variables for unbound generics.
+      const auto opener = OpenUnboundGenericType(CS, locator);
+      const auto result = TypeResolution::forContextual(CS.DC, resCtx, opener)
+                              .resolveType(repr);
       if (result->hasError()) {
         return Type();
       }
@@ -1364,8 +1344,7 @@
         auto *repr = E->getTypeRepr();
         assert(repr && "Explicit node has no type repr!");
         type = resolveTypeReferenceInExpression(
-            repr, TypeResolverContext::InExpression,
-            OpenUnboundGenericType(CS, locator));
+            repr, TypeResolverContext::InExpression, locator);
       }
 
       if (!type || type->hasError()) return Type();
@@ -1774,11 +1753,11 @@
 
         auto type = contextualType->lookThroughAllOptionalTypes();
         if (conformsToKnownProtocol(
-                CS, type, KnownProtocolKind::ExpressibleByArrayLiteral))
+                CS.DC, type, KnownProtocolKind::ExpressibleByArrayLiteral))
           return false;
 
         return conformsToKnownProtocol(
-            CS, type, KnownProtocolKind::ExpressibleByDictionaryLiteral);
+            CS.DC, type, KnownProtocolKind::ExpressibleByDictionaryLiteral);
       };
 
       if (isDictionaryContextualType(contextualType)) {
@@ -2052,7 +2031,7 @@
         }
       }
 
-      auto extInfo = closureEffects(closure);
+      auto extInfo = CS.closureEffects(closure);
 
       // Closure expressions always have function type. In cases where a
       // parameter or return type is omitted, a fresh type variable is used to
@@ -2067,10 +2046,8 @@
           const auto resolvedTy = resolveTypeReferenceInExpression(
               closure->getExplicitResultTypeRepr(),
               TypeResolverContext::InExpression,
-              // Introduce type variables for unbound generics.
-              OpenUnboundGenericType(
-                  CS, CS.getConstraintLocator(
-                          closure, ConstraintLocator::ClosureResult)));
+              CS.getConstraintLocator(closure,
+                                      ConstraintLocator::ClosureResult));
           if (resolvedTy)
             return resolvedTy;
         }
@@ -2354,9 +2331,7 @@
 
         const Type castType = resolveTypeReferenceInExpression(
             isPattern->getCastTypeRepr(), TypeResolverContext::InExpression,
-            OpenUnboundGenericType(CS,
-                                   locator.withPathElement(
-                                       LocatorPathElt::PatternMatch(pattern))));
+            locator.withPathElement(LocatorPathElt::PatternMatch(pattern)));
         if (!castType) return Type();
 
         auto *subPattern = isPattern->getSubPattern();
@@ -2407,32 +2382,31 @@
         FunctionRefKind functionRefKind = FunctionRefKind::Compound;
         if (enumPattern->getParentType() || enumPattern->getParentTypeRepr()) {
           // Resolve the parent type.
-          Type parentType = [&]() -> Type {
-            if (auto preTy = enumPattern->getParentType()) {
-              return preTy;
+          const auto parentType = [&] {
+            auto *const patternMatchLoc = CS.getConstraintLocator(
+                locator, {LocatorPathElt::PatternMatch(pattern),
+                          ConstraintLocator::ParentType});
+
+            // FIXME: Sometimes the parent type is realized eagerly in
+            // ResolvePattern::visitUnresolvedDotExpr, so we have to open it
+            // ex post facto. Remove this once we learn how to resolve patterns
+            // while generating constraints to keep the opening of generic types
+            // contained within the type resolver.
+            if (const auto preresolvedTy = enumPattern->getParentType()) {
+              const auto openedTy =
+                  CS.openUnboundGenericTypes(preresolvedTy, patternMatchLoc);
+              assert(openedTy);
+              return openedTy;
             }
+
             return resolveTypeReferenceInExpression(
                 enumPattern->getParentTypeRepr(),
-                TypeResolverContext::InExpression, [](auto unboundTy) {
-                  // FIXME: We ought to pass an OpenUnboundGenericType object
-                  // rather than calling CS.openUnboundGenericType below, but
-                  // sometimes the parent type is resolved eagerly in
-                  // ResolvePattern::visitUnresolvedDotExpr, letting unbound
-                  // generics escape.
-                  return unboundTy;
-                });
+                TypeResolverContext::InExpression, patternMatchLoc);
           }();
 
           if (!parentType)
             return Type();
 
-          parentType = CS.openUnboundGenericTypes(
-              parentType, CS.getConstraintLocator(
-                              locator, {LocatorPathElt::PatternMatch(pattern),
-                                        ConstraintLocator::ParentType}));
-
-          assert(parentType);
-
           // Perform member lookup into the parent's metatype.
           Type parentMetaType = MetatypeType::get(parentType);
           CS.addValueMemberConstraint(
@@ -2513,214 +2487,6 @@
       return CS.getType(expr->getClosureBody());
     }
 
-    /// Walk a closure AST to determine its effects.
-    ///
-    /// \returns a function's extended info describing the effects, as
-    /// determined syntactically.
-    FunctionType::ExtInfo closureEffects(ClosureExpr *expr) {
-      // A walker that looks for 'try' and 'throw' expressions
-      // that aren't nested within closures, nested declarations,
-      // or exhaustive catches.
-      class FindInnerThrows : public ASTWalker {
-        ConstraintSystem &CS;
-        DeclContext *DC;
-        bool FoundThrow = false;
-        
-        std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
-          // If we've found a 'try', record it and terminate the traversal.
-          if (isa<TryExpr>(expr)) {
-            FoundThrow = true;
-            return { false, nullptr };
-          }
-
-          // Don't walk into a 'try!' or 'try?'.
-          if (isa<ForceTryExpr>(expr) || isa<OptionalTryExpr>(expr)) {
-            return { false, expr };
-          }
-          
-          // Do not recurse into other closures.
-          if (isa<ClosureExpr>(expr))
-            return { false, expr };
-          
-          return { true, expr };
-        }
-        
-        bool walkToDeclPre(Decl *decl) override {
-          // Do not walk into function or type declarations.
-          if (!isa<PatternBindingDecl>(decl))
-            return false;
-          
-          return true;
-        }
-
-        bool isSyntacticallyExhaustive(DoCatchStmt *stmt) {
-          for (auto catchClause : stmt->getCatches()) {
-            for (auto &LabelItem : catchClause->getMutableCaseLabelItems()) {
-              if (isSyntacticallyExhaustive(catchClause->getStartLoc(),
-                                            LabelItem))
-                return true;
-            }
-          }
-
-          return false;
-        }
-
-        bool isSyntacticallyExhaustive(SourceLoc CatchLoc,
-                                       CaseLabelItem &LabelItem) {
-          // If it's obviously non-exhaustive, great.
-          if (LabelItem.getGuardExpr())
-            return false;
-
-          // If we can show that it's exhaustive without full
-          // type-checking, great.
-          if (LabelItem.isSyntacticallyExhaustive())
-            return true;
-
-          // Okay, resolve the pattern.
-          Pattern *pattern = LabelItem.getPattern();
-          if (!LabelItem.isPatternResolved()) {
-            pattern = TypeChecker::resolvePattern(pattern, CS.DC,
-                                           /*isStmtCondition*/false);
-            if (!pattern) return false;
-
-            // Save that aside while we explore the type.
-            LabelItem.setPattern(pattern, /*resolved=*/true);
-          }
-
-          // Require the pattern to have a particular shape: a number
-          // of is-patterns applied to an irrefutable pattern.
-          pattern = pattern->getSemanticsProvidingPattern();
-          while (auto isp = dyn_cast<IsPattern>(pattern)) {
-            const Type castType = TypeResolution::forContextual(
-                                      CS.DC, TypeResolverContext::InExpression,
-                                      /*unboundTyOpener*/ nullptr)
-                                      .resolveType(isp->getCastTypeRepr());
-            if (castType->hasError()) {
-              return false;
-            }
-
-            if (!isp->hasSubPattern()) {
-              pattern = nullptr;
-              break;
-            } else {
-              pattern = isp->getSubPattern()->getSemanticsProvidingPattern();
-            }
-          }
-          if (pattern && pattern->isRefutablePattern()) {
-            return false;
-          }
-
-          // Okay, now it should be safe to coerce the pattern.
-          // Pull the top-level pattern back out.
-          pattern = LabelItem.getPattern();
-          Type exnType = CS.getASTContext().getErrorDecl()->getDeclaredInterfaceType();
-
-          if (!exnType)
-            return false;
-          auto contextualPattern =
-              ContextualPattern::forRawPattern(pattern, DC);
-          pattern = TypeChecker::coercePatternToType(
-            contextualPattern, exnType, TypeResolverContext::InExpression);
-          if (!pattern)
-            return false;
-
-          LabelItem.setPattern(pattern, /*resolved=*/true);
-          return LabelItem.isSyntacticallyExhaustive();
-        }
-
-        std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
-          // If we've found a 'throw', record it and terminate the traversal.
-          if (isa<ThrowStmt>(stmt)) {
-            FoundThrow = true;
-            return { false, nullptr };
-          }
-
-          // Handle do/catch differently.
-          if (auto doCatch = dyn_cast<DoCatchStmt>(stmt)) {
-            // Only walk into the 'do' clause of a do/catch statement
-            // if the catch isn't syntactically exhaustive.
-            if (!isSyntacticallyExhaustive(doCatch)) {
-              if (!doCatch->getBody()->walk(*this))
-                return { false, nullptr };
-            }
-
-            // Walk into all the catch clauses.
-            for (auto catchClause : doCatch->getCatches()) {
-              if (!catchClause->walk(*this))
-                return { false, nullptr };
-            }
-
-            // We've already walked all the children we care about.
-            return { false, stmt };
-          }
-          
-          return { true, stmt };
-        }
-        
-      public:
-        FindInnerThrows(ConstraintSystem &cs, DeclContext *dc)
-            : CS(cs), DC(dc) {}
-
-        bool foundThrow() { return FoundThrow; }
-      };
-
-      // A walker that looks for 'async' and 'await' expressions
-      // that aren't nested within closures or nested declarations.
-      class FindInnerAsync : public ASTWalker {
-        bool FoundAsync = false;
-
-        std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
-          // If we've found an 'await', record it and terminate the traversal.
-          if (isa<AwaitExpr>(expr)) {
-            FoundAsync = true;
-            return { false, nullptr };
-          }
-
-          // Do not recurse into other closures.
-          if (isa<ClosureExpr>(expr))
-            return { false, expr };
-
-          return { true, expr };
-        }
-
-        bool walkToDeclPre(Decl *decl) override {
-          // Do not walk into function or type declarations.
-          if (!isa<PatternBindingDecl>(decl))
-            return false;
-
-          return true;
-        }
-
-      public:
-        bool foundAsync() { return FoundAsync; }
-      };
-
-      // If either 'throws' or 'async' was explicitly specified, use that
-      // set of effects.
-      bool throws = expr->getThrowsLoc().isValid();
-      bool async = expr->getAsyncLoc().isValid();
-      if (throws || async) {
-        return ASTExtInfoBuilder()
-          .withThrows(throws)
-          .withAsync(async)
-          .build();
-      }
-
-      // Scan the body to determine the effects.
-      auto body = expr->getBody();
-      if (!body)
-        return FunctionType::ExtInfo();
-
-      auto throwFinder = FindInnerThrows(CS, expr);
-      body->walk(throwFinder);
-      auto asyncFinder = FindInnerAsync();
-      body->walk(asyncFinder);
-      return ASTExtInfoBuilder()
-        .withThrows(throwFinder.foundThrow())
-        .withAsync(asyncFinder.foundAsync())
-        .build();
-    }
-
     Type visitClosureExpr(ClosureExpr *closure) {
       auto *locator = CS.getConstraintLocator(closure);
       auto closureType = CS.createTypeVariable(locator, TVO_CanBindToNoEscape);
@@ -2976,8 +2742,7 @@
       // Validate the resulting type.
       const auto toType = resolveTypeReferenceInExpression(
           repr, TypeResolverContext::ExplicitCastExpr,
-          // Introduce type variables for unbound generics.
-          OpenUnboundGenericType(CS, CS.getConstraintLocator(expr)));
+          CS.getConstraintLocator(expr));
       if (!toType)
         return nullptr;
 
@@ -3003,8 +2768,7 @@
       auto *const repr = expr->getCastTypeRepr();
       const auto toType = resolveTypeReferenceInExpression(
           repr, TypeResolverContext::ExplicitCastExpr,
-          // Introduce type variables for unbound generics.
-          OpenUnboundGenericType(CS, CS.getConstraintLocator(expr)));
+          CS.getConstraintLocator(expr));
       if (!toType)
         return nullptr;
 
@@ -3036,8 +2800,7 @@
       auto *const repr = expr->getCastTypeRepr();
       const auto toType = resolveTypeReferenceInExpression(
           repr, TypeResolverContext::ExplicitCastExpr,
-          // Introduce type variables for unbound generics.
-          OpenUnboundGenericType(CS, CS.getConstraintLocator(expr)));
+          CS.getConstraintLocator(expr));
       if (!toType)
         return nullptr;
 
@@ -3064,8 +2827,7 @@
       auto &ctx = CS.getASTContext();
       const auto toType = resolveTypeReferenceInExpression(
           expr->getCastTypeRepr(), TypeResolverContext::ExplicitCastExpr,
-          // Introduce type variables for unbound generics.
-          OpenUnboundGenericType(CS, CS.getConstraintLocator(expr)));
+          CS.getConstraintLocator(expr));
       if (!toType)
         return nullptr;
 
@@ -3273,9 +3035,9 @@
     Type visitEditorPlaceholderExpr(EditorPlaceholderExpr *E) {
       if (auto *placeholderRepr = E->getPlaceholderTypeRepr()) {
         // Just resolve the referenced type.
-        // FIXME: The type reference needs to be opened into context.
         return resolveTypeReferenceInExpression(
-            placeholderRepr, TypeResolverContext::InExpression, nullptr);
+            placeholderRepr, TypeResolverContext::InExpression,
+            CS.getConstraintLocator(E));
       }
 
       auto locator = CS.getConstraintLocator(E);
@@ -3346,9 +3108,7 @@
       // If a root type was explicitly given, then resolve it now.
       if (auto rootRepr = E->getRootType()) {
         const auto rootObjectTy = resolveTypeReferenceInExpression(
-            rootRepr, TypeResolverContext::InExpression,
-            // Introduce type variables for unbound generics.
-            OpenUnboundGenericType(CS, locator));
+            rootRepr, TypeResolverContext::InExpression, locator);
         if (!rootObjectTy || rootObjectTy->hasError())
           return Type();
 
diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp
index 0d45d78..cc57a75 100644
--- a/lib/Sema/CSRanking.cpp
+++ b/lib/Sema/CSRanking.cpp
@@ -48,6 +48,10 @@
       llvm::errs() << "use of an unavailable declaration";
       break;
 
+    case SK_AsyncSyncMismatch:
+      llvm::errs() << "async/synchronous mismatch";
+      break;
+
     case SK_ForwardTrailingClosure:
       llvm::errs() << "forward scan when matching a trailing closure";
       break;
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 1ea9cf0..caae9b1 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -2897,7 +2897,7 @@
     return nullptr;
 
   enum class Fix : uint8_t {
-    StorageWrapper,
+    ProjectedValue,
     PropertyWrapper,
     WrappedValue,
   };
@@ -2916,9 +2916,9 @@
       return nullptr;
 
     switch (fix) {
-    case Fix::StorageWrapper:
+    case Fix::ProjectedValue:
     case Fix::PropertyWrapper:
-      return UsePropertyWrapper::create(cs, decl, fix == Fix::StorageWrapper,
+      return UsePropertyWrapper::create(cs, decl, fix == Fix::ProjectedValue,
                                         baseTy, toType.getValueOr(type),
                                         locator);
 
@@ -2929,10 +2929,10 @@
     llvm_unreachable("Unhandled Fix type in switch");
   };
 
-  if (auto storageWrapper =
-          cs.getStorageWrapperInformation(*resolvedOverload)) {
-    if (auto *fix = applyFix(Fix::StorageWrapper, storageWrapper->first,
-                             storageWrapper->second))
+  if (auto projection =
+          cs.getPropertyWrapperProjectionInfo(*resolvedOverload)) {
+    if (auto *fix = applyFix(Fix::ProjectedValue, projection->first,
+                             projection->second))
       return fix;
   }
 
@@ -3829,8 +3829,11 @@
     // If this is an implicit 'something-to-pointer' conversion
     // it's going to be diagnosed by specialized fix which deals
     // with generic argument mismatches.
-    if (matchKind == ConstraintKind::BindToPointerType)
-      break;
+    if (matchKind == ConstraintKind::BindToPointerType) {
+      auto *member = rhs->getAs<DependentMemberType>();
+      if (!(member && member->getBase()->hasHole()))
+        break;
+    }
 
     // If this is a ~= operator implicitly generated by pattern matching
     // let's not try to fix right-hand side of the operator because it's
@@ -6963,40 +6966,6 @@
 
   auto locator = getConstraintLocator(locatorB);
 
-  // If the base type of this member lookup is a "hole" there is no
-  // reason to perform a lookup because it wouldn't return any results.
-  if (shouldAttemptFixes()) {
-    auto markMemberTypeAsPotentialHole = [&](Type memberTy) {
-      if (auto *typeVar = memberTy->getAs<TypeVariableType>())
-        recordPotentialHole(typeVar);
-    };
-
-    // If this is an unresolved member ref e.g. `.foo` and its contextual base
-    // type has been determined to be a "hole", let's mark the resulting member
-    // type as a potential hole and continue solving.
-    if (kind == ConstraintKind::UnresolvedValueMember &&
-        baseObjTy->getMetatypeInstanceType()->isHole()) {
-      auto *fix =
-          SpecifyBaseTypeForContextualMember::create(*this, member, locator);
-      if (recordFix(fix))
-        return SolutionKind::Error;
-
-      markMemberTypeAsPotentialHole(memberTy);
-      return SolutionKind::Solved;
-    } else if ((kind == ConstraintKind::ValueMember ||
-                kind == ConstraintKind::ValueWitness) &&
-               baseObjTy->getMetatypeInstanceType()->isHole()) {
-      // If base type is a "hole" there is no reason to record any
-      // more "member not found" fixes for chained member references.
-      markMemberTypeAsPotentialHole(memberTy);
-      return SolutionKind::Solved;
-    }
-  }
-
-  MemberLookupResult result =
-      performMemberLookup(kind, member, baseTy, functionRefKind, locator,
-                          /*includeInaccessibleMembers*/ shouldAttemptFixes());
-
   auto formUnsolved = [&](bool activate = false) {
     // If requested, generate a constraint.
     if (flags.contains(TMF_GenerateConstraints)) {
@@ -7015,6 +6984,82 @@
     return SolutionKind::Unsolved;
   };
 
+  // If the base type of this member lookup is a "hole" there is no
+  // reason to perform a lookup because it wouldn't return any results.
+  if (shouldAttemptFixes()) {
+    auto markMemberTypeAsPotentialHole = [&](Type memberTy) {
+      if (auto *typeVar = memberTy->getAs<TypeVariableType>())
+        recordPotentialHole(typeVar);
+    };
+
+    // If this is an unresolved member ref e.g. `.foo` and its contextual base
+    // type has been determined to be a "hole", let's mark the resulting member
+    // type as a potential hole and continue solving.
+    if (kind == ConstraintKind::UnresolvedValueMember) {
+      // Let's look through all metatypes to find "underlying" type
+      // of this lookup.
+      Type underlyingType = baseObjTy;
+      while (auto *MT = underlyingType->getAs<AnyMetatypeType>()) {
+        underlyingType = MT->getInstanceType();
+      }
+
+      // Let's delay solving this constraint in diagnostic
+      // mode until it's certain that there is no way to
+      // find out what the base type is.
+      if (underlyingType->isTypeVariableOrMember())
+        return formUnsolved();
+
+      // Let's record a fix only if the hole originates either
+      // at the result of the chain (that could happen since solving
+      // of this constraint is delayed until base could be resolved),
+      // or it is certain that base type can't be bound to any other
+      // type but a hole.
+      auto shouldRecordFixForHole = [&](HoleType *baseType) {
+        auto *originator =
+            baseType->getOriginatorType().dyn_cast<TypeVariableType *>();
+
+        if (!originator)
+          return false;
+
+        auto *originatorLoc = originator->getImpl().getLocator();
+
+        // It could either be a hole associated directly with the base
+        // or a hole which came from result type of the chain.
+        if (originatorLoc->isLastElement<
+                LocatorPathElt::UnresolvedMemberChainResult>()) {
+          auto *UMCR = castToExpr<UnresolvedMemberChainResultExpr>(
+              originatorLoc->getAnchor());
+          return UMCR->getChainBase() == getAsExpr(locator->getAnchor());
+        }
+
+        return originatorLoc == locator;
+      };
+
+      if (auto *hole = underlyingType->getAs<HoleType>()) {
+        if (shouldRecordFixForHole(hole)) {
+          auto *fix = SpecifyBaseTypeForContextualMember::create(*this, member,
+                                                                 locator);
+          if (recordFix(fix))
+            return SolutionKind::Error;
+        }
+
+        markMemberTypeAsPotentialHole(memberTy);
+        return SolutionKind::Solved;
+      }
+    } else if ((kind == ConstraintKind::ValueMember ||
+                kind == ConstraintKind::ValueWitness) &&
+               baseObjTy->getMetatypeInstanceType()->isHole()) {
+      // If base type is a "hole" there is no reason to record any
+      // more "member not found" fixes for chained member references.
+      markMemberTypeAsPotentialHole(memberTy);
+      return SolutionKind::Solved;
+    }
+  }
+
+  MemberLookupResult result =
+      performMemberLookup(kind, member, baseTy, functionRefKind, locator,
+                          /*includeInaccessibleMembers*/ shouldAttemptFixes());
+
   switch (result.OverallResult) {
   case MemberLookupResult::Unsolved:
     return formUnsolved();
@@ -7123,18 +7168,19 @@
                                MemberLookupResult::ErrorAlreadyDiagnosed);
       auto *fix = DefineMemberBasedOnUse::create(*this, baseTy, member,
                                                  alreadyDiagnosed, locator);
-      // Impact is higher if the base is expected to be inferred from context,
-      // because a failure to find a member ultimately means that base type is
-      // not a match in this case.
-      auto impact =
-          locator->findLast<LocatorPathElt::UnresolvedMember>() ? 2 : 1;
 
+      auto instanceTy = baseObjTy->getMetatypeInstanceType();
+
+      auto impact = 2;
       // Impact is higher if the the base type is any function type
       // because function types can't have any members other than self
-      if (baseObjTy->is<AnyFunctionType>()) {
-          impact += 10;
+      if (instanceTy->is<AnyFunctionType>()) {
+        impact += 10;
       }
 
+      if (instanceTy->isAny() || instanceTy->isAnyObject())
+        impact += 5;
+
       if (recordFix(fix, impact))
         return SolutionKind::Error;
 
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 8f0afc7..81c86b5 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -450,11 +450,11 @@
   // Update the "largest" statistics if this system is larger than the
   // previous one.  
   // FIXME: This is not at all thread-safe.
-  if (NumStatesExplored > LargestNumStatesExplored.Value) {
-    LargestSolutionAttemptNumber.Value = SolutionAttempt-1;
+  if (NumStatesExplored > LargestNumStatesExplored.getValue()) {
+    LargestSolutionAttemptNumber = SolutionAttempt-1;
     ++LargestSolutionAttemptNumber;
     #define CS_STATISTIC(Name, Description) \
-      JOIN2(Largest,Name).Value = Name-1; \
+      JOIN2(Largest,Name) = Name-1; \
       ++JOIN2(Largest,Name);
     #include "ConstraintSolverStats.def"
   }
@@ -1406,48 +1406,47 @@
   }
 }
 
-void ConstraintSystem::solveForCodeCompletion(
-    Expr *expr, DeclContext *DC, Type contextualType, ContextualTypePurpose CTP,
-    llvm::function_ref<void(const Solution &)> callback) {
-  // First, pre-check the expression, validating any types that occur in the
-  // expression and folding sequence expressions.
-  if (ConstraintSystem::preCheckExpression(
-          expr, DC, /*replaceInvalidRefsWithErrors=*/true))
-    return;
-
-  ConstraintSystemOptions options;
-  options |= ConstraintSystemFlags::AllowFixes;
-  options |= ConstraintSystemFlags::SuppressDiagnostics;
-
-  ConstraintSystem cs(DC, options);
-
-  if (CTP != ContextualTypePurpose::CTP_Unused)
-    cs.setContextualType(expr, TypeLoc::withoutLoc(contextualType), CTP);
+bool ConstraintSystem::solveForCodeCompletion(
+    SolutionApplicationTarget &target, SmallVectorImpl<Solution> &solutions) {
+  auto *expr = target.getAsExpr();
+  // Tell the constraint system what the contextual type is.
+  setContextualType(expr, target.getExprContextualTypeLoc(),
+                    target.getExprContextualTypePurpose());
 
   // Set up the expression type checker timer.
-  cs.Timer.emplace(expr, cs);
+  Timer.emplace(expr, *this);
 
-  cs.shrink(expr);
+  shrink(expr);
 
-  if (!cs.generateConstraints(expr, DC))
-    return;
+  if (isDebugMode()) {
+    auto &log = llvm::errs();
+    log << "--- Code Completion ---\n";
+  }
 
-  llvm::SmallVector<Solution, 4> solutions;
+  if (generateConstraints(target, FreeTypeVariableBinding::Disallow))
+    return false;
 
   {
-    SolverState state(cs, FreeTypeVariableBinding::Disallow);
+    SolverState state(*this, FreeTypeVariableBinding::Disallow);
 
     // Enable "diagnostic mode" by default, this means that
     // solver would produce "fixed" solutions alongside valid
     // ones, which helps code completion to rank choices.
     state.recordFixes = true;
 
-    cs.solveImpl(solutions);
+    solveImpl(solutions);
   }
 
-  for (const auto &solution : solutions) {
-    callback(solution);
+  if (isDebugMode()) {
+    auto &log = llvm::errs();
+    log << "--- Discovered " << solutions.size() << " solutions ---\n";
+    for (const auto &solution : solutions) {
+      log << "--- Solution ---\n";
+      solution.dump(log);
+    }
   }
+
+  return true;
 }
 
 void ConstraintSystem::collectDisjunctions(
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 5ed7bda..384cad9 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -550,10 +550,11 @@
 
   // If the superclass constructor is @objc but the subclass constructor is
   // not representable in Objective-C, add @nonobjc implicitly.
+  Optional<ForeignAsyncConvention> asyncConvention;
   Optional<ForeignErrorConvention> errorConvention;
   if (superclassCtor->isObjC() &&
       !isRepresentableInObjC(ctor, ObjCReason::MemberOfObjCSubclass,
-                             errorConvention))
+                             asyncConvention, errorConvention))
     ctor->getAttrs().add(new (ctx) NonObjCAttr(/*isImplicit=*/true));
 }
 
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index f27cc50..74dbdd7 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -956,7 +956,7 @@
 }
 
 Optional<std::pair<VarDecl *, Type>>
-ConstraintSystem::getStorageWrapperInformation(
+ConstraintSystem::getPropertyWrapperProjectionInfo(
     SelectedOverload resolvedOverload) {
   return getPropertyWrapperInformationFromOverload(
       resolvedOverload, DC,
@@ -964,12 +964,12 @@
         if (!decl->hasAttachedPropertyWrapper())
           return None;
 
-        auto storageWrapper = decl->getPropertyWrapperStorageWrapper();
-        if (!storageWrapper)
+        auto projectionVar = decl->getPropertyWrapperProjectionVar();
+        if (!projectionVar)
           return None;
 
-        return std::make_pair(storageWrapper,
-                              storageWrapper->getInterfaceType());
+        return std::make_pair(projectionVar,
+                              projectionVar->getInterfaceType());
       });
 }
 
@@ -2151,6 +2151,244 @@
   llvm_unreachable("Unhandled OverloadChoiceKind in switch.");
 }
 
+/// Whether the declaration is considered 'async'.
+static bool isDeclAsync(ValueDecl *value) {
+  if (auto func = dyn_cast<AbstractFunctionDecl>(value))
+    return func->isAsyncContext();
+
+  return false;
+}
+
+/// Walk a closure AST to determine its effects.
+///
+/// \returns a function's extended info describing the effects, as
+/// determined syntactically.
+FunctionType::ExtInfo ConstraintSystem::closureEffects(ClosureExpr *expr) {
+  auto known = closureEffectsCache.find(expr);
+  if (known != closureEffectsCache.end())
+    return known->second;
+
+  // A walker that looks for 'try' and 'throw' expressions
+  // that aren't nested within closures, nested declarations,
+  // or exhaustive catches.
+  class FindInnerThrows : public ASTWalker {
+    ConstraintSystem &CS;
+    DeclContext *DC;
+    bool FoundThrow = false;
+
+    std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
+      // If we've found a 'try', record it and terminate the traversal.
+      if (isa<TryExpr>(expr)) {
+        FoundThrow = true;
+        return { false, nullptr };
+      }
+
+      // Don't walk into a 'try!' or 'try?'.
+      if (isa<ForceTryExpr>(expr) || isa<OptionalTryExpr>(expr)) {
+        return { false, expr };
+      }
+
+      // Do not recurse into other closures.
+      if (isa<ClosureExpr>(expr))
+        return { false, expr };
+
+      return { true, expr };
+    }
+
+    bool walkToDeclPre(Decl *decl) override {
+      // Do not walk into function or type declarations.
+      if (!isa<PatternBindingDecl>(decl))
+        return false;
+
+      return true;
+    }
+
+    bool isSyntacticallyExhaustive(DoCatchStmt *stmt) {
+      for (auto catchClause : stmt->getCatches()) {
+        for (auto &LabelItem : catchClause->getMutableCaseLabelItems()) {
+          if (isSyntacticallyExhaustive(catchClause->getStartLoc(),
+                                        LabelItem))
+            return true;
+        }
+      }
+
+      return false;
+    }
+
+    bool isSyntacticallyExhaustive(SourceLoc CatchLoc,
+                                   CaseLabelItem &LabelItem) {
+      // If it's obviously non-exhaustive, great.
+      if (LabelItem.getGuardExpr())
+        return false;
+
+      // If we can show that it's exhaustive without full
+      // type-checking, great.
+      if (LabelItem.isSyntacticallyExhaustive())
+        return true;
+
+      // Okay, resolve the pattern.
+      Pattern *pattern = LabelItem.getPattern();
+      if (!LabelItem.isPatternResolved()) {
+        pattern = TypeChecker::resolvePattern(pattern, CS.DC,
+                                       /*isStmtCondition*/false);
+        if (!pattern) return false;
+
+        // Save that aside while we explore the type.
+        LabelItem.setPattern(pattern, /*resolved=*/true);
+      }
+
+      // Require the pattern to have a particular shape: a number
+      // of is-patterns applied to an irrefutable pattern.
+      pattern = pattern->getSemanticsProvidingPattern();
+      while (auto isp = dyn_cast<IsPattern>(pattern)) {
+        Type castType;
+        if (auto castTypeRepr = isp->getCastTypeRepr()) {
+          castType = TypeResolution::forContextual(
+                         CS.DC, TypeResolverContext::InExpression,
+                         /*unboundTyOpener*/ nullptr)
+                         .resolveType(castTypeRepr);
+        } else {
+          castType = isp->getCastType();
+        }
+
+        if (castType->hasError()) {
+          return false;
+        }
+
+        if (!isp->hasSubPattern()) {
+          pattern = nullptr;
+          break;
+        } else {
+          pattern = isp->getSubPattern()->getSemanticsProvidingPattern();
+        }
+      }
+      if (pattern && pattern->isRefutablePattern()) {
+        return false;
+      }
+
+      // Okay, now it should be safe to coerce the pattern.
+      // Pull the top-level pattern back out.
+      pattern = LabelItem.getPattern();
+      Type exnType = CS.getASTContext().getErrorDecl()->getDeclaredInterfaceType();
+
+      if (!exnType)
+        return false;
+      auto contextualPattern =
+          ContextualPattern::forRawPattern(pattern, DC);
+      pattern = TypeChecker::coercePatternToType(
+        contextualPattern, exnType, TypeResolverContext::InExpression);
+      if (!pattern)
+        return false;
+
+      LabelItem.setPattern(pattern, /*resolved=*/true);
+      return LabelItem.isSyntacticallyExhaustive();
+    }
+
+    std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
+      // If we've found a 'throw', record it and terminate the traversal.
+      if (isa<ThrowStmt>(stmt)) {
+        FoundThrow = true;
+        return { false, nullptr };
+      }
+
+      // Handle do/catch differently.
+      if (auto doCatch = dyn_cast<DoCatchStmt>(stmt)) {
+        // Only walk into the 'do' clause of a do/catch statement
+        // if the catch isn't syntactically exhaustive.
+        if (!isSyntacticallyExhaustive(doCatch)) {
+          if (!doCatch->getBody()->walk(*this))
+            return { false, nullptr };
+        }
+
+        // Walk into all the catch clauses.
+        for (auto catchClause : doCatch->getCatches()) {
+          if (!catchClause->walk(*this))
+            return { false, nullptr };
+        }
+
+        // We've already walked all the children we care about.
+        return { false, stmt };
+      }
+
+      return { true, stmt };
+    }
+
+  public:
+    FindInnerThrows(ConstraintSystem &cs, DeclContext *dc)
+        : CS(cs), DC(dc) {}
+
+    bool foundThrow() { return FoundThrow; }
+  };
+
+  // A walker that looks for 'async' and 'await' expressions
+  // that aren't nested within closures or nested declarations.
+  class FindInnerAsync : public ASTWalker {
+    bool FoundAsync = false;
+
+    std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
+      // If we've found an 'await', record it and terminate the traversal.
+      if (isa<AwaitExpr>(expr)) {
+        FoundAsync = true;
+        return { false, nullptr };
+      }
+
+      // Do not recurse into other closures.
+      if (isa<ClosureExpr>(expr))
+        return { false, expr };
+
+      return { true, expr };
+    }
+
+    bool walkToDeclPre(Decl *decl) override {
+      // Do not walk into function or type declarations.
+      if (!isa<PatternBindingDecl>(decl))
+        return false;
+
+      return true;
+    }
+
+  public:
+    bool foundAsync() { return FoundAsync; }
+  };
+
+  // If either 'throws' or 'async' was explicitly specified, use that
+  // set of effects.
+  bool throws = expr->getThrowsLoc().isValid();
+  bool async = expr->getAsyncLoc().isValid();
+  if (throws || async) {
+    return ASTExtInfoBuilder()
+      .withThrows(throws)
+      .withAsync(async)
+      .build();
+  }
+
+  // Scan the body to determine the effects.
+  auto body = expr->getBody();
+  if (!body)
+    return FunctionType::ExtInfo();
+
+  auto throwFinder = FindInnerThrows(*this, expr);
+  body->walk(throwFinder);
+  auto asyncFinder = FindInnerAsync();
+  body->walk(asyncFinder);
+  auto result = ASTExtInfoBuilder()
+    .withThrows(throwFinder.foundThrow())
+    .withAsync(asyncFinder.foundAsync())
+    .build();
+  closureEffectsCache[expr] = result;
+  return result;
+}
+
+bool ConstraintSystem::isAsynchronousContext(DeclContext *dc) {
+  if (auto func = dyn_cast<AbstractFunctionDecl>(dc))
+    return isDeclAsync(func);
+
+  if (auto closure = dyn_cast<ClosureExpr>(dc))
+    return closureEffects(closure).isAsync();
+
+  return false;
+}
+
 void ConstraintSystem::bindOverloadType(
     const SelectedOverload &overload, Type boundType,
     ConstraintLocator *locator, DeclContext *useDC,
@@ -2475,6 +2713,11 @@
   assert(!refType->hasTypeParameter() && "Cannot have a dependent type here");
 
   if (auto *decl = choice.getDeclOrNull()) {
+    // If we're choosing an asynchronous declaration within a synchronous
+    // context, or vice-versa, increase the async/async mismatch score.
+    if (isAsynchronousContext(useDC) != isDeclAsync(decl))
+      increaseScore(SK_AsyncSyncMismatch);
+
     // If we're binding to an init member, the 'throws' need to line up
     // between the bound and reference types.
     if (auto CD = dyn_cast<ConstructorDecl>(decl)) {
@@ -3930,11 +4173,11 @@
          doesMemberRefApplyCurriedSelf(baseType, decl);
 }
 
-bool constraints::conformsToKnownProtocol(ConstraintSystem &cs, Type type,
+bool constraints::conformsToKnownProtocol(DeclContext *dc, Type type,
                                           KnownProtocolKind protocol) {
   if (auto *proto =
-          TypeChecker::getProtocol(cs.getASTContext(), SourceLoc(), protocol))
-    return (bool)TypeChecker::conformsToProtocol(type, proto, cs.DC);
+          TypeChecker::getProtocol(dc->getASTContext(), SourceLoc(), protocol))
+    return (bool)TypeChecker::conformsToProtocol(type, proto, dc);
   return false;
 }
 
@@ -3959,7 +4202,8 @@
     ConstraintSystem &cs, Type type,
     KnownProtocolKind rawRepresentableProtocol) {
   Type rawTy = isRawRepresentable(cs, type);
-  if (!rawTy || !conformsToKnownProtocol(cs, rawTy, rawRepresentableProtocol))
+  if (!rawTy ||
+      !conformsToKnownProtocol(cs.DC, rawTy, rawRepresentableProtocol))
     return Type();
 
   return rawTy;
@@ -4253,9 +4497,7 @@
   if (!expr) return false;
 
   if (auto opName = getOperatorName(expr)) {
-    return opName->is("==") || opName->is("!=") || opName->is("===") ||
-           opName->is("!==") || opName->is("<") || opName->is(">") ||
-           opName->is("<=") || opName->is(">=");
+    return opName->isStandardComparisonOperator();
   }
   return false;
 }
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 18579bf..1612bfd 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -700,6 +700,9 @@
   SK_Hole,
   /// A reference to an @unavailable declaration.
   SK_Unavailable,
+  /// A reference to an async function in a synchronous context, or
+  /// vice versa.
+  SK_AsyncSyncMismatch,
   /// A use of the "forward" scan for trailing closures.
   SK_ForwardTrailingClosure,
   /// A use of a disfavored overload.
@@ -1187,6 +1190,8 @@
 
   void setExprTypes(Expr *expr) const;
 
+  bool hasType(ASTNode node) const;
+
   /// Retrieve the type of the given node, as recorded in this solution.
   Type getType(ASTNode node) const;
 
@@ -2025,6 +2030,13 @@
   /// from declared parameters/result and body.
   llvm::MapVector<const ClosureExpr *, FunctionType *> ClosureTypes;
 
+  /// This is a *global* list of all function builder bodies that have
+  /// been determined to be incorrect by failing constraint generation.
+  ///
+  /// Tracking this information is useful to avoid producing duplicate
+  /// diagnostics when function builder has multiple overloads.
+  llvm::SmallDenseSet<AnyFunctionRef> InvalidFunctionBuilderBodies;
+
   /// Maps node types used within all portions of the constraint
   /// system, instead of directly using the types on the
   /// nodes themselves. This allows us to typecheck and
@@ -2115,6 +2127,9 @@
   std::vector<std::pair<AnyFunctionRef, AppliedBuilderTransform>>
       functionBuilderTransformed;
 
+  /// Cache of the effects any closures visited.
+  llvm::SmallDenseMap<ClosureExpr *, FunctionType::ExtInfo, 4> closureEffectsCache;
+
 public:
   /// The locators of \c Defaultable constraints whose defaults were used.
   std::vector<ConstraintLocator *> DefaultedConstraints;
@@ -3055,6 +3070,16 @@
     trailingClosureMatchingChoices.push_back({locator, trailingClosureMatch});
   }
 
+  /// Walk a closure AST to determine its effects.
+  ///
+  /// \returns a function's extended info describing the effects, as
+  /// determined syntactically.
+  FunctionType::ExtInfo closureEffects(ClosureExpr *expr);
+
+  /// Determine whether the given context is asynchronous, e.g., an async
+  /// function or closure.
+  bool isAsynchronousContext(DeclContext *dc);
+
   /// Determine whether constraint system already has a fix recorded
   /// for a particular location.
   bool hasFixFor(ConstraintLocator *locator,
@@ -3436,9 +3461,9 @@
                       ConstraintLocator::PathElementKind kind) const;
 
   /// Gets the VarDecl associateed with resolvedOverload, and the type of the
-  /// storage wrapper if the decl has an associated storage wrapper.
+  /// projection if the decl has an associated property wrapper with a projectedValue.
   Optional<std::pair<VarDecl *, Type>>
-  getStorageWrapperInformation(SelectedOverload resolvedOverload);
+  getPropertyWrapperProjectionInfo(SelectedOverload resolvedOverload);
 
   /// Gets the VarDecl associateed with resolvedOverload, and the type of the
   /// backing storage if the decl has an associated property wrapper.
@@ -5011,21 +5036,15 @@
   /// solution, and constraint solver is allowed to produce partially correct
   /// solutions. Such solutions can have any number of holes in them.
   ///
-  /// \param expr The expression involved in code completion.
+  /// \param target The expression involved in code completion.
   ///
-  /// \param DC The declaration context this expression is found in.
+  /// \param solutions The solutions produced for the given target without
+  /// filtering.
   ///
-  /// \param contextualType The type \p expr is being converted to.
-  ///
-  /// \param CTP When contextualType is specified, this indicates what
-  /// the conversion is doing.
-  ///
-  /// \param callback The callback to be used to provide results to
-  /// code completion.
-  static void
-  solveForCodeCompletion(Expr *expr, DeclContext *DC, Type contextualType,
-                         ContextualTypePurpose CTP,
-                         llvm::function_ref<void(const Solution &)> callback);
+  /// \returns `false` if this call fails (e.g. pre-check or constraint
+  /// generation fails), `true` otherwise.
+  bool solveForCodeCompletion(SolutionApplicationTarget &target,
+                              SmallVectorImpl<Solution> &solutions);
 
 private:
   /// Solve the system of constraints.
@@ -5498,7 +5517,7 @@
                     llvm::function_ref<Type(Type)> getFixedType);
 
 /// Check whether type conforms to a given known protocol.
-bool conformsToKnownProtocol(ConstraintSystem &cs, Type type,
+bool conformsToKnownProtocol(DeclContext *dc, Type type,
                              KnownProtocolKind protocol);
 
 /// Check whether given type conforms to `RawPepresentable` protocol
diff --git a/lib/Sema/ImportResolution.cpp b/lib/Sema/ImportResolution.cpp
index 2ec7aac..c8ed785 100644
--- a/lib/Sema/ImportResolution.cpp
+++ b/lib/Sema/ImportResolution.cpp
@@ -298,6 +298,8 @@
   // Resolve each import declaration.
   for (auto D : SF.getTopLevelDecls())
     resolver.visit(D);
+  for (auto D : SF.getHoistedDecls())
+    resolver.visit(D);
 
   SF.setImports(resolver.getFinishedImports());
 
diff --git a/lib/Sema/LookupVisibleDecls.cpp b/lib/Sema/LookupVisibleDecls.cpp
index 53bb7c8..2989603 100644
--- a/lib/Sema/LookupVisibleDecls.cpp
+++ b/lib/Sema/LookupVisibleDecls.cpp
@@ -234,7 +234,7 @@
 }
 
 static void
-synthesizePropertyWrapperStorageWrapperProperties(IterableDeclContext *IDC);
+synthesizePropertyWrapperVariables(IterableDeclContext *IDC);
 
 /// Lookup members in extensions of \p LookupType, using \p BaseType as the
 /// underlying type when checking any constraints on the extensions.
@@ -253,7 +253,7 @@
                                                        extension)), false))
       continue;
 
-    synthesizePropertyWrapperStorageWrapperProperties(extension);
+    synthesizePropertyWrapperVariables(extension);
 
     collectVisibleMemberDecls(CurrDC, LS, BaseType, extension, FoundDecls);
   }
@@ -538,10 +538,10 @@
                     Consumer, CurrDC, LS, Reason);
 }
 
-// Generate '$' and '_' prefixed variables that have attached property
+// Generate '$' and '_' prefixed variables for members that have attached property
 // wrappers.
 static void
-synthesizePropertyWrapperStorageWrapperProperties(IterableDeclContext *IDC) {
+synthesizePropertyWrapperVariables(IterableDeclContext *IDC) {
   auto SF = IDC->getAsGenericContext()->getParentSourceFile();
   if (!SF || SF->Kind == SourceFileKind::Interface)
     return;
@@ -578,7 +578,7 @@
                                            /*useResolver=*/true);
   }
 
-  synthesizePropertyWrapperStorageWrapperProperties(NTD);
+  synthesizePropertyWrapperVariables(NTD);
 }
 
 static void lookupVisibleMemberDeclsImpl(
diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp
index f8bf7cd..a0fd2ae 100644
--- a/lib/Sema/MiscDiagnostics.cpp
+++ b/lib/Sema/MiscDiagnostics.cpp
@@ -15,8 +15,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "MiscDiagnostics.h"
-#include "TypeChecker.h"
+#include "ConstraintSystem.h"
 #include "TypeCheckAvailability.h"
+#include "TypeChecker.h"
 #include "swift/AST/ASTWalker.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/NameLookupRequests.h"
@@ -34,6 +35,7 @@
 
 #define DEBUG_TYPE "Sema"
 using namespace swift;
+using namespace constraints;
 
 /// Return true if this expression is an implicit promotion from T to T?.
 static Expr *isImplicitPromotionToOptional(Expr *E) {
@@ -4438,6 +4440,131 @@
   const_cast<Expr *>(E)->walk(Walker);
 }
 
+static void diagnoseComparisonWithNaN(const Expr *E, const DeclContext *DC) {
+  class ComparisonWithNaNFinder : public ASTWalker {
+    const ASTContext &C;
+    const DeclContext *DC;
+
+  public:
+    ComparisonWithNaNFinder(const DeclContext *dc)
+        : C(dc->getASTContext()), DC(dc) {}
+
+    void tryDiagnoseComparisonWithNaN(BinaryExpr *BE) {
+      ValueDecl *comparisonDecl = nullptr;
+
+      // Comparison functions like == or <= take two arguments.
+      if (BE->getArg()->getNumElements() != 2) {
+        return;
+      }
+
+      // Dig out the function declaration.
+      if (auto Fn = BE->getFn()) {
+        if (auto DSCE = dyn_cast<DotSyntaxCallExpr>(Fn)) {
+          comparisonDecl = DSCE->getCalledValue();
+        } else {
+          comparisonDecl = BE->getCalledValue();
+        }
+      }
+
+      // Bail out if it isn't a function.
+      if (!comparisonDecl || !isa<FuncDecl>(comparisonDecl)) {
+        return;
+      }
+
+      // We're only interested in comparison functions like == or <=.
+      auto comparisonDeclName = comparisonDecl->getBaseIdentifier();
+      if (!comparisonDeclName.isStandardComparisonOperator()) {
+        return;
+      }
+
+      auto firstArg = BE->getArg()->getElement(0);
+      auto secondArg = BE->getArg()->getElement(1);
+
+      // Both arguments must conform to FloatingPoint protocol.
+      if (!conformsToKnownProtocol(const_cast<DeclContext *>(DC),
+                                   firstArg->getType(),
+                                   KnownProtocolKind::FloatingPoint) ||
+          !conformsToKnownProtocol(const_cast<DeclContext *>(DC),
+                                   secondArg->getType(),
+                                   KnownProtocolKind::FloatingPoint)) {
+        return;
+      }
+
+      // Convenience utility to extract argument decl.
+      auto extractArgumentDecl = [&](Expr *arg) -> ValueDecl * {
+        if (auto DRE = dyn_cast<DeclRefExpr>(arg)) {
+          return DRE->getDecl();
+        } else if (auto MRE = dyn_cast<MemberRefExpr>(arg)) {
+          return MRE->getMember().getDecl();
+        }
+        return nullptr;
+      };
+
+      // Dig out the declarations for the arguments.
+      auto *firstVal = extractArgumentDecl(firstArg);
+      auto *secondVal = extractArgumentDecl(secondArg);
+
+      // If we can't find declarations for both arguments, bail out,
+      // because one of them has to be '.nan'.
+      if (!firstArg && !secondArg) {
+        return;
+      }
+
+      // Convenience utility to check if this is a 'nan' variable.
+      auto isNanDecl = [&](ValueDecl *VD) {
+        return VD && isa<VarDecl>(VD) && VD->getBaseIdentifier().is("nan");
+      };
+
+      // Diagnose comparison with '.nan'.
+      //
+      // If the comparison is done using '<=', '<', '==', '>', '>=', then
+      // the result is always false. If the comparison is done using '!=',
+      // then the result is always true.
+      //
+      // Emit a different diagnostic which doesn't mention using '.isNaN' if
+      // the comparison isn't done using '==' or '!=' or if both sides are
+      // '.nan'.
+      if (isNanDecl(firstVal) && isNanDecl(secondVal)) {
+        C.Diags.diagnose(BE->getLoc(), diag::nan_comparison_both_nan,
+                         comparisonDeclName.str(), comparisonDeclName.is("!="));
+      } else if (isNanDecl(firstVal) || isNanDecl(secondVal)) {
+        if (comparisonDeclName.is("==") || comparisonDeclName.is("!=")) {
+          auto exprStr =
+              C.SourceMgr
+                  .extractText(Lexer::getCharSourceRangeFromSourceRange(
+                      C.SourceMgr, firstArg->getSourceRange()))
+                  .str();
+          auto prefix = exprStr;
+          if (comparisonDeclName.is("!=")) {
+            prefix = "!" + prefix;
+          }
+          C.Diags.diagnose(BE->getLoc(), diag::nan_comparison,
+                           comparisonDeclName, comparisonDeclName.is("!="),
+                           prefix, exprStr);
+        } else {
+          C.Diags.diagnose(BE->getLoc(), diag::nan_comparison_without_isnan,
+                           comparisonDeclName, comparisonDeclName.is("!="));
+        }
+      }
+    }
+
+    std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
+      if (!E || isa<ErrorExpr>(E) || !E->getType())
+        return {false, E};
+
+      if (auto *BE = dyn_cast<BinaryExpr>(E)) {
+        tryDiagnoseComparisonWithNaN(BE);
+        return {false, E};
+      }
+
+      return {true, E};
+    }
+  };
+
+  ComparisonWithNaNFinder Walker(DC);
+  const_cast<Expr *>(E)->walk(Walker);
+}
+
 //===----------------------------------------------------------------------===//
 // High-level entry points.
 //===----------------------------------------------------------------------===//
@@ -4454,6 +4581,7 @@
   diagnoseUnintendedOptionalBehavior(E, DC);
   maybeDiagnoseCallToKeyValueObserveMethod(E, DC);
   diagnoseExplicitUseOfLazyVariableStorage(E, DC);
+  diagnoseComparisonWithNaN(E, DC);
   if (!ctx.isSwiftVersionAtLeast(5))
     diagnoseDeprecatedWritableKeyPath(E, DC);
   if (!ctx.LangOpts.DisableAvailabilityChecking)
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index ee8cf29..8da9fd0 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -16,6 +16,7 @@
 
 #include "TypeChecker.h"
 #include "TypeCheckAvailability.h"
+#include "TypeCheckAccess.h"
 #include "swift/AST/Attr.h"
 #include "swift/AST/Decl.h"
 #include "swift/AST/DeclContext.h"
@@ -171,7 +172,8 @@
 static bool
 diagnoseGenericArgumentsExportability(SourceLoc loc,
                                       SubstitutionMap subs,
-                                      const SourceFile &userSF) {
+                                      const SourceFile &userSF,
+                                      const DeclContext *userDC) {
   bool hadAnyIssues = false;
   for (ProtocolConformanceRef conformance : subs.getConformances()) {
     if (!conformance.isConcrete())
@@ -180,18 +182,23 @@
 
     SubstitutionMap subConformanceSubs =
         concreteConf->getSubstitutions(userSF.getParentModule());
-    diagnoseGenericArgumentsExportability(loc, subConformanceSubs, userSF);
+    diagnoseGenericArgumentsExportability(loc, subConformanceSubs, userSF, userDC);
 
     const RootProtocolConformance *rootConf =
         concreteConf->getRootConformance();
     ModuleDecl *M = rootConf->getDeclContext()->getParentModule();
-    if (!userSF.isImportedImplementationOnly(M))
+
+    auto originKind = getDisallowedOriginKind(
+        rootConf->getDeclContext()->getAsDecl(),
+        userSF, userDC->getInnermostDeclarationDeclContext());
+    if (originKind == DisallowedOriginKind::None)
       continue;
 
     ASTContext &ctx = M->getASTContext();
     ctx.Diags.diagnose(loc, diag::conformance_from_implementation_only_module,
                        rootConf->getType(),
-                       rootConf->getProtocol()->getName(), 0, M->getName());
+                       rootConf->getProtocol()->getName(), 0, M->getName(),
+                       static_cast<unsigned>(originKind));
     hadAnyIssues = true;
   }
   return hadAnyIssues;
@@ -209,10 +216,10 @@
   if (auto *BGT = dyn_cast<BoundGenericType>(T.getPointer())) {
     ModuleDecl *useModule = SF->getParentModule();
     auto subs = T->getContextSubstitutionMap(useModule, BGT->getDecl());
-    (void)diagnoseGenericArgumentsExportability(Loc, subs, *SF);
+    (void)diagnoseGenericArgumentsExportability(Loc, subs, *SF, DC);
   } else if (auto *TAT = dyn_cast<TypeAliasType>(T.getPointer())) {
     auto subs = TAT->getSubstitutionMap();
-    (void)diagnoseGenericArgumentsExportability(Loc, subs, *SF);
+    (void)diagnoseGenericArgumentsExportability(Loc, subs, *SF, DC);
   }
 }
 
@@ -226,19 +233,11 @@
   if (!userSF)
     return false;
 
-  // If the source file doesn't have any implementation-only imports,
-  // we can fast-path this.  In the current language design, we never
-  // need to consider the possibility of implementation-only imports
-  // from other source files in the module (or indirectly in other modules).
-  // TODO: maybe check whether D is from a bridging header?
-  if (!userSF->hasImplementationOnlyImports())
-    return false;
-
   const ValueDecl *D = declRef.getDecl();
   if (diagnoseDeclExportability(loc, D, *userSF, fragileKind))
     return true;
   if (diagnoseGenericArgumentsExportability(loc, declRef.getSubstitutions(),
-                                            *userSF)) {
+                                            *userSF, DC)) {
     return true;
   }
   return false;
diff --git a/lib/Sema/TypeCheckAccess.cpp b/lib/Sema/TypeCheckAccess.cpp
index 8f2556c..67f15ea 100644
--- a/lib/Sema/TypeCheckAccess.cpp
+++ b/lib/Sema/TypeCheckAccess.cpp
@@ -1454,47 +1454,40 @@
   }
 };
 
+/// Returns the kind of origin, implementation-only import or SPI declaration,
+/// that restricts exporting \p decl from the given file and context.
+///
+/// Local variant to swift::getDisallowedOriginKind for downgrade to warnings.
+DisallowedOriginKind
+getDisallowedOriginKind(const Decl *decl,
+                        const SourceFile &userSF,
+                        const Decl *userContext,
+                        DowngradeToWarning &downgradeToWarning) {
+  downgradeToWarning = DowngradeToWarning::No;
+  ModuleDecl *M = decl->getModuleContext();
+  if (userSF.isImportedImplementationOnly(M)) {
+    // Temporarily downgrade implementation-only exportability in SPI to
+    // a warning.
+    if (userContext->isSPI())
+      downgradeToWarning = DowngradeToWarning::Yes;
+
+    // Implementation-only imported, cannot be reexported.
+    return DisallowedOriginKind::ImplementationOnly;
+  } else if (decl->isSPI() && !userContext->isSPI()) {
+    // SPI can only be exported in SPI.
+    return userContext->getModuleContext() == M ?
+      DisallowedOriginKind::SPILocal :
+      DisallowedOriginKind::SPIImported;
+  }
+
+  return DisallowedOriginKind::None;
+};
+
 // Diagnose public APIs exposing types that are either imported as
 // implementation-only or declared as SPI.
 class ExportabilityChecker : public DeclVisitor<ExportabilityChecker> {
   class Diagnoser;
 
-  // Problematic origin of an exported type.
-  //
-  // This enum must be kept in sync with
-  // diag::decl_from_hidden_module and
-  // diag::conformance_from_implementation_only_module.
-  enum class DisallowedOriginKind : uint8_t {
-    ImplementationOnly,
-    SPIImported,
-    SPILocal,
-    None
-  };
-
-  // If there's an exportability problem with \p typeDecl, get its origin kind.
-  static DisallowedOriginKind getDisallowedOriginKind(
-      const TypeDecl *typeDecl, const SourceFile &SF, const Decl *context,
-      DowngradeToWarning &downgradeToWarning) {
-    downgradeToWarning = DowngradeToWarning::No;
-    ModuleDecl *M = typeDecl->getModuleContext();
-    if (SF.isImportedImplementationOnly(M)) {
-      // Temporarily downgrade implementation-only exportability in SPI to
-      // a warning.
-      if (context->isSPI())
-        downgradeToWarning = DowngradeToWarning::Yes;
-
-      // Implementation-only imported, cannot be reexported.
-      return DisallowedOriginKind::ImplementationOnly;
-    } else if (typeDecl->isSPI() && !context->isSPI()) {
-      // SPI can only be exported in SPI.
-      return context->getModuleContext() == M ?
-        DisallowedOriginKind::SPILocal :
-        DisallowedOriginKind::SPIImported;
-    }
-
-    return DisallowedOriginKind::None;
-  };
-
   void checkTypeImpl(
       Type type, const TypeRepr *typeRepr, const SourceFile &SF,
       const Decl *context,
@@ -1560,10 +1553,12 @@
 
           const RootProtocolConformance *rootConf =
               concreteConf->getRootConformance();
-          ModuleDecl *M = rootConf->getDeclContext()->getParentModule();
-          if (!SF.isImportedImplementationOnly(M))
+          auto originKind = getDisallowedOriginKind(
+              rootConf->getDeclContext()->getAsDecl(),
+              SF, context);
+          if (originKind == DisallowedOriginKind::None)
             continue;
-          diagnoser.diagnoseConformance(rootConf);
+          diagnoser.diagnoseConformance(rootConf, originKind);
         }
       }
 
@@ -1674,12 +1669,14 @@
       highlightOffendingType(diag, complainRepr);
     }
 
-    void diagnoseConformance(const ProtocolConformance *offendingConformance) const {
+    void diagnoseConformance(const ProtocolConformance *offendingConformance,
+                             DisallowedOriginKind originKind) const {
       ModuleDecl *M = offendingConformance->getDeclContext()->getParentModule();
       D->diagnose(diag::conformance_from_implementation_only_module,
                   offendingConformance->getType(),
                   offendingConformance->getProtocol()->getName(),
-                  static_cast<unsigned>(reason), M->getName());
+                  static_cast<unsigned>(reason), M->getName(),
+                  static_cast<unsigned>(originKind));
     }
 
     void diagnoseClangFunctionType(Type fnType, const clang::Type *type) const {
@@ -2067,6 +2064,13 @@
       ED, ED, desiredAccessScope, userSpecifiedAccess);
 }
 
+DisallowedOriginKind swift::getDisallowedOriginKind(const Decl *decl,
+                                                    const SourceFile &userSF,
+                                                    const Decl *declContext) {
+  auto downgradeToWarning = DowngradeToWarning::No;
+  return getDisallowedOriginKind(decl, userSF, declContext, downgradeToWarning);
+}
+
 void swift::checkAccessControl(Decl *D) {
   if (isa<ValueDecl>(D) || isa<PatternBindingDecl>(D)) {
     AccessControlChecker().visit(D);
diff --git a/lib/Sema/TypeCheckAccess.h b/lib/Sema/TypeCheckAccess.h
index 181fb44..d29523e 100644
--- a/lib/Sema/TypeCheckAccess.h
+++ b/lib/Sema/TypeCheckAccess.h
@@ -17,9 +17,12 @@
 #ifndef TYPECHECKACCESS_H
 #define TYPECHECKACCESS_H
 
+#include <cstdint>
+
 namespace swift {
 
 class Decl;
+class SourceFile;
 
 /// Performs access-related checks for \p D.
 ///
@@ -28,6 +31,24 @@
 /// itself. Related checks may also be performed.
 void checkAccessControl(Decl *D);
 
+// Problematic origin of an exported type.
+//
+// This enum must be kept in sync with
+// diag::decl_from_hidden_module and
+// diag::conformance_from_implementation_only_module.
+enum class DisallowedOriginKind : uint8_t {
+  ImplementationOnly,
+  SPIImported,
+  SPILocal,
+  None
+};
+
+/// Returns the kind of origin, implementation-only import or SPI declaration,
+/// that restricts exporting \p decl from the given file and context.
+DisallowedOriginKind getDisallowedOriginKind(const Decl *decl,
+                                             const SourceFile &userSF,
+                                             const Decl *userContext);
+
 } // end namespace swift
 
 #endif
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index df4080e..c090319 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -885,7 +885,8 @@
   if (auto VD = dyn_cast<ValueDecl>(D)) {
     // VD must be public or open to use an @_spi attribute.
     auto declAccess = VD->getFormalAccess();
-    if (declAccess < AccessLevel::Public) {
+    if (declAccess < AccessLevel::Public &&
+        !VD->getAttrs().hasAttribute<UsableFromInlineAttr>()) {
       diagnoseAndRemoveAttr(attr,
                             diag::spi_attribute_on_non_public,
                             declAccess,
@@ -3008,8 +3009,32 @@
 }
 
 void AttributeChecker::visitFunctionBuilderAttr(FunctionBuilderAttr *attr) {
-  // TODO: check that the type at least provides a `sequence` factory?
-  // Any other validation?
+  auto *nominal = dyn_cast<NominalTypeDecl>(D);
+  SmallVector<ValueDecl *, 4> potentialMatches;
+  bool supportsBuildBlock = TypeChecker::typeSupportsBuilderOp(
+      nominal->getDeclaredType(), nominal, D->getASTContext().Id_buildBlock,
+      /*argLabels=*/{}, &potentialMatches);
+
+  if (!supportsBuildBlock) {
+    diagnose(nominal->getLoc(), diag::function_builder_static_buildblock);
+
+    // For any close matches, attempt to explain to the user why they aren't
+    // valid.
+    for (auto *member : potentialMatches) {
+      if (member->isStatic() && isa<FuncDecl>(member))
+        continue;
+
+      if (isa<FuncDecl>(member) &&
+          member->getDeclContext()->getSelfNominalTypeDecl() == nominal)
+        diagnose(member->getLoc(), diag::function_builder_non_static_buildblock)
+          .fixItInsert(member->getAttributeInsertionLoc(true), "static ");
+      else if (isa<EnumElementDecl>(member))
+        diagnose(member->getLoc(), diag::function_builder_buildblock_enum_case);
+      else
+        diagnose(member->getLoc(),
+                 diag::function_builder_buildblock_not_static_method);
+    }
+  }
 }
 
 void
@@ -4645,7 +4670,8 @@
     if (originalAFD->getFormalAccess() == derivative->getFormalAccess())
       return true;
     return originalAFD->getFormalAccess() == AccessLevel::Public &&
-           derivative->getEffectiveAccess() == AccessLevel::Public;
+           (derivative->getFormalAccess() == AccessLevel::Public ||
+            derivative->isUsableFromInline());
   };
 
   // Check access level compatibility for original and derivative functions.
diff --git a/lib/Sema/TypeCheckCaptures.cpp b/lib/Sema/TypeCheckCaptures.cpp
index 20a41c6..c83ed13 100644
--- a/lib/Sema/TypeCheckCaptures.cpp
+++ b/lib/Sema/TypeCheckCaptures.cpp
@@ -660,10 +660,11 @@
         AFD->diagnose(diag::objc_generic_extension_using_type_parameter);
 
         // If it's possible, suggest adding @objc.
+        Optional<ForeignAsyncConvention> asyncConvention;
         Optional<ForeignErrorConvention> errorConvention;
         if (!AFD->isObjC() &&
             isRepresentableInObjC(AFD, ObjCReason::MemberOfObjCMembersClass,
-                                  errorConvention)) {
+                                  asyncConvention, errorConvention)) {
           AFD->diagnose(
                    diag::objc_generic_extension_using_type_parameter_try_objc)
             .fixItInsert(AFD->getAttributeInsertionLoc(false), "@objc ");
diff --git a/lib/Sema/TypeCheckCodeCompletion.cpp b/lib/Sema/TypeCheckCodeCompletion.cpp
index 6ba92ae..b78513e 100644
--- a/lib/Sema/TypeCheckCodeCompletion.cpp
+++ b/lib/Sema/TypeCheckCodeCompletion.cpp
@@ -41,6 +41,7 @@
 #include "swift/Basic/STLExtras.h"
 #include "swift/Parse/Lexer.h"
 #include "swift/Sema/IDETypeChecking.h"
+#include "swift/Sema/CodeCompletionTypeChecking.h"
 #include "swift/Strings.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/PointerUnion.h"
@@ -592,11 +593,25 @@
   }
 }
 
-void TypeChecker::typeCheckForCodeCompletion(
-    Expr *expr, DeclContext *DC, Type contextualType, ContextualTypePurpose CTP,
+bool TypeChecker::typeCheckForCodeCompletion(
+    SolutionApplicationTarget &target,
     llvm::function_ref<void(const Solution &)> callback) {
+  auto *DC = target.getDeclContext();
   auto &Context = DC->getASTContext();
 
+  auto *expr = target.getAsExpr();
+  if (!expr)
+    return false;
+
+  // First of all, let's check whether given target expression
+  // does indeed have the code completion location in it.
+  {
+    auto range = expr->getSourceRange();
+    if (range.isInvalid() ||
+        !Context.SourceMgr.rangeContainsCodeCompletionLoc(range))
+      return false;
+  }
+
   FrontendStatsTracer StatsTracer(Context.Stats,
                                   "typecheck-for-code-completion", expr);
   PrettyStackTraceExpr stackTrace(Context, "code-completion", expr);
@@ -604,8 +619,261 @@
   expr = expr->walk(SanitizeExpr(Context,
                                  /*shouldReusePrecheckedType=*/false));
 
-  ConstraintSystem::solveForCodeCompletion(expr, DC, contextualType, CTP,
-                                           callback);
+  enum class ContextKind {
+    Expression,
+    Application,
+    StringInterpolation,
+    SingleStmtClosure,
+    MultiStmtClosure,
+    ErrorExpression
+  };
+
+  class ContextFinder : public ASTWalker {
+    using Context = std::pair<ContextKind, Expr *>;
+
+    // Stack of all "interesting" contexts up to code completion expression.
+    llvm::SmallVector<Context, 4> Contexts;
+
+    Expr *CompletionExpr = nullptr;
+
+  public:
+    ContextFinder(Expr *E) {
+      Contexts.push_back(std::make_pair(ContextKind::Expression, E));
+    }
+
+    std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
+      if (auto *closure = dyn_cast<ClosureExpr>(E)) {
+        Contexts.push_back(std::make_pair(closure->hasSingleExpressionBody()
+                                              ? ContextKind::SingleStmtClosure
+                                              : ContextKind::MultiStmtClosure,
+                                          closure));
+      }
+
+      if (isa<InterpolatedStringLiteralExpr>(E)) {
+        Contexts.push_back(std::make_pair(ContextKind::StringInterpolation, E));
+      }
+
+      if (isa<ApplyExpr>(E)) {
+        Contexts.push_back(std::make_pair(ContextKind::Application, E));
+      }
+
+      if (isa<CodeCompletionExpr>(E)) {
+        CompletionExpr = E;
+        return std::make_pair(false, nullptr);
+      }
+
+      if (auto *Error = dyn_cast<ErrorExpr>(E)) {
+        Contexts.push_back(std::make_pair(ContextKind::ErrorExpression, E));
+        if (auto *OrigExpr = Error->getOriginalExpr()) {
+          OrigExpr->walk(*this);
+          return std::make_pair(false, hasCompletionExpr() ? nullptr : E);
+        }
+      }
+
+      return std::make_pair(true, E);
+    }
+
+    Expr *walkToExprPost(Expr *E) override {
+      if (isa<ClosureExpr>(E) || isa<InterpolatedStringLiteralExpr>(E) ||
+          isa<ApplyExpr>(E) || isa<ErrorExpr>(E))
+        Contexts.pop_back();
+      return E;
+    }
+
+    /// Check whether code completion expression is located inside of a
+    /// multi-statement closure.
+    bool locatedInMultiStmtClosure() const {
+      return hasContext(ContextKind::MultiStmtClosure);
+    }
+
+    bool locatedInStringIterpolation() const {
+      return hasContext(ContextKind::StringInterpolation);
+    }
+
+    bool hasCompletionExpr() const {
+      return CompletionExpr;
+    }
+
+    Expr *getCompletionExpr() const {
+      assert(CompletionExpr);
+      return CompletionExpr;
+    }
+
+    ErrorExpr *getInnermostErrorExpr() const {
+      for (const Context &curr : llvm::reverse(Contexts)) {
+        if (curr.first == ContextKind::ErrorExpression)
+          return cast<ErrorExpr>(curr.second);
+      }
+      return nullptr;
+    }
+
+    ClosureExpr *getOutermostMultiStmtClosure() const {
+      for (const Context &curr : Contexts) {
+        if (curr.first == ContextKind::MultiStmtClosure)
+          return cast<ClosureExpr>(curr.second);
+      }
+      return nullptr;
+    }
+
+    /// As a fallback sometimes its useful to not only type-check
+    /// code completion expression directly but instead add some
+    /// of the enclosing context e.g. when completion is an argument
+    /// to a call.
+    Expr *getCompletionExprInContext() const {
+      assert(CompletionExpr);
+
+      auto &innerContext = Contexts.back();
+      return innerContext.first == ContextKind::Application
+                 ? innerContext.second
+                 : CompletionExpr;
+    }
+
+  private:
+    bool hasContext(ContextKind kind) const {
+      return llvm::find_if(Contexts, [&kind](const Context &currContext) {
+               return currContext.first == kind;
+             }) != Contexts.end();
+    }
+  };
+
+  ContextFinder contextAnalyzer(expr);
+  expr->walk(contextAnalyzer);
+
+  // If there was no completion expr (e.g. if the code completion location was
+  // among tokens that were skipped over during parser error recovery) bail.
+  if (!contextAnalyzer.hasCompletionExpr())
+    return false;
+
+  // If the completion expression is in a valid subexpression of an ErrorExpr,
+  // fallback to trying the valid subexpression without any context. This can
+  // happen for cases like `expectsBoolArg(foo.<complete>).` which becomes an
+  // ErrorExpr due to the missing member name after the final dot.
+  if (auto *errorExpr = contextAnalyzer.getInnermostErrorExpr()) {
+    if (auto *origExpr = errorExpr->getOriginalExpr()) {
+      SolutionApplicationTarget completionTarget(origExpr, DC, CTP_Unused,
+                                                 /*contextualType=*/Type(),
+                                                 /*isDiscarded=*/true);
+      return typeCheckForCodeCompletion(completionTarget, callback);
+    }
+  }
+
+  // Interpolation components are type-checked separately.
+  if (contextAnalyzer.locatedInStringIterpolation())
+    return false;
+
+  // FIXME: There is currently no way to distinguish between
+  // multi-statement closures which are function builder bodies
+  // (that are type-checked together with enclosing context)
+  // and regular closures which are type-checked separately.
+
+  {
+    // First, pre-check the expression, validating any types that occur in the
+    // expression and folding sequence expressions.
+    auto failedPreCheck = ConstraintSystem::preCheckExpression(
+        expr, DC,
+        /*replaceInvalidRefsWithErrors=*/true);
+
+    target.setExpr(expr);
+
+    if (failedPreCheck)
+      return false;
+  }
+
+  enum class CompletionResult { Ok, NotApplicable, Fallback };
+
+  auto solveForCodeCompletion =
+      [&](SolutionApplicationTarget &target) -> CompletionResult {
+    ConstraintSystemOptions options;
+    options |= ConstraintSystemFlags::AllowFixes;
+    options |= ConstraintSystemFlags::SuppressDiagnostics;
+
+    ConstraintSystem cs(DC, options);
+
+    llvm::SmallVector<Solution, 4> solutions;
+
+    // If solve failed to generate constraints or with some other
+    // issue, we need to fallback to type-checking code completion
+    // expression directly.
+    if (!cs.solveForCodeCompletion(target, solutions))
+      return CompletionResult::Fallback;
+
+    // If case type-check didn't produce any solutions, let's
+    // attempt to type-check code completion expression without
+    // enclosing context.
+    if (solutions.empty())
+      return CompletionResult::Fallback;
+
+    // If code completion expression resides inside of multi-statement
+    // closure body it code either be type-checker together with context
+    // or not, it's impossible to say without trying. If solution
+    // doesn't have a type for a code completion expression it means that
+    // we have to wait until body of the closure is type-checked.
+    if (contextAnalyzer.locatedInMultiStmtClosure()) {
+      auto &solution = solutions.front();
+
+      // Let's check whether closure participated in the type-check.
+      if (solution.hasType(contextAnalyzer.getCompletionExpr())) {
+        llvm::for_each(solutions, callback);
+        return CompletionResult::Ok;
+      }
+
+      if (solutions.size() > 1)
+        return CompletionResult::Fallback;
+
+      auto *closure = contextAnalyzer.getOutermostMultiStmtClosure();
+      auto closureType = solution.getResolvedType(closure);
+
+      if (closureType->hasUnresolvedType())
+        return CompletionResult::Fallback;
+
+      return CompletionResult::NotApplicable;
+    }
+
+    llvm::for_each(solutions, callback);
+    return CompletionResult::Ok;
+  };
+
+  switch (solveForCodeCompletion(target)) {
+  case CompletionResult::Ok:
+    return true;
+
+  case CompletionResult::NotApplicable:
+    return false;
+
+  case CompletionResult::Fallback:
+    break;
+  }
+
+  {
+    auto *completionExpr = contextAnalyzer.getCompletionExpr();
+
+    if (contextAnalyzer.locatedInMultiStmtClosure()) {
+      auto completionInContext = contextAnalyzer.getCompletionExprInContext();
+      // If pre-check fails, let's switch to code completion
+      // expression without any enclosing context.
+      if (ConstraintSystem::preCheckExpression(
+              completionInContext, DC, /*replaceInvalidRefsWithErrors=*/true)) {
+        completionExpr = contextAnalyzer.getCompletionExpr();
+      } else {
+        completionExpr = completionInContext;
+      }
+    }
+
+    // If initial solve failed, let's fallback to checking only code completion
+    // expresion without any context.
+    SolutionApplicationTarget completionTarget(completionExpr, DC, CTP_Unused,
+                                               /*contextualType=*/Type(),
+                                               /*isDiscarded=*/true);
+
+    switch (solveForCodeCompletion(completionTarget)) {
+    case CompletionResult::Ok:
+    case CompletionResult::Fallback:
+      break;
+    case CompletionResult::NotApplicable:
+      llvm_unreachable("solve on CodeCompletionExpr produced not applicable?");
+    }
+  }
+  return true;
 }
 
 static Optional<Type> getTypeOfCompletionContextExpr(
@@ -703,3 +971,115 @@
 swift::lookupSemanticMember(DeclContext *DC, Type ty, DeclName name) {
   return TypeChecker::lookupMember(DC, ty, DeclNameRef(name), None);
 }
+
+void DotExprTypeCheckCompletionCallback::fallbackTypeCheck() {
+  assert(!gotCallback());
+  SolutionApplicationTarget completionTarget(CompletionExpr, DC, CTP_Unused,
+                                             Type(), /*isDiscared=*/true);
+  TypeChecker::typeCheckForCodeCompletion(
+      completionTarget, [&](const Solution &S) { sawSolution(S); });
+}
+
+void DotExprTypeCheckCompletionCallback::
+sawSolution(const constraints::Solution &S) {
+  GotCallback = true;
+  auto &CS = S.getConstraintSystem();
+
+  auto GetType = [&](Expr *E) {
+    // To aid code completion, we need to attempt to convert type holes
+    // back into underlying generic parameters if possible, since type
+    // of the code completion expression is used as "expected" (or contextual)
+    // type so it's helpful to know what requirements it has to filter
+    // the list of possible member candidates e.g.
+    //
+    // \code
+    // func test<T: P>(_: [T]) {}
+    //
+    // test(42.#^MEMBERS^#)
+    // \code
+    //
+    // It's impossible to resolve `T` in this case but code completion
+    // expression should still have a type of `[T]` instead of `[<<hole>>]`
+    // because it helps to produce correct contextual member list based on
+    // a conformance requirement associated with generic parameter `T`.
+    if (isa<CodeCompletionExpr>(E)) {
+      auto completionTy = S.getType(E).transform([&](Type type) -> Type {
+        if (auto *typeVar = type->getAs<TypeVariableType>())
+          return S.getFixedType(typeVar);
+        return type;
+      });
+
+      return S.simplifyType(completionTy.transform([&](Type type) {
+        if (auto *hole = type->getAs<HoleType>()) {
+          if (auto *typeVar =
+                  hole->getOriginatorType().dyn_cast<TypeVariableType *>()) {
+            if (auto *GP = typeVar->getImpl().getGenericParameter()) {
+              // Code completion depends on generic parameter type being
+              // represented in terms of `ArchetypeType` since it's easy
+              // to extract protocol requirements from it.
+              if (auto *GPD = GP->getDecl())
+                return GPD->getInnermostDeclContext()->mapTypeIntoContext(GP);
+            }
+          }
+
+          return Type(CS.getASTContext().TheUnresolvedType);
+        }
+
+        return type;
+      }));
+    }
+
+    return S.getResolvedType(E);
+  };
+
+  auto *ParsedExpr = CompletionExpr->getBase();
+  auto *SemanticExpr = ParsedExpr->getSemanticsProvidingExpr();
+
+  auto BaseTy = GetType(ParsedExpr);
+  // If base type couldn't be determined (e.g. because base expression
+  // is an invalid reference), let's not attempt to do a lookup since
+  // it wouldn't produce any useful results anyway.
+  if (!BaseTy || BaseTy->is<UnresolvedType>())
+    return;
+
+  auto *Locator = CS.getConstraintLocator(SemanticExpr);
+  Type ExpectedTy = GetType(CompletionExpr);
+  Expr *ParentExpr = CS.getParentExpr(CompletionExpr);
+  if (!ParentExpr)
+    ExpectedTy = CS.getContextualType(CompletionExpr);
+
+  auto *CalleeLocator = S.getCalleeLocator(Locator);
+  ValueDecl *ReferencedDecl = nullptr;
+  if (auto SelectedOverload = S.getOverloadChoiceIfAvailable(CalleeLocator))
+    ReferencedDecl = SelectedOverload->choice.getDeclOrNull();
+
+  auto Key = std::make_pair(BaseTy, ReferencedDecl);
+  auto Ret = BaseToSolutionIdx.insert({Key, Results.size()});
+  if (!Ret.second && ExpectedTy) {
+    Results[Ret.first->getSecond()].ExpectedTypes.push_back(ExpectedTy);
+  } else {
+    bool ISDMT = S.isStaticallyDerivedMetatype(ParsedExpr);
+    bool SingleExprBody = false;
+    bool DisallowVoid = ExpectedTy
+                            ? !ExpectedTy->isVoid()
+                            : !ParentExpr && CS.getContextualTypePurpose(
+                                                 CompletionExpr) != CTP_Unused;
+
+    if (!ParentExpr) {
+      if (CS.getContextualTypePurpose(CompletionExpr) == CTP_ReturnSingleExpr)
+        SingleExprBody = true;
+    } else if (auto *ParentCE = dyn_cast<ClosureExpr>(ParentExpr)) {
+      if (ParentCE->hasSingleExpressionBody() &&
+          ParentCE->getSingleExpressionBody() == CompletionExpr) {
+        ASTNode Last = ParentCE->getBody()->getLastElement();
+        if (!Last.isStmt(StmtKind::Return) || Last.isImplicit())
+          SingleExprBody = true;
+      }
+    }
+
+    Results.push_back(
+        {BaseTy, ReferencedDecl, {}, DisallowVoid, ISDMT, SingleExprBody});
+    if (ExpectedTy)
+      Results.back().ExpectedTypes.push_back(ExpectedTy);
+  }
+}
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index f0226a6..5e35f39 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -39,6 +39,7 @@
 #include "swift/Basic/Statistic.h"
 #include "swift/Parse/Confusables.h"
 #include "swift/Parse/Lexer.h"
+#include "swift/Sema/CodeCompletionTypeChecking.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -543,6 +544,9 @@
   //       name/module qualifier to access top-level name.
   lookupOptions |= NameLookupFlags::IncludeOuterResults;
 
+  if (Loc.isInvalid())
+    DC = DC->getModuleScopeContext();
+
   auto Lookup = TypeChecker::lookupUnqualified(DC, Name, Loc, lookupOptions);
 
   auto &Context = DC->getASTContext();
@@ -2161,6 +2165,14 @@
                                   "typecheck-expr", expr);
   PrettyStackTraceExpr stackTrace(Context, "type-checking", expr);
 
+  // First let's check whether given expression has a code completion
+  // token which requires special handling.
+  if (Context.CompletionCallback &&
+      typeCheckForCodeCompletion(target, [&](const constraints::Solution &S) {
+        Context.CompletionCallback->sawSolution(S);
+      }))
+    return None;
+
   // First, pre-check the expression, validating any types that occur in the
   // expression and folding sequence expressions.
   if (ConstraintSystem::preCheckExpression(
@@ -2459,8 +2471,9 @@
   auto lookupOptions = defaultUnqualifiedLookupOptions;
   lookupOptions |= NameLookupFlags::KnownPrivate;
   auto matchLookup =
-      lookupUnqualified(DC, DeclNameRef(Context.Id_MatchOperator), SourceLoc(),
-                        lookupOptions);
+      lookupUnqualified(DC->getModuleScopeContext(),
+                        DeclNameRef(Context.Id_MatchOperator),
+                        SourceLoc(), lookupOptions);
   auto &diags = DC->getASTContext().Diags;
   if (!matchLookup) {
     diags.diagnose(EP->getLoc(), diag::no_match_operator);
@@ -3167,21 +3180,14 @@
     return CheckedCastKind::ValueCast;
   };
 
-  // Strip optional wrappers off of the destination type in sync with
-  // stripping them off the origin type.
+  // TODO: Explore optionals using the same strategy used by the
+  // runtime.
+  // For now, if the target is more optional than the source,
+  // just defer it out for the runtime to handle.
   while (auto toValueType = toType->getOptionalObjectType()) {
-    // Complain if we're trying to increase optionality, e.g.
-    // casting an NSObject? to an NSString??.  That's not a subtype
-    // relationship.
     auto fromValueType = fromType->getOptionalObjectType();
     if (!fromValueType) {
-      if (!suppressDiagnostics) {
-        diags.diagnose(diagLoc, diag::downcast_to_more_optional,
-                       origFromType, origToType)
-          .highlight(diagFromRange)
-          .highlight(diagToRange);
-      }
-      return CheckedCastKind::Unresolved;
+      return CheckedCastKind::ValueCast;
     }
 
     toType = toValueType;
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 93c9eff..9956f19 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -25,7 +25,6 @@
 #include "TypeCheckType.h"
 #include "MiscDiagnostics.h"
 #include "swift/AST/AccessScope.h"
-#include "swift/AST/ASTMangler.h"
 #include "swift/AST/ASTPrinter.h"
 #include "swift/AST/ASTVisitor.h"
 #include "swift/AST/ASTWalker.h"
@@ -583,7 +582,7 @@
       // Property wrapper storage wrappers are final if the original property
       // is final.
       if (auto *original = VD->getOriginalWrappedProperty(
-            PropertyWrapperSynthesizedPropertyKind::StorageWrapper)) {
+            PropertyWrapperSynthesizedPropertyKind::Projection)) {
         if (original->isFinal())
           return true;
       }
@@ -2463,21 +2462,16 @@
 // Utility class for deterministically ordering vtable entries for
 // synthesized methods.
 struct SortedFuncList {
-  using Entry = std::pair<std::string, AbstractFunctionDecl *>;
+  using Key = std::tuple<DeclName, std::string>;
+  using Entry = std::pair<Key, AbstractFunctionDecl *>;
   SmallVector<Entry, 2> elts;
   bool sorted = false;
 
   void add(AbstractFunctionDecl *afd) {
-    Mangle::ASTMangler mangler;
-    std::string mangledName;
-    if (auto *cd = dyn_cast<ConstructorDecl>(afd))
-      mangledName = mangler.mangleConstructorEntity(cd, /*allocator=*/false);
-    else if (auto *dd = dyn_cast<DestructorDecl>(afd))
-      mangledName = mangler.mangleDestructorEntity(dd, /*deallocating=*/false);
-    else
-      mangledName = mangler.mangleEntity(afd);
+    assert(!isa<AccessorDecl>(afd));
 
-    elts.push_back(std::make_pair(mangledName, afd));
+    Key key{afd->getName(), afd->getInterfaceType().getString()};
+    elts.emplace_back(key, afd);
   }
 
   bool empty() { return elts.empty(); }
@@ -2506,60 +2500,52 @@
 } // end namespace
 
 ArrayRef<Decl *>
-EmittedMembersRequest::evaluate(Evaluator &evaluator,
-                                ClassDecl *CD) const {
-  auto &Context = CD->getASTContext();
+SemanticMembersRequest::evaluate(Evaluator &evaluator,
+                                IterableDeclContext *idc) const {
+  auto dc = cast<DeclContext>(idc->getDecl());
+  auto &Context = dc->getASTContext();
   SmallVector<Decl *, 8> result;
 
-  if (!CD->getParentSourceFile()) {
-    auto members = CD->getMembers();
+  if (!dc->getParentSourceFile()) {
+    auto members = idc->getMembers();
     result.append(members.begin(), members.end());
     return Context.AllocateCopy(result);
   }
 
-  // We need to add implicit initializers because they
-  // affect vtable layout.
-  TypeChecker::addImplicitConstructors(CD);
+  auto nominal = dyn_cast<NominalTypeDecl>(idc);
 
-  auto forceConformance = [&](ProtocolDecl *protocol) {
-    auto ref = CD->getParentModule()->lookupConformance(
-        CD->getDeclaredInterfaceType(), protocol);
-    if (ref.isInvalid()) {
-      return;
-    }
+  if (nominal) {
+    // We need to add implicit initializers because they
+    // affect vtable layout.
+    TypeChecker::addImplicitConstructors(nominal);
+  }
 
-    auto conformance = ref.getConcrete();
-    if (conformance->getDeclContext() == CD &&
-        conformance->getState() == ProtocolConformanceState::Incomplete) {
+  // Force any derivable conformances in this context. This ensures that any
+  // synthesized members will approach in the member list.
+  for (auto conformance : idc->getLocalConformances()) {
+    if (conformance->getState() == ProtocolConformanceState::Incomplete &&
+        conformance->getProtocol()->getKnownDerivableProtocolKind())
       TypeChecker::checkConformance(conformance->getRootNormalConformance());
-    }
-  };
+  }
 
-  // If the class is Encodable, Decodable or Hashable, force those
-  // conformances to ensure that the synthesized members appear in the vtable.
-  //
-  // FIXME: Generalize this to other protocols for which
-  // we can derive conformances.
-  forceConformance(Context.getProtocol(KnownProtocolKind::Decodable));
-  forceConformance(Context.getProtocol(KnownProtocolKind::Encodable));
-  forceConformance(Context.getProtocol(KnownProtocolKind::Hashable));
-  forceConformance(Context.getProtocol(KnownProtocolKind::Differentiable));
-
-  // If the class conforms to Encodable or Decodable, even via an extension,
+  // If the type conforms to Encodable or Decodable, even via an extension,
   // the CodingKeys enum is synthesized as a member of the type itself.
   // Force it into existence.
-  (void) evaluateOrDefault(Context.evaluator,
-                           ResolveImplicitMemberRequest{CD,
-                                      ImplicitMemberAction::ResolveCodingKeys},
-                           {});
+  if (nominal) {
+    (void) evaluateOrDefault(Context.evaluator,
+                             ResolveImplicitMemberRequest{nominal,
+                                        ImplicitMemberAction::ResolveCodingKeys},
+                             {});
+  }
 
-  // If the class has a @main attribute, we need to force synthesis of the
+  // If the decl has a @main attribute, we need to force synthesis of the
   // $main function.
-  (void) evaluateOrDefault(Context.evaluator,
-                           SynthesizeMainFunctionRequest{CD},
-                           nullptr);
+  (void) evaluateOrDefault(
+      Context.evaluator,
+      SynthesizeMainFunctionRequest{const_cast<Decl *>(idc->getDecl())},
+      nullptr);
 
-  for (auto *member : CD->getMembers()) {
+  for (auto *member : idc->getMembers()) {
     if (auto *var = dyn_cast<VarDecl>(member)) {
       // The projected storage wrapper ($foo) might have dynamically-dispatched
       // accessors, so force them to be synthesized.
@@ -2570,7 +2556,7 @@
 
   SortedFuncList synthesizedMembers;
 
-  for (auto *member : CD->getMembers()) {
+  for (auto *member : idc->getMembers()) {
     if (auto *afd = dyn_cast<AbstractFunctionDecl>(member)) {
       // Add synthesized members to a side table and sort them by their mangled
       // name, since they could have been added to the class in any order.
diff --git a/lib/Sema/TypeCheckDeclObjC.cpp b/lib/Sema/TypeCheckDeclObjC.cpp
index 7e8c1d4..617cb07 100644
--- a/lib/Sema/TypeCheckDeclObjC.cpp
+++ b/lib/Sema/TypeCheckDeclObjC.cpp
@@ -494,8 +494,11 @@
 bool swift::isRepresentableInObjC(
        const AbstractFunctionDecl *AFD,
        ObjCReason Reason,
+       Optional<ForeignAsyncConvention> &asyncConvention,
        Optional<ForeignErrorConvention> &errorConvention) {
-  // Clear out the error convention. It will be added later if needed.
+  // Clear out the async and error conventions. They will be added later if
+  // needed.
+  asyncConvention = None;
   errorConvention = None;
 
   // If you change this function, you must add or modify a test in PrintAsObjC.
@@ -596,7 +599,8 @@
 
   if (auto FD = dyn_cast<FuncDecl>(AFD)) {
     Type ResultType = FD->mapTypeIntoContext(FD->getResultInterfaceType());
-    if (!ResultType->hasError() &&
+    if (!FD->hasAsync() &&
+        !ResultType->hasError() &&
         !ResultType->isVoid() &&
         !ResultType->isUninhabited() &&
         !ResultType->isRepresentableIn(ForeignLanguage::ObjectiveC,
@@ -612,18 +616,95 @@
     }
   }
 
-  // Async functions cannot be mapped into Objective-C.
   if (AFD->hasAsync()) {
-    if (Diagnose) {
-      AFD->diagnose(diag::not_objc_function_async)
-        .highlight(AFD->getAsyncLoc());
-      describeObjCReason(AFD, Reason);
-    }
-    return false;
-  }
+    // Asynchronous functions move all of the result value and thrown error
+    // information into a completion handler.
+    auto FD = dyn_cast<FuncDecl>(AFD);
+    if (!FD) {
+      if (Diagnose) {
+        AFD->diagnose(diag::not_objc_function_async)
+          .highlight(AFD->getAsyncLoc());
+        describeObjCReason(AFD, Reason);
+      }
 
-  // Throwing functions must map to a particular error convention.
-  if (AFD->hasThrows()) {
+      return false;
+    }
+
+    // The completion handler transformation cannot properly represent a
+    // dynamic 'Self' type, so disallow @objc for such methods.
+    if (FD->hasDynamicSelfResult()) {
+      if (Diagnose) {
+        AFD->diagnose(diag::async_objc_dynamic_self)
+            .highlight(AFD->getAsyncLoc());
+        describeObjCReason(AFD, Reason);
+      }
+
+      return false;
+    }
+
+    // The completion handler parameter always goes at the end.
+    unsigned completionHandlerParamIndex = AFD->getParameters()->size();
+
+    // Decompose the return type to form the parameter type of the completion
+    // handler.
+    SmallVector<AnyFunctionType::Param, 2> completionHandlerParams;
+    auto addCompletionHandlerParam = [&](Type type) {
+      // For a throwing asynchronous function, make each parameter type optional
+      // if that's representable in Objective-C.
+      if (AFD->hasThrows() &&
+          !type->getOptionalObjectType() &&
+          isValidObjectiveCErrorResultType(const_cast<FuncDecl *>(FD), type)) {
+        type = OptionalType::get(type);
+      }
+
+      completionHandlerParams.push_back(AnyFunctionType::Param(type));
+
+      // Make sure that the paraneter type is representable in Objective-C.
+      if (!type->isRepresentableIn(
+              ForeignLanguage::ObjectiveC, const_cast<FuncDecl *>(FD))) {
+        if (Diagnose) {
+          AFD->diagnose(diag::objc_invalid_on_func_result_type,
+                        getObjCDiagnosticAttrKind(Reason));
+          diagnoseTypeNotRepresentableInObjC(FD, type,
+                                             FD->getResultTypeSourceRange());
+          describeObjCReason(FD, Reason);
+        }
+
+        return true;
+      }
+
+      return false;
+    };
+
+    // Translate the result type of the function into parameters for the
+    // completion handler parameter, exploding one level of tuple if needed.
+    Type resultType = FD->mapTypeIntoContext(FD->getResultInterfaceType());
+    if (auto tupleType = resultType->getAs<TupleType>()) {
+      for (const auto &tupleElt : tupleType->getElements()) {
+        addCompletionHandlerParam(tupleElt.getType());
+      }
+    } else {
+      addCompletionHandlerParam(resultType);
+    }
+
+    // For a throwing asynchronous function, an Error? parameter is added
+    // to the completion handler parameter, and will be non-nil to signal
+    // a thrown error.
+    Optional<unsigned> completionHandlerErrorParamIndex;
+    if (FD->hasThrows()) {
+      completionHandlerErrorParamIndex = completionHandlerParams.size();
+      addCompletionHandlerParam(OptionalType::get(ctx.getExceptionType()));
+    }
+
+    Type completionHandlerType = FunctionType::get(
+        completionHandlerParams, TupleType::getEmpty(ctx),
+        ASTExtInfoBuilder(FunctionTypeRepresentation::Block, false).build());
+
+    asyncConvention = ForeignAsyncConvention(
+        completionHandlerType->getCanonicalType(), completionHandlerParamIndex,
+        completionHandlerErrorParamIndex);
+  } else if (AFD->hasThrows()) {
+    // Synchronous throwing functions must map to a particular error convention.
     DeclContext *dc = const_cast<AbstractFunctionDecl *>(AFD);
     SourceLoc throwsLoc;
     Type resultType;
@@ -947,9 +1028,10 @@
     return false;
 
   if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
+    Optional<ForeignAsyncConvention> asyncConvention;
     Optional<ForeignErrorConvention> errorConvention;
     return isRepresentableInObjC(func, ObjCReason::MemberOfObjCMembersClass,
-                                 errorConvention);
+                                 asyncConvention, errorConvention);
   }
 
   if (auto var = dyn_cast<VarDecl>(decl))
@@ -1306,6 +1388,7 @@
 
 /// Record that a declaration is @objc.
 static void markAsObjC(ValueDecl *D, ObjCReason reason,
+                       Optional<ForeignAsyncConvention> asyncConvention,
                        Optional<ForeignErrorConvention> errorConvention);
 
 
@@ -1393,6 +1476,7 @@
   }
 
   // If needed, check whether this declaration is representable in Objective-C.
+  Optional<ForeignAsyncConvention> asyncConvention;
   Optional<ForeignErrorConvention> errorConvention;
   if (auto var = dyn_cast<VarDecl>(VD)) {
     if (!isRepresentableInObjC(var, *isObjC)) {
@@ -1407,14 +1491,15 @@
   } else if (isa<DestructorDecl>(VD)) {
     // Destructors need no additional checking.
   } else if (auto func = dyn_cast<AbstractFunctionDecl>(VD)) {
-    if (!isRepresentableInObjC(func, *isObjC, errorConvention)) {
+    if (!isRepresentableInObjC(
+            func, *isObjC, asyncConvention, errorConvention)) {
       makeNotObjC();
       return false;
     }
   }
 
   // Note that this declaration is exposed to Objective-C.
-  markAsObjC(VD, *isObjC, errorConvention);
+  markAsObjC(VD, *isObjC, asyncConvention, errorConvention);
 
   return true;
 }
@@ -1570,6 +1655,7 @@
 /// If the declaration has a @nonobjc attribute, diagnose an error
 /// using the given Reason, if present.
 void markAsObjC(ValueDecl *D, ObjCReason reason,
+                Optional<ForeignAsyncConvention> asyncConvention,
                 Optional<ForeignErrorConvention> errorConvention) {
   ASTContext &ctx = D->getASTContext();
 
@@ -1587,19 +1673,28 @@
   }
 
   if (auto method = dyn_cast<AbstractFunctionDecl>(D)) {
-    // Determine the foreign error convention.
-    Optional<ForeignErrorConvention> inheritedConvention;
-    AbstractFunctionDecl *declProvidingInheritedConvention = nullptr;
+    // Determine the foreign async and error conventions.
+    Optional<ForeignAsyncConvention> inheritedAsyncConvention;
+    AbstractFunctionDecl *declProvidingInheritedAsyncConvention = nullptr;
+    Optional<ForeignErrorConvention> inheritedErrorConvention;
+    AbstractFunctionDecl *declProvidingInheritedErrorConvention = nullptr;
     if (auto baseMethod = method->getOverriddenDecl()) {
-      // If the overridden method has a foreign error convention,
-      // adopt it.  Set the foreign error convention for a throwing
-      // method.  Note that the foreign error convention affects the
+      // If the overridden method has a foreign async or error convention,
+      // adopt it. Note that the foreign async or error convention affects the
       // selector, so we perform this before inferring a selector.
+      if (method->hasAsync()) {
+        if (auto baseAsyncConvention
+              = baseMethod->getForeignAsyncConvention()) {
+          inheritedAsyncConvention = baseAsyncConvention;
+          declProvidingInheritedAsyncConvention = baseMethod;
+        }
+      }
+
       if (method->hasThrows()) {
         if (auto baseErrorConvention
               = baseMethod->getForeignErrorConvention()) {
-          inheritedConvention = baseErrorConvention;
-          declProvidingInheritedConvention = baseMethod;
+          inheritedErrorConvention = baseErrorConvention;
+          declProvidingInheritedErrorConvention = baseMethod;
         }
       }
     }
@@ -1607,42 +1702,78 @@
     for (auto req : findWitnessedObjCRequirements(method)) {
       auto reqMethod = dyn_cast<AbstractFunctionDecl>(req);
       if (!reqMethod) continue;
-      
+
+      // If the method witnesses an ObjC requirement that is async, adopt its
+      // async convention.
+      if (reqMethod->hasAsync()) {
+        if (auto reqAsyncConvention = reqMethod->getForeignAsyncConvention()) {
+          // Check for a conflict among protocol conformances or inherited
+          // methods.
+          if (declProvidingInheritedAsyncConvention
+              && inheritedAsyncConvention != reqAsyncConvention) {
+            method->diagnose(diag::objc_ambiguous_async_convention,
+                             method->getName());
+            declProvidingInheritedAsyncConvention->diagnose(
+                diag::objc_ambiguous_async_convention_candidate,
+                declProvidingInheritedAsyncConvention->getName());
+            reqMethod->diagnose(diag::objc_ambiguous_async_convention_candidate,
+                                reqMethod->getName());
+            break;
+          }
+
+          inheritedAsyncConvention = reqAsyncConvention;
+          declProvidingInheritedAsyncConvention = reqMethod;
+        }
+      }
+
       // If the method witnesses an ObjC requirement that throws, adopt its
       // error convention.
       if (reqMethod->hasThrows()) {
         if (auto reqErrorConvention = reqMethod->getForeignErrorConvention()) {
           // Check for a conflict among protocol conformances or inherited
           // methods.
-          if (declProvidingInheritedConvention
-              && inheritedConvention != reqErrorConvention) {
+          if (declProvidingInheritedErrorConvention
+              && inheritedErrorConvention != reqErrorConvention) {
             method->diagnose(diag::objc_ambiguous_error_convention,
                              method->getName());
-            declProvidingInheritedConvention->diagnose(
-                             diag::objc_ambiguous_error_convention_candidate,
-                             declProvidingInheritedConvention->getName());
+            declProvidingInheritedErrorConvention->diagnose(
+                diag::objc_ambiguous_error_convention_candidate,
+                declProvidingInheritedErrorConvention->getName());
             reqMethod->diagnose(diag::objc_ambiguous_error_convention_candidate,
                                 reqMethod->getName());
             break;
           }
 
-          inheritedConvention = reqErrorConvention;
-          declProvidingInheritedConvention = reqMethod;
+          inheritedErrorConvention = reqErrorConvention;
+          declProvidingInheritedErrorConvention = reqMethod;
         }
       }
     }
 
+    // Attach the foreign async convention.
+    if (inheritedAsyncConvention) {
+      if (!method->hasAsync())
+        method->diagnose(diag::satisfy_async_objc,
+                         isa<ConstructorDecl>(method));
+      else
+        method->setForeignAsyncConvention(*inheritedAsyncConvention);
+
+    } else if (method->hasAsync()) {
+      assert(asyncConvention && "Missing async convention");
+      method->setForeignAsyncConvention(*asyncConvention);
+    }
+
     // Attach the foreign error convention.
-    if (inheritedConvention) {
+    if (inheritedErrorConvention) {
       // Diagnose if this is a method that does not throw
-      // but inherits an ObjC error convention.
+      // but inherits an ObjC error convention.
       if (!method->hasThrows())
         method->diagnose(diag::satisfy_throws_objc,
                          isa<ConstructorDecl>(method));
       else
-        method->setForeignErrorConvention(*inheritedConvention);
+        method->setForeignErrorConvention(*inheritedErrorConvention);
 
-    } else if (method->hasThrows()) {
+    } else if (method->hasThrows() && !method->hasAsync()) {
       assert(errorConvention && "Missing error convention");
       method->setForeignErrorConvention(*errorConvention);
     }
diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp
index 95f13757..e999479 100644
--- a/lib/Sema/TypeCheckDeclPrimary.cpp
+++ b/lib/Sema/TypeCheckDeclPrimary.cpp
@@ -1853,9 +1853,11 @@
     if (auto rawTy = ED->getRawType()) {
       // The raw type must be one of the blessed literal convertible types.
       if (!computeAutomaticEnumValueKind(ED)) {
-        DE.diagnose(ED->getInherited().front().getSourceRange().Start,
-                    diag::raw_type_not_literal_convertible, rawTy);
-        ED->getInherited().front().setType(ErrorType::get(getASTContext()));
+        if (!rawTy->is<ErrorType>()) {
+          DE.diagnose(ED->getInherited().front().getSourceRange().Start,
+                      diag::raw_type_not_literal_convertible, rawTy);
+          ED->getInherited().front().setType(ErrorType::get(getASTContext()));
+        }
       }
       
       // We need at least one case to have a raw value.
@@ -2015,7 +2017,7 @@
 
     TypeChecker::checkDeclAttributes(CD);
 
-    for (Decl *Member : CD->getEmittedMembers())
+    for (Decl *Member : CD->getSemanticMembers())
       visit(Member);
 
     TypeChecker::checkPatternBindingCaptures(CD);
@@ -2345,10 +2347,15 @@
     // FIXME: This needs to be moved to its own request if we want to
     // productize @_cdecl.
     if (auto CDeclAttr = FD->getAttrs().getAttribute<swift::CDeclAttr>()) {
+      Optional<ForeignAsyncConvention> asyncConvention;
       Optional<ForeignErrorConvention> errorConvention;
       if (isRepresentableInObjC(FD, ObjCReason::ExplicitlyCDecl,
-                                errorConvention)) {
-        if (FD->hasThrows()) {
+                                asyncConvention, errorConvention)) {
+        if (FD->hasAsync()) {
+          FD->setForeignAsyncConvention(*asyncConvention);
+          getASTContext().Diags.diagnose(CDeclAttr->getLocation(),
+                                         diag::cdecl_async);
+        } else if (FD->hasThrows()) {
           FD->setForeignErrorConvention(*errorConvention);
           getASTContext().Diags.diagnose(CDeclAttr->getLocation(),
                                          diag::cdecl_throws);
diff --git a/lib/Sema/TypeCheckEffects.cpp b/lib/Sema/TypeCheckEffects.cpp
index 4c595ca..09b4eaf 100644
--- a/lib/Sema/TypeCheckEffects.cpp
+++ b/lib/Sema/TypeCheckEffects.cpp
@@ -1329,6 +1329,29 @@
     void mergeFrom(ContextFlag flag, ContextFlags other) {
       Bits |= (other.Bits & flag);
     }
+
+    void mergeFrom(ContextFlags flags, ContextFlags other) {
+      Bits |= (other.Bits & flags.Bits);
+    }
+
+    // All of the flags that can be set by throw checking.
+    static ContextFlags throwFlags() {
+      ContextFlags result;
+      result.set(IsTryCovered);
+      result.set(IsInTry);
+      result.set(HasAnyThrowSite);
+      result.set(HasTryThrowSite);
+      return result;
+    }
+
+    // All of the flags that can be set by async/await checking.
+    static ContextFlags asyncAwaitFlags() {
+      ContextFlags result;
+      result.set(IsAsyncCovered);
+      result.set(HasAnyAsyncSite);
+      result.set(HasAnyAwait);
+      return result;
+    }
   };
 
   ContextFlags Flags;
@@ -1408,6 +1431,10 @@
       // body for the purposes of deciding whether a try contained
       // a throwing call.
       OldFlags.mergeFrom(ContextFlags::HasTryThrowSite, Self.Flags);
+
+      // "await" doesn't work this way; the "await" needs to be part of
+      // the autoclosure expression itself, and the autoclosure must be
+      // 'async'.
     }
 
     void preserveCoverageFromNonExhaustiveCatch() {
@@ -1417,16 +1444,21 @@
 
     void preserveCoverageFromAwaitOperand() {
       OldFlags.mergeFrom(ContextFlags::HasAnyAwait, Self.Flags);
+      OldFlags.mergeFrom(ContextFlags::throwFlags(), Self.Flags);
+      OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
     }
 
     void preserveCoverageFromTryOperand() {
       OldFlags.mergeFrom(ContextFlags::HasAnyThrowSite, Self.Flags);
+      OldFlags.mergeFrom(ContextFlags::asyncAwaitFlags(), Self.Flags);
       OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
     }
 
     void preserveCoverageFromInterpolatedString() {
       OldFlags.mergeFrom(ContextFlags::HasAnyThrowSite, Self.Flags);
       OldFlags.mergeFrom(ContextFlags::HasTryThrowSite, Self.Flags);
+      OldFlags.mergeFrom(ContextFlags::HasAnyAsyncSite, Self.Flags);
+      OldFlags.mergeFrom(ContextFlags::HasAnyAwait, Self.Flags);
       OldMaxThrowingKind = std::max(OldMaxThrowingKind, Self.MaxThrowingKind);
     }
     
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index 1cddaed..6305169 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -338,7 +338,8 @@
   return result;
 }
 
-bool TypeChecker::isUnsupportedMemberTypeAccess(Type type, TypeDecl *typeDecl) {
+TypeChecker::UnsupportedMemberTypeAccessKind
+TypeChecker::isUnsupportedMemberTypeAccess(Type type, TypeDecl *typeDecl) {
   // We don't allow lookups of a non-generic typealias of an unbound
   // generic type, because we have no way to model such a type in the
   // AST.
@@ -346,10 +347,7 @@
   // For generic typealiases, the typealias itself has an unbound
   // generic form whose parent type can be another unbound generic
   // type.
-  //
-  // FIXME: Could lift this restriction once we have sugared
-  // "member types".
-  if (type->is<UnboundGenericType>()) {
+  if (type->hasUnboundGenericType()) {
     // Generic typealiases can be accessed with an unbound generic
     // base, since we represent the member type as an unbound generic
     // type.
@@ -359,12 +357,12 @@
     if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(typeDecl)) {
       if (!aliasDecl->isGeneric() &&
           aliasDecl->getUnderlyingType()->hasTypeParameter()) {
-        return true;
+        return UnsupportedMemberTypeAccessKind::TypeAliasOfUnboundGeneric;
       }
     }
 
     if (isa<AssociatedTypeDecl>(typeDecl))
-      return true;
+      return UnsupportedMemberTypeAccessKind::AssociatedTypeOfUnboundGeneric;
   }
 
   if (type->isExistentialType() &&
@@ -374,15 +372,13 @@
     if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(typeDecl)) {
       if (aliasDecl->getUnderlyingType()->getCanonicalType()
           ->hasTypeParameter())
-        return true;
-    } else {
-      // Don't allow lookups of other nested types of an existential type,
-      // because there is no way to represent such types.
-      return true;
+        return UnsupportedMemberTypeAccessKind::TypeAliasOfExistential;
+    } else if (isa<AssociatedTypeDecl>(typeDecl)) {
+      return UnsupportedMemberTypeAccessKind::AssociatedTypeOfExistential;
     }
   }
 
-  return false;
+  return UnsupportedMemberTypeAccessKind::None;
 }
 
 LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
@@ -419,7 +415,8 @@
       continue;
     }
 
-    if (isUnsupportedMemberTypeAccess(type, typeDecl)) {
+    if (isUnsupportedMemberTypeAccess(type, typeDecl)
+          != TypeChecker::UnsupportedMemberTypeAccessKind::None) {
       auto memberType = typeDecl->getDeclaredInterfaceType();
 
       // Add the type to the result set, so that we can diagnose the
diff --git a/lib/Sema/TypeCheckObjC.h b/lib/Sema/TypeCheckObjC.h
index 808bb91..41a08f1 100644
--- a/lib/Sema/TypeCheckObjC.h
+++ b/lib/Sema/TypeCheckObjC.h
@@ -17,6 +17,7 @@
 #ifndef SWIFT_SEMA_TYPE_CHECK_OBJC_H
 #define SWIFT_SEMA_TYPE_CHECK_OBJC_H
 
+#include "swift/AST/ForeignAsyncConvention.h"
 #include "swift/AST/ForeignErrorConvention.h"
 #include "llvm/ADT/Optional.h"
 
@@ -123,6 +124,7 @@
 /// and figure out its foreign error convention (if any).
 bool isRepresentableInObjC(const AbstractFunctionDecl *AFD,
                            ObjCReason Reason,
+                           Optional<ForeignAsyncConvention> &asyncConvention,
                            Optional<ForeignErrorConvention> &errorConvention);
 
 /// Determine whether the given variable can be represented in Objective-C.
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 1e5c3a5..72d5446 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -122,7 +122,7 @@
   auto lookupOptions = defaultUnqualifiedLookupOptions;
   lookupOptions |= NameLookupFlags::KnownPrivate;
   auto lookup =
-      TypeChecker::lookupUnqualified(DC, name, SourceLoc(), lookupOptions);
+      TypeChecker::lookupUnqualified(DC, name, UseLoc, lookupOptions);
   return filterForEnumElement(DC, UseLoc,
                               /*unqualifiedLookup=*/true, lookup);
 }
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index b3b57e5..60b2543 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -19,6 +19,7 @@
 #include "DerivedConformances.h"
 #include "MiscDiagnostics.h"
 #include "TypeAccessScopeChecker.h"
+#include "TypeCheckAccess.h"
 #include "TypeCheckAvailability.h"
 #include "TypeCheckObjC.h"
 #include "swift/AST/ASTContext.h"
@@ -4039,7 +4040,8 @@
 static void checkExportability(Type depTy, Type replacementTy,
                                const ProtocolConformance *conformance,
                                NormalProtocolConformance *conformanceBeingChecked,
-                               SourceFile *SF) {
+                               DeclContext *DC) {
+  SourceFile *SF = DC->getParentSourceFile();
   if (!SF)
     return;
 
@@ -4049,13 +4051,17 @@
     if (!subConformance.isConcrete())
       continue;
     checkExportability(depTy, replacementTy, subConformance.getConcrete(),
-                       conformanceBeingChecked, SF);
+                       conformanceBeingChecked, DC);
   }
 
   const RootProtocolConformance *rootConformance =
       conformance->getRootConformance();
   ModuleDecl *M = rootConformance->getDeclContext()->getParentModule();
-  if (!SF->isImportedImplementationOnly(M))
+
+  auto originKind = getDisallowedOriginKind(
+      rootConformance->getDeclContext()->getAsDecl(),
+      *SF, DC->getAsDecl());
+  if (originKind == DisallowedOriginKind::None)
     return;
 
   ASTContext &ctx = SF->getASTContext();
@@ -4066,14 +4072,16 @@
         conformanceBeingChecked->getLoc(),
         diag::conformance_from_implementation_only_module,
         rootConformance->getType(),
-        rootConformance->getProtocol()->getName(), 0, M->getName());
+        rootConformance->getProtocol()->getName(), 0, M->getName(),
+        static_cast<unsigned>(originKind));
   } else {
     ctx.Diags.diagnose(
         conformanceBeingChecked->getLoc(),
         diag::assoc_conformance_from_implementation_only_module,
         rootConformance->getType(),
         rootConformance->getProtocol()->getName(), M->getName(),
-        depTy, replacementTy->getCanonicalType());
+        depTy, replacementTy->getCanonicalType(),
+        static_cast<unsigned>(originKind));
   }
 }
 
@@ -4122,11 +4130,7 @@
 
   // Now check that our associated conformances are at least as visible as
   // the conformance itself.
-  //
-  // FIXME: Do we need to check SPI here too?
   if (getRequiredAccessScope().isPublic() || isUsableFromInlineRequired()) {
-    auto *fileForCheckingExportability = DC->getParentSourceFile();
-
     for (auto req : proto->getRequirementSignature()) {
       if (req.getKind() == RequirementKind::Conformance) {
         auto depTy = req.getFirstType();
@@ -4136,7 +4140,7 @@
           auto *concrete = conformance.getConcrete();
           auto replacementTy = DC->mapTypeIntoContext(concrete->getType());
           checkExportability(depTy, replacementTy, concrete,
-                             Conformance, fileForCheckingExportability);
+                             Conformance, DC);
         }
       }
     }
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index 102b11d..c465e86 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -303,11 +303,6 @@
 /// same label.
 static void checkLabeledStmtShadowing(
     ASTContext &ctx, SourceFile *sourceFile, LabeledStmt *ls) {
-  // If ASTScope lookup is disabled, don't do this check at all.
-  // FIXME: Enable ASTScope lookup everywhere.
-  if (!ctx.LangOpts.EnableASTScopeLookup)
-    return;
-
   auto name = ls->getLabelInfo().Name;
   if (name.empty() || !sourceFile || ls->getStartLoc().isInvalid())
     return;
@@ -404,20 +399,11 @@
 static LabeledStmt *findBreakOrContinueStmtTarget(
     ASTContext &ctx, SourceFile *sourceFile,
     SourceLoc loc, Identifier targetName, SourceLoc targetLoc,
-    bool isContinue, DeclContext *dc,
-    ArrayRef<LabeledStmt *> oldActiveLabeledStmts) {
+    bool isContinue, DeclContext *dc) {
 
   // Retrieve the active set of labeled statements.
-  // FIXME: Once everything uses ASTScope lookup, \c oldActiveLabeledStmts
-  // can go away.
   SmallVector<LabeledStmt *, 4> activeLabeledStmts;
-  if (ctx.LangOpts.EnableASTScopeLookup) {
-    activeLabeledStmts = ASTScope::lookupLabeledStmts(sourceFile, loc);
-  } else {
-    activeLabeledStmts.insert(
-        activeLabeledStmts.end(),
-        oldActiveLabeledStmts.rbegin(), oldActiveLabeledStmts.rend());
-  }
+  activeLabeledStmts = ASTScope::lookupLabeledStmts(sourceFile, loc);
 
   // Handle an unlabeled break separately; that's the easy case.
   if (targetName.empty()) {
@@ -614,22 +600,13 @@
 /// Check the correctness of a 'fallthrough' statement.
 ///
 /// \returns true if an error occurred.
-static bool checkFallthroughStmt(
-    DeclContext *dc, FallthroughStmt *stmt,
-    CaseStmt *oldFallthroughSource, CaseStmt *oldFallthroughDest) {
+static bool checkFallthroughStmt(DeclContext *dc, FallthroughStmt *stmt) {
   CaseStmt *fallthroughSource;
   CaseStmt *fallthroughDest;
   ASTContext &ctx = dc->getASTContext();
-  if (ctx.LangOpts.EnableASTScopeLookup) {
-    auto sourceFile = dc->getParentSourceFile();
-    std::tie(fallthroughSource, fallthroughDest) =
-        ASTScope::lookupFallthroughSourceAndDest(sourceFile, stmt->getLoc());
-    assert(fallthroughSource == oldFallthroughSource);
-    assert(fallthroughDest == oldFallthroughDest);
-  } else {
-    fallthroughSource = oldFallthroughSource;
-    fallthroughDest = oldFallthroughDest;
-  }
+  auto sourceFile = dc->getParentSourceFile();
+  std::tie(fallthroughSource, fallthroughDest) =
+      ASTScope::lookupFallthroughSourceAndDest(sourceFile, stmt->getLoc());
 
   if (!fallthroughSource) {
     ctx.Diags.diagnose(stmt->getLoc(), diag::fallthrough_outside_switch);
@@ -655,85 +632,11 @@
   /// DC - This is the current DeclContext.
   DeclContext *DC;
 
-  // Scope information for control flow statements
-  // (break, continue, fallthrough).
-
-  /// The level of loop nesting. 'break' and 'continue' are valid only in scopes
-  /// where this is greater than one.
-  /// FIXME: Only required because EnableASTScopeLookup can be false
-  SmallVector<LabeledStmt*, 2> ActiveLabeledStmts;
-
-  /// The destination block for a 'fallthrough' statement. Null if the switch
-  /// scope depth is zero or if we are checking the final 'case' of the current
-  /// switch.
-  /// FIXME: Only required because EnableASTScopeLookup can be false
-  CaseStmt /*nullable*/ *FallthroughSource = nullptr;
-  CaseStmt /*nullable*/ *FallthroughDest = nullptr;
-
   /// Skip type checking any elements inside 'BraceStmt', also this is
   /// propagated to ConstraintSystem.
   bool LeaveBraceStmtBodyUnchecked = false;
 
   ASTContext &getASTContext() const { return Ctx; };
-  
-  struct AddLabeledStmt {
-    StmtChecker &SC;
-    AddLabeledStmt(StmtChecker &SC, LabeledStmt *LS) : SC(SC) {
-      // Verify that we don't have label shadowing.
-      auto sourceFile = SC.DC->getParentSourceFile();
-      checkLabeledStmtShadowing(SC.getASTContext(), sourceFile, LS);
-
-      // In any case, remember that we're in this labeled statement so that
-      // break and continue are aware of it.
-      SC.ActiveLabeledStmts.push_back(LS);
-
-      // Verify that the ASTScope-based query for active labeled statements
-      // is equivalent to what we have here.
-      if (LS->getStartLoc().isValid() && sourceFile &&
-          SC.getASTContext().LangOpts.EnableASTScopeLookup &&
-          !SC.getASTContext().Diags.hadAnyError() &&
-          !SC.LeaveBraceStmtBodyUnchecked) {
-        // The labeled statements from ASTScope lookup have the
-        // innermost labeled statement first, so reverse it to
-        // match the data structure maintained here.
-        auto activeFromASTScope = ASTScope::lookupLabeledStmts(
-            sourceFile, LS->getStartLoc());
-        assert(activeFromASTScope.front() == LS);
-        std::reverse(activeFromASTScope.begin(), activeFromASTScope.end());
-        if (activeFromASTScope != SC.ActiveLabeledStmts) {
-          llvm::errs() << "Old: ";
-          llvm::interleave(SC.ActiveLabeledStmts, [&](LabeledStmt *LS) {
-            llvm::errs() << LS;
-          }, [&] {
-            llvm::errs() << ' ';
-          });
-          llvm::errs() << "\nNew: ";
-          llvm::interleave(activeFromASTScope, [&](LabeledStmt *LS) {
-            llvm::errs() << LS;
-          }, [&] {
-            llvm::errs() << ' ';
-          });
-          llvm::errs() << "\n";
-        }
-        assert(activeFromASTScope == SC.ActiveLabeledStmts);
-      }
-    }
-    ~AddLabeledStmt() {
-      SC.ActiveLabeledStmts.pop_back();
-    }
-  };
-  
-  struct AddSwitchNest {
-    StmtChecker &SC;
-    CaseStmt *OuterFallthroughDest;
-    AddSwitchNest(StmtChecker &SC) : SC(SC),
-        OuterFallthroughDest(SC.FallthroughDest) {
-    }
-    
-    ~AddSwitchNest() {
-      SC.FallthroughDest = OuterFallthroughDest;
-    }
-  };
 
   StmtChecker(DeclContext *DC) : Ctx(DC->getASTContext()), DC(DC) { }
 
@@ -989,7 +892,8 @@
   Stmt *visitIfStmt(IfStmt *IS) {
     typeCheckConditionForStatement(IS, DC);
 
-    AddLabeledStmt ifNest(*this, IS);
+    auto sourceFile = DC->getParentSourceFile();
+    checkLabeledStmtShadowing(getASTContext(), sourceFile, IS);
 
     Stmt *S = IS->getThenStmt();
     typeCheckStmt(S);
@@ -1013,7 +917,9 @@
   }
 
   Stmt *visitDoStmt(DoStmt *DS) {
-    AddLabeledStmt loopNest(*this, DS);
+    auto sourceFile = DC->getParentSourceFile();
+    checkLabeledStmtShadowing(getASTContext(), sourceFile, DS);
+
     BraceStmt *S = DS->getBody();
     typeCheckStmt(S);
     DS->setBody(S);
@@ -1023,7 +929,9 @@
   Stmt *visitWhileStmt(WhileStmt *WS) {
     typeCheckConditionForStatement(WS, DC);
 
-    AddLabeledStmt loopNest(*this, WS);
+    auto sourceFile = DC->getParentSourceFile();
+    checkLabeledStmtShadowing(getASTContext(), sourceFile, WS);
+
     Stmt *S = WS->getBody();
     typeCheckStmt(S);
     WS->setBody(S);
@@ -1031,12 +939,12 @@
     return WS;
   }
   Stmt *visitRepeatWhileStmt(RepeatWhileStmt *RWS) {
-    {
-      AddLabeledStmt loopNest(*this, RWS);
-      Stmt *S = RWS->getBody();
-      typeCheckStmt(S);
-      RWS->setBody(S);
-    }
+    auto sourceFile = DC->getParentSourceFile();
+    checkLabeledStmtShadowing(getASTContext(), sourceFile, RWS);
+
+    Stmt *S = RWS->getBody();
+    typeCheckStmt(S);
+    RWS->setBody(S);
 
     Expr *E = RWS->getCond();
     TypeChecker::typeCheckCondition(E, DC);
@@ -1049,7 +957,9 @@
       return nullptr;
 
     // Type-check the body of the loop.
-    AddLabeledStmt loopNest(*this, S);
+    auto sourceFile = DC->getParentSourceFile();
+    checkLabeledStmtShadowing(getASTContext(), sourceFile, S);
+
     BraceStmt *Body = S->getBody();
     typeCheckStmt(Body);
     S->setBody(Body);
@@ -1061,7 +971,7 @@
     if (auto target = findBreakOrContinueStmtTarget(
             getASTContext(), DC->getParentSourceFile(), S->getLoc(),
             S->getTargetName(), S->getTargetLoc(), /*isContinue=*/false,
-            DC, ActiveLabeledStmts)) {
+            DC)) {
       S->setTarget(target);
     }
 
@@ -1072,7 +982,7 @@
     if (auto target = findBreakOrContinueStmtTarget(
             getASTContext(), DC->getParentSourceFile(), S->getLoc(),
             S->getTargetName(), S->getTargetLoc(), /*isContinue=*/true,
-            DC, ActiveLabeledStmts)) {
+            DC)) {
       S->setTarget(target);
     }
 
@@ -1080,7 +990,7 @@
   }
 
   Stmt *visitFallthroughStmt(FallthroughStmt *S) {
-    if (checkFallthroughStmt(DC, S, FallthroughSource, FallthroughDest))
+    if (checkFallthroughStmt(DC, S))
       return nullptr;
 
     return S;
@@ -1226,13 +1136,6 @@
     for (auto i = casesBegin; i != casesEnd; ++i) {
       auto *caseBlock = *i;
 
-      if (parentKind == CaseParentKind::Switch) {
-        // Fallthrough transfers control to the next case block. In the
-        // final case block, it is invalid. Only switch supports fallthrough.
-        FallthroughSource = caseBlock;
-        FallthroughDest = std::next(i) == casesEnd ? nullptr : *std::next(i);
-      }
-
       // Check restrictions on '@unknown'.
       if (caseBlock->hasUnknownAttr()) {
         assert(parentKind == CaseParentKind::Switch &&
@@ -1259,8 +1162,8 @@
     Type subjectType = switchStmt->getSubjectExpr()->getType();
 
     // Type-check the case blocks.
-    AddSwitchNest switchNest(*this);
-    AddLabeledStmt labelNest(*this, switchStmt);
+    auto sourceFile = DC->getParentSourceFile();
+    checkLabeledStmtShadowing(getASTContext(), sourceFile, switchStmt);
 
     // Pre-emptively visit all Decls (#if/#warning/#error) that still exist in
     // the list of raw cases.
@@ -1291,7 +1194,8 @@
     // The labels are in scope for both the 'do' and all of the catch
     // clauses.  This allows the user to break out of (or restart) the
     // entire construct.
-    AddLabeledStmt loopNest(*this, S);
+    auto sourceFile = DC->getParentSourceFile();
+    checkLabeledStmtShadowing(getASTContext(), sourceFile, S);
 
     // Type-check the 'do' body.  Type failures in here will generally
     // not cause type failures in the 'catch' clauses.
@@ -2006,6 +1910,11 @@
       // Wire up the function body now.
       func->setBody(*optBody, AbstractFunctionDecl::BodyKind::TypeChecked);
       return false;
+    } else if (func->hasSingleExpressionBody() &&
+                func->getResultInterfaceType()->isVoid()) {
+       // The function returns void.  We don't need an explicit return, no matter
+       // what the type of the expression is.  Take the inserted return back out.
+      func->getBody()->setFirstElement(func->getSingleExpressionBody());
     }
   }
 
@@ -2076,8 +1985,7 @@
   // Typechecking, in particular ApplySolution is going to replace closures
   // with OpaqueValueExprs and then try to do lookups into the closures.
   // So, build out the body now.
-  if (ctx.LangOpts.EnableASTScopeLookup)
-    ASTScope::expandFunctionBody(AFD);
+  ASTScope::expandFunctionBody(AFD);
 
   // Type check the function body if needed.
   bool hadError = false;
diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp
index 78c4d0b..4f16d32 100644
--- a/lib/Sema/TypeCheckStorage.cpp
+++ b/lib/Sema/TypeCheckStorage.cpp
@@ -590,7 +590,7 @@
 
   if (forProjected) {
     result.accessedProperty =
-        property->getPropertyWrapperBackingPropertyInfo().storageWrapperVar;
+        property->getPropertyWrapperBackingPropertyInfo().projectionVar;
   } else {
     result.accessedProperty = property;
   }
@@ -1380,7 +1380,7 @@
     }
 
     if (var->getOriginalWrappedProperty(
-            PropertyWrapperSynthesizedPropertyKind::StorageWrapper)) {
+            PropertyWrapperSynthesizedPropertyKind::Projection)) {
       return synthesizeTrivialGetterBody(getter, TargetImpl::WrapperStorage,
                                          ctx);
     }
@@ -1629,7 +1629,7 @@
     // Synthesize a setter for the storage wrapper property of a property
     // with an attached wrapper.
     if (auto original = var->getOriginalWrappedProperty(
-            PropertyWrapperSynthesizedPropertyKind::StorageWrapper)) {
+            PropertyWrapperSynthesizedPropertyKind::Projection)) {
       auto backingVar = original->getPropertyWrapperBackingProperty();
       return synthesizeTrivialSetterBodyWithStorage(setter,
                                                     TargetImpl::WrapperStorage,
@@ -1743,7 +1743,7 @@
       }
 
       if (var->getOriginalWrappedProperty(
-              PropertyWrapperSynthesizedPropertyKind::StorageWrapper)) {
+              PropertyWrapperSynthesizedPropertyKind::Projection)) {
         target = TargetImpl::WrapperStorage;
       }
     }
@@ -1961,7 +1961,7 @@
       case PropertyWrapperSynthesizedPropertyKind::Backing:
         break;
     
-      case PropertyWrapperSynthesizedPropertyKind::StorageWrapper: {
+      case PropertyWrapperSynthesizedPropertyKind::Projection: {
         if (auto origVar = var->getOriginalWrappedProperty(wrapperSynthesizedKind)) {
           // The property wrapper info may not actually link back to a wrapper
           // implementation, if there was a semantic error checking the wrapper.
@@ -2261,7 +2261,7 @@
     }
 
     if (auto original = var->getOriginalWrappedProperty(
-            PropertyWrapperSynthesizedPropertyKind::StorageWrapper)) {
+            PropertyWrapperSynthesizedPropertyKind::Projection)) {
       auto backingVar = original->getPropertyWrapperBackingProperty();
       if (backingVar->getFormalAccess() < var->getFormalAccess())
         return false;
@@ -2285,7 +2285,7 @@
 
           break;
         } else if (var->getOriginalWrappedProperty(
-                     PropertyWrapperSynthesizedPropertyKind::StorageWrapper)) {
+                     PropertyWrapperSynthesizedPropertyKind::Projection)) {
           break;
         }
       }
@@ -2381,7 +2381,7 @@
 
 /// Synthesize a computed property `$foo` for a property with an attached
 /// wrapper that has a `projectedValue` property.
-static VarDecl *synthesizePropertyWrapperStorageWrapperProperty(
+static VarDecl *synthesizePropertyWrapperProjectionVar(
     ASTContext &ctx, VarDecl *var, Type wrapperType,
     VarDecl *wrapperVar) {
   // If the original property has a @_projectedValueProperty attribute, use
@@ -2520,7 +2520,7 @@
   bool isProjectedValue = false;
   if (numWrappers < 1) {
     originalVar = var->getOriginalWrappedProperty(
-        PropertyWrapperSynthesizedPropertyKind::StorageWrapper);
+        PropertyWrapperSynthesizedPropertyKind::Projection);
     if (!originalVar)
       return None;
 
@@ -2598,7 +2598,7 @@
   bool isProjectedValue = false;
   if (numWrappers < 1) {
     VD = var->getOriginalWrappedProperty(
-        PropertyWrapperSynthesizedPropertyKind::StorageWrapper);
+        PropertyWrapperSynthesizedPropertyKind::Projection);
     numWrappers = 1; // Can't compose projected values
     isProjectedValue = true;
   }
@@ -2752,7 +2752,7 @@
   // synthesize a computed property for '$foo'.
   VarDecl *storageVar = nullptr;
   if (wrapperInfo.projectedValueVar) {
-    storageVar = synthesizePropertyWrapperStorageWrapperProperty(
+    storageVar = synthesizePropertyWrapperProjectionVar(
         ctx, var, storageInterfaceType, wrapperInfo.projectedValueVar);
   }
 
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index a3845b0..6e3dc8a 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -945,21 +945,32 @@
 
 /// Diagnose a use of an unbound generic type.
 static void diagnoseUnboundGenericType(Type ty, SourceLoc loc) {
-  auto unbound = ty->castTo<UnboundGenericType>();
-  {
-    auto &ctx = ty->getASTContext();
-    InFlightDiagnostic diag = ctx.Diags.diagnose(loc,
-        diag::generic_type_requires_arguments, ty);
-    if (auto *genericD = unbound->getDecl()) {
+  auto &ctx = ty->getASTContext();
+  if (auto unbound = ty->getAs<UnboundGenericType>()) {
+    auto *decl = unbound->getDecl();
+    {
+      InFlightDiagnostic diag = ctx.Diags.diagnose(loc,
+          diag::generic_type_requires_arguments, ty);
       SmallString<64> genericArgsToAdd;
       if (TypeChecker::getDefaultGenericArgumentsString(genericArgsToAdd,
-                                                        genericD))
+                                                        decl))
         diag.fixItInsertAfter(loc, genericArgsToAdd);
     }
+
+    decl->diagnose(diag::kind_declname_declared_here,
+                   DescriptiveDeclKind::GenericType,
+                   decl->getName());
+  } else {
+    ty.findIf([&](Type t) -> bool {
+      if (auto unbound = t->getAs<UnboundGenericType>()) {
+        ctx.Diags.diagnose(loc,
+            diag::generic_type_requires_arguments, t);
+        return true;
+      }
+
+      return false;
+    });
   }
-  unbound->getDecl()->diagnose(diag::kind_declname_declared_here,
-                               DescriptiveDeclKind::GenericType,
-                               unbound->getDecl()->getName());
 }
 
 // Produce a diagnostic if the type we referenced was an
@@ -1417,22 +1428,29 @@
 
   auto maybeDiagnoseBadMemberType = [&](TypeDecl *member, Type memberType,
                                         AssociatedTypeDecl *inferredAssocType) {
-    // Diagnose invalid cases.
-    if (TypeChecker::isUnsupportedMemberTypeAccess(parentTy, member)) {
-      if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
-        if (parentTy->is<UnboundGenericType>())
-          diagnoseUnboundGenericType(parentTy, parentRange.End);
-        else if (parentTy->isExistentialType() &&
-                 isa<AssociatedTypeDecl>(member)) {
-          diags.diagnose(comp->getNameLoc(), diag::assoc_type_outside_of_protocol,
-                         comp->getNameRef());
-        } else if (parentTy->isExistentialType() &&
-                   isa<TypeAliasDecl>(member)) {
-          diags.diagnose(comp->getNameLoc(), diag::typealias_outside_of_protocol,
-                         comp->getNameRef());
-        }
-      }
+    if (options.contains(TypeResolutionFlags::SilenceErrors)) {
+      if (TypeChecker::isUnsupportedMemberTypeAccess(parentTy, member)
+            != TypeChecker::UnsupportedMemberTypeAccessKind::None)
+        return ErrorType::get(ctx);
+    }
 
+    switch (TypeChecker::isUnsupportedMemberTypeAccess(parentTy, member)) {
+    case TypeChecker::UnsupportedMemberTypeAccessKind::None:
+      break;
+
+    case TypeChecker::UnsupportedMemberTypeAccessKind::TypeAliasOfUnboundGeneric:
+    case TypeChecker::UnsupportedMemberTypeAccessKind::AssociatedTypeOfUnboundGeneric:
+      diagnoseUnboundGenericType(parentTy, parentRange.End);
+      return ErrorType::get(ctx);
+
+    case TypeChecker::UnsupportedMemberTypeAccessKind::TypeAliasOfExistential:
+      diags.diagnose(comp->getNameLoc(), diag::typealias_outside_of_protocol,
+                     comp->getNameRef());
+      return ErrorType::get(ctx);
+
+    case TypeChecker::UnsupportedMemberTypeAccessKind::AssociatedTypeOfExistential:
+      diags.diagnose(comp->getNameLoc(), diag::assoc_type_outside_of_protocol,
+                     comp->getNameRef());
       return ErrorType::get(ctx);
     }
 
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index 1b4c382..9433f75 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -215,11 +215,17 @@
     if (!SF)
       continue;
 
-    for (auto D : SF->getTopLevelDecls()) {
+    auto visitTopLevelDecl = [&](Decl *D) {
       if (auto ED = dyn_cast<ExtensionDecl>(D))
         if (!tryBindExtension(ED))
-          worklist.push_back(ED);
-    }
+          worklist.push_back(ED);;
+    };
+
+    for (auto *D : SF->getTopLevelDecls())
+      visitTopLevelDecl(D);
+
+    for (auto *D : SF->getHoistedDecls())
+      visitTopLevelDecl(D);
   }
 
   // Phase 2 - repeatedly go through the worklist and attempt to bind each
@@ -285,9 +291,8 @@
   // scope-based lookups. Only the top-level scopes because extensions have not
   // been bound yet.
   auto &Ctx = SF->getASTContext();
-  if (Ctx.LangOpts.EnableASTScopeLookup)
-    SF->getScope()
-        .buildEnoughOfTreeForTopLevelExpressionsButDontRequestGenericsOrExtendedNominals();
+  SF->getScope()
+      .buildEnoughOfTreeForTopLevelExpressionsButDontRequestGenericsOrExtendedNominals();
 
   BufferIndirectlyCausingDiagnosticRAII cpr(*SF);
 
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index ddc5711..356c6c6 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -636,8 +636,11 @@
 /// it doesn't mutate given expression, even if there is a single valid
 /// solution, and constraint solver is allowed to produce partially correct
 /// solutions. Such solutions can have any number of holes in them.
-void typeCheckForCodeCompletion(
-    Expr *expr, DeclContext *DC, Type contextualType, ContextualTypePurpose CTP,
+///
+/// \returns `true` if target was applicable and it was possible to infer
+/// types for code completion, `false` othrewise.
+bool typeCheckForCodeCompletion(
+    constraints::SolutionApplicationTarget &target,
     llvm::function_ref<void(const constraints::Solution &)> callback);
 
 /// Check the key-path expression.
@@ -927,9 +930,18 @@
 PrecedenceGroupLookupResult
 lookupPrecedenceGroup(DeclContext *dc, Identifier name, SourceLoc nameLoc);
 
+enum class UnsupportedMemberTypeAccessKind : uint8_t {
+  None,
+  TypeAliasOfUnboundGeneric,
+  TypeAliasOfExistential,
+  AssociatedTypeOfUnboundGeneric,
+  AssociatedTypeOfExistential
+};
+
 /// Check whether the given declaration can be written as a
 /// member of the given base type.
-bool isUnsupportedMemberTypeAccess(Type type, TypeDecl *typeDecl);
+UnsupportedMemberTypeAccessKind
+isUnsupportedMemberTypeAccess(Type type, TypeDecl *typeDecl);
 
 /// @}
 
@@ -1212,6 +1224,13 @@
 /// If \c expr is not part of a member chain or the base is something other than
 /// an \c UnresolvedMemberExpr, \c nullptr is returned.
 UnresolvedMemberExpr *getUnresolvedMemberChainBase(Expr *expr);
+
+/// Checks whether a function builder type has a well-formed function builder
+/// method with the given name. If provided and non-empty, the argument labels
+/// are verified against any candidates.
+bool typeSupportsBuilderOp(Type builderType, DeclContext *dc, Identifier fnName,
+                           ArrayRef<Identifier> argLabels = {},
+                           SmallVectorImpl<ValueDecl *> *allResults = nullptr);
 }; // namespace TypeChecker
 
 /// Temporary on-stack storage and unescaping for encoded diagnostic
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 724aef5..f2f70f9 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -2905,13 +2905,13 @@
       }
 
       VarDecl *backingVar = cast<VarDecl>(backingDecl.get());
-      VarDecl *storageWrapperVar = nullptr;
+      VarDecl *projectionVar = nullptr;
       if (numBackingProperties > 1) {
-        storageWrapperVar = cast<VarDecl>(MF.getDecl(backingPropertyIDs[1]));
+        projectionVar = cast<VarDecl>(MF.getDecl(backingPropertyIDs[1]));
       }
 
       PropertyWrapperBackingPropertyInfo info(
-          backingVar, storageWrapperVar, nullptr, nullptr);
+          backingVar, projectionVar, nullptr, nullptr);
       ctx.evaluator.cacheOutput(
           PropertyWrapperBackingPropertyInfoRequest{var}, std::move(info));
       ctx.evaluator.cacheOutput(
@@ -2919,8 +2919,8 @@
           backingVar->getInterfaceType());
       backingVar->setOriginalWrappedProperty(var);
 
-      if (storageWrapperVar)
-        storageWrapperVar->setOriginalWrappedProperty(var);
+      if (projectionVar)
+        projectionVar->setOriginalWrappedProperty(var);
     }
 
     return var;
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index b2cfae7..b3024b0 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -511,14 +511,14 @@
   GenericSignatureID genericSigID;
   unsigned rawLinkage, isTransparent, isSerialized, isThunk,
       isWithoutactuallyEscapingThunk, specialPurpose, inlineStrategy,
-      optimizationMode, subclassScope, effect, numSpecAttrs,
+      optimizationMode, subclassScope, hasCReferences, effect, numSpecAttrs,
       hasQualifiedOwnership, isWeakImported, LIST_VER_TUPLE_PIECES(available),
       isDynamic, isExactSelfClass;
   ArrayRef<uint64_t> SemanticsIDs;
   SILFunctionLayout::readRecord(
       scratch, rawLinkage, isTransparent, isSerialized, isThunk,
       isWithoutactuallyEscapingThunk, specialPurpose, inlineStrategy,
-      optimizationMode, subclassScope, effect, numSpecAttrs,
+      optimizationMode, subclassScope, hasCReferences, effect, numSpecAttrs,
       hasQualifiedOwnership, isWeakImported, LIST_VER_TUPLE_PIECES(available),
       isDynamic, isExactSelfClass, funcTyID, replacedFunctionID, genericSigID,
       clangNodeOwnerID, SemanticsIDs);
@@ -639,6 +639,7 @@
     fn->setOptimizationMode(OptimizationMode(optimizationMode));
     fn->setAlwaysWeakImported(isWeakImported);
     fn->setClassSubclassScope(SubclassScope(subclassScope));
+    fn->setHasCReferences(bool(hasCReferences));
 
     llvm::VersionTuple available;
     DECODE_VER_TUPLE(available);
@@ -1178,7 +1179,7 @@
   // FIXME: validate
   SILInstructionKind OpCode = (SILInstructionKind) RawOpCode;
 
-  SILInstruction *ResultVal;
+  SILInstruction *ResultInst;
   switch (OpCode) {
   case SILInstructionKind::DebugValueInst:
   case SILInstructionKind::DebugValueAddrInst:
@@ -1186,19 +1187,19 @@
 
   case SILInstructionKind::AllocBoxInst:
     assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
-    ResultVal = Builder.createAllocBox(Loc,
-                       cast<SILBoxType>(MF->getType(TyID)->getCanonicalType()),
-                       None, /*bool hasDynamicLifetime*/ Attr != 0);
+    ResultInst = Builder.createAllocBox(
+        Loc, cast<SILBoxType>(MF->getType(TyID)->getCanonicalType()), None,
+        /*bool hasDynamicLifetime*/ Attr != 0);
     break;
   case SILInstructionKind::AllocStackInst:
     assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
-    ResultVal = Builder.createAllocStack(
+    ResultInst = Builder.createAllocStack(
         Loc, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn),
         None, /*bool hasDynamicLifetime*/ Attr != 0);
     break;
   case SILInstructionKind::MetatypeInst:
     assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
-    ResultVal = Builder.createMetatype(
+    ResultInst = Builder.createMetatype(
         Loc, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
     break;
 
@@ -1206,7 +1207,7 @@
   case SILInstructionKind::ID##Inst:                                           \
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&                           \
            "Layout should be OneTypeOneOperand.");                             \
-    ResultVal = Builder.create##ID(                                            \
+    ResultInst = Builder.create##ID(                                           \
         Loc, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn),  \
         getLocalValue(ValID, getSILType(MF->getType(TyID2),                    \
                                         (SILValueCategory)TyCategory2, Fn)));  \
@@ -1221,7 +1222,7 @@
   case SILInstructionKind::DeallocBoxInst:
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
            "Layout should be OneTypeOneOperand.");
-    ResultVal = Builder.createDeallocBox(
+    ResultInst = Builder.createDeallocBox(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2, Fn)));
@@ -1229,7 +1230,7 @@
   case SILInstructionKind::OpenExistentialAddrInst:
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
            "Layout should be OneTypeOneOperand.");
-    ResultVal = Builder.createOpenExistentialAddr(
+    ResultInst = Builder.createOpenExistentialAddr(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2, Fn)),
@@ -1242,7 +1243,7 @@
   case SILInstructionKind::ID##Inst:                                           \
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&                           \
            "Layout should be OneTypeOneOperand.");                             \
-    ResultVal = Builder.create##ID(                                            \
+    ResultInst = Builder.create##ID(                                           \
         Loc,                                                                   \
         getLocalValue(ValID, getSILType(MF->getType(TyID2),                    \
                                         (SILValueCategory)TyCategory2, Fn)),   \
@@ -1282,7 +1283,7 @@
   case SILInstructionKind::ProjectBoxInst: {
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
            "Layout should be OneTypeOneOperand.");
-    ResultVal = Builder.createProjectBox(
+    ResultInst = Builder.createProjectBox(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2, Fn)),
@@ -1293,7 +1294,7 @@
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
            "Layout should be OneTypeOneOperand.");
     bool isLifetimeGuaranteed = Attr & 0x01;
-    ResultVal = Builder.createConvertEscapeToNoEscape(
+    ResultInst = Builder.createConvertEscapeToNoEscape(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2, Fn)),
@@ -1305,7 +1306,7 @@
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND
            && "Layout should be OneTypeOneOperand.");
     bool withoutActuallyEscaping = Attr & 0x01;
-    ResultVal = Builder.createConvertFunction(
+    ResultInst = Builder.createConvertFunction(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2, Fn)),
@@ -1318,18 +1319,18 @@
            "Layout should be OneTypeOneOperand.");
     bool isStrict = Attr & 0x01;
     bool isInvariant = Attr & 0x02;
-    ResultVal = Builder.createPointerToAddress(
+    ResultInst = Builder.createPointerToAddress(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2, Fn)),
-        getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn), isStrict,
-        isInvariant);
+        getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn),
+        isStrict, isInvariant);
     break;
   }
   case SILInstructionKind::DeallocExistentialBoxInst: {
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
            "Layout should be OneTypeOneOperand.");
-    ResultVal = Builder.createDeallocExistentialBox(
+    ResultInst = Builder.createDeallocExistentialBox(
         Loc, MF->getType(TyID)->getCanonicalType(),
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2, Fn)));
@@ -1344,15 +1345,15 @@
     auto BitsTy =
         getSILType(MF->getType(TyID2), (SILValueCategory)TyCategory2, Fn);
     auto Bits = getLocalValue(ValID2, BitsTy);
-    
-    ResultVal = Builder.createRefToBridgeObject(Loc, Ref, Bits);
+
+    ResultInst = Builder.createRefToBridgeObject(Loc, Ref, Bits);
     break;
   }
 
   case SILInstructionKind::ObjCProtocolInst: {
     auto Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
     auto Proto = MF->getDecl(ValID);
-    ResultVal = Builder.createObjCProtocol(Loc, cast<ProtocolDecl>(Proto), Ty);
+    ResultInst = Builder.createObjCProtocol(Loc, cast<ProtocolDecl>(Proto), Ty);
     break;
   }
 
@@ -1383,28 +1384,24 @@
     switch (OpCode) {
     default: llvm_unreachable("Out of sync with parent switch");
     case SILInstructionKind::InitExistentialAddrInst:
-      ResultVal = Builder.createInitExistentialAddr(Loc, operand,
-                                                ConcreteTy,
-                                                Ty,
-                                                ctxConformances);
+      ResultInst = Builder.createInitExistentialAddr(Loc, operand, ConcreteTy,
+                                                     Ty, ctxConformances);
       break;
     case SILInstructionKind::InitExistentialValueInst:
-      ResultVal = Builder.createInitExistentialValue(Loc, Ty, ConcreteTy,
+      ResultInst = Builder.createInitExistentialValue(Loc, Ty, ConcreteTy,
                                                       operand, ctxConformances);
       break;
     case SILInstructionKind::InitExistentialMetatypeInst:
-      ResultVal = Builder.createInitExistentialMetatype(Loc, operand, Ty,
-                                                        ctxConformances);
+      ResultInst = Builder.createInitExistentialMetatype(Loc, operand, Ty,
+                                                         ctxConformances);
       break;
     case SILInstructionKind::InitExistentialRefInst:
-      ResultVal = Builder.createInitExistentialRef(Loc, Ty,
-                                         ConcreteTy,
-                                         operand,
-                                         ctxConformances);
+      ResultInst = Builder.createInitExistentialRef(Loc, Ty, ConcreteTy,
+                                                    operand, ctxConformances);
       break;
     case SILInstructionKind::AllocExistentialBoxInst:
-      ResultVal = Builder.createAllocExistentialBox(Loc, Ty, ConcreteTy,
-                                  ctxConformances);
+      ResultInst = Builder.createAllocExistentialBox(Loc, Ty, ConcreteTy,
+                                                     ctxConformances);
       break;
     }
     break;
@@ -1438,12 +1435,12 @@
       SILType MetadataType = getSILType(MF->getType(ListOfValues[i+1]),
                                         SILValueCategory::Object, Fn);
       SILValue MetadataOp = getLocalValue(ListOfValues[i], MetadataType);
-      ResultVal = Builder.createAllocRefDynamic(Loc, MetadataOp, ClassTy,
-                                                isObjC, TailTypes, Counts);
+      ResultInst = Builder.createAllocRefDynamic(Loc, MetadataOp, ClassTy,
+                                                 isObjC, TailTypes, Counts);
     } else {
       assert(i == NumVals);
-      ResultVal = Builder.createAllocRef(Loc, ClassTy, isObjC, canAllocOnStack,
-                                         TailTypes, Counts);
+      ResultInst = Builder.createAllocRef(Loc, ClassTy, isObjC, canAllocOnStack,
+                                          TailTypes, Counts);
     }
     break;
   }
@@ -1468,13 +1465,13 @@
     SubstitutionMap Substitutions = MF->getSubstitutionMap(NumSubs);
 
     if (OpCode == SILInstructionKind::ApplyInst) {
-      ResultVal = Builder.createApply(Loc, getLocalValue(ValID, FnTy),
-                                      Substitutions, Args,
-                                      IsNonThrowingApply != 0);
+      ResultInst =
+          Builder.createApply(Loc, getLocalValue(ValID, FnTy), Substitutions,
+                              Args, IsNonThrowingApply != 0);
     } else {
-      ResultVal = Builder.createBeginApply(Loc, getLocalValue(ValID, FnTy),
-                                           Substitutions, Args,
-                                           IsNonThrowingApply != 0);
+      ResultInst = Builder.createBeginApply(Loc, getLocalValue(ValID, FnTy),
+                                            Substitutions, Args,
+                                            IsNonThrowingApply != 0);
     }
     break;
   }
@@ -1504,9 +1501,8 @@
                                        I, Builder.getTypeExpansionContext())));
     SubstitutionMap Substitutions = MF->getSubstitutionMap(NumSubs);
 
-    ResultVal = Builder.createTryApply(Loc, getLocalValue(ValID, FnTy),
-                                       Substitutions, Args, normalBB,
-                                       errorBB);
+    ResultInst = Builder.createTryApply(Loc, getLocalValue(ValID, FnTy),
+                                        Substitutions, Args, normalBB, errorBB);
     break;
   }
   case SILInstructionKind::PartialApplyInst: {
@@ -1540,7 +1536,7 @@
                        ? PartialApplyInst::OnStackKind::OnStack
                        : PartialApplyInst::OnStackKind::NotOnStack;
     // FIXME: Why the arbitrary order difference in IRBuilder type argument?
-    ResultVal = Builder.createPartialApply(
+    ResultInst = Builder.createPartialApply(
         Loc, FnVal, Substitutions, Args,
         closureTy.castTo<SILFunctionType>()->getCalleeConvention(), onStack);
     break;
@@ -1557,9 +1553,9 @@
     }
     SubstitutionMap Substitutions = MF->getSubstitutionMap(NumSubs);
     Identifier Name = MF->getIdentifier(ValID);
-    
-    ResultVal = Builder.createBuiltin(Loc, Name, ResultTy, Substitutions,
-                                      Args);
+
+    ResultInst =
+        Builder.createBuiltin(Loc, Name, ResultTy, Substitutions, Args);
     break;
   }
   case SILInstructionKind::AllocGlobalInst: {
@@ -1570,7 +1566,7 @@
     SILGlobalVariable *g = getGlobalForReference(Name);
     assert(g && "Can't deserialize global variable");
 
-    ResultVal = Builder.createAllocGlobal(Loc, g);
+    ResultInst = Builder.createAllocGlobal(Loc, g);
     break;
   }
   case SILInstructionKind::GlobalAddrInst:
@@ -1592,20 +1588,20 @@
     (void)Ty;
     (void)expectedType;
     if (OpCode == SILInstructionKind::GlobalAddrInst) {
-      ResultVal = Builder.createGlobalAddr(Loc, g);
+      ResultInst = Builder.createGlobalAddr(Loc, g);
     } else {
-      ResultVal = Builder.createGlobalValue(Loc, g);
+      ResultInst = Builder.createGlobalValue(Loc, g);
     }
     break;
   }
   case SILInstructionKind::BaseAddrForOffsetInst:
     assert(RecordKind == SIL_ONE_TYPE && "Layout should be OneType.");
-    ResultVal = Builder.createBaseAddrForOffset(Loc,
-              getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
+    ResultInst = Builder.createBaseAddrForOffset(
+        Loc, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
     break;
   case SILInstructionKind::DeallocStackInst: {
     auto Ty = MF->getType(TyID);
-    ResultVal = Builder.createDeallocStack(
+    ResultInst = Builder.createDeallocStack(
         Loc,
         getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)));
     break;
@@ -1613,7 +1609,7 @@
   case SILInstructionKind::DeallocRefInst: {
     auto Ty = MF->getType(TyID);
     bool OnStack = (bool)Attr;
-    ResultVal = Builder.createDeallocRef(
+    ResultInst = Builder.createDeallocRef(
         Loc,
         getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
         OnStack);
@@ -1622,17 +1618,17 @@
   case SILInstructionKind::DeallocPartialRefInst: {
     auto Ty = MF->getType(TyID);
     auto Ty2 = MF->getType(TyID2);
-    ResultVal = Builder.createDeallocPartialRef(Loc,
-        getLocalValue(ValID,
-                      getSILType(Ty,  (SILValueCategory)TyCategory, Fn)),
+    ResultInst = Builder.createDeallocPartialRef(
+        Loc,
+        getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
         getLocalValue(ValID2,
-                      getSILType(Ty2,  (SILValueCategory)TyCategory2, Fn)));
+                      getSILType(Ty2, (SILValueCategory)TyCategory2, Fn)));
     break;
   }
   case SILInstructionKind::FunctionRefInst: {
     auto Ty = MF->getType(TyID);
     StringRef FuncName = MF->getIdentifierText(ValID);
-    ResultVal = Builder.createFunctionRef(
+    ResultInst = Builder.createFunctionRef(
         Loc,
         getFuncForReference(
             FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr)));
@@ -1641,7 +1637,7 @@
   case SILInstructionKind::DynamicFunctionRefInst: {
     auto Ty = MF->getType(TyID);
     StringRef FuncName = MF->getIdentifierText(ValID);
-    ResultVal = Builder.createDynamicFunctionRef(
+    ResultInst = Builder.createDynamicFunctionRef(
         Loc,
         getFuncForReference(
             FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr)));
@@ -1650,7 +1646,7 @@
   case SILInstructionKind::PreviousDynamicFunctionRefInst: {
     auto Ty = MF->getType(TyID);
     StringRef FuncName = MF->getIdentifierText(ValID);
-    ResultVal = Builder.createPreviousDynamicFunctionRef(
+    ResultInst = Builder.createPreviousDynamicFunctionRef(
         Loc,
         getFuncForReference(
             FuncName, getSILType(Ty, (SILValueCategory)TyCategory, nullptr)));
@@ -1659,7 +1655,7 @@
   case SILInstructionKind::MarkDependenceInst: {
     auto Ty = MF->getType(TyID);
     auto Ty2 = MF->getType(TyID2);
-    ResultVal = Builder.createMarkDependence(
+    ResultInst = Builder.createMarkDependence(
         Loc,
         getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
         getLocalValue(ValID2,
@@ -1669,7 +1665,7 @@
   case SILInstructionKind::CopyBlockWithoutEscapingInst: {
     auto Ty = MF->getType(TyID);
     auto Ty2 = MF->getType(TyID2);
-    ResultVal = Builder.createCopyBlockWithoutEscaping(
+    ResultInst = Builder.createCopyBlockWithoutEscaping(
         Loc,
         getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
         getLocalValue(ValID2,
@@ -1679,7 +1675,7 @@
   case SILInstructionKind::IndexAddrInst: {
     auto Ty = MF->getType(TyID);
     auto Ty2 = MF->getType(TyID2);
-    ResultVal = Builder.createIndexAddr(
+    ResultInst = Builder.createIndexAddr(
         Loc,
         getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
         getLocalValue(ValID2,
@@ -1690,7 +1686,7 @@
     auto Ty = MF->getType(TyID);
     auto Ty2 = MF->getType(TyID2);
     auto ResultTy = MF->getType(TyID3);
-    ResultVal = Builder.createTailAddr(
+    ResultInst = Builder.createTailAddr(
         Loc,
         getLocalValue(ValID, getSILType(Ty, SILValueCategory::Address, Fn)),
         getLocalValue(ValID2, getSILType(Ty2, SILValueCategory::Object, Fn)),
@@ -1700,7 +1696,7 @@
   case SILInstructionKind::IndexRawPointerInst: {
     auto Ty = MF->getType(TyID);
     auto Ty2 = MF->getType(TyID2);
-    ResultVal = Builder.createIndexRawPointer(
+    ResultInst = Builder.createIndexRawPointer(
         Loc,
         getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
         getLocalValue(ValID2,
@@ -1714,7 +1710,7 @@
     bool negate = text[0] == '-';
     if (negate) text = text.drop_front();
     APInt value = intTy->getWidth().parse(text, 10, negate);
-    ResultVal = Builder.createIntegerLiteral(
+    ResultInst = Builder.createIntegerLiteral(
         Loc, getSILType(Ty, (SILValueCategory)TyCategory, Fn), value);
     break;
   }
@@ -1729,7 +1725,7 @@
 
     APFloat value(floatTy->getAPFloatSemantics(), bits);
 
-    ResultVal = Builder.createFloatLiteral(
+    ResultInst = Builder.createFloatLiteral(
         Loc, getSILType(Ty, (SILValueCategory)TyCategory, Fn), value);
     break;
   }
@@ -1737,15 +1733,15 @@
     StringRef StringVal = MF->getIdentifierText(ValID);
     auto encoding = fromStableStringEncoding(Attr);
     if (!encoding) return true;
-    ResultVal = Builder.createStringLiteral(Loc, StringVal,
-                                            encoding.getValue());
+    ResultInst =
+        Builder.createStringLiteral(Loc, StringVal, encoding.getValue());
     break;
   }
   case SILInstructionKind::CondFailInst: {
     SILValue Op = getLocalValue(
         ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
     StringRef StringVal = MF->getIdentifierText(ValID2);
-    ResultVal = Builder.createCondFail(Loc, Op, StringVal);
+    ResultInst = Builder.createCondFail(Loc, Op, StringVal);
     break;
   }
   case SILInstructionKind::MarkFunctionEscapeInst: {
@@ -1758,7 +1754,7 @@
           ListOfValues[I + 2],
           getSILType(EltTy, (SILValueCategory)ListOfValues[I + 1], Fn)));
     }
-    ResultVal = Builder.createMarkFunctionEscape(Loc, OpList);
+    ResultInst = Builder.createMarkFunctionEscape(Loc, OpList);
     break;
   }
   // Checked Conversion instructions.
@@ -1771,7 +1767,7 @@
         getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
     CanType targetFormalType =
         MF->getType(ListOfValues[3])->getCanonicalType();
-    ResultVal = Builder.createUnconditionalCheckedCast(
+    ResultInst = Builder.createUnconditionalCheckedCast(
         Loc, src, targetLoweredType, targetFormalType);
     break;
   }
@@ -1779,7 +1775,7 @@
 #define UNARY_INSTRUCTION(ID)                                                  \
   case SILInstructionKind::ID##Inst:                                           \
     assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");   \
-    ResultVal = Builder.create##ID(                                            \
+    ResultInst = Builder.create##ID(                                           \
         Loc,                                                                   \
         getLocalValue(ValID, getSILType(MF->getType(TyID),                     \
                                         (SILValueCategory)TyCategory, Fn)));   \
@@ -1788,7 +1784,7 @@
 #define REFCOUNTING_INSTRUCTION(ID)                                            \
   case SILInstructionKind::ID##Inst:                                           \
     assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");   \
-    ResultVal = Builder.create##ID(                                            \
+    ResultInst = Builder.create##ID(                                           \
         Loc,                                                                   \
         getLocalValue(ValID, getSILType(MF->getType(TyID),                     \
                                         (SILValueCategory)TyCategory, Fn)),    \
@@ -1838,7 +1834,7 @@
   case SILInstructionKind::IsEscapingClosureInst: {
     assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
     unsigned verificationType = Attr;
-    ResultVal = Builder.createIsEscapingClosure(
+    ResultInst = Builder.createIsEscapingClosure(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID),
                                         (SILValueCategory)TyCategory, Fn)),
@@ -1849,10 +1845,10 @@
   case SILInstructionKind::BeginCOWMutationInst: {
     assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
     unsigned isNative = Attr;
-    ResultVal = Builder.createBeginCOWMutation(
+    ResultInst = Builder.createBeginCOWMutation(
         Loc,
-        getLocalValue(ValID,
-            getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn)),
+        getLocalValue(ValID, getSILType(MF->getType(TyID),
+                                        (SILValueCategory)TyCategory, Fn)),
         isNative != 0);
     break;
   }
@@ -1860,7 +1856,7 @@
   case SILInstructionKind::EndCOWMutationInst: {
     assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
     unsigned keepUnique = Attr;
-    ResultVal = Builder.createEndCOWMutation(
+    ResultInst = Builder.createEndCOWMutation(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID),
                                         (SILValueCategory)TyCategory, Fn)),
@@ -1872,20 +1868,20 @@
     assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
     SILValue Operand = getLocalValue(
         ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
-    ResultVal = Builder.createDestructureTuple(Loc, Operand);
+    ResultInst = Builder.createDestructureTuple(Loc, Operand);
     break;
   }
   case SILInstructionKind::DestructureStructInst: {
     assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
     SILValue Operand = getLocalValue(
         ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
-    ResultVal = Builder.createDestructureStruct(Loc, Operand);
+    ResultInst = Builder.createDestructureStruct(Loc, Operand);
     break;
   }
   case SILInstructionKind::UncheckedOwnershipConversionInst: {
     auto Ty = MF->getType(TyID);
     auto ResultKind = ValueOwnershipKind(Attr);
-    ResultVal = Builder.createUncheckedOwnershipConversion(
+    ResultInst = Builder.createUncheckedOwnershipConversion(
         Loc,
         getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
         ResultKind);
@@ -1895,7 +1891,7 @@
   case SILInstructionKind::LoadInst: {
     auto Ty = MF->getType(TyID);
     auto Qualifier = LoadOwnershipQualifier(Attr);
-    ResultVal = Builder.createLoad(
+    ResultInst = Builder.createLoad(
         Loc,
         getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
         Qualifier);
@@ -1908,7 +1904,7 @@
     bool isTake = (Attr > 0);                                                  \
     auto Val = getLocalValue(                                                  \
         ValID, getSILType(Ty, SILValueCategory(TyCategory), Fn));              \
-    ResultVal = Builder.createLoad##Name(Loc, Val, IsTake_t(isTake));          \
+    ResultInst = Builder.createLoad##Name(Loc, Val, IsTake_t(isTake));         \
     break;                                                                     \
   }                                                                            \
   case SILInstructionKind::Store##Name##Inst: {                                \
@@ -1917,9 +1913,9 @@
     auto refType = addrType.castTo<Name##StorageType>();                       \
     auto ValType = SILType::getPrimitiveObjectType(refType.getReferentType()); \
     bool isInit = (Attr > 0);                                                  \
-    ResultVal = Builder.createStore##Name(Loc, getLocalValue(ValID, ValType),  \
-                                          getLocalValue(ValID2, addrType),     \
-                                          IsInitialization_t(isInit));         \
+    ResultInst = Builder.createStore##Name(Loc, getLocalValue(ValID, ValType), \
+                                           getLocalValue(ValID2, addrType),    \
+                                           IsInitialization_t(isInit));        \
     break;                                                                     \
   }
 #include "swift/AST/ReferenceStorage.def"
@@ -1927,7 +1923,7 @@
     auto Ty = getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
     auto Kind = (MarkUninitializedInst::Kind)Attr;
     auto Val = getLocalValue(ValID, Ty);
-    ResultVal = Builder.createMarkUninitialized(Loc, Val, Kind);
+    ResultInst = Builder.createMarkUninitialized(Loc, Val, Kind);
     break;
   }
   case SILInstructionKind::StoreInst: {
@@ -1935,16 +1931,17 @@
     SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
     SILType ValType = addrType.getObjectType();
     auto Qualifier = StoreOwnershipQualifier(Attr);
-    ResultVal = Builder.createStore(Loc, getLocalValue(ValID, ValType),
-                                    getLocalValue(ValID2, addrType), Qualifier);
+    ResultInst =
+        Builder.createStore(Loc, getLocalValue(ValID, ValType),
+                            getLocalValue(ValID2, addrType), Qualifier);
     break;
   }
   case SILInstructionKind::StoreBorrowInst: {
     auto Ty = MF->getType(TyID);
     SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
     SILType ValType = addrType.getObjectType();
-    ResultVal = Builder.createStoreBorrow(Loc, getLocalValue(ValID, ValType),
-                                          getLocalValue(ValID2, addrType));
+    ResultInst = Builder.createStoreBorrow(Loc, getLocalValue(ValID, ValType),
+                                           getLocalValue(ValID2, addrType));
     break;
   }
   case SILInstructionKind::BeginAccessInst: {
@@ -1954,16 +1951,15 @@
     auto enforcement = SILAccessEnforcement((Attr >> 2) & 0x3);
     bool noNestedConflict = (Attr >> 4) & 0x01;
     bool fromBuiltin = (Attr >> 5) & 0x01;
-    ResultVal =
-        Builder.createBeginAccess(Loc, op, accessKind, enforcement,
-                                  noNestedConflict, fromBuiltin);
+    ResultInst = Builder.createBeginAccess(Loc, op, accessKind, enforcement,
+                                           noNestedConflict, fromBuiltin);
     break;
   }
   case SILInstructionKind::EndAccessInst: {
     SILValue op = getLocalValue(
         ValID, getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
     bool aborted = Attr & 0x1;
-    ResultVal = Builder.createEndAccess(Loc, op, aborted);
+    ResultInst = Builder.createEndAccess(Loc, op, aborted);
     break;
   }
   case SILInstructionKind::BeginUnpairedAccessInst: {
@@ -1976,9 +1972,9 @@
     auto enforcement = SILAccessEnforcement((Attr >> 2) & 0x03);
     bool noNestedConflict = (Attr >> 4) & 0x01;
     bool fromBuiltin = (Attr >> 5) & 0x01;
-    ResultVal = Builder.createBeginUnpairedAccess(
-      Loc, source, buffer, accessKind, enforcement, noNestedConflict,
-      fromBuiltin);
+    ResultInst = Builder.createBeginUnpairedAccess(
+        Loc, source, buffer, accessKind, enforcement, noNestedConflict,
+        fromBuiltin);
     break;
   }
   case SILInstructionKind::EndUnpairedAccessInst: {
@@ -1987,8 +1983,8 @@
     bool aborted = Attr & 0x1;
     auto enforcement = SILAccessEnforcement((Attr >> 1) & 0x03);
     bool fromBuiltin = (Attr >> 3) & 0x01;
-    ResultVal = Builder.createEndUnpairedAccess(Loc, op, enforcement, aborted,
-                                                fromBuiltin);
+    ResultInst = Builder.createEndUnpairedAccess(Loc, op, enforcement, aborted,
+                                                 fromBuiltin);
     break;
   }
   case SILInstructionKind::CopyAddrInst: {
@@ -1996,11 +1992,9 @@
     SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
     bool isInit = (Attr & 0x2) > 0;
     bool isTake = (Attr & 0x1) > 0;
-    ResultVal = Builder.createCopyAddr(Loc,
-                    getLocalValue(ValID, addrType),
-                    getLocalValue(ValID2, addrType),
-                    IsTake_t(isTake),
-                    IsInitialization_t(isInit));
+    ResultInst = Builder.createCopyAddr(
+        Loc, getLocalValue(ValID, addrType), getLocalValue(ValID2, addrType),
+        IsTake_t(isTake), IsInitialization_t(isInit));
     break;
   }
   case SILInstructionKind::AssignInst: {
@@ -2008,10 +2002,9 @@
     SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory, Fn);
     SILType valType = addrType.getObjectType();
     auto qualifier = AssignOwnershipQualifier(Attr);
-    ResultVal = Builder.createAssign(Loc,
-                    getLocalValue(ValID, valType),
-                    getLocalValue(ValID2, addrType),
-                    qualifier);
+    ResultInst =
+        Builder.createAssign(Loc, getLocalValue(ValID, valType),
+                             getLocalValue(ValID2, addrType), qualifier);
     break;
   }
   case SILInstructionKind::AssignByWrapperInst:
@@ -2020,7 +2013,7 @@
     assert(RecordKind == SIL_ONE_TYPE_VALUES &&
            "Layout should be OneTypeValues.");
     auto Ty = MF->getType(TyID);   // BoundTy
-    ResultVal = Builder.createBindMemory(
+    ResultInst = Builder.createBindMemory(
         Loc,
         getLocalValue(ListOfValues[2],
                       getSILType(MF->getType(ListOfValues[0]),
@@ -2041,11 +2034,11 @@
     auto ResultTy = Val->getType().getFieldType(
         Field, SILMod, Builder.getTypeExpansionContext());
     if (OpCode == SILInstructionKind::StructElementAddrInst)
-      ResultVal = Builder.createStructElementAddr(Loc, Val, Field,
-                                                  ResultTy.getAddressType());
+      ResultInst = Builder.createStructElementAddr(Loc, Val, Field,
+                                                   ResultTy.getAddressType());
     else
-      ResultVal = Builder.createStructExtract(Loc, Val, Field,
-                                              ResultTy.getObjectType());
+      ResultInst = Builder.createStructExtract(Loc, Val, Field,
+                                               ResultTy.getObjectType());
     break;
   }
   case SILInstructionKind::StructInst: {
@@ -2059,7 +2052,7 @@
           ListOfValues[I + 2],
           getSILType(EltTy, (SILValueCategory)ListOfValues[I + 1], Fn)));
     }
-    ResultVal = Builder.createStruct(
+    ResultInst = Builder.createStruct(
         Loc, getSILType(Ty, (SILValueCategory)TyCategory, Fn), OpList);
     break;
   }
@@ -2074,12 +2067,12 @@
     switch (OpCode) {
     default: llvm_unreachable("Out of sync with parent switch");
     case SILInstructionKind::TupleElementAddrInst:
-      ResultVal = Builder.createTupleElementAddr(
+      ResultInst = Builder.createTupleElementAddr(
           Loc, getLocalValue(ValID, ST), TyID,
           getSILType(ResultTy, SILValueCategory::Address, Fn));
       break;
     case SILInstructionKind::TupleExtractInst:
-      ResultVal = Builder.createTupleExtract(
+      ResultInst = Builder.createTupleExtract(
           Loc, getLocalValue(ValID, ST), TyID,
           getSILType(ResultTy, SILValueCategory::Object, Fn));
       break;
@@ -2099,7 +2092,7 @@
         getLocalValue(ListOfValues[I],
                       getSILType(EltTy, SILValueCategory::Object, Fn)));
     }
-    ResultVal = Builder.createTuple(
+    ResultInst = Builder.createTuple(
         Loc, getSILType(Ty, (SILValueCategory)TyCategory, Fn), OpList);
     break;
   }
@@ -2118,7 +2111,7 @@
       SILValue elementVal = getLocalValue(ListOfValues[i], elementType);
       elements.push_back(elementVal);
     }
-    ResultVal = Builder.createObject(Loc, ClassTy, elements, numBaseElements);
+    ResultInst = Builder.createObject(Loc, ClassTy, elements, numBaseElements);
     break;
   }
   case SILInstructionKind::BranchInst: {
@@ -2129,8 +2122,7 @@
                         getSILType(MF->getType(ListOfValues[I]),
                                    (SILValueCategory)ListOfValues[I + 1], Fn)));
 
-    ResultVal = Builder.createBranch(Loc, getBBForReference(Fn, TyID),
-                    Args);
+    ResultInst = Builder.createBranch(Loc, getBBForReference(Fn, TyID), Args);
     break;
   }
   case SILInstructionKind::CondBranchInst: {
@@ -2160,9 +2152,9 @@
                         getSILType(MF->getType(ListOfValues[I]),
                                    (SILValueCategory)ListOfValues[I + 1], Fn)));
 
-    ResultVal = Builder.createCondBranch(Loc, Cond,
-                    getBBForReference(Fn, ListOfValues[1]), TrueArgs,
-                    getBBForReference(Fn, ListOfValues[2]), FalseArgs);
+    ResultInst = Builder.createCondBranch(
+        Loc, Cond, getBBForReference(Fn, ListOfValues[1]), TrueArgs,
+        getBBForReference(Fn, ListOfValues[2]), FalseArgs);
     break;
   }
   case SILInstructionKind::SwitchEnumInst:
@@ -2185,10 +2177,9 @@
                             getBBForReference(Fn, ListOfValues[I+1])} );
     }
     if (OpCode == SILInstructionKind::SwitchEnumInst)
-      ResultVal = Builder.createSwitchEnum(Loc, Cond, DefaultBB, CaseBBs);
+      ResultInst = Builder.createSwitchEnum(Loc, Cond, DefaultBB, CaseBBs);
     else
-      ResultVal = Builder.createSwitchEnumAddr(Loc, Cond,
-                      DefaultBB, CaseBBs);
+      ResultInst = Builder.createSwitchEnumAddr(Loc, Cond, DefaultBB, CaseBBs);
     break;
   }
   case SILInstructionKind::SelectEnumInst:
@@ -2217,11 +2208,11 @@
                          Value});
     }
     if (OpCode == SILInstructionKind::SelectEnumInst)
-      ResultVal = Builder.createSelectEnum(Loc, Cond, ResultTy,
-                                           DefaultVal, CaseVals);
+      ResultInst =
+          Builder.createSelectEnum(Loc, Cond, ResultTy, DefaultVal, CaseVals);
     else
-      ResultVal = Builder.createSelectEnumAddr(Loc, Cond, ResultTy,
-                                               DefaultVal, CaseVals);
+      ResultInst = Builder.createSelectEnumAddr(Loc, Cond, ResultTy, DefaultVal,
+                                                CaseVals);
     break;
   }
   case SILInstructionKind::SwitchValueInst: {
@@ -2244,7 +2235,7 @@
       auto value = getLocalValue(ListOfValues[I], ResultTy);
       CaseBBs.push_back( {value, getBBForReference(Fn, ListOfValues[I+1])} );
     }
-    ResultVal = Builder.createSwitchValue(Loc, Cond, DefaultBB, CaseBBs);
+    ResultInst = Builder.createSwitchValue(Loc, Cond, DefaultBB, CaseBBs);
     break;
   }
   case SILInstructionKind::SelectValueInst: {
@@ -2272,8 +2263,8 @@
       CaseValuesAndResults.push_back({CaseValue, Result});
     }
 
-    ResultVal = Builder.createSelectValue(Loc, Cond, ResultTy,
-                                          DefaultVal, CaseValuesAndResults);
+    ResultInst = Builder.createSelectValue(Loc, Cond, ResultTy, DefaultVal,
+                                           CaseValuesAndResults);
     break;
   }  
   case SILInstructionKind::EnumInst: {
@@ -2284,7 +2275,7 @@
       Operand =
           getLocalValue(ValID2, getSILType(MF->getType(TyID2),
                                            (SILValueCategory)TyCategory2, Fn));
-    ResultVal = Builder.createEnum(
+    ResultInst = Builder.createEnum(
         Loc, Operand, cast<EnumElementDecl>(MF->getDecl(ValID)),
         getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn));
     break;
@@ -2296,9 +2287,8 @@
                                    (SILValueCategory) TyCategory, Fn);
     SILType ResultTy = OperandTy.getEnumElementType(
         Elt, SILMod, Builder.getTypeExpansionContext());
-    ResultVal = Builder.createInitEnumDataAddr(Loc,
-                    getLocalValue(ValID2, OperandTy),
-                    Elt, ResultTy);
+    ResultInst = Builder.createInitEnumDataAddr(
+        Loc, getLocalValue(ValID2, OperandTy), Elt, ResultTy);
     break;
   }
   case SILInstructionKind::UncheckedEnumDataInst: {
@@ -2308,9 +2298,8 @@
         getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
     SILType ResultTy = OperandTy.getEnumElementType(
         Elt, SILMod, Builder.getTypeExpansionContext());
-    ResultVal = Builder.createUncheckedEnumData(Loc,
-                    getLocalValue(ValID2, OperandTy),
-                    Elt, ResultTy);
+    ResultInst = Builder.createUncheckedEnumData(
+        Loc, getLocalValue(ValID2, OperandTy), Elt, ResultTy);
     break;
   }
   case SILInstructionKind::UncheckedTakeEnumDataAddrInst: {
@@ -2320,16 +2309,15 @@
         getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
     SILType ResultTy = OperandTy.getEnumElementType(
         Elt, SILMod, Builder.getTypeExpansionContext());
-    ResultVal = Builder.createUncheckedTakeEnumDataAddr(Loc,
-                    getLocalValue(ValID2, OperandTy),
-                    Elt, ResultTy);
+    ResultInst = Builder.createUncheckedTakeEnumDataAddr(
+        Loc, getLocalValue(ValID2, OperandTy), Elt, ResultTy);
     break;
   }
   case SILInstructionKind::InjectEnumAddrInst: {
     // Use SILOneValueOneOperandLayout.
     EnumElementDecl *Elt = cast<EnumElementDecl>(MF->getDecl(ValID));
     auto Ty = MF->getType(TyID);
-    ResultVal = Builder.createInjectEnumAddr(
+    ResultInst = Builder.createInjectEnumAddr(
         Loc,
         getLocalValue(ValID2, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
         Elt);
@@ -2343,15 +2331,15 @@
                              getSILType(Ty, (SILValueCategory)TyCategory, Fn));
     auto ResultTy = Val->getType().getFieldType(
         Field, SILMod, Builder.getTypeExpansionContext());
-    ResultVal = Builder.createRefElementAddr(Loc, Val, Field,
-                                          ResultTy, /*Immutable*/ Attr & 0x1);
+    ResultInst = Builder.createRefElementAddr(Loc, Val, Field, ResultTy,
+                                              /*Immutable*/ Attr & 0x1);
     break;
   }
   case SILInstructionKind::RefTailAddrInst: {
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
            "Layout should be OneTypeOneOperand.");
     assert((SILValueCategory)TyCategory == SILValueCategory::Address);
-    ResultVal = Builder.createRefTailAddr(
+    ResultInst = Builder.createRefTailAddr(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2, Fn)),
@@ -2379,24 +2367,24 @@
     switch (OpCode) {
     default: llvm_unreachable("Out of sync with parent switch");
     case SILInstructionKind::ClassMethodInst:
-      ResultVal = Builder.createClassMethod(Loc,
-                    getLocalValue(ListOfValues[NextValueIndex], operandTy),
-                    DRef, Ty);
+      ResultInst = Builder.createClassMethod(
+          Loc, getLocalValue(ListOfValues[NextValueIndex], operandTy), DRef,
+          Ty);
       break;
     case SILInstructionKind::SuperMethodInst:
-      ResultVal = Builder.createSuperMethod(Loc,
-                    getLocalValue(ListOfValues[NextValueIndex], operandTy),
-                    DRef, Ty);
+      ResultInst = Builder.createSuperMethod(
+          Loc, getLocalValue(ListOfValues[NextValueIndex], operandTy), DRef,
+          Ty);
       break;
     case SILInstructionKind::ObjCMethodInst:
-      ResultVal = Builder.createObjCMethod(Loc,
-                    getLocalValue(ListOfValues[NextValueIndex], operandTy),
-                    DRef, Ty);
+      ResultInst = Builder.createObjCMethod(
+          Loc, getLocalValue(ListOfValues[NextValueIndex], operandTy), DRef,
+          Ty);
       break;
     case SILInstructionKind::ObjCSuperMethodInst:
-      ResultVal = Builder.createObjCSuperMethod(Loc,
-                    getLocalValue(ListOfValues[NextValueIndex], operandTy),
-                    DRef, Ty);
+      ResultInst = Builder.createObjCSuperMethod(
+          Loc, getLocalValue(ListOfValues[NextValueIndex], operandTy), DRef,
+          Ty);
       break;
     }
     break;
@@ -2420,8 +2408,8 @@
       if (ValID3)
         ExistentialOperand = getLocalValue(ValID3, ExistentialOperandTy);
     }
-    ResultVal = Builder.createWitnessMethod(
-        Loc, Ty, Conformance, DRef, OperandTy);
+    ResultInst =
+        Builder.createWitnessMethod(Loc, Ty, Conformance, DRef, OperandTy);
     break;
   }
   case SILInstructionKind::DynamicMethodBranchInst: {
@@ -2431,7 +2419,7 @@
     SILDeclRef DRef = getSILDeclRef(MF, ListOfValues, NextValueIndex);
     assert(ListOfValues.size() == NextValueIndex + 2 &&
            "Wrong number of entries for DynamicMethodBranchInst");
-    ResultVal = Builder.createDynamicMethodBranch(
+    ResultInst = Builder.createDynamicMethodBranch(
         Loc,
         getLocalValue(
             ListOfValues[0],
@@ -2454,9 +2442,9 @@
     auto *successBB = getBBForReference(Fn, ListOfValues[5]);
     auto *failureBB = getBBForReference(Fn, ListOfValues[6]);
 
-    ResultVal = Builder.createCheckedCastBranch(
-        Loc, isExact, op, targetLoweredType, targetFormalType,
-        successBB, failureBB);
+    ResultInst =
+        Builder.createCheckedCastBranch(Loc, isExact, op, targetLoweredType,
+                                        targetFormalType, successBB, failureBB);
     break;
   }
   case SILInstructionKind::CheckedCastValueBranchInst: {
@@ -2471,9 +2459,9 @@
     auto *successBB = getBBForReference(Fn, ListOfValues[5]);
     auto *failureBB = getBBForReference(Fn, ListOfValues[6]);
 
-    ResultVal = Builder.createCheckedCastValueBranch(
-        Loc, op, srcFormalType, targetLoweredType, targetFormalType,
-        successBB, failureBB);
+    ResultInst = Builder.createCheckedCastValueBranch(
+        Loc, op, srcFormalType, targetLoweredType, targetFormalType, successBB,
+        failureBB);
     break;
   }
   case SILInstructionKind::UnconditionalCheckedCastValueInst: {
@@ -2485,9 +2473,8 @@
     SILType targetLoweredType =
         getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
     CanType targetFormalType = MF->getType(ListOfValues[4])->getCanonicalType();
-    ResultVal = Builder.createUnconditionalCheckedCastValue(Loc, src, srcFormalType,
-                                                            targetLoweredType,
-                                                            targetFormalType);
+    ResultInst = Builder.createUnconditionalCheckedCastValue(
+        Loc, src, srcFormalType, targetLoweredType, targetFormalType);
     break;
   }
   case SILInstructionKind::UnconditionalCheckedCastAddrInst: {
@@ -2502,8 +2489,8 @@
         getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
     SILValue dest = getLocalValue(ListOfValues[5], targetLoweredType);
 
-    ResultVal = Builder.createUnconditionalCheckedCastAddr(Loc, src, srcFormalType,
-                                                           dest, targetFormalType);
+    ResultInst = Builder.createUnconditionalCheckedCastAddr(
+        Loc, src, srcFormalType, dest, targetFormalType);
     break;
   }
   case SILInstructionKind::CheckedCastAddrBranchInst: {
@@ -2522,10 +2509,9 @@
 
     auto *successBB = getBBForReference(Fn, ListOfValues[7]);
     auto *failureBB = getBBForReference(Fn, ListOfValues[8]);
-    ResultVal = Builder.createCheckedCastAddrBranch(Loc, consumption,
-                                                    src, srcFormalType,
-                                                    dest, targetFormalType,
-                                                    successBB, failureBB);
+    ResultInst = Builder.createCheckedCastAddrBranch(
+        Loc, consumption, src, srcFormalType, dest, targetFormalType, successBB,
+        failureBB);
     break;
   }
   case SILInstructionKind::UncheckedRefCastAddrInst: {
@@ -2540,8 +2526,8 @@
         getSILType(MF->getType(TyID), (SILValueCategory)TyCategory, Fn);
     SILValue dest = getLocalValue(ListOfValues[5], destAddrTy);
 
-    ResultVal = Builder.createUncheckedRefCastAddr(Loc, src, sourceType,
-                                                   dest, targetType);
+    ResultInst = Builder.createUncheckedRefCastAddr(Loc, src, sourceType, dest,
+                                                    targetType);
     break;
   }
   case SILInstructionKind::InitBlockStorageHeaderInst: {
@@ -2562,16 +2548,16 @@
     
     auto SubMap = MF->getSubstitutionMap(ListOfValues[4]);
 
-    ResultVal = Builder.createInitBlockStorageHeader(Loc, storage, invoke,
-                                                     blockTy, SubMap);
+    ResultInst = Builder.createInitBlockStorageHeader(Loc, storage, invoke,
+                                                      blockTy, SubMap);
     break;
   }
   case SILInstructionKind::UnreachableInst: {
-    ResultVal = Builder.createUnreachable(Loc);
+    ResultInst = Builder.createUnreachable(Loc);
     break;
   }
   case SILInstructionKind::UnwindInst: {
-    ResultVal = Builder.createUnwind(Loc);
+    ResultInst = Builder.createUnwind(Loc);
     break;
   }
   case SILInstructionKind::YieldInst: {
@@ -2588,7 +2574,7 @@
           ListOfValues[I + 2], getSILType(valueTy, valueCategory, Fn)));
     }
 
-    ResultVal = Builder.createYield(Loc, yieldedValues, resumeBB, unwindBB);
+    ResultInst = Builder.createYield(Loc, yieldedValues, resumeBB, unwindBB);
     break;
   }
   case SILInstructionKind::KeyPathInst: {
@@ -2639,8 +2625,8 @@
       auto opCat = (SILValueCategory)ListOfValues[nextValue++];
       operands.push_back(getLocalValue(opValue, getSILType(opTy, opCat, Fn)));
     }
-    
-    ResultVal = Builder.createKeyPath(Loc, pattern, subMap, operands, kpTy);
+
+    ResultInst = Builder.createKeyPath(Loc, pattern, subMap, operands, kpTy);
     break;
   }
   case SILInstructionKind::DifferentiableFunctionInst: {
@@ -2673,7 +2659,7 @@
     Optional<std::pair<SILValue, SILValue>> derivativeFunctions = None;
     if (hasDerivativeFunctions)
       derivativeFunctions = std::make_pair(operands[1], operands[2]);
-    ResultVal = Builder.createDifferentiableFunction(
+    ResultInst = Builder.createDifferentiableFunction(
         Loc, paramIndices, resultIndices, operands[0], derivativeFunctions);
     break;
   }
@@ -2698,8 +2684,8 @@
     Optional<SILValue> transposeFunction = None;
     if (hasLinearFunction)
       transposeFunction = operands[1];
-    ResultVal = Builder.createLinearFunction(
-        Loc, paramIndices, operands[0], transposeFunction);
+    ResultInst = Builder.createLinearFunction(Loc, paramIndices, operands[0],
+                                              transposeFunction);
     break;
   }
   case SILInstructionKind::DifferentiableFunctionExtractInst: {
@@ -2710,7 +2696,7 @@
     Optional<SILType> explicitExtracteeType = None;
     if (Attr2)
       explicitExtracteeType = silTy;
-    ResultVal = Builder.createDifferentiableFunctionExtract(
+    ResultInst = Builder.createDifferentiableFunctionExtract(
         Loc, extractee, val, explicitExtracteeType);
     break;
   }
@@ -2719,7 +2705,7 @@
     auto silTy = getSILType(astTy, SILValueCategory::Object, Fn);
     auto val = getLocalValue(ValID, silTy);
     LinearDifferentiableFunctionTypeComponent extractee(Attr);
-    ResultVal = Builder.createLinearFunctionExtract(Loc, extractee, val);
+    ResultInst = Builder.createLinearFunctionExtract(Loc, extractee, val);
     break;
   }
   case SILInstructionKind::DifferentiabilityWitnessFunctionInst: {
@@ -2731,13 +2717,13 @@
     auto astTy = MF->getType(TyID);
     if (TyID)
       explicitFnTy = getSILType(astTy, SILValueCategory::Object, Fn);
-    ResultVal = Builder.createDifferentiabilityWitnessFunction(
+    ResultInst = Builder.createDifferentiabilityWitnessFunction(
         Loc, witnessKind, witness, explicitFnTy);
     break;
   }
   }
 
-  for (auto result : ResultVal->getResults()) {
+  for (auto result : ResultInst->getResults()) {
     LastValueID = LastValueID + 1;
     setLocalValue(result, LastValueID);
   }
@@ -2824,14 +2810,14 @@
   GenericSignatureID genericSigID;
   unsigned rawLinkage, isTransparent, isSerialized, isThunk,
       isWithoutactuallyEscapingThunk, isGlobal, inlineStrategy,
-      optimizationMode, subclassScope, effect, numSpecAttrs,
+      optimizationMode, subclassScope, hasCReferences, effect, numSpecAttrs,
       hasQualifiedOwnership, isWeakImported, LIST_VER_TUPLE_PIECES(available),
       isDynamic, isExactSelfClass;
   ArrayRef<uint64_t> SemanticsIDs;
   SILFunctionLayout::readRecord(
       scratch, rawLinkage, isTransparent, isSerialized, isThunk,
       isWithoutactuallyEscapingThunk, isGlobal, inlineStrategy,
-      optimizationMode, subclassScope, effect, numSpecAttrs,
+      optimizationMode, subclassScope, hasCReferences, effect, numSpecAttrs,
       hasQualifiedOwnership, isWeakImported, LIST_VER_TUPLE_PIECES(available),
       isDynamic, isExactSelfClass, funcTyID, replacedFunctionID, genericSigID,
       clangOwnerID, SemanticsIDs);
diff --git a/lib/Serialization/ModuleDependencyScanner.cpp b/lib/Serialization/ModuleDependencyScanner.cpp
index fbe77f0..7f05888 100644
--- a/lib/Serialization/ModuleDependencyScanner.cpp
+++ b/lib/Serialization/ModuleDependencyScanner.cpp
@@ -176,13 +176,19 @@
   auto moduleId = Ctx.getIdentifier(moduleName);
   // Instantiate dependency scanning "loaders".
   SmallVector<std::unique_ptr<ModuleDependencyScanner>, 2> scanners;
-  scanners.push_back(std::make_unique<ModuleDependencyScanner>(
-      Ctx, LoadMode, moduleId, delegate));
+  // Placeholder dependencies must be resolved first, to prevent the ModuleDependencyScanner
+  // from first discovering artifacts of a previous build. Such artifacts are captured
+  // as compiledModuleCandidates in the dependency graph of the placeholder dependency module
+  // itself.
   scanners.push_back(std::make_unique<PlaceholderSwiftModuleScanner>(
       Ctx, LoadMode, moduleId, Ctx.SearchPathOpts.PlaceholderDependencyModuleMap,
       delegate));
+  scanners.push_back(std::make_unique<ModuleDependencyScanner>(
+      Ctx, LoadMode, moduleId, delegate));
 
   // Check whether there is a module with this name that we can import.
+  assert(isa<PlaceholderSwiftModuleScanner>(scanners[0].get()) &&
+         "Expected PlaceholderSwiftModuleScanner as the first dependency scanner loader.");
   for (auto &scanner : scanners) {
     if (scanner->canImportModule({moduleId, SourceLoc()})) {
       // Record the dependencies.
diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp
index 7b17160..80b4b9d 100644
--- a/lib/Serialization/ModuleFile.cpp
+++ b/lib/Serialization/ModuleFile.cpp
@@ -349,17 +349,14 @@
     llvm::MemoryBuffer::getMemBuffer(llvm::MemoryBufferRef(*moduleBuf.get()),
     /*RequiresNullTerminator=*/false);
   std::shared_ptr<const ModuleFileSharedCore> loadedModuleFile;
-  ExtendedValidationInfo ExtInfo;
   bool isFramework = false;
   serialization::ValidationInfo loadInfo =
      ModuleFileSharedCore::load(modulePath.str(),
                       std::move(newBuf),
                       nullptr,
                       nullptr,
-                      /*isFramework*/isFramework, loadedModuleFile,
-                      &ExtInfo);
-
-  Name = loadedModuleFile->Name;
+                      /*isFramework*/isFramework, loadedModuleFile);
+  Name = loadedModuleFile->Name.str();
   return std::move(moduleBuf.get());
 }
 
diff --git a/lib/Serialization/ModuleFile.h b/lib/Serialization/ModuleFile.h
index 8a0c296..413bd6a 100644
--- a/lib/Serialization/ModuleFile.h
+++ b/lib/Serialization/ModuleFile.h
@@ -438,11 +438,31 @@
     return Core->CompatibilityVersion;
   }
 
+  /// Whether this module is compiled with `-enable-private-imports`.
+  bool arePrivateImportsEnabled() const {
+    return Core->Bits.ArePrivateImportsEnabled;
+  }
+
   /// Is this module file actually a .sib file? .sib files are serialized SIL at
   /// arbitrary granularity and arbitrary stage; unlike serialized Swift
   /// modules, which are assumed to contain canonical SIL for an entire module.
   bool isSIB() const {
-    return Core->IsSIB;
+    return Core->Bits.IsSIB;
+  }
+
+  /// Whether this module file is compiled with '-enable-testing'.
+  bool isTestable() const {
+    return Core->Bits.IsTestable;
+  }
+
+  /// Whether the module is resilient. ('-enable-library-evolution')
+  ResilienceStrategy getResilienceStrategy() const {
+    return ResilienceStrategy(Core->Bits.ResilienceStrategy);
+  }
+
+  /// Whether this module is compiled with implicit dynamic.
+  bool isImplicitDynamicEnabled() const {
+    return Core->Bits.IsImplicitDynamicEnabled;
   }
 
   /// Associates this module file with the AST node representing it.
diff --git a/lib/Serialization/ModuleFileCoreTableInfo.h b/lib/Serialization/ModuleFileCoreTableInfo.h
index 3030d6a..63d6943 100644
--- a/lib/Serialization/ModuleFileCoreTableInfo.h
+++ b/lib/Serialization/ModuleFileCoreTableInfo.h
@@ -455,7 +455,7 @@
     while (data < limit) {
       DeclID genSigId = endian::readNext<uint32_t, little, unaligned>(data);
       int32_t nameLength = endian::readNext<int32_t, little, unaligned>(data);
-      StringRef mangledName(reinterpret_cast<const char *>(data), nameLength);
+      std::string mangledName(reinterpret_cast<const char *>(data), nameLength);
       data += nameLength;
       result.push_back({mangledName, genSigId});
     }
diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp
index aa0adae..a2032f6 100644
--- a/lib/Serialization/ModuleFileSharedCore.cpp
+++ b/lib/Serialization/ModuleFileSharedCore.cpp
@@ -1087,8 +1087,7 @@
     std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
     std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
     std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
-    bool isFramework, serialization::ValidationInfo &info,
-    serialization::ExtendedValidationInfo *extInfo)
+    bool isFramework, serialization::ValidationInfo &info)
     : ModuleInputBuffer(std::move(moduleInputBuffer)),
       ModuleDocInputBuffer(std::move(moduleDocInputBuffer)),
       ModuleSourceInfoInputBuffer(std::move(moduleSourceInfoInputBuffer)) {
@@ -1134,10 +1133,11 @@
         return;
       }
 
+      ExtendedValidationInfo extInfo;
       info = validateControlBlock(cursor, scratch,
                                   {SWIFTMODULE_VERSION_MAJOR,
                                    SWIFTMODULE_VERSION_MINOR},
-                                  extInfo);
+                                  &extInfo);
       if (info.status != Status::Valid) {
         error(info.status);
         return;
@@ -1145,7 +1145,11 @@
       Name = info.name;
       TargetTriple = info.targetTriple;
       CompatibilityVersion = info.compatibilityVersion;
-      IsSIB = extInfo->isSIB();
+      Bits.ArePrivateImportsEnabled = extInfo.arePrivateImportsEnabled();
+      Bits.IsSIB = extInfo.isSIB();
+      Bits.IsTestable = extInfo.isTestable();
+      Bits.ResilienceStrategy = unsigned(extInfo.getResilienceStrategy());
+      Bits.IsImplicitDynamicEnabled = extInfo.isImplicitDynamicEnabled();
       MiscVersion = info.miscVersion;
 
       hasValidControlBlock = true;
diff --git a/lib/Serialization/ModuleFileSharedCore.h b/lib/Serialization/ModuleFileSharedCore.h
index f7be1d1..3277578 100644
--- a/lib/Serialization/ModuleFileSharedCore.h
+++ b/lib/Serialization/ModuleFileSharedCore.h
@@ -69,11 +69,6 @@
   /// The data blob containing all of the module's identifiers.
   StringRef IdentifierData;
 
-  /// Is this module file actually a .sib file? .sib files are serialized SIL at
-  /// arbitrary granularity and arbitrary stage; unlike serialized Swift
-  /// modules, which are assumed to contain canonical SIL for an entire module.
-  bool IsSIB = false;
-
   // Full blob from the misc. version field of the metadata block. This should
   // include the version string of the compiler that built the module.
   StringRef MiscVersion;
@@ -307,6 +302,21 @@
     /// Whether an error has been detected setting up this module file.
     unsigned HasError : 1;
 
+    /// Whether this module is `-enable-private-imports`.
+    unsigned ArePrivateImportsEnabled : 1;
+
+    /// Whether this module file is actually a .sib file.
+    unsigned IsSIB: 1;
+
+    /// Whether this module file is compiled with '-enable-testing'.
+    unsigned IsTestable : 1;
+
+    /// Discriminator for resilience strategy.
+    unsigned ResilienceStrategy : 2;
+
+    /// Whether this module is compiled with implicit dynamic.
+    unsigned IsImplicitDynamicEnabled: 1;
+
     // Explicitly pad out to the next word boundary.
     unsigned : 0;
   } Bits = {};
@@ -326,8 +336,7 @@
   ModuleFileSharedCore(std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
                  std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
                  std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
-                 bool isFramework, serialization::ValidationInfo &info,
-                 serialization::ExtendedValidationInfo *extInfo);
+                 bool isFramework, serialization::ValidationInfo &info);
 
   /// Change the status of the current module.
   Status error(Status issue) {
@@ -447,7 +456,6 @@
   /// \param isFramework If true, this is treated as a framework module for
   /// linking purposes.
   /// \param[out] theModule The loaded module.
-  /// \param[out] extInfo Optionally, extra info serialized about the module.
   /// \returns Whether the module was successfully loaded, or what went wrong
   ///          if it was not.
   static serialization::ValidationInfo
@@ -455,14 +463,17 @@
        std::unique_ptr<llvm::MemoryBuffer> moduleInputBuffer,
        std::unique_ptr<llvm::MemoryBuffer> moduleDocInputBuffer,
        std::unique_ptr<llvm::MemoryBuffer> moduleSourceInfoInputBuffer,
-       bool isFramework, std::shared_ptr<const ModuleFileSharedCore> &theModule,
-       serialization::ExtendedValidationInfo *extInfo = nullptr) {
+       bool isFramework,
+       std::shared_ptr<const ModuleFileSharedCore> &theModule) {
     serialization::ValidationInfo info;
     auto *core = new ModuleFileSharedCore(
         std::move(moduleInputBuffer), std::move(moduleDocInputBuffer),
-        std::move(moduleSourceInfoInputBuffer), isFramework, info, extInfo);
-    if (!moduleInterfacePath.empty())
-      core->ModuleInterfacePath = moduleInterfacePath;
+        std::move(moduleSourceInfoInputBuffer), isFramework, info);
+    if (!moduleInterfacePath.empty()) {
+      ArrayRef<char> path;
+      core->allocateBuffer(path, moduleInterfacePath);
+      core->ModuleInterfacePath = StringRef(path.data(), path.size());
+    }
     theModule.reset(core);
     return info;
   }
diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h
index 2b95150..a3e1f36 100644
--- a/lib/Serialization/ModuleFormat.h
+++ b/lib/Serialization/ModuleFormat.h
@@ -55,7 +55,7 @@
 /// describe what change you made. The content of this comment isn't important;
 /// it just ensures a conflict if two people change the module format.
 /// Don't worry about adhering to the 80-column limit for this line.
-const uint16_t SWIFTMODULE_VERSION_MINOR = 575; // GlobalInitOnceFunction SILFunction purpose
+const uint16_t SWIFTMODULE_VERSION_MINOR = 576; // hasCReferences
 
 /// A standard hash seed used for all string hashes in a serialized module.
 ///
diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h
index c1178d5..696f06b 100644
--- a/lib/Serialization/SILFormat.h
+++ b/lib/Serialization/SILFormat.h
@@ -281,6 +281,7 @@
                      BCFixed<2>,  // inlineStrategy
                      BCFixed<2>,  // optimizationMode
                      BCFixed<2>,  // classSubclassScope
+                     BCFixed<1>,  // hasCReferences
                      BCFixed<3>,  // side effect info.
                      BCVBR<8>,    // number of specialize attributes
                      BCFixed<1>,  // has qualified ownership
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index c8b5946..6c5d3bf 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -46,6 +46,7 @@
 #include "swift/Demangling/ManglingMacros.h"
 #include "swift/Serialization/SerializationOptions.h"
 #include "swift/Strings.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Bitcode/RecordLayout.h"
@@ -609,7 +610,8 @@
     isSerializable = false;
   }
   if (!isSerializable) {
-    PrettyStackTraceClangType trace("staging a serialized reference to", ty);
+    PrettyStackTraceClangType trace(loader->getClangASTContext(),
+                                    "staging a serialized reference to", ty);
     llvm::report_fatal_error("Clang function type is not serializable");
   }
 
@@ -3312,9 +3314,9 @@
         ++numBackingProperties;
         arrayFields.push_back(S.addDeclRef(backingInfo.backingVar));
       }
-      if (backingInfo.storageWrapperVar) {
+      if (backingInfo.projectionVar) {
         ++numBackingProperties;
-        arrayFields.push_back(S.addDeclRef(backingInfo.storageWrapperVar));
+        arrayFields.push_back(S.addDeclRef(backingInfo.projectionVar));
       }
     }
     for (Type dependency : collectDependenciesFromType(ty->getCanonicalType()))
@@ -4411,7 +4413,8 @@
 
 void Serializer::writeASTBlockEntity(const clang::Type *ty) {
   using namespace decls_block;
-  PrettyStackTraceClangType traceRAII("serializing clang type", ty);
+  auto &ctx = getASTContext().getClangModuleLoader()->getClangASTContext();
+  PrettyStackTraceClangType traceRAII(ctx, "serializing clang type", ty);
   assert(ClangTypesToSerialize.hasRef(ty));
 
   // Serialize the type as an opaque sequence of data.
@@ -5159,7 +5162,7 @@
     DerivativeFunctionConfigTable derivativeConfigs;
     for (auto entry : uniquedDerivativeConfigs) {
       for (auto config : entry.second) {
-        auto paramIndices = config.first.str();
+        std::string paramIndices = config.first.str().str();
         auto genSigID = addGenericSignatureRef(config.second);
         derivativeConfigs[entry.first].push_back({paramIndices, genSigID});
       }
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index da46d36..7c81a0c 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -248,6 +248,12 @@
     void writeSILBlock(const SILModule *SILMod);
     void writeIndexTables();
 
+    void writeNoOperandLayout(const SILInstruction *I) {
+      unsigned abbrCode = SILAbbrCodes[SILInstNoOperandLayout::Code];
+      SILInstNoOperandLayout::emitRecord(Out, ScratchRecord, abbrCode,
+                                         (unsigned)I->getKind());
+    }
+
     void writeConversionLikeInstruction(const SingleValueInstruction *I,
                                         unsigned attrs);
     void writeOneTypeLayout(SILInstructionKind valueKind,
@@ -433,9 +439,9 @@
       Out, ScratchRecord, abbrCode, toStableSILLinkage(Linkage),
       (unsigned)F.isTransparent(), (unsigned)F.isSerialized(),
       (unsigned)F.isThunk(), (unsigned)F.isWithoutActuallyEscapingThunk(),
-      (unsigned)F.getSpecialPurpose(),
-      (unsigned)F.getInlineStrategy(), (unsigned)F.getOptimizationMode(),
-      (unsigned)F.getClassSubclassScope(), (unsigned)F.getEffectsKind(),
+      (unsigned)F.getSpecialPurpose(), (unsigned)F.getInlineStrategy(),
+      (unsigned)F.getOptimizationMode(), (unsigned)F.getClassSubclassScope(),
+      (unsigned)F.hasCReferences(), (unsigned)F.getEffectsKind(),
       (unsigned)numSpecAttrs, (unsigned)F.hasOwnership(),
       F.isAlwaysWeakImported(), LIST_VER_TUPLE_PIECES(available),
       (unsigned)F.isDynamicallyReplaceable(), (unsigned)F.isExactSelfClass(),
@@ -763,9 +769,7 @@
       
   case SILInstructionKind::UnwindInst:
   case SILInstructionKind::UnreachableInst: {
-    unsigned abbrCode = SILAbbrCodes[SILInstNoOperandLayout::Code];
-    SILInstNoOperandLayout::emitRecord(Out, ScratchRecord, abbrCode,
-                                       (unsigned)SI.getKind());
+    writeNoOperandLayout(&SI);
     break;
   }
   case SILInstructionKind::AllocExistentialBoxInst:
diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp
index a82ee47..33c84e8 100644
--- a/lib/Serialization/SerializedModuleLoader.cpp
+++ b/lib/Serialization/SerializedModuleLoader.cpp
@@ -22,13 +22,14 @@
 #include "swift/Basic/STLExtras.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/Basic/Version.h"
+
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Support/Debug.h"
 #include <system_error>
 
 using namespace swift;
@@ -386,14 +387,12 @@
   // Load the module file without validation.
   std::shared_ptr<const ModuleFileSharedCore> loadedModuleFile;
   bool isFramework = false;
-  serialization::ExtendedValidationInfo extInfo;
   serialization::ValidationInfo loadInfo =
       ModuleFileSharedCore::load(modulePath.str(),
                        std::move(moduleBuf.get()),
                        nullptr,
                        nullptr,
-                       isFramework, loadedModuleFile,
-                       &extInfo);
+                       isFramework, loadedModuleFile);
 
   // Map the set of dependencies over to the "module dependencies".
   auto dependencies = ModuleDependencies::forSwiftModule(modulePath.str(), isFramework);
@@ -694,7 +693,6 @@
     return nullptr;
   }
 
-  serialization::ExtendedValidationInfo extendedInfo;
   std::unique_ptr<ModuleFile> loadedModuleFile;
   std::shared_ptr<const ModuleFileSharedCore> loadedModuleFileCore;
   serialization::ValidationInfo loadInfo =
@@ -702,20 +700,19 @@
                        std::move(moduleInputBuffer),
                        std::move(moduleDocInputBuffer),
                        std::move(moduleSourceInfoInputBuffer),
-                       isFramework, loadedModuleFileCore,
-                       &extendedInfo);
+                       isFramework, loadedModuleFileCore);
   if (loadInfo.status == serialization::Status::Valid) {
     loadedModuleFile =
         std::make_unique<ModuleFile>(std::move(loadedModuleFileCore));
-    M.setResilienceStrategy(extendedInfo.getResilienceStrategy());
+    M.setResilienceStrategy(loadedModuleFile->getResilienceStrategy());
 
     // We've loaded the file. Now try to bring it into the AST.
     auto fileUnit = new (Ctx) SerializedASTFile(M, *loadedModuleFile);
-    if (extendedInfo.isTestable())
+    if (loadedModuleFile->isTestable())
       M.setTestingEnabled();
-    if (extendedInfo.arePrivateImportsEnabled())
+    if (loadedModuleFile->arePrivateImportsEnabled())
       M.setPrivateImportsEnabled();
-    if (extendedInfo.isImplicitDynamicEnabled())
+    if (loadedModuleFile->isImplicitDynamicEnabled())
       M.setImplicitDynamicEnabled();
 
     auto diagLocOrInvalid = diagLoc.getValueOr(SourceLoc());
@@ -743,7 +740,7 @@
 
   if (diagLoc)
     serialization::diagnoseSerializedASTLoadFailure(
-        Ctx, *diagLoc, loadInfo, extendedInfo, moduleBufferID,
+        Ctx, *diagLoc, loadInfo, moduleBufferID,
         moduleDocBufferID, loadedModuleFile.get(), M.getName());
 
   // Even though the module failed to load, it's possible its contents include
@@ -760,7 +757,6 @@
 void swift::serialization::diagnoseSerializedASTLoadFailure(
     ASTContext &Ctx, SourceLoc diagLoc,
     const serialization::ValidationInfo &loadInfo,
-    const serialization::ExtendedValidationInfo &extendedInfo,
     StringRef moduleBufferID, StringRef moduleDocBufferID,
     ModuleFile *loadedModuleFile, Identifier ModuleName) {
   auto diagnoseDifferentLanguageVersion = [&](StringRef shortVersion) -> bool {
@@ -990,10 +986,8 @@
   Ctx.addLoadedModule(M);
   SWIFT_DEFER { M->setHasResolvedImports(); };
 
-  StringRef moduleInterfacePathStr =
-    Ctx.AllocateCopy(moduleInterfacePath.str());
   auto *file =
-      loadAST(*M, moduleID.Loc, moduleInterfacePathStr,
+      loadAST(*M, moduleID.Loc, moduleInterfacePath,
               std::move(moduleInputBuffer), std::move(moduleDocInputBuffer),
               std::move(moduleSourceInfoInputBuffer), isFramework);
   if (file) {
diff --git a/lib/SymbolGraphGen/AvailabilityMixin.cpp b/lib/SymbolGraphGen/AvailabilityMixin.cpp
index aa446f4..4dc66f0 100644
--- a/lib/SymbolGraphGen/AvailabilityMixin.cpp
+++ b/lib/SymbolGraphGen/AvailabilityMixin.cpp
@@ -56,6 +56,8 @@
       return { "tvOSAppExtension" };
     case swift::PlatformKind::watchOSApplicationExtension:
       return { "watchOSAppExtension" };
+    case swift::PlatformKind::OpenBSD:
+      return { "OpenBSD" };
     case swift::PlatformKind::none:
       return { "*" };
   }
diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp
index 623e3d0..e3523a6 100644
--- a/lib/TBDGen/TBDGen.cpp
+++ b/lib/TBDGen/TBDGen.cpp
@@ -249,6 +249,8 @@
   switch(Ver.Platform) {
   case swift::PlatformKind::none:
     llvm_unreachable("cannot find platform kind");
+  case swift::PlatformKind::OpenBSD:
+    llvm_unreachable("not used for this platform");
   case swift::PlatformKind::iOS:
   case swift::PlatformKind::iOSApplicationExtension:
     return Ver.IsSimulator ? LinkerPlatformId::iOS_sim:
diff --git a/localization/CMakeLists.txt b/localization/CMakeLists.txt
index 6a4ac7b..53c7e05 100644
--- a/localization/CMakeLists.txt
+++ b/localization/CMakeLists.txt
@@ -4,6 +4,9 @@
   COMMAND
     ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/diagnostics/ ${CMAKE_BINARY_DIR}/share/swift/diagnostics/
   COMMAND
+    "${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/swift-def-to-yaml-converter"
+      --output-directory ${CMAKE_BINARY_DIR}/share/swift/diagnostics/
+  COMMAND
     "${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/swift-serialize-diagnostics"
       --input-file-path ${CMAKE_BINARY_DIR}/share/swift/diagnostics/en.yaml
       --output-directory ${CMAKE_BINARY_DIR}/share/swift/diagnostics/
@@ -11,6 +14,7 @@
 
 add_dependencies(swift-frontend diagnostic-database)
 add_dependencies(diagnostic-database swift-serialize-diagnostics)
+add_dependencies(diagnostic-database swift-def-to-yaml-converter)
 
 swift_install_in_component(
   DIRECTORY ${CMAKE_BINARY_DIR}/share/swift/diagnostics/
diff --git a/localization/diagnostics/.gitkeep b/localization/diagnostics/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/localization/diagnostics/.gitkeep
diff --git a/localization/diagnostics/en.yaml b/localization/diagnostics/en.yaml
deleted file mode 100644
index d8b545c..0000000
--- a/localization/diagnostics/en.yaml
+++ /dev/null
@@ -1,8321 +0,0 @@
-#===--- en.yaml - Localized diagnostic messages for English ---*- YAML -*-===#
-#
-# This source file is part of the Swift.org open source project
-#
-# Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
-# Licensed under Apache License v2.0 with Runtime Library Exception
-#
-# See https://swift.org/LICENSE.txt for license information
-# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-#
-#===----------------------------------------------------------------------===#
-#
-# This file defines the diagnostic messages for the English language.
-# Each diagnostic is described in the following format:
-# - id: <diagnostic-id>
-#   msg: "<diagnostic-message>"
-# 
-# The diagnostic message should be in double quotes and in one line, that
-# means we will break the 80 characters line limit rule. That's mainly
-# because currently `llvm::YAMLParser` doesn't support literal string
-# folding, therefore we can't use YAML block scalars i.e. `>-`.
-#
-#===----------------------------------------------------------------------===#
-
-- id: invalid_diagnostic
-  msg: "INTERNAL ERROR: this diagnostic should not be produced"
-
-- id: not_implemented
-  msg: "INTERNAL ERROR: feature not implemented: %0"
-
-- id: error_opening_output
-  msg: "error opening '%0' for output: %1"
-
-- id: cannot_find_group_info_file
-  msg: "cannot find group info file at path: '%0'"
-
-- id: cannot_parse_group_info_file
-  msg: "cannot parse group info file at path: '%0'"
-
-- id: error_no_group_info
-  msg: "no group info found for file: '%0'"
-
-- id: previous_decldef
-  msg: "previous definition of %0 is here"
-
-- id: brace_stmt_suggest_do
-  msg: "did you mean to use a 'do' statement?"
-
-- id: while_parsing_as_left_angle_bracket
-  msg: "while parsing this '<' as a type parameter bracket"
-
-- id: remark_max_determinism_overriding
-  msg: "SWIFTC_MAXIMUM_DETERMINISM overriding %0"
-
-- id: super_not_in_class_method
-  msg: "'super' cannot be used outside of class members"
-
-- id: class_func_not_in_class
-  msg: "class methods are only allowed within classes; use 'static' to declare a %select{static|requirement fulfilled by either a static or class}0 method"
-
-- id: class_var_not_in_class
-  msg: "class properties are only allowed within classes; use 'static' to declare a %select{static|requirement fulfilled by either a static or class}0 property"
-
-- id: class_subscript_not_in_class
-  msg: "class subscripts are only allowed within classes; use 'static' to declare a %select{static|requirement fulfilled by either a static or class}0 subscript"
-
-- id: func_decl_without_brace
-  msg: "expected '{' in body of function declaration"
-
-- id: convert_let_to_var
-  msg: "change 'let' to 'var' to make it mutable"
-
-- id: note_typo_candidate
-  msg: "did you mean '%0'?"
-
-- id: profile_read_error
-  msg: "failed to load profile data '%0': '%1'"
-
-- id: protocol_extension_redundant_requirement
-  msg: "requirement of '%1' to '%2' is redundant in an extension of '%0'"
-
-- id: attr_only_on_parameters
-  msg: "'%0' may only be used on parameters"
-
-- id: function_type_no_parens
-  msg: "single argument function types require parentheses"
-
-- id: error_underlying_module_not_found
-  msg: "underlying Objective-C module %0 not found"
-
-- id: generic_signature_not_minimal
-  msg: "generic requirement '%0' is redundant in %1"
-
-- id: generic_signature_not_valid
-  msg: "generic signature %0 is invalid"
-
-- id: generic_signature_not_equal
-  msg: "generic signature %0 is not equal to new signature %1"
-
-- id: sdk_node_unrecognized_key
-  msg: "unrecognized key '%0' in SDK node"
-
-- id: sdk_node_unrecognized_node_kind
-  msg: "unrecognized SDK node kind '%0'"
-
-- id: sdk_node_unrecognized_type_attr_kind
-  msg: "unrecognized type attribute '%0' in SDK node"
-
-- id: sdk_node_unrecognized_decl_attr_kind
-  msg: "unrecognized declaration attribute '%0' in SDK node"
-
-- id: sdk_node_unrecognized_decl_kind
-  msg: "unrecognized declaration kind '%0' in SDK node"
-
-- id: sdk_node_unrecognized_accessor_kind
-  msg: "unrecognized accessor kind '%0' in SDK node"
-
-- id: source_location_creates_file_id_conflicts
-  msg: "'#sourceLocation' directive produces '#fileID' string of '%0', which conflicts with '#fileID' strings produced by other paths in the module"
-
-- id: fixit_correct_source_location_file
-  msg: "change file in '#sourceLocation' to '%0'"
-
-- id: error_two_files_same_name
-  msg: "filename \"%0\" used twice: '%1' and '%2'"
-
-- id: note_explain_two_files_same_name
-  msg: "filenames are used to distinguish private declarations with the same name"
-
-- id: circular_reference
-  msg: "circular reference"
-
-- id: circular_reference_through
-  msg: "through reference here"
-
-- id: circular_class_inheritance
-  msg: "%0 inherits from itself"
-
-- id: circular_enum_inheritance
-  msg: "%0 has a raw type that depends on itself"
-
-- id: circular_protocol_def
-  msg: "protocol %0 refines itself"
-
-- id: kind_declname_declared_here
-  msg: "%0 %1 declared here"
-
-- id: warn_property_wrapper_module_scope
-  msg: "ignoring associated type %0 in favor of module-scoped property wrapper %0; please qualify the reference with %1"
-
-- id: circular_type_resolution_note
-  msg: "while resolving type %0"
-
-- id: cannot_load_swiftoverlay_file
-  msg: "cannot load cross-import overlay for '%0' and '%1': %2 (declared by '%3')"
-
-- id: cannot_list_swiftcrossimport_dir
-  msg: "cannot list cross-import overlays for '%0': %1 (declared in '%2')"
-
-- id: cross_imported_by_both_modules
-  msg: "modules %0 and %1 both declare module %2 as a cross-import overlay, which may cause paradoxical behavior when looking up names in them; please report this bug to the maintainers of these modules"
-
-- id: scanner_find_cycle
-  msg: "dependency scanner detected dependency cycle: '%0'"
-
-- id: opening_brace
-  msg: "to match this opening '{'"
-
-- id: opening_bracket
-  msg: "to match this opening '['"
-
-- id: opening_paren
-  msg: "to match this opening '('"
-
-- id: opening_angle
-  msg: "to match this opening '<'"
-
-- id: extra_rbrace
-  msg: "extraneous '}' at top level"
-
-- id: structure_overflow
-  msg: "structure nesting level exceeded maximum of %0"
-
-- id: expected_close_to_if_directive
-  msg: "expected #else or #endif at end of conditional compilation block"
-
-- id: expected_close_after_else_directive
-  msg: "further conditions after #else are unreachable"
-
-- id: unexpected_conditional_compilation_block_terminator
-  msg: "unexpected conditional compilation block terminator"
-
-- id: incomplete_conditional_compilation_directive
-  msg: "incomplete condition in conditional compilation directive"
-
-- id: extra_tokens_conditional_compilation_directive
-  msg: "extra tokens following conditional compilation directive"
-
-- id: unexpected_rbrace_in_conditional_compilation_block
-  msg: "unexpected '}' in conditional compilation block"
-
-- id: unexpected_if_following_else_compilation_directive
-  msg: "unexpected 'if' keyword following '#else' conditional compilation directive; did you mean '#elseif'?"
-
-- id: pound_diagnostic_expected_string
-  msg: "expected string literal in %select{#warning|#error}0 directive"
-
-- id: pound_diagnostic_expected
-  msg: "expected '%0' in %select{#warning|#error}1 directive"
-
-- id: pound_diagnostic_expected_parens
-  msg: "%select{#warning|#error}0 directive requires parentheses"
-
-- id: pound_diagnostic_interpolation
-  msg: "string interpolation is not allowed in %select{#warning|#error}0 directives"
-
-- id: extra_tokens_pound_diagnostic_directive
-  msg: "extra tokens following %select{#warning|#error}0 directive"
-
-- id: sourceLocation_expected
-  msg: "expected '%0' in #sourceLocation directive"
-
-- id: unexpected_line_directive
-  msg: "parameterless closing #sourceLocation() directive without prior opening #sourceLocation(file:,line:) directive"
-
-- id: expected_line_directive_number
-  msg: "expected starting line number for #sourceLocation directive"
-
-- id: expected_line_directive_name
-  msg: "expected filename string literal for #sourceLocation directive"
-
-- id: extra_tokens_line_directive
-  msg: "extra tokens at the end of #sourceLocation directive"
-
-- id: line_directive_line_zero
-  msg: "the line number needs to be greater than zero"
-
-- id: escaped_parameter_name
-  msg: "keyword '%0' does not need to be escaped in argument list"
-
-- id: forbidden_interpolated_string
-  msg: "%0 cannot be an interpolated string literal"
-
-- id: forbidden_extended_escaping_string
-  msg: "%0 cannot be an extended escaping string literal"
-
-- id: lex_nul_character
-  msg: "nul character embedded in middle of file"
-
-- id: lex_utf16_bom_marker
-  msg: "input files must be encoded as UTF-8 instead of UTF-16"
-
-- id: lex_hashbang_not_allowed
-  msg: "hashbang line is allowed only in the main file"
-
-- id: lex_unprintable_ascii_character
-  msg: "unprintable ASCII character found in source file"
-
-- id: lex_invalid_utf8
-  msg: "invalid UTF-8 found in source file"
-
-- id: lex_single_quote_string
-  msg: "single-quoted string literal found, use '\"'"
-
-- id: lex_invalid_curly_quote
-  msg: "unicode curly quote found, replace with '\"'"
-
-- id: lex_confusable_character
-  msg: "unicode character '%0' (%1) looks similar to '%2' (%3); did you mean to use '%2' (%3)?"
-
-- id: lex_nonbreaking_space
-  msg: "non-breaking space (U+00A0) used instead of regular space"
-
-- id: lex_unterminated_block_comment
-  msg: "unterminated '/*' comment"
-
-- id: lex_comment_start
-  msg: "comment started here"
-
-- id: lex_unterminated_string
-  msg: "unterminated string literal"
-
-- id: lex_invalid_escape
-  msg: "invalid escape sequence in literal"
-
-- id: lex_invalid_u_escape
-  msg: "\\u{...} escape sequence expects between 1 and 8 hex digits"
-
-- id: lex_invalid_u_escape_rbrace
-  msg: "expected '}' in \\u{...} escape sequence"
-
-- id: lex_invalid_escape_delimiter
-  msg: "too many '#' characters in delimited escape"
-
-- id: lex_invalid_closing_delimiter
-  msg: "too many '#' characters in closing delimiter"
-
-- id: lex_invalid_unicode_scalar
-  msg: "invalid unicode scalar"
-
-- id: lex_unicode_escape_braces
-  msg: "expected hexadecimal code in braces after unicode escape"
-
-- id: lex_illegal_multiline_string_start
-  msg: "multi-line string literal content must begin on a new line"
-
-- id: lex_illegal_multiline_string_end
-  msg: "multi-line string literal closing delimiter must begin on a new line"
-
-- id: lex_multiline_string_indent_inconsistent
-  msg: "%select{unexpected space in|unexpected tab in|insufficient}2 indentation of %select{line|next %1 lines}0 in multi-line string literal"
-
-- id: lex_multiline_string_indent_should_match_here
-  msg: "should match %select{space|tab}0 here"
-
-- id: lex_multiline_string_indent_change_line
-  msg: "change indentation of %select{this line|these lines}0 to match closing delimiter"
-
-- id: lex_escaped_newline_at_lastline
-  msg: "escaped newline at the last line is not allowed"
-
-- id: lex_invalid_character
-  msg: "invalid character in source file"
-
-- id: lex_invalid_identifier_start_character
-  msg: "an identifier cannot begin with this character"
-
-- id: lex_expected_digit_in_fp_exponent
-  msg: "expected a digit in floating point exponent"
-
-- id: lex_invalid_digit_in_fp_exponent
-  msg: "'%0' is not a valid %select{digit|first character}1 in floating point exponent"
-
-- id: lex_invalid_digit_in_int_literal
-  msg: "'%0' is not a valid %select{binary digit (0 or 1)|octal digit (0-7)|digit|hexadecimal digit (0-9, A-F)}1 in integer literal"
-
-- id: lex_expected_binary_exponent_in_hex_float_literal
-  msg: "hexadecimal floating point literal must end with an exponent"
-
-- id: lex_unexpected_block_comment_end
-  msg: "unexpected end of block comment"
-
-- id: lex_unary_equal
-  msg: "'=' must have consistent whitespace on both sides"
-
-- id: extra_whitespace_period
-  msg: "extraneous whitespace after '.' is not permitted"
-
-- id: lex_editor_placeholder
-  msg: "editor placeholder in source file"
-
-- id: lex_editor_placeholder_in_playground
-  msg: "editor placeholder in source file"
-
-- id: lex_conflict_marker_in_file
-  msg: "source control conflict marker in source file"
-
-- id: note_in_decl_extension
-  msg: "in %select{declaration|extension}0 of %1"
-
-- id: line_directive_style_deprecated
-  msg: "#line directive was renamed to #sourceLocation"
-
-- id: declaration_same_line_without_semi
-  msg: "consecutive declarations on a line must be separated by ';'"
-
-- id: expected_decl
-  msg: "expected declaration"
-
-- id: expected_identifier_in_decl
-  msg: "expected identifier in %0 declaration"
-
-- id: expected_keyword_in_decl
-  msg: "expected '%0' keyword in %1 declaration"
-
-- id: number_cant_start_decl_name
-  msg: "%0 name can only start with a letter or underscore, not a number"
-
-- id: expected_identifier_after_case_comma
-  msg: "expected identifier after comma in enum 'case' declaration"
-
-- id: decl_redefinition
-  msg: "definition conflicts with previous value"
-
-- id: let_cannot_be_computed_property
-  msg: "'let' declarations cannot be computed properties"
-
-- id: let_cannot_be_observing_property
-  msg: "'let' declarations cannot be observing properties"
-
-- id: let_cannot_be_addressed_property
-  msg: "'let' declarations cannot have addressors"
-
-- id: disallowed_var_multiple_getset
-  msg: "'var' declarations with multiple variables cannot have explicit getters/setters"
-
-- id: disallowed_init
-  msg: "initial value is not allowed here"
-
-- id: var_init_self_referential
-  msg: "variable used within its own initial value"
-
-- id: disallowed_enum_element
-  msg: "enum 'case' is not allowed outside of an enum"
-
-- id: decl_inner_scope
-  msg: "declaration is only valid at file scope"
-
-- id: decl_not_static
-  msg: "declaration cannot be marked %0"
-
-- id: cskeyword_not_attribute
-  msg: "'%0' is a declaration modifier, not an attribute"
-
-- id: decl_already_static
-  msg: "%0 cannot appear after another 'static' or 'class' keyword"
-
-- id: enum_case_dot_prefix
-  msg: "extraneous '.' in enum 'case' declaration"
-
-- id: static_var_decl_global_scope
-  msg: "%select{%error|static properties|class properties}0 may only be declared on a type"
-
-- id: computed_property_no_accessors
-  msg: "%select{computed property|subscript}0 must have accessors specified"
-
-- id: expected_getset_in_protocol
-  msg: "expected get or set in a protocol property"
-
-- id: computed_property_missing_type
-  msg: "computed property must have an explicit type"
-
-- id: getset_nontrivial_pattern
-  msg: "getter/setter can only be defined for a single variable"
-
-- id: expected_rbrace_in_getset
-  msg: "expected '}' at end of variable get/set clause"
-
-- id: duplicate_accessor
-  msg: "%select{variable|subscript}0 already has %1"
-
-- id: conflicting_accessor
-  msg: "%select{variable|subscript}0 cannot provide both %1 and %2"
-
-- id: previous_accessor
-  msg: "%select{|previous definition of }1%0 %select{defined |}1here"
-
-- id: expected_accessor_parameter_name
-  msg: "expected %select{setter|willSet|didSet}0 parameter name"
-
-- id: expected_rparen_set_name
-  msg: "expected ')' after setter parameter name"
-
-- id: expected_rparen_willSet_name
-  msg: "expected ')' after willSet parameter name"
-
-- id: expected_rparen_didSet_name
-  msg: "expected ')' after didSet parameter name"
-
-- id: expected_lbrace_accessor
-  msg: "expected '{' to start %0 definition"
-
-- id: expected_accessor_kw
-  msg: "expected 'get', 'set', 'willSet', or 'didSet' keyword to start an accessor definition"
-
-- id: missing_getter
-  msg: "%select{variable|subscript}0 with %1 must also have a getter"
-
-- id: missing_reading_accessor
-  msg: "%select{variable|subscript}0 with %1 must also have a getter, addressor, or 'read' accessor"
-
-- id: observing_accessor_conflicts_with_accessor
-  msg: "%select{'willSet'|'didSet'}0 cannot be provided together with %1"
-
-- id: observing_accessor_in_subscript
-  msg: "%select{'willSet'|'didSet'}0 is not allowed in subscripts"
-
-- id: getset_cannot_be_implied
-  msg: "variable with implied type cannot have implied getter/setter"
-
-- id: decl_expected_module_name
-  msg: "expected module name in import declaration"
-
-- id: expected_lbrace_extension
-  msg: "expected '{' in extension"
-
-- id: expected_rbrace_extension
-  msg: "expected '}' at end of extension"
-
-- id: extension_type_expected
-  msg: "expected type name in extension declaration"
-
-- id: expected_equal_in_typealias
-  msg: "expected '=' in type alias declaration"
-
-- id: expected_type_in_typealias
-  msg: "expected type in type alias declaration"
-
-- id: expected_type_in_associatedtype
-  msg: "expected type in associated type declaration"
-
-- id: associated_type_generic_parameter_list
-  msg: "associated types must not have a generic parameter list"
-
-- id: func_decl_without_paren
-  msg: "expected '(' in argument list of function declaration"
-
-- id: static_func_decl_global_scope
-  msg: "%select{%error|static methods|class methods}0 may only be declared on a type"
-
-- id: func_decl_expected_arrow
-  msg: "expected '->' after function parameter tuple"
-
-- id: operator_static_in_protocol
-  msg: "operator '%0' declared in protocol must be 'static'"
-
-- id: expected_lbrace_enum
-  msg: "expected '{' in enum"
-
-- id: expected_rbrace_enum
-  msg: "expected '}' at end of enum"
-
-- id: expected_lbrace_struct
-  msg: "expected '{' in struct"
-
-- id: expected_rbrace_struct
-  msg: "expected '}' in struct"
-
-- id: expected_lbrace_class
-  msg: "expected '{' in class"
-
-- id: expected_rbrace_class
-  msg: "expected '}' in class"
-
-- id: expected_colon_class
-  msg: "expected ':' to begin inheritance clause"
-
-- id: generic_arguments_protocol
-  msg: "protocols do not allow generic parameters; use associated types instead"
-
-- id: expected_lbrace_protocol
-  msg: "expected '{' in protocol type"
-
-- id: expected_rbrace_protocol
-  msg: "expected '}' in protocol"
-
-- id: protocol_setter_name
-  msg: "setter in a protocol cannot have a name"
-
-- id: protocol_method_with_body
-  msg: "protocol methods must not have bodies"
-
-- id: protocol_init_with_body
-  msg: "protocol initializers must not have bodies"
-
-- id: subscript_decl_wrong_scope
-  msg: "'subscript' functions may only be declared within a type"
-
-- id: expected_lparen_subscript
-  msg: "expected '(' for subscript parameters"
-
-- id: subscript_has_name
-  msg: "subscripts cannot have a name"
-
-- id: expected_arrow_subscript
-  msg: "expected '->' for subscript element type"
-
-- id: expected_type_subscript
-  msg: "expected subscripting element type"
-
-- id: expected_lbrace_subscript
-  msg: "expected '{' in subscript to specify getter and setter implementation"
-
-- id: expected_lbrace_subscript_protocol
-  msg: "subscript in protocol must have explicit { get } or { get set } specifier"
-
-- id: subscript_without_get
-  msg: "subscript declarations must have a getter"
-
-- id: invalid_nested_init
-  msg: "missing '%select{super.|self.}0' at initializer invocation"
-
-- id: initializer_decl_wrong_scope
-  msg: "initializers may only be declared within a type"
-
-- id: expected_lparen_initializer
-  msg: "expected '(' for initializer parameters"
-
-- id: initializer_has_name
-  msg: "initializers cannot have a name"
-
-- id: destructor_decl_outside_class
-  msg: "deinitializers may only be declared within a class"
-
-- id: expected_lbrace_destructor
-  msg: "expected '{' for deinitializer"
-
-- id: destructor_has_name
-  msg: "deinitializers cannot have a name"
-
-- id: opened_destructor_expected_rparen
-  msg: "expected ')' to close parameter list"
-
-- id: destructor_params
-  msg: "no parameter clause allowed on deinitializer"
-
-- id: operator_decl_inner_scope
-  msg: "'operator' may only be declared at file scope"
-
-- id: expected_operator_name_after_operator
-  msg: "expected operator name in operator declaration"
-
-- id: identifier_within_operator_name
-  msg: "'%0' is considered an identifier and must not appear within an operator name"
-
-- id: operator_name_invalid_char
-  msg: "'%0' is not allowed in operator names"
-
-- id: postfix_operator_name_cannot_start_with_unwrap
-  msg: "postfix operator names starting with '?' or '!' are disallowed to avoid collisions with built-in unwrapping operators"
-
-- id: deprecated_operator_body
-  msg: "operator should no longer be declared with body"
-
-- id: deprecated_operator_body_use_group
-  msg: "operator should no longer be declared with body; use a precedence group instead"
-
-- id: operator_decl_no_fixity
-  msg: "operator must be declared as 'prefix', 'postfix', or 'infix'"
-
-- id: operator_decl_expected_type
-  msg: "expected designated type in operator declaration"
-
-- id: operator_decl_trailing_comma
-  msg: "trailing comma in operator declaration"
-
-- id: precedencegroup_not_infix
-  msg: "only infix operators may declare a precedence"
-
-- id: expected_precedencegroup_name
-  msg: "expected identifier after 'precedencegroup'"
-
-- id: expected_precedencegroup_lbrace
-  msg: "expected '{' after name of precedence group"
-
-- id: expected_precedencegroup_attribute
-  msg: "expected operator attribute identifier in precedence group body"
-
-- id: unknown_precedencegroup_attribute
-  msg: "'%0' is not a valid precedence group attribute"
-
-- id: expected_precedencegroup_attribute_colon
-  msg: "expected colon after attribute name in precedence group"
-
-- id: precedencegroup_attribute_redeclared
-  msg: "'%0' attribute for precedence group declared multiple times"
-
-- id: expected_precedencegroup_associativity
-  msg: "expected 'none', 'left', or 'right' after 'associativity'"
-
-- id: expected_precedencegroup_assignment
-  msg: "expected 'true' or 'false' after 'assignment'"
-
-- id: expected_precedencegroup_relation
-  msg: "expected name of related precedence group after '%0'"
-
-- id: expected_sil_keyword
-  msg: "expected SIL keyword"
-
-- id: inout_not_attribute
-  msg: "@inout is no longer an attribute"
-
-- id: only_allowed_in_sil
-  msg: "'%0' only allowed in SIL modules"
-
-- id: expected_sil_type
-  msg: "expected type in SIL code"
-
-- id: expected_sil_colon_value_ref
-  msg: "expected ':' before type in SIL value reference"
-
-- id: expected_sil_value_name
-  msg: "expected SIL value name"
-
-- id: expected_sil_type_kind
-  msg: "expected SIL type to %0"
-
-- id: expected_sil_constant
-  msg: "expected constant in SIL code"
-
-- id: referenced_value_no_accessor
-  msg: "referenced declaration has no %select{getter|setter}0"
-
-- id: expected_sil_value_ownership_kind
-  msg: "expected value ownership kind in SIL code"
-
-- id: silfunc_and_silarg_have_incompatible_sil_value_ownership
-  msg: "SILFunction and SILArgument have mismatching ValueOwnershipKinds. Function type specifies: '@%0'. SIL argument specifies: '@%1'."
-
-- id: expected_sil_colon
-  msg: "expected ':' before %0"
-
-- id: expected_sil_tuple_index
-  msg: "expected tuple element index"
-
-- id: invalid_index_subset
-  msg: "invalid index subset; expected '[SU]+' where 'S' represents set indices and 'U' represents unset indices"
-
-- id: sil_value_redefinition
-  msg: "redefinition of value '%0'"
-
-- id: sil_value_use_type_mismatch
-  msg: "value '%0' defined with mismatching type %1 (expected %2)"
-
-- id: sil_value_def_type_mismatch
-  msg: "value '%0' used with mismatching type %1 (expected %2)"
-
-- id: sil_use_of_undefined_value
-  msg: "use of undefined value '%0'"
-
-- id: sil_prior_reference
-  msg: "prior reference was here"
-
-- id: expected_colon_in_sil_location
-  msg: "expected ':' in SIL location"
-
-- id: sil_invalid_line_in_sil_location
-  msg: "line number must be a positive integer"
-
-- id: sil_invalid_column_in_sil_location
-  msg: "column number must be a positive integer"
-
-- id: sil_invalid_scope_slot
-  msg: "scope number must be a positive integer "
-
-- id: sil_scope_undeclared
-  msg: "scope number %0 needs to be declared before first use"
-
-- id: sil_scope_redefined
-  msg: "scope number %0 is already defined"
-
-- id: expected_sil_instr_start_of_line
-  msg: "SIL instructions must be at the start of a line"
-
-- id: expected_equal_in_sil_instr
-  msg: "expected '=' in SIL instruction"
-
-- id: wrong_result_count_in_sil_instr
-  msg: "wrong number of results for SIL instruction, expected %0"
-
-- id: expected_sil_instr_opcode
-  msg: "expected SIL instruction opcode"
-
-- id: expected_tok_in_sil_instr
-  msg: "expected '%0' in SIL instruction"
-
-- id: sil_property_generic_signature_mismatch
-  msg: "sil_property generic signature must match original declaration"
-
-- id: sil_string_no_encoding
-  msg: "string_literal instruction requires an encoding"
-
-- id: sil_string_invalid_encoding
-  msg: "unknown string literal encoding '%0'"
-
-- id: expected_tuple_type_in_tuple
-  msg: "tuple instruction requires a tuple type"
-
-- id: sil_tuple_inst_wrong_value_count
-  msg: "tuple instruction requires %0 values"
-
-- id: sil_tuple_inst_wrong_field
-  msg: "tuple instruction requires a field number"
-
-- id: sil_struct_inst_wrong_field
-  msg: "struct instruction requires a field name"
-
-- id: sil_ref_inst_wrong_field
-  msg: "ref_element_addr instruction requires a field name"
-
-- id: sil_invalid_instr_operands
-  msg: "invalid instruction operands"
-
-- id: sil_operand_not_address
-  msg: "%0 operand of '%1' must have address type"
-
-- id: sil_operand_not_ref_storage_address
-  msg: "%0 operand of '%1' must have address of %2 type"
-
-- id: sil_integer_literal_not_integer_type
-  msg: "integer_literal instruction requires a 'Builtin.Int<n>' type"
-
-- id: sil_integer_literal_not_well_formed
-  msg: "integer_literal value not well-formed for type %0"
-
-- id: sil_float_literal_not_float_type
-  msg: "float_literal instruction requires a 'Builtin.FP<n>' type"
-
-- id: sil_substitutions_on_non_polymorphic_type
-  msg: "apply of non-polymorphic function cannot have substitutions"
-
-- id: sil_witness_method_not_protocol
-  msg: "witness_method is not a protocol method"
-
-- id: sil_witness_method_type_does_not_conform
-  msg: "witness_method type does not conform to protocol"
-
-- id: sil_member_decl_not_found
-  msg: "member not found"
-
-- id: sil_named_member_decl_not_found
-  msg: "member %0 not found in type %1"
-
-- id: sil_member_lookup_bad_type
-  msg: "cannot lookup member %0 in non-nominal, non-module type %1"
-
-- id: sil_member_decl_type_mismatch
-  msg: "member defined with mismatching type %0 (expected %1)"
-
-- id: sil_substitution_mismatch
-  msg: "substitution replacement type %0 does not conform to protocol %1"
-
-- id: sil_not_class
-  msg: "substitution replacement type %0 is not a class type"
-
-- id: sil_missing_substitutions
-  msg: "missing substitutions"
-
-- id: sil_too_many_substitutions
-  msg: "too many substitutions"
-
-- id: sil_dbg_unknown_key
-  msg: "unknown key '%0' in debug variable declaration"
-
-- id: sil_objc_with_tail_elements
-  msg: "alloc_ref [objc] cannot have tail allocated elements"
-
-- id: sil_expected_access_kind
-  msg: "%0 instruction must have explicit access kind"
-
-- id: sil_expected_access_enforcement
-  msg: "%0 instruction must have explicit access enforcement"
-
-- id: sil_keypath_expected_component_kind
-  msg: "expected keypath component kind"
-
-- id: sil_keypath_unknown_component_kind
-  msg: "unknown keypath component kind %0"
-
-- id: sil_keypath_computed_property_missing_part
-  msg: "keypath %select{gettable|settable}0_property component needs an %select{id and getter|id, getter, and setter}0"
-
-- id: sil_keypath_no_root
-  msg: "keypath must have a root component declared"
-
-- id: sil_keypath_index_not_hashable
-  msg: "key path index type %0 does not conform to Hashable"
-
-- id: sil_keypath_index_operand_type_conflict
-  msg: "conflicting types for key path operand %0: %1 vs. %2"
-
-- id: sil_keypath_no_use_of_operand_in_pattern
-  msg: "operand %0 is not referenced by any component in the pattern"
-
-- id: expected_sil_block_name
-  msg: "expected basic block name or '}'"
-
-- id: expected_sil_block_colon
-  msg: "expected ':' after basic block name"
-
-- id: sil_undefined_basicblock_use
-  msg: "use of undefined basic block %0"
-
-- id: sil_basicblock_redefinition
-  msg: "redefinition of basic block %0"
-
-- id: sil_basicblock_arg_rparen
-  msg: "expected ')' in basic block argument list"
-
-- id: expected_sil_function_name
-  msg: "expected SIL function name"
-
-- id: expected_sil_rbrace
-  msg: "expected '}' at the end of a sil body"
-
-- id: expected_sil_function_type
-  msg: "sil function expected to have SIL function type"
-
-- id: sil_dynamically_replaced_func_not_found
-  msg: "dynamically replaced function not found %0"
-
-- id: sil_availability_expected_version
-  msg: "expected version number in 'available' attribute"
-
-- id: expected_sil_stage_name
-  msg: "expected 'raw' or 'canonical' after 'sil_stage'"
-
-- id: multiple_sil_stage_decls
-  msg: "sil_stage declared multiple times"
-
-- id: expected_sil_vtable_colon
-  msg: "expected ':' in a vtable entry"
-
-- id: sil_vtable_func_not_found
-  msg: "sil function not found %0"
-
-- id: sil_vtable_class_not_found
-  msg: "sil class not found %0"
-
-- id: sil_vtable_bad_entry_kind
-  msg: "expected 'inherited' or 'override'"
-
-- id: sil_vtable_expect_rsquare
-  msg: "expected ']' after vtable entry kind"
-
-- id: sil_global_variable_not_found
-  msg: "sil global not found %0"
-
-- id: expected_sil_witness_colon
-  msg: "expected ':' in a witness table"
-
-- id: expected_sil_witness_lparen
-  msg: "expected '(' in a witness table"
-
-- id: expected_sil_witness_rparen
-  msg: "expected ')' in a witness table"
-
-- id: sil_witness_func_not_found
-  msg: "sil function not found %0"
-
-- id: sil_witness_protocol_not_found
-  msg: "sil protocol not found %0"
-
-- id: sil_witness_assoc_not_found
-  msg: "sil associated type decl not found %0"
-
-- id: sil_witness_assoc_conf_not_found
-  msg: "sil associated type path for conformance not found %0"
-
-- id: sil_witness_protocol_conformance_not_found
-  msg: "sil protocol conformance not found"
-
-- id: sil_diff_witness_expected_token
-  msg: "expected '%0' in differentiability witness"
-
-- id: sil_diff_witness_serialized_declaration
-  msg: "differentiability witness declaration should not be serialized"
-
-- id: sil_diff_witness_undefined
-  msg: "reference to undefined differentiability witness"
-
-- id: sil_diff_witness_invalid_generic_signature
-  msg: "expected witness generic signature '%0' does not have same generic parameters as original function generic signature '%1'"
-
-- id: sil_coverage_invalid_hash
-  msg: "expected coverage hash"
-
-- id: sil_coverage_expected_lbrace
-  msg: "expected '{' in coverage map"
-
-- id: sil_coverage_expected_loc
-  msg: "expected line:column pair"
-
-- id: sil_coverage_expected_arrow
-  msg: "expected '->' after start location"
-
-- id: sil_coverage_expected_colon
-  msg: "expected ':' after source range"
-
-- id: sil_coverage_invalid_counter
-  msg: "expected counter expression, id, or 'zero'"
-
-- id: sil_coverage_expected_rparen
-  msg: "expected ')' to end counter expression"
-
-- id: sil_coverage_expected_quote
-  msg: "expected quotes surrounding PGO function name"
-
-- id: sil_coverage_invalid_operator
-  msg: "expected '+' or '-'"
-
-- id: expected_type
-  msg: "expected type"
-
-- id: expected_init_value
-  msg: "expected initial value after '='"
-
-- id: expected_identifier_in_dotted_type
-  msg: "expected identifier in dotted type"
-
-- id: expected_identifier_for_type
-  msg: "expected identifier for type name"
-
-- id: expected_rangle_generic_arg_list
-  msg: "expected '>' to complete generic argument list"
-
-- id: expected_type_function_result
-  msg: "expected type for function result"
-
-- id: generic_non_function
-  msg: "only syntactic function types can be generic"
-
-- id: rethrowing_function_type
-  msg: "only function declarations may be marked 'rethrows'; did you mean 'throws'?"
-
-- id: async_or_throws_in_wrong_position
-  msg: "%select{'throws'|'rethrows'|'async'}0 may only occur before '->'"
-
-- id: throw_in_function_type
-  msg: "expected throwing specifier; did you mean 'throws'?"
-
-- id: expected_type_before_arrow
-  msg: "expected type before '->'"
-
-- id: expected_type_after_arrow
-  msg: "expected type after '->'"
-
-- id: function_type_argument_label
-  msg: "function types cannot have argument labels; use '_' before %0"
-
-- id: expected_dynamic_func_attr
-  msg: "expected a dynamically_replaceable function"
-
-- id: async_after_throws
-  msg: "'async' must precede %select{'throws'|'rethrows'}0"
-
-- id: async_init
-  msg: "initializer cannot be marked 'async'"
-
-- id: expected_expr_enum_case_raw_value
-  msg: "expected expression after '=' in 'case'"
-
-- id: nonliteral_enum_case_raw_value
-  msg: "raw value for enum case must be a literal"
-
-- id: new_array_syntax
-  msg: "array types are now written with the brackets around the element type"
-
-- id: expected_rbracket_array_type
-  msg: "expected ']' in array type"
-
-- id: expected_element_type
-  msg: "expected element type"
-
-- id: expected_dictionary_value_type
-  msg: "expected dictionary value type"
-
-- id: expected_rbracket_dictionary_type
-  msg: "expected ']' in dictionary type"
-
-- id: extra_rbracket
-  msg: "unexpected ']' in type; did you mean to write an array type?"
-
-- id: extra_colon
-  msg: "unexpected ':' in type; did you mean to write a dictionary type?"
-
-- id: subscript_array_element
-  msg: "unexpected subscript in array literal; did you mean to write two separate elements instead?"
-
-- id: subscript_array_element_fix_it_add_comma
-  msg: "add a separator between the elements"
-
-- id: subscript_array_element_fix_it_remove_space
-  msg: "remove the space between the elements to silence this warning"
-
-- id: expected_rparen_tuple_type_list
-  msg: "expected ')' at end of tuple list"
-
-- id: multiple_ellipsis_in_tuple
-  msg: "only a single element can be variadic"
-
-- id: tuple_type_init
-  msg: "default argument not permitted in a tuple type"
-
-- id: protocol_method_argument_init
-  msg: "default argument not permitted in a protocol method"
-
-- id: protocol_init_argument_init
-  msg: "default argument not permitted in a protocol initializer"
-
-- id: tuple_type_multiple_labels
-  msg: "tuple element cannot have two labels"
-
-- id: expected_rangle_protocol
-  msg: "expected '>' to complete protocol-constrained type"
-
-- id: deprecated_protocol_composition
-  msg: "'protocol<...>' composition syntax has been removed; join the protocols using '&'"
-
-- id: deprecated_protocol_composition_single
-  msg: "'protocol<...>' composition syntax has been removed and is not needed here"
-
-- id: deprecated_any_composition
-  msg: "'protocol<>' syntax has been removed; use 'Any' instead"
-
-- id: sil_box_expected_var_or_let
-  msg: "expected 'var' or 'let' to introduce SIL box field type"
-
-- id: sil_box_expected_r_brace
-  msg: "expected '}' to complete SIL box field type list"
-
-- id: sil_box_expected_r_angle
-  msg: "expected '>' to complete SIL box generic argument list"
-
-- id: sil_function_subst_expected_l_angle
-  msg: "expected '<' to begin SIL function type substitution list after 'for'"
-
-- id: sil_function_subst_expected_r_angle
-  msg: "expected '>' to end SIL function type substitution list after 'for <...'"
-
-- id: sil_function_subst_expected_generics
-  msg: "expected '<' to begin substituted parameter list after '@substituted'"
-
-- id: sil_function_subst_expected_function
-  msg: "expected function type after '@substituted'"
-
-- id: sil_function_subst_expected_subs
-  msg: "expected 'for' to begin substitutions after '@substituted' function type"
-
-- id: sil_function_subs_without_generics
-  msg: "unexpected 'for' to begin substitutions after non-generic function type"
-
-- id: opaque_mid_composition
-  msg: "'some' should appear at the beginning of a composition"
-
-- id: layout_size_should_be_positive
-  msg: "expected non-negative size to be specified in layout constraint"
-
-- id: layout_alignment_should_be_positive
-  msg: "expected non-negative alignment to be specified in layout constraint"
-
-- id: expected_rparen_layout_constraint
-  msg: "expected ')' to complete layout constraint"
-
-- id: layout_constraints_only_inside_specialize_attr
-  msg: "layout constraints are only allowed inside '_specialize' attributes"
-
-- id: expected_pattern
-  msg: "expected pattern"
-
-- id: keyword_cant_be_identifier
-  msg: "keyword '%0' cannot be used as an identifier here"
-
-- id: repeated_identifier
-  msg: "found an unexpected second identifier in %0 declaration; is there an accidental break?"
-
-- id: join_identifiers
-  msg: "join the identifiers together"
-
-- id: join_identifiers_camel_case
-  msg: "join the identifiers together with camel-case"
-
-- id: backticks_to_escape
-  msg: "if this name is unavoidable, use backticks to escape it"
-
-- id: expected_rparen_tuple_pattern_list
-  msg: "expected ')' at end of tuple pattern"
-
-- id: untyped_pattern_ellipsis
-  msg: "'...' cannot be applied to a subpattern which is not explicitly typed"
-
-- id: no_default_arg_closure
-  msg: "default arguments are not allowed in closures"
-
-- id: no_default_arg_curried
-  msg: "default arguments are not allowed in curried parameter lists"
-
-- id: var_pattern_in_var
-  msg: "'%select{var|let}0' cannot appear nested inside another 'var' or 'let' pattern"
-
-- id: extra_var_in_multiple_pattern_list
-  msg: "%0 must be bound in every pattern"
-
-- id: let_pattern_in_immutable_context
-  msg: "'let' pattern cannot appear nested in an already immutable context"
-
-- id: specifier_must_have_type
-  msg: "%0 arguments must have a type specified"
-
-- id: expected_rparen_parameter
-  msg: "expected ')' in parameter"
-
-- id: expected_parameter_type
-  msg: "expected parameter type following ':'"
-
-- id: expected_parameter_name
-  msg: "expected parameter name followed by ':'"
-
-- id: expected_parameter_colon
-  msg: "expected ':' following argument label and parameter name"
-
-- id: expected_assignment_instead_of_comparison_operator
-  msg: "expected '=' instead of '==' to assign default value for parameter"
-
-- id: multiple_parameter_ellipsis
-  msg: "only a single variadic parameter '...' is permitted"
-
-- id: parameter_vararg_default
-  msg: "variadic parameter cannot have a default value"
-
-- id: parameter_specifier_as_attr_disallowed
-  msg: "'%0' before a parameter name is not allowed, place it before the parameter type instead"
-
-- id: parameter_specifier_repeated
-  msg: "parameter must not have multiple '__owned', 'inout', or '__shared' specifiers"
-
-- id: parameter_let_var_as_attr
-  msg: "'%0' in this position is interpreted as an argument label"
-
-- id: parameter_extraneous_double_up
-  msg: "extraneous duplicate parameter name; %0 already has an argument label"
-
-- id: parameter_operator_keyword_argument
-  msg: "%select{operator|closure|enum case}0 cannot have keyword arguments"
-
-- id: parameter_unnamed
-  msg: "unnamed parameters must be written with the empty name '_'"
-
-- id: parameter_unnamed_warn
-  msg: "unnamed parameters must be written with the empty name '_'"
-
-- id: parameter_curry_syntax_removed
-  msg: "cannot have more than one parameter list"
-
-- id: initializer_as_typed_pattern
-  msg: "unexpected initializer in pattern; did you mean to use '='?"
-
-- id: unlabeled_parameter_following_variadic_parameter
-  msg: "a parameter following a variadic parameter requires a label"
-
-- id: enum_element_empty_arglist
-  msg: "enum element with associated values must have at least one associated value"
-
-- id: enum_element_empty_arglist_swift4
-  msg: "enum element with associated values must have at least one associated value; this will be an error in the future version of Swift"
-
-- id: enum_element_empty_arglist_delete
-  msg: "did you mean to remove the empty associated value list?"
-
-- id: enum_element_empty_arglist_add_void
-  msg: "did you mean to explicitly add a 'Void' associated value?"
-
-- id: expected_stmt
-  msg: "expected statement"
-
-- id: illegal_top_level_stmt
-  msg: "statements are not allowed at the top level"
-
-- id: illegal_top_level_expr
-  msg: "expressions are not allowed at the top level"
-
-- id: illegal_semi_stmt
-  msg: "';' statements are not allowed"
-
-- id: statement_begins_with_closure
-  msg: "top-level statement cannot begin with a closure expression"
-
-- id: statement_same_line_without_semi
-  msg: "consecutive statements on a line must be separated by ';'"
-
-- id: invalid_label_on_stmt
-  msg: "labels are only valid on loops, if, and switch statements"
-
-- id: labeled_block_needs_do
-  msg: "labeled block needs 'do'"
-
-- id: snake_case_deprecated
-  msg: "%0 has been replaced with %1 in Swift 3"
-
-- id: expected_expr_assignment
-  msg: "expected expression in assignment"
-
-- id: expected_rbrace_in_brace_stmt
-  msg: "expected '}' at end of brace statement"
-
-- id: typealias_inside_protocol_without_type
-  msg: "type alias is missing an assigned type; use 'associatedtype' to define an associated type requirement"
-
-- id: associatedtype_outside_protocol
-  msg: "associated types can only be defined in a protocol; define a type or introduce a 'typealias' to satisfy an associated type requirement"
-
-- id: expected_expr_return
-  msg: "expected expression in 'return' statement"
-
-- id: unindented_code_after_return
-  msg: "expression following 'return' is treated as an argument of the 'return'"
-
-- id: indent_expression_to_silence
-  msg: "indent the expression to silence this warning"
-
-- id: expected_expr_throw
-  msg: "expected expression in 'throw' statement"
-
-- id: expected_expr_yield
-  msg: "expected expression in 'yield' statement"
-
-- id: expected_lbrace_after_defer
-  msg: "expected '{' after 'defer'"
-
-- id: expected_comma_stmtcondition
-  msg: "expected ',' joining parts of a multi-clause condition"
-
-- id: expected_expr_conditional
-  msg: "expected expression in conditional"
-
-- id: expected_binding_keyword
-  msg: "expected '%0' in conditional"
-
-- id: expected_expr_conditional_var
-  msg: "expected expression after '=' in conditional binding"
-
-- id: conditional_var_initializer_required
-  msg: "variable binding in a condition requires an initializer"
-
-- id: wrong_condition_case_location
-  msg: "pattern matching binding is spelled with 'case %0', not '%0 case'"
-
-- id: expected_condition_if
-  msg: "expected expression, var, or let in 'if' condition"
-
-- id: missing_condition_after_if
-  msg: "missing condition in an 'if' statement"
-
-- id: expected_lbrace_after_if
-  msg: "expected '{' after 'if' condition"
-
-- id: expected_lbrace_or_if_after_else
-  msg: "expected '{' or 'if' after 'else'"
-
-- id: expected_lbrace_or_if_after_else_fixit
-  msg: "expected '{' or 'if' after 'else'; did you mean to write 'if'?"
-
-- id: unexpected_else_after_if
-  msg: "unexpected 'else' immediately following 'if' condition"
-
-- id: suggest_removing_else
-  msg: "remove 'else' to execute the braced block of statements when the condition is true"
-
-- id: expected_condition_guard
-  msg: "expected expression, var, let or case in 'guard' condition"
-
-- id: missing_condition_after_guard
-  msg: "missing condition in an 'guard' statement"
-
-- id: expected_else_after_guard
-  msg: "expected 'else' after 'guard' condition"
-
-- id: expected_lbrace_after_guard
-  msg: "expected '{' after 'guard' else"
-
-- id: bound_var_guard_body
-  msg: "variable declared in 'guard' condition is not usable in its body"
-
-- id: expected_condition_while
-  msg: "expected expression, var, or let in 'while' condition"
-
-- id: missing_condition_after_while
-  msg: "missing condition in a 'while' statement"
-
-- id: expected_lbrace_after_while
-  msg: "expected '{' after 'while' condition"
-
-- id: expected_lbrace_after_repeat
-  msg: "expected '{' after 'repeat'"
-
-- id: expected_while_after_repeat_body
-  msg: "expected 'while' after body of 'repeat' statement"
-
-- id: expected_expr_repeat_while
-  msg: "expected expression in 'repeat-while' condition"
-
-- id: do_while_now_repeat_while
-  msg: "'do-while' statement is not allowed"
-
-- id: do_while_expected_repeat_while
-  msg: "did you mean 'repeat-while' statement?"
-
-- id: do_while_expected_separate_stmt
-  msg: "did you mean separate 'do' and 'while' statements?"
-
-- id: expected_lbrace_after_do
-  msg: "expected '{' after 'do'"
-
-- id: expected_lbrace_after_catch
-  msg: "expected '{' after 'catch' pattern"
-
-- id: expected_catch_where_expr
-  msg: "expected expression for 'where' guard of 'catch'"
-
-- id: docatch_not_trycatch
-  msg: "the 'do' keyword is used to specify a 'catch' region"
-
-- id: c_style_for_stmt_removed
-  msg: "C-style for statement has been removed in Swift 3"
-
-- id: expected_foreach_in
-  msg: "expected 'in' after for-each pattern"
-
-- id: expected_foreach_container
-  msg: "expected Sequence expression for for-each loop"
-
-- id: expected_foreach_lbrace
-  msg: "expected '{' to start the body of for-each loop"
-
-- id: expected_foreach_where_expr
-  msg: "expected expression in 'where' guard of 'for/in'"
-
-- id: expected_switch_expr
-  msg: "expected expression in 'switch' statement"
-
-- id: expected_lbrace_after_switch
-  msg: "expected '{' after 'switch' subject expression"
-
-- id: expected_rbrace_switch
-  msg: "expected '}' at end of 'switch' statement"
-
-- id: case_outside_of_switch
-  msg: "'%0' label can only appear inside a 'switch' statement"
-
-- id: stmt_in_switch_not_covered_by_case
-  msg: "all statements inside a switch must be covered by a 'case' or 'default'"
-
-- id: case_after_default
-  msg: "additional 'case' blocks cannot appear after the 'default' block of a 'switch'"
-
-- id: expected_case_where_expr
-  msg: "expected expression for 'where' guard of 'case'"
-
-- id: expected_case_colon
-  msg: "expected ':' after '%0'"
-
-- id: default_with_where
-  msg: "'default' cannot be used with a 'where' guard expression"
-
-- id: case_stmt_without_body
-  msg: "%select{'case'|'default'}0 label in a 'switch' should have at least one executable statement"
-
-- id: try_on_stmt
-  msg: "'try' cannot be used with '%0'"
-
-- id: try_on_return_throw_yield
-  msg: "'try' must be placed on the %select{returned|thrown|yielded}0 expression"
-
-- id: try_on_var_let
-  msg: "'try' must be placed on the initial value expression"
-
-- id: expected_expr
-  msg: "expected expression"
-
-- id: expected_separator
-  msg: "expected '%0' separator"
-
-- id: unexpected_separator
-  msg: "unexpected '%0' separator"
-
-- id: expected_expr_after_operator
-  msg: "expected expression after operator"
-
-- id: expected_expr_after_unary_operator
-  msg: "expected expression after unary operator"
-
-- id: expected_prefix_operator
-  msg: "unary operator cannot be separated from its operand"
-
-- id: expected_operator_ref
-  msg: "expected operator name in operator reference"
-
-- id: invalid_postfix_operator
-  msg: "operator with postfix spacing cannot start a subexpression"
-
-- id: expected_member_name
-  msg: "expected member name following '.'"
-
-- id: dollar_numeric_too_large
-  msg: "numeric value following '$' is too large"
-
-- id: numeric_literal_numeric_member
-  msg: "expected named member of numeric literal"
-
-- id: standalone_dollar_identifier
-  msg: "'$' is not an identifier; use backticks to escape it"
-
-- id: dollar_identifier_decl
-  msg: "cannot declare entity named %0; the '$' prefix is reserved for implicitly-synthesized declarations"
-
-- id: anon_closure_arg_not_in_closure
-  msg: "anonymous closure argument not contained in a closure"
-
-- id: anon_closure_arg_in_closure_with_args
-  msg: "anonymous closure arguments cannot be used inside a closure that has explicit arguments"
-
-- id: anon_closure_arg_in_closure_with_args_typo
-  msg: "anonymous closure arguments cannot be used inside a closure that has explicit arguments; did you mean '%0'?"
-
-- id: anon_closure_tuple_param_destructuring
-  msg: "closure tuple parameter does not support destructuring"
-
-- id: expected_closure_parameter_name
-  msg: "expected the name of a closure parameter"
-
-- id: expected_capture_specifier
-  msg: "expected 'weak', 'unowned', or no specifier in capture list"
-
-- id: expected_capture_specifier_name
-  msg: "expected name of in closure capture list"
-
-- id: expected_init_capture_specifier
-  msg: "expected initializer for closure capture specifier"
-
-- id: expected_capture_list_end_rsquare
-  msg: "expected ']' at end of capture list"
-
-- id: cannot_capture_fields
-  msg: "fields may only be captured by assigning to a specific name"
-
-- id: expected_closure_result_type
-  msg: "expected closure result type after '->'"
-
-- id: expected_closure_in
-  msg: "expected 'in' after the closure signature"
-
-- id: unexpected_tokens_before_closure_in
-  msg: "unexpected tokens prior to 'in'"
-
-- id: expected_closure_rbrace
-  msg: "expected '}' at end of closure"
-
-- id: trailing_closure_after_newlines
-  msg: "braces here form a trailing closure separated from its callee by multiple newlines"
-
-- id: trailing_closure_callee_here
-  msg: "callee is here"
-
-- id: string_literal_no_atsign
-  msg: "string literals in Swift are not preceded by an '@' sign"
-
-- id: invalid_float_literal_missing_leading_zero
-  msg: "'.%0' is not a valid floating point literal; it must be written '0.%0'"
-
-- id: availability_query_outside_if_stmt_guard
-  msg: "#available may only be used as condition of an 'if', 'guard' or 'while' statement"
-
-- id: empty_arg_label_underscore
-  msg: "an empty argument label is spelled with '_'"
-
-- id: expected_identifier_after_dot_expr
-  msg: "expected identifier after '.' expression"
-
-- id: expected_identifier_after_super_dot_expr
-  msg: "expected identifier or 'init' after super '.' expression"
-
-- id: expected_dot_or_subscript_after_super
-  msg: "expected '.' or '[' after 'super'"
-
-- id: super_in_closure_with_capture
-  msg: "using 'super' in a closure where 'self' is explicitly captured is not yet supported"
-
-- id: super_in_closure_with_capture_here
-  msg: "'self' explicitly captured here"
-
-- id: expected_expr_in_expr_list
-  msg: "expected expression in list of expressions"
-
-- id: expected_expr_in_collection_literal
-  msg: "expected expression in container literal"
-
-- id: expected_key_in_dictionary_literal
-  msg: "expected key expression in dictionary literal"
-
-- id: expected_value_in_dictionary_literal
-  msg: "expected value in dictionary literal"
-
-- id: expected_colon_in_dictionary_literal
-  msg: "expected ':' in dictionary literal"
-
-- id: expected_rparen_expr_list
-  msg: "expected ')' in expression list"
-
-- id: expected_rsquare_expr_list
-  msg: "expected ']' in expression list"
-
-- id: expected_rsquare_array_expr
-  msg: "expected ']' in container literal expression"
-
-- id: expected_arg_list_in_object_literal
-  msg: "expected argument list in object literal"
-
-- id: legacy_object_literal
-  msg: "'%select{|[}0#%1(...)%select{|#]}0' has been renamed to '#%2(...)'"
-
-- id: unknown_pound_expr
-  msg: "use of unknown directive '#%0'"
-
-- id: expected_expr_after_if_question
-  msg: "expected expression after '?' in ternary expression"
-
-- id: expected_colon_after_if_question
-  msg: "expected ':' after '? ...' in ternary expression"
-
-- id: expected_expr_after_if_colon
-  msg: "expected expression after '? ... :' in ternary expression"
-
-- id: expected_expr_after_try
-  msg: "expected expression after 'try'"
-
-- id: expected_expr_after_await
-  msg: "expected expression after 'await'"
-
-- id: expected_type_after_is
-  msg: "expected type after 'is'"
-
-- id: expected_type_after_as
-  msg: "expected type after 'as'"
-
-- id: string_interpolation_extra
-  msg: "extra tokens after interpolated string expression"
-
-- id: string_interpolation_list_changing
-  msg: "interpolating multiple values will not form a tuple in Swift 5"
-
-- id: string_interpolation_list_insert_parens
-  msg: "insert parentheses to keep current behavior"
-
-- id: string_interpolation_label_changing
-  msg: "labeled interpolations will not be ignored in Swift 5"
-
-- id: string_interpolation_remove_label
-  msg: "remove %0 label to keep current behavior"
-
-- id: expr_keypath_expected_lparen
-  msg: "expected '(' following '#keyPath'"
-
-- id: expr_keypath_expected_property_or_type
-  msg: "expected property or type name within '#keyPath(...)'"
-
-- id: expr_keypath_expected_rparen
-  msg: "expected ')' to complete '#keyPath' expression"
-
-- id: expr_keypath_expected_expr
-  msg: "expected expression path in Swift key path"
-
-- id: expr_selector_expected_lparen
-  msg: "expected '(' following '#selector'"
-
-- id: expr_selector_expected_method_expr
-  msg: "expected expression naming a method within '#selector(...)'"
-
-- id: expr_selector_expected_property_expr
-  msg: "expected expression naming a property within '#selector(...)'"
-
-- id: expr_selector_expected_rparen
-  msg: "expected ')' to complete '#selector' expression"
-
-- id: expr_dynamictype_deprecated
-  msg: "'.dynamicType' is deprecated. Use 'type(of: ...)' instead"
-
-- id: pound_assert_disabled
-  msg: "#assert is an experimental feature that is currently disabled"
-
-- id: pound_assert_expected_lparen
-  msg: "expected '(' in #assert directive"
-
-- id: pound_assert_expected_rparen
-  msg: "expected ')' in #assert directive"
-
-- id: pound_assert_expected_expression
-  msg: "expected a condition expression"
-
-- id: pound_assert_expected_string_literal
-  msg: "expected a string literal"
-
-- id: replace_equal_with_colon_for_value
-  msg: "'=' has been replaced with ':' in attribute arguments"
-
-- id: expected_attribute_name
-  msg: "expected an attribute name"
-
-- id: unknown_attribute
-  msg: "unknown attribute '%0'"
-
-- id: unexpected_lparen_in_attribute
-  msg: "unexpected '(' in attribute '%0'"
-
-- id: duplicate_attribute
-  msg: "duplicate %select{attribute|modifier}0"
-
-- id: previous_attribute
-  msg: "%select{attribute|modifier}0 already specified here"
-
-- id: mutually_exclusive_attrs
-  msg: "'%0' contradicts previous %select{attribute|modifier}2 '%1'"
-
-- id: invalid_infix_on_func
-  msg: "'infix' modifier is not required or allowed on func declarations"
-
-- id: expected_in_attribute_list
-  msg: "expected ']' or ',' in attribute list"
-
-- id: type_attribute_applied_to_decl
-  msg: "attribute can only be applied to types, not declarations"
-
-- id: decl_attribute_applied_to_type
-  msg: "attribute can only be applied to declarations, not types"
-
-- id: attr_expected_lparen
-  msg: "expected '(' in '%0' %select{attribute|modifier}1"
-
-- id: attr_expected_rparen
-  msg: "expected ')' in '%0' %select{attribute|modifier}1"
-
-- id: attr_expected_comma
-  msg: "expected ',' in '%0' %select{attribute|modifier}1"
-
-- id: attr_expected_string_literal
-  msg: "expected string literal in '%0' attribute"
-
-- id: attr_missing_label
-  msg: "missing label '%0:' in '@%1' attribute"
-
-- id: attr_expected_label
-  msg: "expected label '%0:' in '@%1' attribute"
-
-- id: alignment_must_be_positive_integer
-  msg: "alignment value must be a positive integer literal"
-
-- id: swift_native_objc_runtime_base_must_be_identifier
-  msg: "@_swift_native_objc_runtime_base class name must be an identifier"
-
-- id: objc_runtime_name_must_be_identifier
-  msg: "@_objcRuntimeName name must be an identifier"
-
-- id: attr_only_at_non_local_scope
-  msg: "attribute '%0' can only be used in a non-local scope"
-
-- id: projection_value_property_not_identifier
-  msg: "@_projectedValueProperty name must be an identifier"
-
-- id: attr_access_expected_set
-  msg: "expected 'set' as subject of '%0' modifier"
-
-- id: attr_access_expected_spi_name
-  msg: "expected an SPI identifier as subject of the '@_spi' attribute"
-
-- id: attr_renamed
-  msg: "'@%0' has been renamed to '@%1'"
-
-- id: attr_renamed_warning
-  msg: "'@%0' has been renamed to '@%1'"
-
-- id: attr_name_close_match
-  msg: "no attribute named '@%0'; did you mean '@%1'?"
-
-- id: attr_unsupported_on_target
-  msg: "attribute '%0' is unsupported on target '%1'"
-
-- id: attr_availability_platform
-  msg: "expected platform name or '*' for '%0' attribute"
-
-- id: attr_availability_unavailable_deprecated
-  msg: "'%0' attribute cannot be both unconditionally 'unavailable' and 'deprecated'"
-
-- id: attr_availability_invalid_duplicate
-  msg: "'%0' argument has already been specified"
-
-- id: attr_availability_unknown_platform
-  msg: "unknown platform '%0' for attribute '%1'"
-
-- id: attr_availability_invalid_renamed
-  msg: "'renamed' argument of '%0' attribute must be an operator, identifier, or full function name, optionally prefixed by a type name"
-
-- id: attr_availability_expected_option
-  msg: "expected '%0' option such as 'unavailable', 'introduced', 'deprecated', 'obsoleted', 'message', or 'renamed'"
-
-- id: attr_availability_expected_equal
-  msg: "expected ':' after '%1' in '%0' attribute"
-
-- id: attr_availability_expected_version
-  msg: "expected version number in '%0' attribute"
-
-- id: attr_availability_platform_agnostic_expected_option
-  msg: "expected 'introduced', 'deprecated', or 'obsoleted' in '%0' attribute for platform '%1'"
-
-- id: attr_availability_platform_agnostic_expected_deprecated_version
-  msg: "expected version number with 'deprecated' in '%0' attribute for platform '%1'"
-
-- id: attr_availability_platform_agnostic_infeasible_option
-  msg: "'%0' cannot be used in '%1' attribute for platform '%2'"
-
-- id: attr_availability_nonspecific_platform_unexpected_version
-  msg: "unexpected version number in '%0' attribute for non-specific platform '*'"
-
-- id: originally_defined_in_missing_rparen
-  msg: "expected ')' in @_originallyDefinedIn argument list"
-
-- id: originally_defined_in_unrecognized_platform
-  msg: "unrecognized platform name in @_originallyDefinedIn argument list"
-
-- id: originally_defined_in_unrecognized_property
-  msg: "unrecognized property in @_originallyDefinedIn argument list"
-
-- id: originally_defined_in_need_original_module_name
-  msg: "expected 'module: \"original\"' in the first argument to @_originallyDefinedIn"
-
-- id: originally_defined_in_need_nonempty_module_name
-  msg: "original module name cannot be empty in @_originallyDefinedIn"
-
-- id: originally_defined_in_need_platform_version
-  msg: "expected at least one platform version in @_originallyDefinedIn"
-
-- id: originally_defined_in_major_minor_only
-  msg: "@_originallyDefinedIn only uses major and minor version number"
-
-- id: originally_defined_in_missing_platform_name
-  msg: "* as platform name has no effect"
-
-- id: convention_attribute_expected_lparen
-  msg: "expected '(' after 'convention' attribute"
-
-- id: convention_attribute_expected_name
-  msg: "expected convention name identifier in 'convention' attribute"
-
-- id: convention_attribute_expected_rparen
-  msg: "expected ')' after convention name for 'convention' attribute"
-
-- id: convention_attribute_ctype_expected_label
-  msg: "expected 'cType' label in 'convention' attribute"
-
-- id: convention_attribute_ctype_expected_colon
-  msg: "expected ':' after 'cType' for 'convention' attribute"
-
-- id: convention_attribute_ctype_expected_string
-  msg: "expected string literal containing clang type for 'cType' in 'convention' attribute"
-
-- id: convention_attribute_witness_method_expected_colon
-  msg: "expected ':' after 'witness_method' for 'convention' attribute"
-
-- id: convention_attribute_witness_method_expected_protocol
-  msg: "expected protocol name in 'witness_method' 'convention' attribute"
-
-- id: attr_objc_missing_colon
-  msg: "missing ':' after selector piece in @objc attribute"
-
-- id: attr_objc_expected_rparen
-  msg: "expected ')' after name for @objc"
-
-- id: attr_objc_empty_name
-  msg: "expected name within parentheses of @objc attribute"
-
-- id: attr_dynamic_replacement_expected_rparen
-  msg: "expected ')' after function name for @_dynamicReplacement"
-
-- id: attr_dynamic_replacement_expected_function
-  msg: "expected a function name in @_dynamicReplacement(for:)"
-
-- id: attr_dynamic_replacement_expected_for
-  msg: "expected 'for' in '_dynamicReplacement' attribute"
-
-- id: attr_dynamic_replacement_expected_colon
-  msg: "expected ':' after @_dynamicReplacement(for"
-
-- id: attr_type_eraser_expected_type_name
-  msg: "expected a type name in @_typeEraser()"
-
-- id: attr_type_eraser_expected_rparen
-  msg: "expected ')' after type name for @_typeEraser"
-
-- id: attr_private_import_expected_rparen
-  msg: "expected ')' after function name for @_private"
-
-- id: attr_private_import_expected_sourcefile
-  msg: "expected 'sourceFile' in '_private' attribute"
-
-- id: attr_private_import_expected_sourcefile_name
-  msg: "expected a source file name in @_private(sourceFile:)"
-
-- id: attr_private_import_expected_colon
-  msg: "expected ':' after @_private(sourceFile"
-
-- id: opened_attribute_expected_lparen
-  msg: "expected '(' after 'opened' attribute"
-
-- id: opened_attribute_id_value
-  msg: "known id for 'opened' attribute must be a UUID string"
-
-- id: opened_attribute_expected_rparen
-  msg: "expected ')' after id value for 'opened' attribute"
-
-- id: optimization_attribute_expect_option
-  msg: "expected '%0' option such as '%1'"
-
-- id: optimization_attribute_unknown_option
-  msg: "unknown option '%0' for attribute '%1'"
-
-- id: effects_attribute_expect_option
-  msg: "expected '%0' option (readnone, readonly, readwrite)"
-
-- id: effects_attribute_unknown_option
-  msg: "unknown option '%0' for attribute '%1'"
-
-- id: attr_unowned_invalid_specifier
-  msg: "expected 'safe' or 'unsafe'"
-
-- id: attr_unowned_expected_rparen
-  msg: "expected ')' after specifier for 'unowned'"
-
-- id: attr_warn_unused_result_removed
-  msg: "'warn_unused_result' attribute behavior is now the default"
-
-- id: attr_warn_unused_result_expected_rparen
-  msg: "expected ')' after 'warn_unused_result' attribute"
-
-- id: attr_specialize_missing_colon
-  msg: "missing ':' after %0 in '_specialize' attribute"
-
-- id: attr_specialize_missing_comma
-  msg: "missing ',' in '_specialize' attribute"
-
-- id: attr_specialize_unknown_parameter_name
-  msg: "unknown parameter %0 in '_specialize attribute'"
-
-- id: attr_specialize_expected_bool_value
-  msg: "expected a boolean true or false value in '_specialize' attribute"
-
-- id: attr_specialize_export_true_no_op
-  msg: "'exported: true' has no effect in '_specialize' attribute"
-
-- id: attr_specialize_missing_parameter_label_or_where_clause
-  msg: "expected a parameter label or a where clause in '_specialize' attribute"
-
-- id: attr_specialize_parameter_already_defined
-  msg: "parameter '%0' was already defined in '_specialize' attribute"
-
-- id: attr_specialize_expected_partial_or_full
-  msg: "expected 'partial' or 'full' as values of the 'kind' parameter in '_specialize' attribute"
-
-- id: attr_implements_expected_member_name
-  msg: "expected a member name as second parameter in '_implements' attribute"
-
-- id: attr_differentiable_expected_parameter_list
-  msg: "expected a list of parameters to differentiate with respect to"
-
-- id: attr_differentiable_use_wrt_not_withrespectto
-  msg: "use 'wrt:' to specify parameters to differentiate with respect to"
-
-- id: attr_differentiable_expected_label
-  msg: "expected 'wrt:' or 'where' in '@differentiable' attribute"
-
-- id: attr_differentiable_unexpected_argument
-  msg: "unexpected argument '%0' in '@differentiable' attribute"
-
-- id: expected_colon_after_label
-  msg: "expected a colon ':' after '%0'"
-
-- id: diff_params_clause_expected_parameter
-  msg: "expected a parameter, which can be a function parameter name, parameter index, or 'self'"
-
-- id: diff_params_clause_expected_parameter_unnamed
-  msg: "expected a parameter, which can be a function parameter index or 'self'"
-
-- id: autodiff_attr_expected_original_decl_name
-  msg: "expected an original function name"
-
-- id: sil_autodiff_expected_lsquare
-  msg: "expected '[' to start the %0"
-
-- id: sil_autodiff_expected_rsquare
-  msg: "expected ']' to complete the %0"
-
-- id: sil_autodiff_expected_index_list
-  msg: "expected a space-separated list of indices, e.g. '0 1'"
-
-- id: sil_autodiff_expected_index_list_label
-  msg: "expected label '%0' in index list"
-
-- id: sil_autodiff_expected_parameter_index
-  msg: "expected the index of a parameter to differentiate with respect to"
-
-- id: sil_autodiff_expected_result_index
-  msg: "expected the index of a result to differentiate from"
-
-- id: sil_inst_autodiff_operand_list_expected_lbrace
-  msg: "expected '{' to start a derivative function list"
-
-- id: sil_inst_autodiff_operand_list_expected_comma
-  msg: "expected ',' between operands in a derivative function list"
-
-- id: sil_inst_autodiff_operand_list_expected_rbrace
-  msg: "expected '}' to start a derivative function list"
-
-- id: sil_inst_autodiff_expected_differentiable_extractee_kind
-  msg: "expected an extractee kind attribute, which can be one of '[original]', '[jvp]', and '[vjp]'"
-
-- id: sil_inst_autodiff_expected_linear_extractee_kind
-  msg: "expected an extractee kind attribute, which can be one of '[original]' and '[transpose]'"
-
-- id: sil_inst_autodiff_expected_function_type_operand
-  msg: "expected an operand of a function type"
-
-- id: sil_inst_autodiff_expected_differentiability_witness_kind
-  msg: "expected a differentiability witness kind, which can be one of '[jvp]', '[vjp]', or '[transpose]'"
-
-- id: sil_inst_autodiff_invalid_witness_generic_signature
-  msg: "expected witness_generic signature '%0' does not have same generic parameters as original function generic signature '%1'"
-
-- id: expected_rangle_generics_param
-  msg: "expected '>' to complete generic parameter list"
-
-- id: expected_generics_parameter_name
-  msg: "expected an identifier to name generic parameter"
-
-- id: unexpected_class_constraint
-  msg: "'class' constraint can only appear on protocol declarations"
-
-- id: suggest_anyobject
-  msg: "did you mean to write an 'AnyObject' constraint?"
-
-- id: expected_generics_type_restriction
-  msg: "expected a class type or protocol-constrained type restricting %0"
-
-- id: requires_single_equal
-  msg: "use '==' for same-type requirements rather than '='"
-
-- id: requires_comma
-  msg: "expected ',' to separate the requirements of this 'where' clause"
-
-- id: expected_requirement_delim
-  msg: "expected ':' or '==' to indicate a conformance or same-type requirement"
-
-- id: redundant_class_requirement
-  msg: "redundant 'class' requirement"
-
-- id: late_class_requirement
-  msg: "'class' must come first in the requirement list"
-
-- id: where_inside_brackets
-  msg: "'where' clause next to generic parameters is obsolete, must be written following the declaration's type"
-
-- id: unsupported_conditional_compilation_binary_expression
-  msg: "expected '&&' or '||' expression"
-
-- id: unsupported_conditional_compilation_unary_expression
-  msg: "expected unary '!' expression"
-
-- id: unsupported_platform_condition_expression
-  msg: "unexpected platform condition (expected 'os', 'arch', or 'swift')"
-
-- id: platform_condition_expected_one_argument
-  msg: "expected only one argument to platform condition"
-
-- id: unsupported_platform_runtime_condition_argument
-  msg: "unexpected argument for the '_runtime' condition; expected '_Native' or '_ObjC'"
-
-- id: unsupported_platform_condition_argument
-  msg: "unexpected platform condition argument: expected %0"
-
-- id: unsupported_conditional_compilation_expression_type
-  msg: "invalid conditional compilation expression"
-
-- id: unsupported_conditional_compilation_integer
-  msg: "'%0' is not a valid conditional compilation expression, use '%1'"
-
-- id: version_component_not_number
-  msg: "version component contains non-numeric characters"
-
-- id: compiler_version_too_many_components
-  msg: "compiler version must not have more than five components"
-
-- id: unused_compiler_version_component
-  msg: "the second version component is not used for comparison"
-
-- id: empty_version_component
-  msg: "found empty version component"
-
-- id: compiler_version_component_out_of_range
-  msg: "compiler version component out of range: must be in [0, %0]"
-
-- id: empty_version_string
-  msg: "version requirement is empty"
-
-- id: unknown_platform_condition_argument
-  msg: "unknown %0 for build configuration '%1'"
-
-- id: renamed_platform_condition_argument
-  msg: "'%0' has been renamed to '%1'"
-
-- id: likely_simulator_platform_condition
-  msg: "platform condition appears to be testing for simulator environment; use 'targetEnvironment(simulator)' instead"
-
-- id: avail_query_expected_condition
-  msg: "expected availability condition"
-
-- id: avail_query_expected_platform_name
-  msg: "expected platform name"
-
-- id: avail_query_expected_version_number
-  msg: "expected version number"
-
-- id: avail_query_expected_rparen
-  msg: "expected ')' in availability query"
-
-- id: avail_query_unrecognized_platform_name
-  msg: "unrecognized platform name %0"
-
-- id: avail_query_disallowed_operator
-  msg: "'%0' cannot be used in an availability condition"
-
-- id: avail_query_argument_and_shorthand_mix_not_allowed
-  msg: "'%0' can't be combined with shorthand specification '%1'"
-
-- id: avail_query_meant_introduced
-  msg: "did you mean to specify an introduction version?"
-
-- id: avail_query_version_comparison_not_needed
-  msg: "version comparison not needed"
-
-- id: availability_query_wildcard_required
-  msg: "must handle potential future platforms with '*'"
-
-- id: availability_must_occur_alone
-  msg: "'%0' version-availability must be specified alone"
-
-- id: pound_available_swift_not_allowed
-  msg: "Swift language version checks not allowed in #available(...)"
-
-- id: pound_available_package_description_not_allowed
-  msg: "PackageDescription version checks not allowed in #available(...)"
-
-- id: availability_query_repeated_platform
-  msg: "version for '%0' already specified"
-
-- id: unknown_syntax_entity
-  msg: "unknown %0 syntax exists in the source"
-
-- id: expected_argument_label_followed_by_closure_literal
-  msg: "expected an argument label followed by a closure literal"
-
-- id: expected_closure_literal
-  msg: "expected a closure literal"
-
-- id: expected_multiple_closures_block_rbrace
-  msg: "expected '}' at the end of a trailing closures block"
-
-- id: decl_declared_here
-  msg: "%0 declared here"
-
-- id: kind_declared_here
-  msg: "%0 declared here"
-
-- id: implicit_member_declared_here
-  msg: "%1 '%0' is implicitly declared"
-
-- id: extended_type_declared_here
-  msg: "extended type declared here"
-
-- id: opaque_return_type_declared_here
-  msg: "opaque return type declared here"
-
-- id: ambiguous_member_overload_set
-  msg: "ambiguous reference to member %0"
-
-- id: ambiguous_reference_to_decl
-  msg: "ambiguous reference to %0 %1"
-
-- id: no_overloads_match_exactly_in_call
-  msg: "no exact matches in %select{reference|call}0 to %1 %select{%3|}2"
-
-- id: candidate_partial_match
-  msg: "candidate has partially matching parameter list %0"
-
-- id: could_not_find_value_subscript
-  msg: "value of type %0 has no subscripts"
-
-- id: could_not_find_tuple_member
-  msg: "value of tuple type %0 has no member %1"
-
-- id: could_not_find_value_member
-  msg: "value of type %0 has no member %1"
-
-- id: could_not_find_value_member_corrected
-  msg: "value of type %0 has no member %1; did you mean %2?"
-
-- id: could_not_find_value_dynamic_member_corrected
-  msg: "value of type %0 has no dynamic member %2 using key path from root type %1; did you mean %3?"
-
-- id: could_not_find_value_dynamic_member
-  msg: "value of type %0 has no dynamic member %2 using key path from root type %1"
-
-- id: cannot_infer_contextual_keypath_type_specify_root
-  msg: "cannot infer key path type from context; consider explicitly specifying a root type"
-
-- id: cannot_infer_keypath_root_anykeypath_context
-  msg: "'AnyKeyPath' does not provide enough context for root type to be inferred; consider explicitly specifying a root type"
-
-- id: could_not_find_type_member
-  msg: "type %0 has no member %1"
-
-- id: could_not_find_type_member_corrected
-  msg: "type %0 has no member %1; did you mean %2?"
-
-- id: could_not_find_subscript_member_did_you_mean
-  msg: "value of type %0 has no property or method named 'subscript'; did you mean to use the subscript operator?"
-
-- id: could_not_find_subscript_member_tuple
-  msg: "cannot access element using subscript for tuple type %0; use '.' notation instead"
-
-- id: could_not_find_subscript_member_tuple_did_you_mean_use_dot
-  msg: "cannot access element using subscript for tuple type %0; did you mean to use '.%1'?"
-
-- id: could_not_find_enum_case
-  msg: "enum type %0 has no case %1; did you mean %2?"
-
-- id: did_you_mean_raw_type
-  msg: "did you mean to specify a raw type on the enum declaration?"
-
-- id: did_you_mean_generic_param_as_conformance
-  msg: "did you mean to declare %0 as a protocol conformance for %1?"
-
-- id: any_as_anyobject_fixit
-  msg: "cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members"
-
-- id: expected_argument_in_contextual_member
-  msg: "member %0 expects argument of type %1"
-
-- id: expected_parens_in_contextual_member
-  msg: "member %0 is a function; did you mean to call it?"
-
-- id: expected_parens_in_contextual_member_type
-  msg: >-
-    member %0 is a function that produces expected type %1; did you mean to call it?
-
-- id: expected_result_in_contextual_member
-  msg: "member %0 in %2 produces result of type %1, but context expects %2"
-
-- id: unexpected_arguments_in_enum_case
-  msg: "enum case %0 has no associated values"
-
-- id: could_not_use_type_member_on_instance
-  msg: "static member %1 cannot be used on instance of type %0"
-
-- id: could_not_use_enum_element_on_instance
-  msg: "enum case %0 cannot be used as an instance member"
-
-- id: could_not_use_type_member_on_protocol_metatype
-  msg: "static member %1 cannot be used on protocol metatype %0"
-
-- id: could_not_use_instance_member_on_type
-  msg: "instance member %1%select{| of type %2}3 cannot be used on%select{| instance of nested}3 type %0"
-
-- id: could_not_use_member_on_existential
-  msg: "member %1 cannot be used on value of protocol type %0; use a generic constraint instead"
-
-- id: candidate_inaccessible
-  msg: "%0 is inaccessible due to '%select{private|fileprivate|internal|@_spi|@_spi}1' protection level"
-
-- id: note_candidate_inaccessible
-  msg: "%0 is inaccessible due to '%select{private|fileprivate|internal|@_spi|@_spi}1' protection level"
-
-- id: init_candidate_inaccessible
-  msg: "%0 initializer is inaccessible due to '%select{private|fileprivate|internal|@_spi|@_spi}1' protection level"
-
-- id: cannot_pass_rvalue_mutating_subelement
-  msg: "cannot use mutating member on immutable value: %0"
-
-- id: cannot_pass_rvalue_mutating
-  msg: "cannot use mutating member on immutable value of type %0"
-
-- id: cannot_pass_rvalue_mutating_getter_subelement
-  msg: "cannot use mutating getter on immutable value: %0"
-
-- id: cannot_pass_rvalue_mutating_getter
-  msg: "cannot use mutating getter on immutable value of type %0"
-
-- id: expression_too_complex
-  msg: "the compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions"
-
-- id: value_type_comparison_with_nil_illegal_did_you_mean
-  msg: "value of type %0 cannot be compared by reference; did you mean to compare by value?"
-
-- id: value_type_comparison_with_nil_illegal
-  msg: "type %0 is not optional, value can never be nil"
-
-- id: cannot_match_expr_pattern_with_value
-  msg: "expression pattern of type %0 cannot match values of type %1"
-
-- id: cannot_match_expr_tuple_pattern_with_nontuple_value
-  msg: "tuple pattern cannot match values of non-tuple type %0"
-
-- id: cannot_match_unresolved_expr_pattern_with_value
-  msg: "pattern cannot match values of type %0"
-
-- id: cannot_reference_compare_types
-  msg: "cannot check reference equality of functions; operands here have types %1 and %2"
-
-- id: cannot_apply_binop_to_args
-  msg: "binary operator '%0' cannot be applied to operands of type %1 and %2"
-
-- id: cannot_apply_binop_to_same_args
-  msg: "binary operator '%0' cannot be applied to two %1 operands"
-
-- id: cannot_apply_unop_to_arg
-  msg: "unary operator '%0' cannot be applied to an operand of type %1"
-
-- id: cannot_apply_lvalue_unop_to_subelement
-  msg: "cannot pass immutable value to mutating operator: %0"
-
-- id: cannot_apply_lvalue_unop_to_rvalue
-  msg: "cannot pass immutable value of type %0 to mutating operator"
-
-- id: cannot_apply_lvalue_binop_to_subelement
-  msg: "left side of mutating operator isn't mutable: %0"
-
-- id: cannot_apply_lvalue_binop_to_rvalue
-  msg: "left side of mutating operator has immutable type %0"
-
-- id: cannot_subscript_base
-  msg: "cannot subscript a value of type %0"
-
-- id: cannot_subscript_ambiguous_base
-  msg: "cannot subscript a value of incorrect or ambiguous type"
-
-- id: cannot_subscript_nil_literal
-  msg: "cannot subscript a nil literal value"
-
-- id: conditional_cast_from_nil
-  msg: "nil literal cannot be the source of a conditional cast"
-
-- id: cannot_pass_rvalue_inout_subelement
-  msg: "cannot pass immutable value as inout argument: %0"
-
-- id: cannot_pass_rvalue_inout_converted
-  msg: "inout argument could be set to a value with a type other than %0; use a value declared as type %1 instead"
-
-- id: inout_change_var_type_if_possible
-  msg: "change variable type to %1 if it doesn't need to be declared as %0"
-
-- id: cannot_pass_rvalue_inout
-  msg: "cannot pass immutable value of type %0 as inout argument"
-
-- id: cannot_provide_default_value_inout
-  msg: "cannot provide default value to inout parameter %0"
-
-- id: cannot_call_with_params
-  msg: "cannot invoke %select{|initializer for type }2'%0' with an argument list of type '%1'"
-
-- id: cannot_call_non_function_value
-  msg: "cannot call value of non-function type %0"
-
-- id: no_candidates_match_result_type
-  msg: "no '%0' candidates produce the expected contextual result type %1"
-
-- id: no_candidates_match_argument_type
-  msg: "no '%0' candidates produce the expected type %1 for parameter #%2"
-
-- id: cannot_infer_closure_parameter_type
-  msg: "unable to infer type of a closure parameter %0 in the current context"
-
-- id: cannot_infer_closure_type
-  msg: "unable to infer closure type in the current context"
-
-- id: cannot_infer_closure_result_type
-  msg: "unable to infer%select{ complex|}0 closure return type; add explicit type to disambiguate"
-
-- id: incorrect_explicit_closure_result
-  msg: "declared closure result %0 is incompatible with contextual type %1"
-
-- id: suggest_expected_match
-  msg: "%select{expected an argument list|produces result}0 of type '%1'"
-
-- id: suggest_partial_overloads
-  msg: "overloads for '%1' exist with these %select{partially matching parameter lists|result types}0: %2"
-
-- id: no_binary_op_overload_for_enum_with_payload
-  msg: "binary operator '%0' cannot be synthesized for enums with associated values"
-
-- id: cannot_convert_initializer_value
-  msg: "cannot convert value of type %0 to specified type %1"
-
-- id: cannot_convert_initializer_value_protocol
-  msg: "value of type %0 does not conform to specified type %1"
-
-- id: cannot_convert_initializer_value_anyobject
-  msg: "value of type %0 expected to be instance of class or class-constrained type"
-
-- id: cannot_convert_initializer_value_nil
-  msg: "'nil' cannot initialize specified type %0"
-
-- id: cannot_convert_to_return_type
-  msg: "cannot convert return expression of type %0 to return type %1"
-
-- id: cannot_convert_to_return_type_protocol
-  msg: "return expression of type %0 does not conform to %1"
-
-- id: cannot_convert_return_type_to_anyobject
-  msg: "return expression of type %0 expected to be an instance of a class or class-constrained type"
-
-- id: cannot_convert_to_return_type_nil
-  msg: "'nil' is incompatible with return type %0"
-
-- id: cannot_convert_thrown_type
-  msg: "thrown expression type %0 does not conform to 'Error'"
-
-- id: cannot_throw_error_code
-  msg: "thrown error code type %0 does not conform to 'Error'; construct an %1 instance"
-
-- id: bad_yield_count
-  msg: "expected %0 yield value(s)"
-
-- id: cannot_throw_nil
-  msg: "cannot infer concrete Error for thrown 'nil' value"
-
-- id: cannot_convert_raw_initializer_value
-  msg: "cannot convert value of type %0 to raw type %1"
-
-- id: cannot_convert_raw_initializer_value_nil
-  msg: "cannot convert 'nil' to raw type %0"
-
-- id: cannot_convert_default_arg_value
-  msg: "default argument value of type %0 cannot be converted to type %1"
-
-- id: cannot_convert_default_arg_value_protocol
-  msg: "default argument value of type %0 does not conform to %1"
-
-- id: cannot_convert_default_arg_value_nil
-  msg: "nil default argument value cannot be converted to type %0"
-
-- id: cannot_convert_argument_value
-  msg: "cannot convert value of type %0 to expected argument type %1"
-
-- id: candidate_has_invalid_argument_at_position
-  msg: "candidate expects %select{|in-out }2value of type %0 for parameter #%1"
-
-- id: cannot_convert_array_to_variadic
-  msg: "cannot pass array of type %0 as variadic arguments of type %1"
-
-- id: candidate_would_match_array_to_variadic
-  msg: "candidate would match if array elements were passed as variadic arguments of type %0"
-
-- id: suggest_pass_elements_directly
-  msg: "remove brackets to pass array elements directly"
-
-- id: cannot_convert_argument_value_generic
-  msg: "cannot convert value of type %0 (%1) to expected argument type %2 (%3)"
-
-- id: conflicting_arguments_for_generic_parameter
-  msg: "conflicting arguments to generic parameter %0 (%1)"
-
-- id: cannot_pass_type_to_non_ephemeral
-  msg: "cannot pass %0 to parameter; argument %1 must be a pointer that outlives the call%select{| to %3}2"
-
-- id: cannot_pass_type_to_non_ephemeral_warning
-  msg: "passing %0 to parameter, but argument %1 should be a pointer that outlives the call%select{| to %3}2"
-
-- id: cannot_use_inout_non_ephemeral
-  msg: "cannot use inout expression here; argument %0 must be a pointer that outlives the call%select{| to %2}1"
-
-- id: cannot_use_inout_non_ephemeral_warning
-  msg: "inout expression creates a temporary pointer, but argument %0 should be a pointer that outlives the call%select{| to %2}1"
-
-- id: cannot_construct_dangling_pointer
-  msg: "initialization of %0 results in a dangling %select{|buffer }1pointer"
-
-- id: cannot_construct_dangling_pointer_warning
-  msg: "initialization of %0 results in a dangling %select{|buffer }1pointer"
-
-- id: ephemeral_pointer_argument_conversion_note
-  msg: "implicit argument conversion from %0 to %1 produces a pointer valid only for the duration of the call%select{| to %3}2"
-
-- id: ephemeral_use_with_unsafe_pointer
-  msg: "use 'withUnsafe%select{Bytes|MutableBytes|Pointer|MutablePointer}0' in order to explicitly convert argument to %select{buffer |buffer ||}0pointer valid for a defined scope"
-
-- id: ephemeral_use_string_with_c_string
-  msg: "use the 'withCString' method on String in order to explicitly convert argument to pointer valid for a defined scope"
-
-- id: ephemeral_use_array_with_unsafe_buffer
-  msg: "use the 'withUnsafe%select{Bytes|MutableBytes|BufferPointer|MutableBufferPointer}0' method on Array in order to explicitly convert argument to buffer pointer valid for a defined scope"
-
-- id: candidate_performs_illegal_ephemeral_conv
-  msg: "candidate expects pointer that outlives the call for parameter #%0"
-
-- id: cannot_convert_argument_value_protocol
-  msg: "argument type %0 does not conform to expected type %1"
-
-- id: cannot_convert_argument_value_anyobject
-  msg: "argument type %0 expected to be an instance of a class or class-constrained type"
-
-- id: cannot_convert_argument_value_nil
-  msg: "'nil' is not compatible with expected argument type %0"
-
-- id: cannot_convert_condition_value
-  msg: "cannot convert value of type %0 to expected condition type %1"
-
-- id: cannot_convert_condition_value_nil
-  msg: "'nil' is not compatible with expected condition type %0"
-
-- id: cannot_yield_rvalue_by_reference_same_type
-  msg: "cannot yield immutable value of type %0 as an inout yield"
-
-- id: cannot_yield_rvalue_by_reference
-  msg: "cannot yield immutable value of type %0 as an inout yield of type %1"
-
-- id: cannot_yield_wrong_type_by_reference
-  msg: "cannot yield reference to storage of type %0 as an inout yield of type %1"
-
-- id: cannot_convert_yield_value
-  msg: "cannot convert value of type %0 to expected yield type %1"
-
-- id: cannot_convert_yield_value_protocol
-  msg: "yielded type %0 does not conform to expected type %1"
-
-- id: cannot_convert_yield_value_nil
-  msg: "nil is not compatible with expected yield type %0"
-
-- id: cannot_convert_closure_result
-  msg: "cannot convert value of type %0 to closure result type %1"
-
-- id: cannot_convert_closure_result_protocol
-  msg: "result value of type %0 does not conform to closure result type %1"
-
-- id: cannot_convert_closure_result_nil
-  msg: "'nil' is not compatible with closure result type %0"
-
-- id: cannot_convert_parent_type
-  msg: "cannot convert parent type %0 to expected type %1"
-
-- id: cannot_convert_chain_result_type
-  msg: >-
-    member chain produces result of type %0 but contextual base was inferred as %1
-
-- id: generic_argument_mismatch
-  msg: "arguments to generic parameter %0 (%1 and %2) are expected to be equal"
-
-- id: destructor_not_accessible
-  msg: "deinitializers cannot be accessed"
-
-- id: cannot_convert_array_element
-  msg: "cannot convert value of type %0 to expected element type %1"
-
-- id: cannot_convert_array_element_protocol
-  msg: "value of type %0 does not conform to expected element type %1"
-
-- id: cannot_convert_array_element_nil
-  msg: "'nil' is not compatible with expected element type %0"
-
-- id: cannot_convert_dict_key
-  msg: "cannot convert value of type %0 to expected dictionary key type %1"
-
-- id: cannot_convert_dict_key_protocol
-  msg: "value of type %0 does not conform to expected dictionary key type %1"
-
-- id: cannot_convert_dict_key_nil
-  msg: "'nil' is not compatible with expected dictionary key type %0"
-
-- id: cannot_convert_dict_value
-  msg: "cannot convert value of type %0 to expected dictionary value type %1"
-
-- id: cannot_convert_dict_value_protocol
-  msg: "value of type %0 does not conform to expected dictionary value type %1"
-
-- id: cannot_convert_dict_value_nil
-  msg: "'nil' is not compatible with expected dictionary value type %0"
-
-- id: cannot_convert_coerce
-  msg: "cannot convert value of type %0 to type %1 in coercion"
-
-- id: cannot_convert_coerce_protocol
-  msg: "value of type %0 does not conform to %1 in coercion"
-
-- id: cannot_convert_coerce_nil
-  msg: "'nil' is not compatible with type %0 in coercion"
-
-- id: cannot_convert_assign
-  msg: "cannot assign value of type %0 to type %1"
-
-- id: assign_protocol_conformance_fix_it
-  msg: "add missing conformance to %0 to %1 %2"
-
-- id: cannot_convert_assign_protocol
-  msg: "value of type %0 does not conform to %1 in assignment"
-
-- id: cannot_convert_assign_anyobject
-  msg: "value of type %0 expected to be an instance of a class or class-constrained type in assignment"
-
-- id: cannot_convert_assign_nil
-  msg: "'nil' cannot be assigned to type %0"
-
-- id: cannot_convert_subscript_assign
-  msg: "cannot assign value of type %0 to subscript of type %1"
-
-- id: cannot_convert_subscript_assign_protocol
-  msg: "value of type %0 does not conform to %1 in subscript assignment"
-
-- id: cannot_convert_subscript_assign_nil
-  msg: "'nil' cannot be assigned to subscript of type %0"
-
-- id: cannot_convert_candidate_result_to_contextual_type
-  msg: "%0 produces %1, not the expected contextual result type %2"
-
-- id: cannot_convert_sequence_element_value
-  msg: "cannot convert sequence element type %0 to expected type %1"
-
-- id: cannot_convert_sequence_element_protocol
-  msg: "sequence element type %0 does not conform to expected protocol %1"
-
-- id: throws_functiontype_mismatch
-  msg: "invalid conversion from throwing function of type %0 to non-throwing function type %1"
-
-- id: expr_keypath_no_objc_runtime
-  msg: "'#keyPath' can only be used with the Objective-C runtime"
-
-- id: expression_unused_keypath_result
-  msg: "result of key path is unused"
-
-- id: expr_keypath_non_objc_property
-  msg: "argument of '#keyPath' refers to non-'@objc' property %0"
-
-- id: expr_keypath_swift3_objc_inference
-  msg: "argument of '#keyPath' refers to property %0 in %1 that depends on '@objc' inference deprecated in Swift 4"
-
-- id: expr_keypath_type_of_property
-  msg: "cannot refer to type member %0 within instance of type %1"
-
-- id: expr_keypath_generic_type
-  msg: "key path cannot refer to generic type %0"
-
-- id: expr_keypath_not_property
-  msg: "%select{key path|dynamic key path member lookup}2 cannot refer to %0 %1"
-
-- id: expr_keypath_mutating_getter
-  msg: "%select{key path|dynamic key path member lookup}1 cannot refer to %0, which has a mutating getter"
-
-- id: expr_keypath_static_member
-  msg: "%select{key path|dynamic key path member lookup}1 cannot refer to static member %0"
-
-- id: expr_keypath_enum_case
-  msg: "%select{key path|dynamic key path member lookup}1 cannot refer to enum case %0"
-
-- id: expr_keypath_empty
-  msg: "empty key path does not refer to a property"
-
-- id: expr_unsupported_objc_key_path_component
-  msg: "an Objective-C key path cannot contain %select{BAD|subscript|BAD|BAD|optional-forcing|optional-chaining|BAD} components"
-
-- id: expr_unsupported_objc_key_path_compound_name
-  msg: "an Objective-C key path cannot reference a declaration with a compound name"
-
-- id: expr_keypath_no_keypath_type
-  msg: "broken standard library: no 'KeyPath' type found"
-
-- id: expr_swift_keypath_invalid_component
-  msg: "invalid component of Swift key path"
-
-- id: expr_swift_keypath_not_starting_with_type
-  msg: "a Swift key path must begin with a type"
-
-- id: expr_swift_keypath_not_starting_with_dot
-  msg: "a Swift key path with contextual root must begin with a leading dot"
-
-- id: expr_smart_keypath_value_covert_to_contextual_type
-  msg: "key path value type %0 cannot be converted to contextual type %1"
-
-- id: expr_swift_keypath_empty
-  msg: "key path must have at least one component"
-
-- id: expr_string_interpolation_outside_string
-  msg: "string interpolation can only appear inside a string literal"
-
-- id: expr_keypath_subscript_index_not_hashable
-  msg: "subscript index of type %0 in a key path must be Hashable"
-
-- id: expr_smart_keypath_application_type_mismatch
-  msg: "key path of type %0 cannot be applied to a base of type %1"
-
-- id: expr_keypath_root_type_mismatch
-  msg: "key path with root type %0 cannot be applied to a base of type %1"
-
-- id: expr_swift_keypath_anyobject_root
-  msg: "the root type of a Swift key path cannot be 'AnyObject'"
-
-- id: expr_keypath_multiparam_func_conversion
-  msg: "cannot convert key path into a multi-argument function type %0"
-
-- id: expr_deprecated_writable_keypath
-  msg: "forming a writable keypath to property %0 that is read-only in this context is deprecated and will be removed in a future release"
-
-- id: expr_selector_no_objc_runtime
-  msg: "'#selector' can only be used with the Objective-C runtime"
-
-- id: expr_selector_module_missing
-  msg: "import the 'ObjectiveC' module to use '#selector'"
-
-- id: expr_selector_no_declaration
-  msg: "argument of '#selector' does not refer to an '@objc' method, property, or initializer"
-
-- id: expr_selector_not_method
-  msg: "argument of '#selector' cannot refer to %select{local|global}0 function %1"
-
-- id: expr_selector_expected_property
-  msg: "cannot reference %1 %2 as a property; remove '%select{getter|setter}0:'"
-
-- id: expr_selector_not_property
-  msg: "argument of '#selector' cannot refer to %select{variable|parameter}0 %1"
-
-- id: expr_selector_expected_method
-  msg: "use 'getter:'%select{| or 'setter:'}0 to refer to the Objective-C getter%select{| or setter}0 of property %1%select{|, respectively}0"
-
-- id: expr_selector_add_modifier
-  msg: "add '%select{getter|setter}0:' to reference the Objective-C %select{getter|setter}0 for %1"
-
-- id: expr_selector_property_not_settable
-  msg: "argument of '#selector(setter:)' refers to non-settable %0 %1"
-
-- id: expr_selector_property_setter_inaccessible
-  msg: "setter of %0 %1 is inaccessible"
-
-- id: expr_selector_cannot_be_used
-  msg: "cannot use %0 as a selector because protocol %1 is not exposed to Objective-C"
-
-- id: expr_selector_not_objc
-  msg: "argument of '#selector' refers to %0 %1 that is not exposed to Objective-C"
-
-- id: make_decl_objc
-  msg: "add '@objc' to expose this %0 to Objective-C"
-
-- id: expr_selector_swift3_objc_inference
-  msg: "argument of '#selector' refers to %0 %1 in %2 that depends on '@objc' inference deprecated in Swift 4"
-
-- id: selector_literal_invalid
-  msg: "string literal is not a valid Objective-C selector"
-
-- id: selector_literal_undeclared
-  msg: "no method declared with Objective-C selector %0"
-
-- id: selector_literal_deprecated
-  msg: "use of string literal for Objective-C selectors is deprecated; use '#selector' or explicitly construct a 'Selector'"
-
-- id: selector_literal_deprecated_suggest
-  msg: "use of string literal for Objective-C selectors is deprecated; use '#selector' instead"
-
-- id: selector_construction_suggest
-  msg: "use '#selector' instead of explicitly constructing a 'Selector'"
-
-- id: selector_construction_suppress_warning
-  msg: "wrap the selector name in parentheses to suppress this warning"
-
-- id: cannot_return_value_from_void_func
-  msg: "unexpected non-void return value in void function"
-
-- id: add_return_type_note
-  msg: "did you mean to add a return type?"
-
-- id: sema_no_import
-  msg: "no such module '%0'"
-
-- id: sema_no_import_target
-  msg: "could not find module '%0' for target '%1'; found: %2"
-
-- id: sema_no_import_repl
-  msg: "no such module '%0'"
-
-- id: sema_no_import_no_sdk
-  msg: "did you forget to set an SDK using -sdk or SDKROOT?"
-
-- id: sema_no_import_no_sdk_xcrun
-  msg: "use \"xcrun swiftc\" to select the default macOS SDK installed with Xcode"
-
-- id: sema_import_current_module
-  msg: "this file is part of module %0; ignoring import"
-
-- id: sema_import_current_module_with_file
-  msg: "file '%0' is part of module %1; ignoring import"
-
-- id: sema_opening_import
-  msg: "opening import file for module %0: %1"
-
-- id: serialization_load_failed
-  msg: "failed to load module '%0'"
-
-- id: module_interface_build_failed
-  msg: "failed to build module '%0' from its module interface; %select{the compiler that produced it, '%2', may have used features that aren't supported by this compiler, '%3'|it may have been damaged or it may have triggered a bug in the Swift compiler when it was produced}1"
-
-- id: serialization_malformed_module
-  msg: "malformed compiled module: %0"
-
-- id: serialization_module_too_new
-  msg: "compiled module was created by a newer version of the compiler: %0"
-
-- id: serialization_module_language_version_mismatch
-  msg: "module compiled with Swift %0 cannot be imported by the Swift %1 compiler: %2"
-
-- id: serialization_module_too_old
-  msg: "compiled module was created by an older version of the compiler; rebuild %0 and try again: %1"
-
-- id: serialization_missing_single_dependency
-  msg: "missing required module '%0'"
-
-- id: serialization_missing_dependencies
-  msg: "missing required modules: %0"
-
-- id: serialization_circular_dependency
-  msg: "circular dependency between modules '%0' and %1"
-
-- id: serialization_missing_underlying_module
-  msg: "cannot load underlying module for %0"
-
-- id: serialization_name_mismatch
-  msg: "cannot load module '%0' as '%1'"
-
-- id: serialization_name_mismatch_repl
-  msg: "cannot load module '%0' as '%1'"
-
-- id: serialization_target_incompatible
-  msg: "module %0 was created for incompatible target %1: %2"
-
-- id: serialization_target_incompatible_repl
-  msg: "module %0 was created for incompatible target %1: %2"
-
-- id: serialization_target_too_new
-  msg: "compiling for %0 %1, but module %2 has a minimum deployment target of %0 %3: %4"
-
-- id: serialization_target_too_new_repl
-  msg: "compiling for %0 %1, but module %2 has a minimum deployment target of %0 %3: %4"
-
-- id: serialization_fatal
-  msg: "fatal error encountered while reading from module '%0'; please file a bug report with your project and the crash log"
-
-- id: serialization_misc_version
-  msg: "module '%0' full misc version is '%1'"
-
-- id: serialization_compatibility_version_mismatch
-  msg: "compiling as Swift %0, with '%1' built as Swift %2 (this is supported but may expose additional compiler issues)"
-
-- id: reserved_member_name
-  msg: "type member must not be named %0, since it would conflict with the 'foo.%1' expression"
-
-- id: invalid_redecl
-  msg: "invalid redeclaration of %0"
-
-- id: invalid_redecl_init
-  msg: "invalid redeclaration of synthesized %select{|memberwise }1%0"
-
-- id: invalid_redecl_implicit
-  msg: "invalid redeclaration of synthesized %select{%0|implementation for protocol requirement}1 %2"
-
-- id: invalid_redecl_swift5_warning
-  msg: "redeclaration of %0 is deprecated and will be an error in Swift 5"
-
-- id: invalid_redecl_prev
-  msg: "%0 previously declared here"
-
-- id: invalid_redecl_implicit_wrapper
-  msg: "%0 synthesized for property wrapper %select{projected value|backing storage}1"
-
-- id: ambiguous_type_base
-  msg: "%0 is ambiguous for type lookup in this context"
-
-- id: invalid_member_type
-  msg: "%0 is not a member type of %1"
-
-- id: invalid_member_type_suggest
-  msg: "%0 does not have a member type named %1; did you mean %2?"
-
-- id: invalid_member_reference
-  msg: "%0 %1 is not a member type of %2"
-
-- id: ambiguous_member_type
-  msg: "ambiguous type name %0 in %1"
-
-- id: no_module_type
-  msg: "no type named %0 in module %1"
-
-- id: ambiguous_module_type
-  msg: "ambiguous type name %0 in module %1"
-
-- id: use_nonmatching_operator
-  msg: "%0 is not a %select{binary|prefix unary|postfix unary}1 operator"
-
-- id: unsupported_recursion_in_associated_type_reference
-  msg: "unsupported recursion for reference to %select{associated type|type alias}0 %1 of type %2"
-
-- id: broken_associated_type_witness
-  msg: "reference to invalid %select{associated type|type alias}0 %1 of type %2"
-
-- id: unspaced_binary_operator_fixit
-  msg: "missing whitespace between %0 and %1 operators"
-
-- id: unspaced_binary_operator
-  msg: "ambiguous missing whitespace between unary and binary operators"
-
-- id: unspaced_binary_operators_candidate
-  msg: "could be %select{binary|postfix}2 %0 and %select{prefix|binary}2 %1"
-
-- id: unspaced_unary_operator
-  msg: "unary operators must not be juxtaposed; parenthesize inner expression"
-
-- id: cannot_find_in_scope
-  msg: "cannot %select{find|find operator}1 %0 in scope"
-
-- id: cannot_find_in_scope_corrected
-  msg: "cannot %select{find|find operator}1 %0 in scope; did you mean '%2'?"
-
-- id: confusable_character
-  msg: "%select{identifier|operator}0 '%1' contains possibly confused characters; did you mean to use '%2'?"
-
-- id: single_confusable_character
-  msg: "%select{identifier|operator}0 '%1' (%2) looks similar to '%3' (%4); did you mean '%3' (%4)?"
-
-- id: cannot_find_type_in_scope
-  msg: "cannot find type %0 in scope"
-
-- id: cannot_find_type_in_scope_did_you_mean
-  msg: "cannot find type %0 in scope; did you mean to use '%1'?"
-
-- id: note_typo_candidate_implicit_member
-  msg: "did you mean the implicitly-synthesized %1 '%0'?"
-
-- id: note_remapped_type
-  msg: "did you mean to use '%0'?"
-
-- id: note_module_as_type
-  msg: "cannot use module %0 as a type"
-
-- id: use_unknown_object_literal_protocol
-  msg: "cannot deduce protocol for %0 literal"
-
-- id: object_literal_default_type_missing
-  msg: "could not infer type of %0 literal"
-
-- id: object_literal_resolve_import
-  msg: "import %0 to use '%1' as the default %2 literal type"
-
-- id: use_local_before_declaration
-  msg: "use of local variable %0 before its declaration"
-
-- id: unsupported_existential_type
-  msg: "protocol %0 can only be used as a generic constraint because it has Self or associated type requirements"
-
-- id: decl_does_not_exist_in_module
-  msg: "%select{%error|type|struct|class|enum|protocol|variable|function}0 %1 does not exist in module %2"
-
-- id: imported_decl_is_wrong_kind
-  msg: "%0 was imported as '%1', but is %select{%error|a type|a struct|a class|an enum|a protocol|a variable|a function}2"
-
-- id: imported_decl_is_wrong_kind_typealias
-  msg: "%0 %1 cannot be imported as '%2'"
-
-- id: ambiguous_decl_in_module
-  msg: "ambiguous name %0 in module %1"
-
-- id: module_not_testable
-  msg: "module %0 was not compiled for testing"
-
-- id: module_not_compiled_for_private_import
-  msg: "module %0 was not compiled for private import"
-
-- id: import_implementation_cannot_be_exported
-  msg: "module %0 cannot be both exported and implementation-only"
-
-- id: module_not_compiled_with_library_evolution
-  msg: "module %0 was not compiled with library evolution support; using it means binary compatibility for %1 can't be guaranteed"
-
-- id: cross_import_added
-  msg: "import of %0 and %1 triggered a cross-import of %2"
-
-- id: ambiguous_operator_decls
-  msg: "ambiguous operator declarations found for operator"
-
-- id: found_this_operator_decl
-  msg: "found this matching operator declaration"
-
-- id: operator_redeclared
-  msg: "operator redeclared"
-
-- id: previous_operator_decl
-  msg: "previous operator declaration here"
-
-- id: declared_operator_without_operator_decl
-  msg: "operator implementation without matching operator declaration"
-
-- id: declared_unary_op_without_attribute
-  msg: "unary operator implementation must have a 'prefix' or 'postfix' modifier"
-
-- id: unary_op_missing_prepos_attribute
-  msg: "%select{prefix|postfix}0 unary operator missing '%select{prefix|postfix}0' modifier"
-
-- id: unary_operator_declaration_here
-  msg: "%select{prefix|postfix}0 operator found here"
-
-- id: invalid_arg_count_for_operator
-  msg: "operators must have one or two arguments"
-
-- id: operator_in_local_scope
-  msg: "operator functions can only be declared at global or in type scope"
-
-- id: nonstatic_operator_in_nominal
-  msg: "operator %0 declared in type %1 must be 'static'"
-
-- id: nonstatic_operator_in_extension
-  msg: "operator %0 declared in extension%select{| of %2}1 must be 'static'"
-
-- id: nonfinal_operator_in_class
-  msg: "operator %0 declared in non-final class %1 must be 'final'"
-
-- id: operator_in_unrelated_type
-  msg: "member operator %2%select{| of protocol %0}1 must have at least one argument of type %select{%0|'Self'}1"
-
-- id: ambiguous_precedence_groups
-  msg: "multiple precedence groups found"
-
-- id: found_this_precedence_group
-  msg: "found this matching precedence group"
-
-- id: unknown_precedence_group
-  msg: "unknown precedence group %0"
-
-- id: precedence_group_cycle
-  msg: "cycle in '%select{lowerThan|higherThan}0' relation"
-
-- id: higher_than_precedence_group_cycle
-  msg: "cycle in higherThan relation: %0"
-
-- id: precedence_group_lower_within_module
-  msg: "precedence group cannot be given lower precedence than group in same module; make the other precedence group higher than this one instead"
-
-- id: precedence_group_redeclared
-  msg: "precedence group redeclared"
-
-- id: previous_precedence_group_decl
-  msg: "previous precedence group declaration here"
-
-- id: circular_reference_through_precedence_group
-  msg: "through reference to precedence group %0 here"
-
-- id: tuple_types_not_convertible_nelts
-  msg: "%0 is not convertible to %1, tuples have a different number of elements"
-
-- id: tuple_types_not_convertible
-  msg: "tuple type %0 is not convertible to tuple type %1"
-
-- id: invalid_force_unwrap
-  msg: "cannot force unwrap value of non-optional type %0"
-
-- id: invalid_optional_chain
-  msg: "cannot use optional chaining on non-optional value of type %0"
-
-- id: if_expr_cases_mismatch
-  msg: "result values in '? :' expression have mismatching types %0 and %1"
-
-- id: did_not_call_function_value
-  msg: "function value was used as a property; add () to call it"
-
-- id: did_not_call_function
-  msg: "function %0 was used as a property; add () to call it"
-
-- id: did_not_call_method
-  msg: "method %0 was used as a property; add () to call it"
-
-- id: init_not_instance_member_use_assignment
-  msg: "'init' is a member of the type; use assignment to initalize the value instead"
-
-- id: init_not_instance_member
-  msg: "'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type"
-
-- id: super_initializer_not_in_initializer
-  msg: "'super.init' cannot be called outside of an initializer"
-
-- id: isa_is_always_true
-  msg: "'%0' test is always true"
-
-- id: isa_is_foreign_check
-  msg: "'is' test is always true because %0 is a Core Foundation type"
-
-- id: conditional_downcast_coercion
-  msg: "conditional cast from %0 to %1 always succeeds"
-
-- id: literal_conditional_downcast_to_coercion
-  msg: "conditional downcast from literal to %0 always fails; consider using 'as' coercion"
-
-- id: forced_downcast_noop
-  msg: "forced cast of %0 to same type has no effect"
-
-- id: forced_downcast_coercion
-  msg: "forced cast from %0 to %1 always succeeds; did you mean to use 'as'?"
-
-- id: downcast_same_type
-  msg: "forced cast from %0 to %1 %select{only unwraps optionals|only unwraps and bridges}3; did you mean to use '%2'%select{| with 'as'}3?"
-
-- id: conditional_downcast_same_type
-  msg: "conditional downcast from %0 to %1 %select{does nothing|is equivalent to an implicit conversion to an optional %1|is a bridging conversion; did you mean to use 'as'?}2"
-
-- id: is_expr_same_type
-  msg: "checking a value with optional type %0 against dynamic type %1 succeeds whenever the value is non-nil; did you mean to use '!= nil'?"
-
-- id: downcast_to_unrelated
-  msg: "cast from %0 to unrelated type %1 always fails"
-
-- id: downcast_to_unrelated_fixit
-  msg: "did you mean to call %0 with '()'?"
-
-- id: downcast_to_more_optional
-  msg: "cannot downcast from %0 to a more optional type %1"
-
-- id: optional_chain_noop
-  msg: "optional chain has no effect, expression already produces %0"
-
-- id: optional_chain_isnt_chaining
-  msg: "'?' must be followed by a call, member lookup, or subscript"
-
-- id: pattern_in_expr
-  msg: "%0 cannot appear in an expression"
-
-- id: note_call_to_operator
-  msg: "in call to operator %0"
-
-- id: note_call_to_func
-  msg: "in call to function %0"
-
-- id: note_call_to_subscript
-  msg: "in call to %0"
-
-- id: note_call_to_initializer
-  msg: "in call to initializer"
-
-- id: note_init_parameter
-  msg: "in initialization of parameter %0"
-
-- id: missing_nullary_call
-  msg: "function produces expected type %0; did you mean to call it with '()'?"
-
-- id: optional_not_unwrapped
-  msg: "value of optional type %0 must be unwrapped to a value of type %1"
-
-- id: unwrap_with_default_value
-  msg: "coalesce using '??' to provide a default when the optional value contains 'nil'"
-
-- id: unwrap_with_force_value
-  msg: "force-unwrap using '!' to abort execution if the optional value contains 'nil'"
-
-- id: unwrap_iuo_initializer
-  msg: "value inferred to be type %0 when initialized with an implicitly unwrapped value"
-
-- id: unwrap_with_guard
-  msg: "short-circuit using 'guard' to exit this function early if the optional value contains 'nil'"
-
-- id: optional_base_not_unwrapped
-  msg: "value of optional type %0 must be unwrapped to refer to member %1 of wrapped base type %2"
-
-- id: invalid_optional_infered_keypath_root
-  msg: "key path root inferred as optional type %0 must be unwrapped to refer to member %1 of unwrapped type %2"
-
-- id: optional_base_chain
-  msg: "chain the optional using '?' to access member %0 only for non-'nil' base values"
-
-- id: optional_base_remove_optional_for_keypath_root
-  msg: "use unwrapped type %0 as key path root"
-
-- id: optional_keypath_application_base
-  msg: "use '?' to access key path subscript only for non-'nil' base values"
-
-- id: optional_key_path_root_base_chain
-  msg: "chain the optional using '?.' to access unwrapped type member %0"
-
-- id: optional_key_path_root_base_unwrap
-  msg: "unwrap the optional using '!.' to access unwrapped type member %0"
-
-- id: missing_unwrap_optional_try
-  msg: "value of optional type %0 not unwrapped; did you mean to use 'try!' or chain with '?'?"
-
-- id: missing_forced_downcast
-  msg: "%0 is not convertible to %1; did you mean to use 'as!' to force downcast?"
-
-- id: coercion_may_fail_warning
-  msg: "coercion from %0 to %1 may fail; use 'as?' or 'as!' instead"
-
-- id: missing_explicit_conversion
-  msg: "%0 is not implicitly convertible to %1; did you mean to use 'as' to explicitly convert?"
-
-- id: missing_address_of
-  msg: "passing value of type %0 to an inout parameter requires explicit '&'"
-
-- id: missing_address_of_yield
-  msg: "yielding mutable value of type %0 requires explicit '&'"
-
-- id: extraneous_address_of
-  msg: "use of extraneous '&'"
-
-- id: extra_address_of
-  msg: "'&' used with non-inout argument of type %0"
-
-- id: extra_address_of_unsafepointer
-  msg: "'&' is not allowed passing array value as %0 argument"
-
-- id: cannot_pass_inout_arg_to_subscript
-  msg: "cannot pass an inout argument to a subscript; use 'withUnsafeMutablePointer' to explicitly convert argument to a pointer"
-
-- id: incorrect_property_wrapper_reference
-  msg: "cannot convert value %0 of type %1 to expected type %2, use %select{wrapper|wrapped value}3 instead"
-
-- id: incorrect_property_wrapper_reference_member
-  msg: "referencing %0 %1 requires %select{wrapper|wrapped value of type}2 %3"
-
-- id: missing_init_on_metatype_initialization
-  msg: "initializing from a metatype value must reference 'init' explicitly"
-
-- id: extra_argument_labels
-  msg: "extraneous argument label%select{|s}0 '%1' in %select{call|subscript}2"
-
-- id: missing_argument_labels
-  msg: "missing argument label%select{|s}0 '%1' in %select{call|subscript}2"
-
-- id: wrong_argument_labels
-  msg: "incorrect argument label%select{|s}0 in %select{call|subscript}3 (have '%1', expected '%2')"
-
-- id: argument_out_of_order_named_named
-  msg: "argument %0 must precede argument %1"
-
-- id: argument_out_of_order_named_unnamed
-  msg: "argument %0 must precede unnamed argument #%1"
-
-- id: argument_out_of_order_unnamed_named
-  msg: "unnamed argument #%0 must precede argument %1"
-
-- id: argument_out_of_order_unnamed_unnamed
-  msg: "unnamed argument #%0 must precede unnamed argument #%1"
-
-- id: argument_out_of_order_binary_op
-  msg: "operator argument #%0 must precede operator argument #%1"
-
-- id: candidate_expected_different_labels
-  msg: "incorrect labels for candidate (have: '%0', expected: '%1')"
-
-- id: member_shadows_function
-  msg: "use of %0 refers to %1 rather than %2 %3"
-
-- id: member_shadows_global_function
-  msg: "use of %0 refers to %1 rather than %2 %3 in module %4"
-
-- id: instance_member_use_on_type
-  msg: "instance member %1 cannot be used on type %0; did you mean to use a value of this type instead?"
-
-- id: instance_member_in_initializer
-  msg: "cannot use instance member %0 within property initializer; property initializers run before 'self' is available"
-
-- id: instance_member_in_default_parameter
-  msg: "cannot use instance member %0 as a default parameter"
-
-- id: missing_argument_named
-  msg: "missing argument for parameter %0 in call"
-
-- id: missing_argument_positional
-  msg: "missing argument for parameter #%0 in call"
-
-- id: missing_arguments_in_call
-  msg: "missing arguments for parameters %0 in call"
-
-- id: extra_argument_named
-  msg: "extra argument %0 in call"
-
-- id: extra_argument_positional
-  msg: "extra argument in call"
-
-- id: extra_arguments_in_call
-  msg: "extra arguments at positions %0 in call"
-
-- id: extra_argument_to_nullary_call
-  msg: "argument passed to call that takes no arguments"
-
-- id: extra_trailing_closure_in_call
-  msg: "extra trailing closure passed in call"
-
-- id: trailing_closure_bad_param
-  msg: "trailing closure passed to parameter of type %0 that does not accept a closure"
-
-- id: unlabeled_trailing_closure_deprecated
-  msg: "backward matching of the unlabeled trailing closure is deprecated; label the argument with %0 to suppress this warning"
-
-- id: decl_multiple_defaulted_closure_parameters
-  msg: "%0 contains defaulted closure parameters %1 and %2"
-
-- id: candidate_with_extraneous_args
-  msg: "candidate %0 requires %1 argument%s1, but %2 %select{were|was}3 %select{provided|used in closure body}4"
-
-- id: no_accessible_initializers
-  msg: "%0 cannot be constructed because it has no accessible initializers"
-
-- id: non_nominal_no_initializers
-  msg: "non-nominal type %0 does not support explicit initialization"
-
-- id: unbound_generic_parameter
-  msg: "generic parameter %0 could not be inferred"
-
-- id: unbound_generic_parameter_cast
-  msg: "generic parameter %0 could not be inferred in cast to %1"
-
-- id: archetype_declared_in_type
-  msg: "%0 declared as parameter to type %1"
-
-- id: unbound_generic_parameter_explicit_fix
-  msg: "explicitly specify the generic arguments to fix this issue"
-
-- id: invalid_dynamic_callable_type
-  msg: "@dynamicCallable attribute requires %0 to have either a valid 'dynamicallyCall(withArguments:)' method or 'dynamicallyCall(withKeywordArguments:)' method"
-
-- id: missing_dynamic_callable_kwargs_method
-  msg: "@dynamicCallable type %0 cannot be applied with keyword arguments; missing 'dynamicCall(withKeywordArguments:)' method"
-
-- id: invalid_dynamic_member_lookup_type
-  msg: "@dynamicMemberLookup attribute requires %0 to have a 'subscript(dynamicMember:)' method that accepts either 'ExpressibleByStringLiteral' or a key path"
-
-- id: invalid_dynamic_member_subscript
-  msg: "add an explicit argument label to this subscript to satisfy the @dynamicMemberLookup requirement"
-
-- id: string_index_not_integer
-  msg: "String must not be indexed with %0, it has variable size elements"
-
-- id: string_index_not_integer_note
-  msg: "consider using an existing high level algorithm, str.startIndex.advanced(by: n), or a projection like str.utf8"
-
-- id: invalid_c_function_pointer_conversion_expr
-  msg: "a C function pointer can only be formed from a reference to a 'func' or a literal closure"
-
-- id: c_function_pointer_from_method
-  msg: "a C function pointer cannot be formed from a method"
-
-- id: c_function_pointer_from_generic_function
-  msg: "a C function pointer cannot be formed from a reference to a generic function"
-
-- id: unsupported_linear_to_differentiable_conversion
-  msg: "conversion from '@differentiable(linear)' to '@differentiable' is not yet supported"
-
-- id: invalid_autoclosure_forwarding
-  msg: "add () to forward @autoclosure parameter"
-
-- id: invalid_differentiable_function_conversion_expr
-  msg: "a '@differentiable%select{|(linear)}0' function can only be formed from a reference to a 'func' or 'init' or a literal closure"
-
-- id: invalid_differentiable_function_conversion_parameter
-  msg: "did you mean to take a '%0' closure?"
-
-- id: invalid_autoclosure_pointer_conversion
-  msg: "cannot perform pointer conversion of value of type %0 to autoclosure result type %1"
-
-- id: missing_initializer_def
-  msg: "initializer requires a body"
-
-- id: pound_warning
-  msg: "%0"
-
-- id: pound_error
-  msg: "%0"
-
-- id: operator_not_func
-  msg: "operators must be declared with 'func'"
-
-- id: redefining_builtin_operator
-  msg: "cannot declare a custom %0 '%1' operator"
-
-- id: attribute_requires_operator_identifier
-  msg: "'%0' requires a function with an operator identifier"
-
-- id: attribute_requires_single_argument
-  msg: "'%0' requires a function with one argument"
-
-- id: nominal_type_not_attribute
-  msg: "%0 %1 cannot be used as an attribute"
-
-- id: mutating_invalid_global_scope
-  msg: "%0 is only valid on methods"
-
-- id: mutating_invalid_classes
-  msg: "%0 is not valid on %1s in %select{classes|class-bound protocols}2"
-
-- id: functions_mutating_and_not
-  msg: "method must not be declared both %0 and %1"
-
-- id: static_functions_not_mutating
-  msg: "static functions must not be declared mutating"
-
-- id: modify_mutatingness_differs_from_setter
-  msg: "'modify' accessor cannot be %0 when the setter is %1"
-
-- id: transparent_in_protocols_not_supported
-  msg: "'@_transparent' attribute is not supported on declarations within protocols"
-
-- id: transparent_in_classes_not_supported
-  msg: "'@_transparent' attribute is not supported on declarations within classes"
-
-- id: invalid_iboutlet
-  msg: "only instance properties can be declared @IBOutlet"
-
-- id: iboutlet_nonobjc_class
-  msg: "@IBOutlet property cannot %select{have|be an array of}0 non-'@objc' class type %1"
-
-- id: iboutlet_nonobjc_protocol
-  msg: "@IBOutlet property cannot %select{have|be an array of}0 non-'@objc' protocol type %1"
-
-- id: iboutlet_nonobject_type
-  msg: "@IBOutlet property cannot %select{have|be an array of}0 non-object type %1"
-
-- id: iboutlet_only_mutable
-  msg: "@IBOutlet attribute requires property to be mutable"
-
-- id: iboutlet_non_optional
-  msg: "@IBOutlet property has non-optional type %0"
-
-- id: note_make_optional
-  msg: "add '?' to form the optional type %0"
-
-- id: note_make_implicitly_unwrapped_optional
-  msg: "add '!' to form an implicitly unwrapped optional"
-
-- id: invalid_ibdesignable_extension
-  msg: "@IBDesignable can only be applied to classes and extensions of classes"
-
-- id: invalid_ibinspectable
-  msg: "only instance properties can be declared @%0"
-
-- id: invalid_ibaction_decl
-  msg: "only instance methods can be declared @%0"
-
-- id: invalid_ibaction_result
-  msg: "methods declared @%0 must %select{|not }1return a value"
-
-- id: invalid_ibaction_argument_count
-  msg: "@%0 methods must have %1 to %2 arguments"
-
-- id: invalid_ibaction_argument_count_exact
-  msg: "@%0 methods must have %2 argument%s2"
-
-- id: invalid_ibaction_argument_count_max
-  msg: "@%0 methods must have at most %2 argument%s2"
-
-- id: ibsegueaction_objc_method_family
-  msg: "@%0 method cannot have selector %1 because it has special memory management behavior"
-
-- id: fixit_rename_in_swift
-  msg: "change Swift name to %0"
-
-- id: fixit_rename_in_objc
-  msg: "change Objective-C selector to %0"
-
-- id: no_objc_tagged_pointer_not_class_protocol
-  msg: "@unsafe_no_objc_tagged_pointer can only be applied to class protocols"
-
-- id: swift_native_objc_runtime_base_not_on_root_class
-  msg: "@_swift_native_objc_runtime_base_not_on_root_class can only be applied to root classes"
-
-- id: cdecl_not_at_top_level
-  msg: "@_cdecl can only be applied to global functions"
-
-- id: cdecl_empty_name
-  msg: "@_cdecl symbol name cannot be empty"
-
-- id: cdecl_throws
-  msg: "raising errors from @_cdecl functions is not supported"
-
-- id: attr_methods_only
-  msg: "only methods can be declared %0"
-
-- id: access_control_in_protocol
-  msg: "%0 modifier cannot be used in protocols"
-
-- id: access_control_in_protocol_detail
-  msg: "protocol requirements implicitly have the same access as the protocol itself"
-
-- id: access_control_setter
-  msg: "'%select{private|fileprivate|internal|public|open}0(set)' modifier can only be applied to variables and subscripts"
-
-- id: access_control_setter_read_only
-  msg: "'%select{private|fileprivate|internal|public|%error}0(set)' modifier cannot be applied to %select{constants|read-only variables|read-only properties|read-only subscripts}1"
-
-- id: access_control_setter_more
-  msg: "%select{private|fileprivate|internal|public|%error}0 %select{variable|property|subscript}1 cannot have %select{%error|a fileprivate|an internal|a public|an open}2 setter"
-
-- id: access_control_setter_redundant
-  msg: "'%select{private|fileprivate|internal|public|open}0(set)' modifier is redundant for %select{a private|a fileprivate|an internal|a public|an open}2 %1"
-
-- id: access_control_ext_member_more
-  msg: "'%select{%error|fileprivate|internal|public|open}0' modifier conflicts with extension's default access of '%select{private|fileprivate|internal|public|%error}1'"
-
-- id: access_control_ext_member_redundant
-  msg: "'%select{%error|fileprivate|internal|public|%error}0' modifier is redundant for %1 declared in %select{a private (equivalent to fileprivate)|a fileprivate|an internal|a public|%error}2 extension"
-
-- id: access_control_ext_requirement_member_more
-  msg: "cannot declare %select{%error|a fileprivate|an internal|a public|an open}0 %1 in an extension with %select{private|fileprivate|internal|public|%error}2 requirements"
-
-- id: access_control_extension_more
-  msg: "extension of %select{private|fileprivate|internal|%error|%error}0 %1 cannot be declared %select{%error|fileprivate|internal|public|%error}2"
-
-- id: access_control_extension_open
-  msg: "extensions cannot use 'open' as their default access; use 'public'"
-
-- id: access_control_open_bad_decl
-  msg: "only classes and overridable class members can be declared 'open'; use 'public'"
-
-- id: invalid_decl_attribute
-  msg: "'%0' attribute cannot be applied to this declaration"
-
-- id: invalid_decl_modifier
-  msg: "%0 modifier cannot be applied to this declaration"
-
-- id: attribute_does_not_apply_to_type
-  msg: "attribute does not apply to type"
-
-- id: optional_attribute_non_protocol
-  msg: "'optional' can only be applied to protocol members"
-
-- id: optional_attribute_non_objc_protocol
-  msg: "'optional' can only be applied to members of an @objc protocol"
-
-- id: optional_attribute_missing_explicit_objc
-  msg: "'optional' requirements are an Objective-C compatibility feature; add '@objc'"
-
-- id: objcmembers_attribute_nonclass
-  msg: "'@objcMembers' attribute can only be applied to a class"
-
-- id: optional_attribute_initializer
-  msg: "'optional' cannot be applied to an initializer"
-
-- id: unavailable_method_non_objc_protocol
-  msg: "protocol members can only be marked unavailable in an @objc protocol"
-
-- id: missing_in_class_init_1
-  msg: "stored property %0 requires an initial value%select{| or should be @NSManaged}1"
-
-- id: missing_in_class_init_2
-  msg: "stored properties %0 and %1 require initial values%select{| or should be @NSManaged}2"
-
-- id: missing_in_class_init_3plus
-  msg: "stored properties %0, %1, %select{and %2|%2, and others}3 require initial values%select{| or should be @NSManaged}4"
-
-- id: requires_stored_property_inits_here
-  msg: "%select{superclass|class}1 %0 requires all stored properties to have initial values%select{| or use @NSManaged}2"
-
-- id: class_without_init
-  msg: "class %0 has no initializers"
-
-- id: note_no_in_class_init_1
-  msg: "stored property %0 without initial value prevents synthesized initializers"
-
-- id: note_no_in_class_init_2
-  msg: "stored properties %0 and %1 without initial values prevent synthesized initializers"
-
-- id: note_no_in_class_init_3plus
-  msg: "stored properties %0, %1, %select{and %2|%2, and others}3 without initial values prevent synthesized initializers"
-
-- id: missing_unimplemented_init_runtime
-  msg: "standard library error: missing _unimplementedInitializer"
-
-- id: missing_undefined_runtime
-  msg: "standard library error: missing _undefined"
-
-- id: expr_dynamic_lookup_swift3_objc_inference
-  msg: "reference to %0 %1 of %2 depends on '@objc' inference deprecated in Swift 4"
-
-- id: inherited_default_value_not_in_designated_constructor
-  msg: "default value inheritance via 'super' is only valid on the parameters of designated initializers"
-
-- id: inherited_default_value_used_in_non_overriding_constructor
-  msg: "default value inheritance via 'super' can only be used when overriding a designated initializer"
-
-- id: corresponding_param_not_defaulted
-  msg: "default value inheritance via 'super' requires that the corresponding parameter of the overridden designated initializer has a default value"
-
-- id: inherited_default_param_here
-  msg: "corresponding parameter declared here"
-
-- id: option_set_zero_constant
-  msg: "static property %0 produces an empty option set"
-
-- id: option_set_empty_set_init
-  msg: "use [] to silence this warning"
-
-- id: originally_defined_in_dupe_platform
-  msg: "duplicate version number for platform %0"
-
-- id: originally_definedin_topleve_decl
-  msg: "@%0 is only applicable to top-level decl"
-
-- id: originally_definedin_need_available
-  msg: "need @available attribute for @%0"
-
-- id: originally_definedin_must_after_available_version
-  msg: "moved version from @%0 must after introduced OS version"
-
-- id: alignment_not_power_of_two
-  msg: "alignment value must be a power of two"
-
-- id: indirect_case_without_payload
-  msg: "enum case %0 without associated value cannot be 'indirect'"
-
-- id: indirect_case_in_indirect_enum
-  msg: "enum case in 'indirect' enum cannot also be 'indirect'"
-
-- id: enum_frozen_nonpublic
-  msg: "%0 has no effect on non-public enums"
-
-- id: getset_init
-  msg: "variable with getter/setter cannot have an initial value"
-
-- id: unimplemented_static_var
-  msg: "%select{ERROR|static|class}1 stored properties not supported%select{ in this context| in generic types| in classes| in protocol extensions}0%select{|; did you mean 'static'?}2"
-
-- id: observingprop_requires_initializer
-  msg: "non-member observing properties require an initializer"
-
-- id: global_requires_initializer
-  msg: "global '%select{var|let}0' declaration requires an initializer expression%select{ or getter/setter specifier|}0"
-
-- id: static_requires_initializer
-  msg: "%select{ERROR|'static var'|'class var'|}0 declaration requires an initializer expression or getter/setter specifier"
-
-- id: pattern_type_access
-  msg: "%select{%select{variable|constant}0|property}1 %select{must be declared %select{%select{private|fileprivate|internal|%error|%error}3|private or fileprivate}4|cannot be declared %select{in this context|fileprivate|internal|public|open}3}2 because its type uses %select{a private|a fileprivate|an internal|%error|%error}5 type"
-
-- id: pattern_type_access_warn
-  msg: "%select{%select{variable|constant}0|property}1 %select{should be declared %select{private|fileprivate|internal|%error|%error}5|should not be declared %select{in this context|fileprivate|internal|public|open}3}2 because its type uses %select{a private|a fileprivate|an internal|%error|%error}5 type"
-
-- id: pattern_type_access_inferred
-  msg: "%select{%select{variable|constant}0|property}1 %select{must be declared %select{%select{private|fileprivate|internal|%error|%error}3|private or fileprivate}4|cannot be declared %select{in this context|fileprivate|internal|public|open}3}2 because its type %6 uses %select{a private|a fileprivate|an internal|%error|%error}5 type"
-
-- id: pattern_type_access_inferred_warn
-  msg: "%select{%select{variable|constant}0|property}1 %select{should be declared %select{private|fileprivate|internal|%error|%error}5|should not be declared %select{in this context|fileprivate|internal|public|open}3}2 because its type %6 uses %select{a private|a fileprivate|an internal|%error|%error}5 type"
-
-- id: pattern_type_not_usable_from_inline
-  msg: "type referenced from a '@usableFromInline' %select{%select{variable|constant}0|property}1 must be '@usableFromInline' or public"
-
-- id: pattern_type_not_usable_from_inline_warn
-  msg: "type referenced from a '@usableFromInline' %select{%select{variable|constant}0|property}1 should be '@usableFromInline' or public"
-
-- id: pattern_type_not_usable_from_inline_frozen
-  msg: "type referenced from a stored property in a '@frozen' struct must be '@usableFromInline' or public"
-
-- id: pattern_type_not_usable_from_inline_inferred
-  msg: "type referenced from a '@usableFromInline' %select{%select{variable|constant}0|property}1 with inferred type %2 must be '@usableFromInline' or public"
-
-- id: pattern_type_not_usable_from_inline_inferred_warn
-  msg: "type referenced from a '@usableFromInline' %select{%select{variable|constant}0|property}1 with inferred type %2 should be '@usableFromInline' or public"
-
-- id: pattern_type_not_usable_from_inline_inferred_frozen
-  msg: "type referenced from a stored property with inferred type %2 in a '@frozen' struct must be '@usableFromInline' or public"
-
-- id: pattern_binds_no_variables
-  msg: "%select{property|global variable}0 declaration does not bind any variables"
-
-- id: variable_bound_by_no_pattern
-  msg: "variable %0 is not bound by any pattern"
-
-- id: optional_ambiguous_case_ref
-  msg: "assuming you mean '%0.%2'; did you mean '%1.%2' instead?"
-
-- id: optional_fixit_ambiguous_case_ref
-  msg: "explicitly specify 'Optional' to silence this warning"
-
-- id: optional_fixit_ambiguous_case_ref_switch
-  msg: "use 'nil' to silence this warning"
-
-- id: type_fixit_optional_ambiguous_case_ref
-  msg: "use '%0.%1' instead"
-
-- id: type_fixit_optional_ambiguous_case_ref_switch
-  msg: "use '%0' instead"
-
-- id: nscoding_unstable_mangled_name
-  msg: "%select{private|fileprivate|nested|local}0 class %1 has an unstable name when archiving via 'NSCoding'"
-
-- id: unstable_mangled_name_add_objc_new
-  msg: "for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name"
-
-- id: unstable_mangled_name_add_objc
-  msg: "for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name"
-
-- id: unsupported_type_nested_in_generic_function
-  msg: "type %0 cannot be nested in generic function %1"
-
-- id: unsupported_type_nested_in_generic_closure
-  msg: "type %0 cannot be nested in closure in generic context"
-
-- id: unsupported_type_nested_in_protocol
-  msg: "type %0 cannot be nested in protocol %1"
-
-- id: unsupported_type_nested_in_protocol_extension
-  msg: "type %0 cannot be nested in protocol extension of %1"
-
-- id: unsupported_nested_protocol
-  msg: "protocol %0 cannot be nested inside another declaration"
-
-- id: where_nongeneric_ctx
-  msg: "'where' clause on non-generic member declaration requires a generic context"
-
-- id: where_nongeneric_toplevel
-  msg: "'where' clause cannot be applied to a non-generic top-level declaration"
-
-- id: type_alias_underlying_type_access
-  msg: "type alias %select{must be declared %select{%select{private|fileprivate|internal|%error|%error}1|private or fileprivate}3|cannot be declared %select{in this context|fileprivate|internal|public|open}1}0 because its underlying type uses %select{a private|a fileprivate|an internal|%error|%error}2 type"
-
-- id: type_alias_underlying_type_access_warn
-  msg: "type alias %select{should be declared %select{private|fileprivate|internal|%error|%error}1|should not be declared %select{in this context|fileprivate|internal|public|open}1}0 because its underlying type uses %select{a private|a fileprivate|an internal|%error|%error}2 type"
-
-- id: type_alias_underlying_type_not_usable_from_inline
-  msg: "type referenced from the underlying type of a '@usableFromInline' type alias must be '@usableFromInline' or public"
-
-- id: type_alias_underlying_type_not_usable_from_inline_warn
-  msg: "type referenced from the underlying type of a '@usableFromInline' type alias should be '@usableFromInline' or public"
-
-- id: subscript_type_access
-  msg: "subscript %select{must be declared %select{private|fileprivate|internal|%error|%error}1|cannot be declared %select{in this context|fileprivate|internal|public|open}1}0 because its %select{index|element type}3 uses %select{a private|a fileprivate|an internal|%error|%error}2 type"
-
-- id: subscript_type_access_warn
-  msg: "subscript %select{should be declared %select{private|fileprivate|internal|%error|%error}1|should not be declared %select{in this context|fileprivate|internal|public|open}1}0 because its %select{index|element type}3 uses %select{a private|a fileprivate|an internal|%error|%error}2 type"
-
-- id: subscript_type_usable_from_inline
-  msg: "%select{index type|element type}0 of a '@usableFromInline' subscript must be '@usableFromInline' or public"
-
-- id: subscript_type_usable_from_inline_warn
-  msg: "%select{index type|element type}0 of a '@usableFromInline' subscript should be '@usableFromInline' or public"
-
-- id: function_type_access
-  msg: "%select{function|method|initializer}4 %select{must be declared %select{%select{private|fileprivate|internal|%error|%error}1|private or fileprivate}2|cannot be declared %select{in this context|fileprivate|internal|public|open}1}0 because its %select{parameter|result}5 uses %select{a private|a fileprivate|an internal|an '@_spi'|an '@_spi'}3 type"
-
-- id: function_type_spi
-  msg: "%select{function|method|initializer}0 cannot be declared '@_spi' because its %select{parameter|result}1 uses %select{a private|a fileprivate|an internal|a public|an open}2 type%select{| that is not '@_spi'}3"
-
-- id: function_type_access_warn
-  msg: "%select{function|method|initializer}4 %select{should be declared %select{private|fileprivate|internal|%error|%error}1|should not be declared %select{in this context|fileprivate|internal|public|open}1}0 because its %select{parameter|result}5 uses %select{a private|a fileprivate|an internal|%error|%error}3 type"
-
-- id: function_type_usable_from_inline
-  msg: "the %select{parameter|result}1 of a '@usableFromInline' %select{function|method|initializer}0 must be '@usableFromInline' or public"
-
-- id: function_type_usable_from_inline_warn
-  msg: "the %select{parameter|result}1 of a '@usableFromInline' %select{function|method|initializer}0 should be '@usableFromInline' or public"
-
-- id: spi_attribute_on_non_public
-  msg: "%select{private|fileprivate|internal|%error|%error}0 %1 cannot be declared '@_spi' because only public and open declarations can be '@_spi'"
-
-- id: spi_attribute_on_protocol_requirement
-  msg: "protocol requirement %0 cannot be declared '@_spi' without a default implementation in a protocol extension"
-
-- id: spi_attribute_on_frozen_stored_properties
-  msg: "stored property %0 cannot be declared '@_spi' in a '@frozen' struct"
-
-- id: opaque_type_invalid_constraint
-  msg: "an 'opaque' type must specify only 'Any', 'AnyObject', protocols, and/or a base class"
-
-- id: inferred_opaque_type
-  msg: "property definition has inferred type %0, involving the 'some' return type of another declaration"
-
-- id: non_nominal_extension
-  msg: "non-nominal type %0 cannot be extended"
-
-- id: composition_in_extended_type
-  msg: "extending a protocol composition is not supported; extending %0 instead"
-
-- id: composition_in_extended_type_alternative
-  msg: "did you mean to extend the most specific type %0 instead?"
-
-- id: extension_access_with_conformances
-  msg: "%0 modifier cannot be used with extensions that declare protocol conformances"
-
-- id: extension_metatype
-  msg: "cannot extend a metatype %0"
-
-- id: extension_specialization
-  msg: "constrained extension must be declared on the unspecialized generic type %0 with constraints specified by a 'where' clause"
-
-- id: extension_stored_property
-  msg: "extensions must not contain stored properties"
-
-- id: extension_stored_property_fixit
-  msg: "Remove '=' to make %0 a computed property"
-
-- id: extension_nongeneric_trailing_where
-  msg: "trailing 'where' clause for extension of non-generic type %0"
-
-- id: extension_protocol_inheritance
-  msg: "extension of protocol %0 cannot have an inheritance clause"
-
-- id: objc_generic_extension_using_type_parameter
-  msg: "extension of a generic Objective-C class cannot access the class's generic parameters at runtime"
-
-- id: objc_generic_extension_using_type_parameter_here
-  msg: "generic parameter used here"
-
-- id: objc_generic_extension_using_type_parameter_try_objc
-  msg: "add '@objc' to allow uses of 'self' within the function body"
-
-- id: invalid_nominal_extension
-  msg: "extension of type %0 must be declared as an extension of %1"
-
-- id: invalid_nominal_extension_rewrite
-  msg: "did you mean to extend %0 instead?"
-
-- id: type_does_not_conform
-  msg: "type %0 does not conform to protocol %1"
-
-- id: cannot_use_nil_with_this_type
-  msg: "'nil' cannot be used in context expecting type %0"
-
-- id: type_cannot_conform_to_nsobject
-  msg: "cannot declare conformance to 'NSObjectProtocol' in Swift; %0 should inherit 'NSObject' instead"
-
-- id: use_of_equal_instead_of_equality
-  msg: "use of '=' in a boolean context, did you mean '=='?"
-
-- id: type_cannot_conform
-  msg: "%select{type %1|protocol %1 as a type}0 cannot conform to %select{%3|the protocol itself}2; only concrete types such as structs, enums and classes can conform to protocols"
-
-- id: required_by_opaque_return
-  msg: "required by opaque return type of %0 %1"
-
-- id: required_by_decl
-  msg: "required by %0 %1 where %2 = %3"
-
-- id: required_by_decl_ref
-  msg: "required by referencing %0 %1 on %2 where %3 = %4"
-
-- id: protocol_does_not_conform_static
-  msg: "%0 cannot be used as a type conforming to protocol %1 because %1 has static requirements"
-
-- id: protocol_derivation_is_broken
-  msg: "protocol %0 is broken; cannot derive conformance for type %1"
-
-- id: type_does_not_inherit
-  msg: "%0 requires that %1 inherit from %2"
-
-- id: type_does_not_inherit_or_conform_requirement
-  msg: "requirement specified as %0 : %1%2"
-
-- id: types_not_equal
-  msg: "%0 requires the types %1 and %2 be equivalent"
-
-- id: type_does_not_conform_owner
-  msg: "%0 requires that %1 conform to %2"
-
-- id: type_does_not_conform_in_decl_ref
-  msg: "referencing %0 %1 on %2 requires that %3 conform to %4"
-
-- id: type_does_not_conform_anyobject_in_decl_ref
-  msg: "referencing %0 %1 on %2 requires that %3 be a class type"
-
-- id: type_does_not_conform_decl_owner
-  msg: "%0 %1 requires that %2 conform to %3"
-
-- id: type_does_not_conform_anyobject_decl_owner
-  msg: "%0 %1 requires that %2 be a class type"
-
-- id: type_does_not_conform_in_opaque_return
-  msg: "return type of %0 %1 requires that %2 %select{conform to %3|be a class type}4"
-
-- id: types_not_equal_decl
-  msg: "%0 %1 requires the types %2 and %3 be equivalent"
-
-- id: types_not_equal_in_decl_ref
-  msg: "referencing %0 %1 on %2 requires the types %3 and %4 be equivalent"
-
-- id: types_not_inherited_decl
-  msg: "%0 %1 requires that %2 inherit from %3"
-
-- id: types_not_inherited_in_decl_ref
-  msg: "referencing %0 %1 on %2 requires that %3 inherit from %4"
-
-- id: where_requirement_failure_one_subst
-  msg: "where %0 = %1"
-
-- id: where_requirement_failure_both_subst
-  msg: "where %0 = %1, %2 = %3"
-
-- id: requirement_implied_by_conditional_conformance
-  msg: "requirement from conditional conformance of %0 to %1"
-
-- id: wrapped_type_satisfies_requirement
-  msg: "wrapped type %0 satisfies this requirement; did you mean to unwrap?"
-
-- id: candidate_types_conformance_requirement
-  msg: "candidate requires that %0 conform to %1 (requirement specified as %2 == %3%4)"
-
-- id: candidate_types_equal_requirement
-  msg: "candidate requires that the types %0 and %1 be equivalent (requirement specified as %2 == %3%4)"
-
-- id: candidate_types_inheritance_requirement
-  msg: "candidate requires that %1 inherit from %2 (requirement specified as %2 : %3%4)"
-
-- id: types_not_equal_requirement
-  msg: "requirement specified as %0 == %1%2"
-
-- id: type_is_not_a_class
-  msg: "%0 requires that %1 be a class type"
-
-- id: anyobject_requirement
-  msg: "requirement specified as %0 : 'AnyObject'%2"
-
-- id: non_class_cannot_conform_to_class_protocol
-  msg: "non-class type %0 cannot conform to class protocol %1"
-
-- id: cf_class_cannot_conform_to_objc_protocol
-  msg: "Core Foundation class %0 cannot conform to @objc protocol %1 because Core Foundation types are not classes in Objective-C"
-
-- id: objc_runtime_visible_cannot_conform_to_objc_protocol
-  msg: "class %0 cannot conform to @objc protocol %1 because the class is only visible via the Objective-C runtime"
-
-- id: objc_generics_cannot_conditionally_conform
-  msg: "type %0 cannot conditionally conform to protocol %1 because the type uses the Objective-C generics model"
-
-- id: objc_protocol_cannot_have_conditional_conformance
-  msg: "type %0 cannot conditionally conform to @objc protocol %1 because Objective-C does not support conditional conformances"
-
-- id: objc_protocol_in_generic_extension
-  msg: "conformance of %select{class from generic context|generic class}0 %1 to @objc protocol %2 cannot be in an extension"
-
-- id: conditional_conformances_cannot_imply_conformances
-  msg: "conditional conformance of type %0 to protocol %1 does not imply conformance to inherited protocol %2"
-
-- id: note_explicitly_state_conditional_conformance_different
-  msg: "did you mean to explicitly state the conformance with different bounds?"
-
-- id: note_explicitly_state_conditional_conformance_relaxed
-  msg: "did you mean to explicitly state the conformance with relaxed bounds?"
-
-- id: note_explicitly_state_conditional_conformance_same
-  msg: "did you mean to explicitly state the conformance with the same bounds?"
-
-- id: note_explicitly_state_conditional_conformance_noneditor
-  msg: "did you mean to explicitly state the conformance like '%0where ...'?"
-
-- id: protocol_has_missing_requirements
-  msg: "type %0 cannot conform to protocol %1 because it has requirements that cannot be satisfied"
-
-- id: protocol_has_missing_requirements_versioned
-  msg: "type %0 cannot conform to protocol %1 (compiled with Swift %2) because it has requirements that could not be loaded in Swift %3"
-
-- id: requirement_restricts_self
-  msg: "%0 requirement %1 cannot add constraint '%2%select{:|:| ==|:}3 %4' on 'Self'"
-
-- id: witness_argument_name_mismatch
-  msg: "%0 %1 has different argument labels from those required by protocol %2 (%3)"
-
-- id: witness_initializer_not_required
-  msg: "initializer requirement %0 can only be satisfied by a 'required' initializer in%select{| the definition of}1 non-final class %2"
-
-- id: witness_initializer_failability
-  msg: "non-failable initializer requirement %0%select{| in Objective-C protocol}1 cannot be satisfied by a failable initializer ('init%select{?|!}1')"
-
-- id: witness_self_non_subtype
-  msg: "protocol %0 requirement %1 cannot be satisfied by a non-final class (%2) because it uses 'Self' in a non-parameter, non-result type position"
-
-- id: witness_self_same_type
-  msg: "%0 %1 in non-final class %2 cannot be used to satisfy requirement %3 %4 (in protocol %5) due to same-type requirement involving 'Self'"
-
-- id: witness_self_weaken_same_type
-  msg: "consider weakening the same-type requirement %0 == %1 to a superclass requirement"
-
-- id: witness_requires_dynamic_self
-  msg: "method %0 in non-final class %1 must return 'Self' to conform to protocol %2"
-
-- id: witness_requires_class_implementation
-  msg: "method %0 in non-final class %1 cannot be implemented in a protocol extension because it returns 'Self' and has associated type requirements"
-
-- id: witness_not_accessible_proto
-  msg: "%select{initializer %1|method %1|%select{|setter for }2property %1|subscript%select{| setter}2}0 must be declared %select{%error|fileprivate|internal|public|%error}3 because it matches a requirement in %select{private|fileprivate|internal|public|%error}4 protocol %5"
-
-- id: witness_not_accessible_type
-  msg: "%select{initializer %1|method %1|%select{|setter for }2property %1|subscript%select{| setter}2}0 must be as accessible as its enclosing type because it matches a requirement in protocol %5"
-
-- id: type_witness_not_accessible_proto
-  msg: "%0 %1 must be declared %select{%error|fileprivate|internal|public|%error}2 because it matches a requirement in %select{%error|fileprivate|internal|public|%error}2 protocol %3"
-
-- id: type_witness_not_accessible_type
-  msg: "%0 %1 must be as accessible as its enclosing type because it matches a requirement in protocol %3"
-
-- id: witness_not_usable_from_inline
-  msg: "%0 %1 must be declared '@usableFromInline' because it matches a requirement in protocol %2"
-
-- id: witness_not_usable_from_inline_warn
-  msg: "%0 %1 should be declared '@usableFromInline' because it matches a requirement in protocol %2"
-
-- id: type_witness_objc_generic_parameter
-  msg: "type %0 involving Objective-C type parameter%select{| %1}2 cannot be used for associated type %3 of protocol %4"
-
-- id: witness_fix_access
-  msg: "mark the %0 as '%select{%error|fileprivate|internal|public|%error}1' to satisfy the requirement"
-
-- id: witness_move_to_another_extension
-  msg: "move the %0 to another extension where it can be declared '%select{%error|%error|internal|public|%error}1' to satisfy the requirement"
-
-- id: assoc_type_default_conformance_failed
-  msg: "default type %0 for associated type %1 does not satisfy constraint %2: %3"
-
-- id: assoc_type_default_here
-  msg: "associated type %0 has default type %1 written here"
-
-- id: protocol_access
-  msg: "%select{protocol must be declared %select{%select{private|fileprivate|internal|%error|%error}1|private or fileprivate}4 because %select{it refines|its 'where' clause uses}2|%select{in this context|fileprivate|internal|public|%error}1 %select{protocol cannot refine|protocol's 'where' clause cannot use}2}0 %select{a private|a fileprivate|an internal|%error|%error}3 %5"
-
-- id: protocol_access_warn
-  msg: "%select{protocol should be declared %select{private|fileprivate|internal|%error|%error}1 because %select{it refines|its 'where' clause uses}2|%select{in this context|fileprivate|internal|public|%error}1 %select{protocol should not refine|protocol's 'where' clause should not use}2}0 %select{a private|a fileprivate|an internal|%error|%error}3 %5"
-
-- id: protocol_usable_from_inline
-  msg: "protocol %select{refined|used}0 by '@usableFromInline' protocol must be '@usableForInline' or public"
-
-- id: protocol_usable_from_inline_warn
-  msg: "protocol %select{refined|used}0 by '@usableFromInline' protocol should be '@usableForInline' or public"
-
-- id: protocol_property_must_be_computed_var
-  msg: "protocols cannot require properties to be immutable; declare read-only properties by using 'var' with a '{ get }' specifier"
-
-- id: protocol_property_must_be_computed
-  msg: "property in protocol must have explicit { get } or { get set } specifier"
-
-- id: inherited_protocol_does_not_conform
-  msg: "type %0 does not conform to inherited protocol %1"
-
-- id: no_witnesses
-  msg: "protocol requires %select{initializer %1|function %1|property %1|subscript}0 with type %2%select{|; do you want to add a stub?}3"
-
-- id: missing_witnesses_general
-  msg: "do you want to add protocol stubs?"
-
-- id: ambiguous_witnesses
-  msg: "multiple matching %select{initializers named %1|functions named %1|properties named %1|subscript operators}0 with type %2"
-
-- id: ambiguous_witnesses_wrong_name
-  msg: "multiple matching %select{initializers named %1|functions named %1|properties named %1|subscript operators}0 with type %2"
-
-- id: no_witnesses_type
-  msg: "protocol requires nested type %0; do you want to add it?"
-
-- id: default_associated_type_req_fail
-  msg: "default type %0 for associated type %1 (from protocol %2) does not %select{inherit from|conform to}4 %3"
-
-- id: associated_type_access
-  msg: "associated type in %select{a private|a fileprivate|an internal|a public|%error}0 protocol uses %select{a private|a fileprivate|an internal|%error|%error}1 type in its %select{default definition|requirement}2 "
-
-- id: associated_type_access_warn
-  msg: "associated type in %select{a private|a fileprivate|an internal|a public|%error}0 protocol uses %select{a private|a fileprivate|an internal|%error|%error}1 type in its %select{default definition|requirement}2 "
-
-- id: associated_type_not_usable_from_inline
-  msg: "type referenced from a %select{default definition|requirement}0 of an associated type in a '@usableFromInline' protocol must be '@usableFromInline' or public"
-
-- id: associated_type_not_usable_from_inline_warn
-  msg: "type referenced from a %select{default definition|requirement}0 of an associated type in a '@usableFromInline' protocol should be '@usableFromInline' or public"
-
-- id: bad_associated_type_deduction
-  msg: "unable to infer associated type %0 for protocol %1"
-
-- id: associated_type_deduction_witness_failed
-  msg: "candidate would match and infer %0 = %1 if %1 %select{inherited from|conformed to}3 %2"
-
-- id: associated_type_witness_conform_impossible
-  msg: "candidate can not infer %0 = %1 because %1 is not a nominal type and so can't conform to %2"
-
-- id: associated_type_witness_inherit_impossible
-  msg: "candidate can not infer %0 = %1 because %1 is not a class type and so can't inherit from %2"
-
-- id: ambiguous_associated_type_deduction
-  msg: "ambiguous inference of associated type %0: %1 vs. %2"
-
-- id: associated_type_deduction_witness
-  msg: "matching requirement %0 to this declaration inferred associated type to %1"
-
-- id: associated_type_deduction_default
-  msg: "using associated type default %0"
-
-- id: ambiguous_witnesses_type
-  msg: "multiple matching types named %0"
-
-- id: protocol_witness_exact_match
-  msg: "candidate exactly matches%0"
-
-- id: protocol_witness_renamed
-  msg: "rename to %0 to satisfy this requirement%1"
-
-- id: protocol_witness_kind_conflict
-  msg: "candidate is not %select{an initializer|a function|a variable|a subscript}0"
-
-- id: protocol_witness_type_conflict
-  msg: "candidate has non-matching type %0%1"
-
-- id: protocol_witness_missing_requirement
-  msg: "candidate would match if %0 %select{conformed to|subclassed|was the same type as}2 %1"
-
-- id: protocol_witness_optionality_conflict
-  msg: "candidate %select{type has|result type has|parameter type has|parameter types have|result and parameter types have}0 incorrect optionality%1"
-
-- id: err_protocol_witness_optionality
-  msg: "%select{type|result|parameter|parameters|result and parameters}0 of %1 %select{has|has|has|have|have|}0 different optionality than required by protocol %2"
-
-- id: warn_protocol_witness_optionality
-  msg: "%select{type|result|parameter|parameters|result and parameters}0 of %1 %select{has|has|has|have|have|}0 different optionality than expected by protocol %2"
-
-- id: protocol_witness_static_conflict
-  msg: "candidate operates on %select{a type|an instance}0, not %select{an instance|a type}0 as required"
-
-- id: protocol_witness_prefix_postfix_conflict
-  msg: "candidate is %select{|prefix, |postfix, }1not %select{prefix|postfix}0 as required"
-
-- id: protocol_witness_mutation_modifier_conflict
-  msg: "candidate is marked %0 but protocol does not allow it"
-
-- id: protocol_witness_settable_conflict
-  msg: "candidate is not settable, but protocol requires it"
-
-- id: protocol_witness_rethrows_conflict
-  msg: "candidate is not 'rethrows', but protocol requires it"
-
-- id: protocol_witness_throws_conflict
-  msg: "candidate throws, but protocol does not allow it"
-
-- id: protocol_witness_not_objc
-  msg: "candidate is explicitly '@nonobjc'"
-
-- id: protocol_witness_enum_case_payload
-  msg: "candidate is an enum case with associated values, but protocol does not allow it"
-
-- id: protocol_witness_type
-  msg: "possibly intended match"
-
-- id: protocol_witness_nonconform_type
-  msg: "possibly intended match %0 does not %select{inherit from|conform to}2 %1"
-
-- id: protocol_witness_circularity
-  msg: "candidate references itself"
-
-- id: protocol_conformance_here
-  msg: "%select{|class }0%1 declares conformance to protocol %2 here"
-
-- id: declared_protocol_conformance_here
-  msg: "%select{%0 inherits conformance to protocol %2 from superclass|%0 declares conformance to protocol %2|%0 implicitly conforms to protocol %2 (via conformance to %3)|%0 implicitly conforms to protocol %2}1 here"
-
-- id: witness_unavailable
-  msg: "unavailable %0 %1 was used to satisfy a requirement of protocol %2"
-
-- id: redundant_conformance
-  msg: "redundant conformance of %0 to protocol %1"
-
-- id: redundant_conformance_conditional
-  msg: "conflicting conformance of %0 to protocol %1; there cannot be more than one conformance, even with different conditional bounds"
-
-- id: redundant_conformance_adhoc
-  msg: "conformance of %0 to protocol %1 was already stated in %select{the protocol's|the type's}2 module %3"
-
-- id: redundant_conformance_adhoc_conditional
-  msg: "conformance of %0 to protocol %1 conflicts with that stated in %select{the protocol's|the type's}2 module %3 and will be ignored; there cannot be more than one conformance, even with different conditional bounds"
-
-- id: redundant_conformance_witness_ignored
-  msg: "%0 %1 will not be used to satisfy the conformance to %2"
-
-- id: req_near_match
-  msg: "%0 %1 nearly matches %select{defaulted|optional}2 requirement %3 of protocol %4"
-
-- id: optional_req_nonobjc_near_match_add_objc
-  msg: "add '@objc' to provide an Objective-C entrypoint"
-
-- id: req_near_match_move
-  msg: "move %0 to %select{an|another}1 extension to silence this warning"
-
-- id: req_near_match_nonobjc
-  msg: "add '@nonobjc' to silence this %select{warning|error}0"
-
-- id: req_near_match_access
-  msg: "make %0 %select{ERROR|private|private|non-public|non-public}1 to silence this warning"
-
-- id: missing_append_interpolation
-  msg: "type conforming to 'StringInterpolationProtocol' does not implement a valid 'appendInterpolation' method"
-
-- id: append_interpolation_static
-  msg: "'appendInterpolation' method will never be used because it is static"
-
-- id: append_interpolation_void_or_discardable
-  msg: "'appendInterpolation' method does not return 'Void' or have a discardable result"
-
-- id: append_interpolation_access_control
-  msg: "'appendInterpolation' method is %select{private|fileprivate|internal|public|open}0, but %1 is %select{private|fileprivate|internal|public|open}2"
-
-- id: assoc_type_outside_of_protocol
-  msg: "associated type %0 can only be used with a concrete type or generic parameter base"
-
-- id: typealias_outside_of_protocol
-  msg: "type alias %0 can only be used with a concrete type or generic parameter base"
-
-- id: objc_protocol_inherits_non_objc_protocol
-  msg: "@objc protocol %0 cannot refine non-@objc protocol %1"
-
-- id: protocol_where_clause_self_requirement
-  msg: "constraint with subject type of 'Self' is not supported; consider adding requirement to protocol inheritance clause instead"
-
-- id: invalid_protocol_composition_member
-  msg: "non-protocol, non-class type %0 cannot be used within a protocol-constrained type"
-
-- id: protocol_composition_one_class
-  msg: "protocol-constrained type cannot contain class %0 because it already contains class %1"
-
-- id: requires_conformance_nonprotocol
-  msg: "type %0 constrained to non-protocol, non-class type %1"
-
-- id: requires_conformance_nonprotocol_fixit
-  msg: "use '%0 == %1' to require '%0' to be '%1'"
-
-- id: requires_not_suitable_archetype
-  msg: "type %0 in conformance requirement does not refer to a generic parameter or associated type"
-
-- id: requires_no_same_type_archetype
-  msg: "neither type in same-type constraint (%0 or %1) refers to a generic parameter or associated type"
-
-- id: requires_generic_params_made_equal
-  msg: "same-type requirement makes generic parameters %0 and %1 equivalent"
-
-- id: requires_generic_param_made_equal_to_concrete
-  msg: "same-type requirement makes generic parameter %0 non-generic"
-
-- id: recursive_decl_reference
-  msg: "%0 %1 references itself"
-
-- id: recursive_same_type_constraint
-  msg: "same-type constraint %0 == %1 is recursive"
-
-- id: recursive_superclass_constraint
-  msg: "superclass constraint %0 : %1 is recursive"
-
-- id: requires_generic_param_same_type_does_not_conform
-  msg: "same-type constraint type %0 does not conform to required protocol %1"
-
-- id: requires_same_concrete_type
-  msg: "generic signature requires types %0 and %1 to be the same"
-
-- id: redundant_conformance_constraint
-  msg: "redundant conformance constraint %0: %1"
-
-- id: redundant_conformance_here
-  msg: "conformance constraint %1: %2 %select{written here|implied here|inferred from type here}0"
-
-- id: unsupported_recursive_requirements
-  msg: "requirement involves recursion that is not currently supported"
-
-- id: same_type_conflict
-  msg: "%select{generic parameter |protocol |}0%1 cannot be equal to both %2 and %3"
-
-- id: redundant_same_type_to_concrete
-  msg: "redundant same-type constraint %0 == %1"
-
-- id: same_type_redundancy_here
-  msg: "same-type constraint %1 == %2 %select{written here|implied here|inferred from type here}0"
-
-- id: requires_superclass_conflict
-  msg: "%select{generic parameter %1 cannot|protocol %1 cannot require 'Self' to|%1 cannot}0 be a subclass of both %2 and %3"
-
-- id: redundant_superclass_constraint
-  msg: "redundant superclass constraint %0 : %1"
-
-- id: superclass_redundancy_here
-  msg: "superclass constraint %1 : %2 %select{written here|implied here|inferred from type here}0"
-
-- id: conflicting_layout_constraints
-  msg: "%select{generic parameter |protocol |}0%1 has conflicting constraints %2 and %3"
-
-- id: redundant_layout_constraint
-  msg: "redundant constraint %0 : %1"
-
-- id: previous_layout_constraint
-  msg: "constraint %1 : %2 %select{written here|implied here|inferred from type here}0"
-
-- id: redundant_same_type_constraint
-  msg: "redundant same-type constraint %0 == %1"
-
-- id: previous_same_type_constraint
-  msg: "previous same-type constraint %1 == %2 %select{written here|implied here|inferred from type here}0"
-
-- id: inherited_associated_type_redecl
-  msg: "redeclaration of associated type %0 from protocol %1 is better expressed as a 'where' clause on the protocol"
-
-- id: typealias_override_associated_type
-  msg: "typealias overriding associated type %0 from protocol %1 is better expressed as same-type constraint on the protocol"
-
-- id: associated_type_override_typealias
-  msg: "associated type %0 is redundant with type %0 declared in inherited %1 %2"
-
-- id: associated_type_objc
-  msg: "associated type %0 cannot be declared inside '@objc' protocol %1"
-
-- id: generic_param_access
-  msg: "%0 %select{must be declared %select{%select{private|fileprivate|internal|%error|%error}3|private or fileprivate}4|cannot be declared %select{in this context|fileprivate|internal|public|open}2}1 because its generic %select{parameter|requirement}5 uses %select{a private|a fileprivate|an internal|an '@_spi'|an '@_spi'}3 type"
-
-- id: generic_param_access_warn
-  msg: "%0 %select{should be declared %select{private|fileprivate|internal|%error|%error}3|should not be declared %select{in this context|fileprivate|internal|public|open}2}1 because its generic %select{parameter|requirement}5 uses %select{a private|a fileprivate|an internal|an '@_spi'|an '@_spi'}3 type"
-
-- id: generic_param_usable_from_inline
-  msg: "type referenced from a generic %select{parameter|requirement}1 of a '@usableFromInline' %0 must be '@usableFromInline' or public"
-
-- id: generic_param_usable_from_inline_warn
-  msg: "type referenced from a generic %select{parameter|requirement}1 of a '@usableFromInline' %0 should be '@usableFromInline' or public"
-
-- id: override_multiple_decls_base
-  msg: "declaration %0 cannot override more than one superclass declaration"
-
-- id: override_multiple_decls_arg_mismatch
-  msg: "declaration %0 has different argument labels from any potential overrides"
-
-- id: overridden_near_match_here
-  msg: "potential overridden %0 %1 here"
-
-- id: override_decl_extension
-  msg: "overriding %select{|non-@objc }0declarations %select{in extensions|from extensions}0 is not supported"
-
-- id: overridden_here
-  msg: "overridden declaration is here"
-
-- id: overridden_here_can_be_objc
-  msg: "add '@objc' to make this declaration overridable"
-
-- id: missing_override
-  msg: "overriding declaration requires an 'override' keyword"
-
-- id: missing_override_warn
-  msg: "implicit override should be marked with 'override' or suppressed with '@_nonoverride'"
-
-- id: multiple_override
-  msg: "%0 has already been overridden"
-
-- id: multiple_override_prev
-  msg: "%0 previously overridden here"
-
-- id: override_unavailable
-  msg: "cannot override %0 which has been marked unavailable%select{|: %1}1"
-
-- id: suggest_removing_override
-  msg: "remove 'override' modifier to declare a new %0"
-
-- id: override_less_available
-  msg: "overriding %0 must be as available as declaration it overrides"
-
-- id: override_accessor_less_available
-  msg: "overriding %0 for %1 must be as available as declaration it overrides"
-
-- id: override_let_property
-  msg: "cannot override immutable 'let' property %0 with the getter of a 'var'"
-
-- id: override_not_accessible
-  msg: "%select{|setter of }0overriding %1 must be as accessible as %select{its enclosing type|the declaration it overrides}2"
-
-- id: override_of_non_open
-  msg: "overriding non-open %0 outside of its defining module"
-
-- id: method_does_not_override
-  msg: "method does not override any method from its %select{parent protocol|superclass}0"
-
-- id: property_does_not_override
-  msg: "property does not override any property from its %select{parent protocol|superclass}0"
-
-- id: subscript_does_not_override
-  msg: "subscript does not override any subscript from its %select{parent protocol|superclass}0"
-
-- id: initializer_does_not_override
-  msg: "initializer does not override a designated initializer from its %select{parent protocol|superclass}0"
-
-- id: failable_initializer_override
-  msg: "failable initializer %0 cannot override a non-failable initializer"
-
-- id: nonfailable_initializer_override_here
-  msg: "non-failable initializer %0 overridden here"
-
-- id: property_override_here
-  msg: "attempt to override property here"
-
-- id: subscript_override_here
-  msg: "attempt to override subscript here"
-
-- id: convenience_init_override_here
-  msg: "attempt to override convenience initializer here"
-
-- id: override_type_mismatch_with_fixits
-  msg: "type does not match superclass %0 with type %1"
-
-- id: override_type_mismatch_with_fixits_init
-  msg: "type does not match superclass initializer with %select{no arguments|argument %1|arguments %1}0"
-
-- id: override_nonclass_decl
-  msg: "'override' can only be specified on class members"
-
-- id: nonoverride_wrong_decl_context
-  msg: "'@_nonoverride' can only be specified on class or protocol members"
-
-- id: nonoverride_and_override_attr
-  msg: "'override' cannot be combined with '@_nonoverride'"
-
-- id: override_property_type_mismatch
-  msg: "property %0 with type %1 cannot override a property with type %2"
-
-- id: override_with_stored_property
-  msg: "cannot override with a stored property %0"
-
-- id: override_with_stored_property_warn
-  msg: "cannot override with a stored property %0"
-
-- id: observing_readonly_property
-  msg: "cannot observe read-only property %0; it can't change"
-
-- id: override_mutable_with_readonly_property
-  msg: "cannot override mutable property with read-only property %0"
-
-- id: override_argument_name_mismatch
-  msg: "argument labels for %select{method|initializer}0 %1 do not match those of overridden %select{method|initializer}0 %2"
-
-- id: override_ownership_mismatch
-  msg: "cannot override %0 property with %1 property"
-
-- id: override_dynamic_self_mismatch
-  msg: "cannot override a Self return type with a non-Self return type"
-
-- id: override_class_declaration_in_extension
-  msg: "cannot override a non-dynamic class declaration from an extension"
-
-- id: override_throws
-  msg: "cannot override non-throwing %select{method|initializer}0 with throwing %select{method|initializer}0"
-
-- id: override_throws_objc
-  msg: "overriding a throwing @objc %select{method|initializer}0 with a non-throwing %select{method|initializer}0 is not supported"
-
-- id: satisfy_throws_objc
-  msg: "satisfying a throwing @objc %select{method|initializer}0 with a non-throwing %select{method|initializer}0 is not supported"
-
-- id: override_optional_mismatch
-  msg: "cannot override %0 %select{parameter|index}1 of type %2 with non-optional type %3"
-
-- id: override_optional_result_mismatch
-  msg: "cannot override %0 %select{result|element}1 type %2 with optional type %3"
-
-- id: override_unnecessary_IUO
-  msg: "overriding %0 parameter of type %1 with implicitly unwrapped optional type %2"
-
-- id: override_unnecessary_result_IUO
-  msg: "overriding %0 optional result type %1 with implicitly unwrapped optional type %2"
-
-- id: override_unnecessary_IUO_remove
-  msg: "remove '!' to make the parameter required"
-
-- id: override_unnecessary_IUO_use_strict
-  msg: "use '?' to make the result optional"
-
-- id: override_unnecessary_IUO_silence
-  msg: "add parentheses to silence this warning"
-
-- id: override_mutable_covariant_property
-  msg: "cannot override mutable property %0 of type %1 with covariant type %2"
-
-- id: override_mutable_covariant_subscript
-  msg: "cannot override mutable subscript of type %0 with covariant type %1"
-
-- id: static_decl_already_final
-  msg: "static declarations are already final"
-
-- id: open_decl_cannot_be_final
-  msg: "%0 cannot be declared both 'final' and 'open'"
-
-- id: implicitly_final_cannot_be_open
-  msg: "%select{'let' properties|members of 'final' classes|static declarations}0 are implicitly 'final'; use 'public' instead of 'open'"
-
-- id: implicitly_final_cannot_be_open_swift4
-  msg: "%select{'let' properties|members of 'final' classes|static declarations}0 are implicitly 'final'; use 'public' instead of 'open'"
-
-- id: override_swift3_objc_inference
-  msg: "override of %0 %1 from extension of %2 depends on deprecated inference of '@objc'"
-
-- id: override_method_different_generic_sig
-  msg: "overridden method %0 has generic signature %1 which is incompatible with base method's generic signature %2; expected generic signature to be %3"
-
-- id: duplicate_inheritance
-  msg: "duplicate inheritance from %0"
-
-- id: duplicate_anyobject_class_inheritance
-  msg: "redundant inheritance from 'AnyObject' and Swift 3 'class' keyword"
-
-- id: inheritance_from_protocol_with_superclass
-  msg: "inheritance from class-constrained protocol composition type %0"
-
-- id: multiple_inheritance
-  msg: "multiple inheritance from classes %0 and %1"
-
-- id: inheritance_from_non_protocol_or_class
-  msg: "inheritance from non-protocol, non-class type %0"
-
-- id: inheritance_from_non_protocol
-  msg: "inheritance from non-protocol type %0"
-
-- id: superclass_not_first
-  msg: "superclass %0 must appear first in the inheritance clause"
-
-- id: superclass_not_open
-  msg: "cannot inherit from non-open class %0 outside of its defining module"
-
-- id: superclass_here
-  msg: "superclass is declared here"
-
-- id: superclass_of_open_not_open
-  msg: "superclass %0 of open class must be open"
-
-- id: inheritance_from_final_class
-  msg: "inheritance from a final class %0"
-
-- id: inheritance_from_unspecialized_objc_generic_class
-  msg: "inheritance from a generic Objective-C class %0 must bind type parameters of %0 to specific concrete types"
-
-- id: inheritance_from_class_with_missing_vtable_entries
-  msg: "cannot inherit from class %0 because it has overridable members that could not be loaded"
-
-- id: inheritance_from_class_with_missing_vtable_entries_versioned
-  msg: "cannot inherit from class %0 (compiled with Swift %1) because it has overridable members that could not be loaded in Swift %2"
-
-- id: inheritance_from_cf_class
-  msg: "cannot inherit from Core Foundation type %0"
-
-- id: inheritance_from_objc_runtime_visible_class
-  msg: "cannot inherit from class %0 because it is only visible via the Objective-C runtime"
-
-- id: enum_case_access
-  msg: "enum case in %select{a private|a fileprivate|an internal|a public|%error}0 enum uses %select{a private|a fileprivate|an internal|%error|%error}1 type"
-
-- id: enum_case_access_warn
-  msg: "enum case in %select{a private|a fileprivate|an internal|a public|%error}0 enum uses %select{a private|a fileprivate|an internal|%error|%error}1 type"
-
-- id: enum_case_usable_from_inline
-  msg: "type of enum case in '@usableFromInline' enum must be '@usableFromInline' or public"
-
-- id: enum_case_usable_from_inline_warn
-  msg: "type of enum case in '@usableFromInline' enum should be '@usableFromInline' or public"
-
-- id: enum_stored_property
-  msg: "enums must not contain stored properties"
-
-- id: multiple_enum_raw_types
-  msg: "multiple enum raw types %0 and %1"
-
-- id: raw_type_not_first
-  msg: "raw type %0 must appear first in the enum inheritance clause"
-
-- id: raw_type_not_literal_convertible
-  msg: "raw type %0 is not expressible by a string, integer, or floating-point literal"
-
-- id: enum_raw_type_not_equatable
-  msg: "RawRepresentable conformance cannot be synthesized because raw type %0 is not Equatable"
-
-- id: enum_raw_type_nonconforming_and_nonsynthable
-  msg: "%0 declares raw type %1, but does not conform to RawRepresentable and conformance could not be synthesized"
-
-- id: enum_declares_rawrep_with_raw_type
-  msg: "%0 declares raw type %1, which implies RawRepresentable"
-
-- id: enum_raw_type_access
-  msg: "enum %select{must be declared %select{%select{private|fileprivate|internal|%error|%error}1|private or fileprivate}3|cannot be declared %select{in this context|fileprivate|internal|public|open}1}0 because its raw type uses %select{a private|a fileprivate|an internal|%error|%error}2 type"
-
-- id: enum_raw_type_access_warn
-  msg: "enum %select{should be declared %select{private|fileprivate|internal|%error|%error}1|should not be declared %select{in this context|fileprivate|internal|public|open}1}0 because its raw type uses %select{a private|a fileprivate|an internal|%error|%error}2 type"
-
-- id: enum_raw_type_not_usable_from_inline
-  msg: "type referenced from the raw type of a '@usableFromInline' enum must be '@usableFromInline' or public"
-
-- id: enum_raw_type_not_usable_from_inline_warn
-  msg: "type referenced from the raw type of a '@usableFromInline' enum should be '@usableFromInline' or public"
-
-- id: empty_enum_raw_type
-  msg: "an enum with no cases cannot declare a raw type"
-
-- id: enum_raw_value_without_raw_type
-  msg: "enum case cannot have a raw value if the enum does not have a raw type"
-
-- id: enum_with_raw_type_case_with_argument
-  msg: "enum with raw type cannot have cases with arguments"
-
-- id: enum_raw_type_here
-  msg: "declared raw type %0 here"
-
-- id: objc_enum_no_raw_type
-  msg: "'@objc' enum must declare an integer raw type"
-
-- id: objc_enum_raw_type_not_integer
-  msg: "'@objc' enum raw type %0 is not an integer type"
-
-- id: enum_non_integer_raw_value_auto_increment
-  msg: "enum case must declare a raw value when the preceding raw value is not an integer"
-
-- id: enum_non_integer_convertible_raw_type_no_value
-  msg: "enum cases require explicit raw values when the raw type is not expressible by integer or string literal"
-
-- id: enum_raw_value_not_unique
-  msg: "raw value for enum case is not unique"
-
-- id: enum_raw_value_magic_literal
-  msg: "use of '%0' literal as raw value for enum case is not supported"
-
-- id: enum_raw_value_used_here
-  msg: "raw value previously used here"
-
-- id: enum_raw_value_incrementing_from_here
-  msg: "raw value auto-incremented from here"
-
-- id: enum_raw_value_incrementing_from_zero
-  msg: "raw value implicitly auto-incremented from zero"
-
-- id: construct_raw_representable_from_unwrapped_value
-  msg: "construct %0 from unwrapped %1 value"
-
-- id: decl_from_hidden_module
-  msg: "cannot use %0 %1 %select{here|as property wrapper here|in an extension with public or '@usableFromInline' members|in an extension with conditional conformances}2; %select{%3 has been imported as implementation-only|it is an SPI imported from %3|it is SPI}4"
-
-- id: decl_from_hidden_module_warn
-  msg: "cannot use %0 %1 %select{in SPI|as property wrapper in SPI|in an extension with public or '@usableFromInline' members|in an extension with conditional conformances}2; %select{%3 has been imported as implementation-only}4"
-
-- id: conformance_from_implementation_only_module
-  msg: "cannot use conformance of %0 to %1 %select{here|as property wrapper here|in an extension with public or '@usableFromInline' members|in an extension with conditional conformances}2; %3 has been imported as implementation-only"
-
-- id: assoc_conformance_from_implementation_only_module
-  msg: "cannot use conformance of %0 to %1 in associated type %3 (inferred as %4); %2 has been imported as implementation-only"
-
-- id: unexportable_clang_function_type
-  msg: "cannot export the underlying C type of the function type %0; it may use anonymous types or types defined outside of a module"
-
-- id: warn_implementation_only_conflict
-  msg: "%0 inconsistently imported as implementation-only"
-
-- id: implementation_only_conflict_here
-  msg: "imported as implementation-only here"
-
-- id: implementation_only_decl_non_override
-  msg: "'@_implementationOnly' can only be used on overrides"
-
-- id: implementation_only_override_changed_type
-  msg: "'@_implementationOnly' override must have the same type as the declaration it overrides (%0)"
-
-- id: implementation_only_override_without_attr
-  msg: "override of '@_implementationOnly' %0 should also be declared '@_implementationOnly'"
-
-- id: implementation_only_override_import_without_attr
-  msg: "override of %0 imported as implementation-only must be declared '@_implementationOnly'"
-
-- id: cannot_synthesize_init_in_extension_of_nonfinal
-  msg: "implementation of %0 for non-final class cannot be automatically synthesized in extension because initializer requirement %1 can only be satisfied by a 'required' initializer in the class definition"
-
-- id: cannot_synthesize_in_crossfile_extension
-  msg: "extension outside of file declaring %0 %1 prevents automatic synthesis of %2 for protocol %3"
-
-- id: broken_additive_arithmetic_requirement
-  msg: "AdditiveArithmetic protocol is broken: unexpected requirement"
-
-- id: broken_case_iterable_requirement
-  msg: "CaseIterable protocol is broken: unexpected requirement"
-
-- id: broken_raw_representable_requirement
-  msg: "RawRepresentable protocol is broken: unexpected requirement"
-
-- id: broken_comparable_requirement
-  msg: "Comparable protocol is broken: unexpected requirement"
-
-- id: broken_equatable_requirement
-  msg: "Equatable protocol is broken: unexpected requirement"
-
-- id: broken_hashable_requirement
-  msg: "Hashable protocol is broken: unexpected requirement"
-
-- id: broken_hashable_no_hasher
-  msg: "Hashable protocol is broken: Hasher type not found"
-
-- id: broken_errortype_requirement
-  msg: "Error protocol is broken: unexpected requirement"
-
-- id: broken_int_hashable_conformance
-  msg: "Int type is broken: does not conform to Hashable"
-
-- id: broken_int_integer_literal_convertible_conformance
-  msg: "Int type is broken: does not conform to ExpressibleByIntegerLiteral"
-
-- id: no_less_than_overload_for_int
-  msg: "no overload of '<' for Int"
-
-- id: no_equal_overload_for_int
-  msg: "no overload of '==' for Int"
-
-- id: broken_coding_key_requirement
-  msg: "CodingKey protocol is broken: unexpected requirement"
-
-- id: broken_encodable_requirement
-  msg: "Encodable protocol is broken: unexpected requirement"
-
-- id: broken_decodable_requirement
-  msg: "Decodable protocol is broken: unexpected requirement"
-
-- id: broken_differentiable_requirement
-  msg: "Differentiable protocol is broken: unexpected requirement"
-
-- id: differentiable_nondiff_type_implicit_noderivative_fixit
-  msg: "stored property %0 has no derivative because %1 does not conform to 'Differentiable'; add an explicit '@noDerivative' attribute%select{|, or conform %2 to 'AdditiveArithmetic'}3"
-
-- id: differentiable_immutable_wrapper_implicit_noderivative_fixit
-  msg: "synthesis of the 'Differentiable.move(along:)' requirement for %1 requires 'wrappedValue' in property wrapper %0 to be mutable; add an explicit '@noDerivative' attribute%select{|, or conform %1 to 'AdditiveArithmetic'}2"
-
-- id: differentiable_let_property_implicit_noderivative_fixit
-  msg: "synthesis of the 'Differentiable.move(along:)' requirement for %0 requires all stored properties not marked with `@noDerivative` to be mutable; use 'var' instead, or add an explicit '@noDerivative' attribute%select{|, or conform %0 to 'AdditiveArithmetic'}1"
-
-- id: codable_extraneous_codingkey_case_here
-  msg: "CodingKey case %0 does not match any stored properties"
-
-- id: codable_non_conforming_property_here
-  msg: "cannot automatically synthesize %0 because %1 does not conform to %0"
-
-- id: codable_non_decoded_property_here
-  msg: "cannot automatically synthesize %0 because %1 does not have a matching CodingKey and does not have a default value"
-
-- id: codable_codingkeys_type_is_not_an_enum_here
-  msg: "cannot automatically synthesize %0 because 'CodingKeys' is not an enum"
-
-- id: codable_codingkeys_type_does_not_conform_here
-  msg: "cannot automatically synthesize %0 because 'CodingKeys' does not conform to CodingKey"
-
-- id: decodable_no_super_init_here
-  msg: "cannot automatically synthesize %0 because superclass does not have a callable %1"
-
-- id: decodable_super_init_not_designated_here
-  msg: "cannot automatically synthesize %0 because implementation would need to call %1, which is not designated"
-
-- id: decodable_inaccessible_super_init_here
-  msg: "cannot automatically synthesize %0 because implementation would need to call %1, which is inaccessible due to '%select{private|fileprivate|internal|%error|%error}2' protection level"
-
-- id: decodable_super_init_is_failable_here
-  msg: "cannot automatically synthesize %0 because implementation would need to call %1, which is failable"
-
-- id: decodable_suggest_overriding_init_here
-  msg: "did you mean to override 'init(from:)'?"
-
-- id: codable_suggest_overriding_init_here
-  msg: "did you mean to override 'init(from:)' and 'encode(to:)'?"
-
-- id: decodable_property_will_not_be_decoded
-  msg: "immutable property will not be decoded because it is declared with an initial value which cannot be overwritten"
-
-- id: decodable_property_init_or_codingkeys_implicit
-  msg: "set the initial value via the initializer or explicitly define a CodingKeys enum %select{including|without}0 a %1 case to silence this warning"
-
-- id: decodable_property_init_or_codingkeys_explicit
-  msg: "set the initial value via the initializer or remove the %0 case from the CodingKeys enum to silence this warning"
-
-- id: decodable_make_property_mutable
-  msg: "make the property mutable instead"
-
-- id: missing_member_type_conformance_prevents_synthesis
-  msg: "%select{associated value|stored property}0 type %1 does not conform to protocol %2, preventing synthesized conformance of %3 to %2"
-
-- id: automatic_protocol_synthesis_unsupported
-  msg: "automatic synthesis of '%0' is not supported for %select{classes|structs}1"
-
-- id: comparable_synthesis_raw_value_not_allowed
-  msg: "enum declares raw type %0, preventing synthesized conformance of %1 to %2"
-
-- id: dynamic_self_non_method
-  msg: "%select{global|local}0 function cannot return 'Self'"
-
-- id: dynamic_self_invalid
-  msg: "covariant 'Self' can only appear as the type of a property, subscript or method result; did you mean '%0'?"
-
-- id: dynamic_self_in_mutable_property
-  msg: "mutable property cannot have covariant 'Self' type"
-
-- id: dynamic_self_in_stored_property
-  msg: "stored property cannot have covariant 'Self' type"
-
-- id: dynamic_self_in_mutable_subscript
-  msg: "mutable subscript cannot have covariant 'Self' type"
-
-- id: dynamic_self_invalid_property
-  msg: "covariant 'Self' can only appear at the top level of property type"
-
-- id: dynamic_self_invalid_subscript
-  msg: "covariant 'Self' can only appear at the top level of subscript element type"
-
-- id: dynamic_self_invalid_method
-  msg: "covariant 'Self' can only appear at the top level of method result type"
-
-- id: dynamic_self_stored_property_init
-  msg: "covariant 'Self' type cannot be referenced from a stored property initializer"
-
-- id: dynamic_self_default_arg
-  msg: "covariant 'Self' type cannot be referenced from a default argument expression"
-
-- id: attr_only_one_decl_kind
-  msg: "%0 may only be used on '%1' declarations"
-
-- id: attr_not_on_variadic_parameters
-  msg: "'%0' must not be used on variadic parameters"
-
-- id: attr_not_on_subscript_parameters
-  msg: "'%0' must not be used on subscript parameters"
-
-- id: attr_ambiguous_reference_to_decl
-  msg: "ambiguous reference to %0 in '@%1' attribute"
-
-- id: override_final
-  msg: "%0 overrides a 'final' %1"
-
-- id: override_static
-  msg: "cannot override %0"
-
-- id: member_cannot_be_final
-  msg: "only classes and class members may be marked with 'final'"
-
-- id: final_not_allowed_here
-  msg: "'final' may only be applied to classes, properties, methods, and subscripts"
-
-- id: final_not_on_accessors
-  msg: "'final' cannot be applied to accessors, it must be put on the %select{var|let|subscript}0"
-
-- id: override_rethrows_with_non_rethrows
-  msg: "override of 'rethrows' %select{method|initializer}0 should also be 'rethrows'"
-
-- id: rethrows_without_throwing_parameter
-  msg: "'rethrows' function must take a throwing function argument"
-
-- id: autoclosure_function_type
-  msg: "@autoclosure attribute only applies to function types"
-
-- id: invalid_autoclosure_and_convention_attributes
-  msg: "'@convention(%0)' attribute is not allowed on '@autoclosure' types"
-
-- id: autoclosure_function_input_nonunit
-  msg: "argument type of @autoclosure parameter must be '()'"
-
-- id: escaping_non_function_parameter
-  msg: "@escaping attribute may only be used in function parameter position"
-
-- id: escaping_optional_type_argument
-  msg: "closure is already escaping in optional type argument"
-
-- id: non_ephemeral_non_pointer_type
-  msg: "@_nonEphemeral attribute only applies to pointer types"
-
-- id: attr_NSManaged_not_instance_member
-  msg: "@NSManaged only allowed on an instance property or method"
-
-- id: attr_NSManaged_not_stored
-  msg: "@NSManaged not allowed on %select{computed|observing|addressed}0 properties"
-
-- id: attr_NSManaged_let_property
-  msg: "@NSManaged not allowed on a 'let' property"
-
-- id: attr_NSManaged_initial_value
-  msg: "@NSManaged property cannot have an initial value"
-
-- id: attr_NSManaged_NSCopying
-  msg: "@NSManaged property cannot also be marked @NSCopying"
-
-- id: attr_NSManaged_method_body
-  msg: "@NSManaged method cannot have a body; it must be provided at runtime"
-
-- id: nscopying_only_on_class_properties
-  msg: "@NSCopying may only be used on properties in classes"
-
-- id: nscopying_only_mutable
-  msg: "@NSCopying requires property to be mutable"
-
-- id: nscopying_only_stored_property
-  msg: "@NSCopying is only valid on stored properties"
-
-- id: nscopying_doesnt_conform
-  msg: "@NSCopying is only valid with types that conform to the NSCopying protocol"
-
-- id: attr_ApplicationMain_not_ApplicationDelegate
-  msg: "%select{'UIApplicationMain'|'NSApplicationMain'|'main'}0 class must conform to the %select{'UIApplicationDelegate'|'NSApplicationDelegate'}0 protocol"
-
-- id: attr_generic_ApplicationMain_not_supported
-  msg: "generic %select{'UIApplicationMain'|'NSApplicationMain'|'main'}0 %select{classes|classes|types}0 are not supported"
-
-- id: attr_ApplicationMain_multiple
-  msg: "%select{'UIApplicationMain'|'NSApplicationMain'|'main'}0 attribute can only apply to one %select{class|class|type}0 in a module"
-
-- id: attr_ApplicationMain_with_script
-  msg: "%select{'UIApplicationMain'|'NSApplicationMain'|'main'}0 attribute cannot be used in a module that contains top-level code"
-
-- id: attr_ApplicationMain_script_here
-  msg: "top-level code defined in this source file"
-
-- id: attr_MainType_without_main
-  msg: "%0 is annotated with @main and must provide a main static function of type () -> Void or () throws -> Void."
-
-- id: lazy_not_on_let
-  msg: "'lazy' cannot be used on a let"
-
-- id: lazy_not_on_computed
-  msg: "'lazy' must not be used on a computed property"
-
-- id: lazy_on_already_lazy_global
-  msg: "'lazy' must not be used on an already-lazy global"
-
-- id: lazy_not_in_protocol
-  msg: "'lazy' isn't allowed on a protocol requirement"
-
-- id: lazy_requires_initializer
-  msg: "lazy properties must have an initializer"
-
-- id: lazy_requires_single_var
-  msg: "'lazy' cannot destructure an initializer"
-
-- id: lazy_must_be_property
-  msg: "lazy is only valid for members of a struct or class"
-
-- id: lazy_not_strong
-  msg: "lazy properties cannot be %0"
-
-- id: lazy_var_storage_access
-  msg: "access to the underlying storage of a lazy property is not allowed"
-
-- id: attr_for_debugger_support_only
-  msg: "@LLDBDebuggerSupport may only be used when debugger support is on"
-
-- id: implements_attr_protocol_lacks_member
-  msg: "protocol %0 has no member %1"
-
-- id: implements_attr_non_protocol_type
-  msg: "non-protocol type in @_implements attribute"
-
-- id: implements_attr_protocol_not_conformed_to
-  msg: "containing type %0 does not conform to protocol %1"
-
-- id: differentiable_attr_no_vjp_or_jvp_when_linear
-  msg: "cannot specify 'vjp:' or 'jvp:' for linear functions; use '@transpose' attribute for transpose registration instead"
-
-- id: differentiable_attr_overload_not_found
-  msg: "%0 does not have expected type %1"
-
-- id: differentiable_attr_duplicate
-  msg: "duplicate '@differentiable' attribute with same parameters"
-
-- id: differentiable_attr_duplicate_note
-  msg: "other attribute declared here"
-
-- id: differentiable_attr_function_not_same_type_context
-  msg: "%0 is not defined in the current type context"
-
-- id: differentiable_attr_derivative_not_function
-  msg: "registered derivative %0 must be a 'func' declaration"
-
-- id: differentiable_attr_class_derivative_not_final
-  msg: "class member derivative must be final"
-
-- id: differentiable_attr_invalid_access
-  msg: "derivative function %0 is required to either be public or '@usableFromInline' because the original function %1 is public or '@usableFromInline'"
-
-- id: differentiable_attr_protocol_req_where_clause
-  msg: "'@differentiable' attribute on protocol requirement cannot specify 'where' clause"
-
-- id: differentiable_attr_class_member_dynamic_self_result_unsupported
-  msg: "'@differentiable' attribute cannot be declared on class members returning 'Self'"
-
-- id: differentiable_attr_nonfinal_class_init_unsupported
-  msg: "'@differentiable' attribute cannot be declared on 'init' in a non-final class; consider making %0 final"
-
-- id: differentiable_attr_empty_where_clause
-  msg: "empty 'where' clause in '@differentiable' attribute"
-
-- id: differentiable_attr_where_clause_for_nongeneric_original
-  msg: "'where' clause is valid only when original function is generic %0"
-
-- id: differentiable_attr_layout_req_unsupported
-  msg: "'@differentiable' attribute does not yet support layout requirements"
-
-- id: overriding_decl_missing_differentiable_attr
-  msg: "overriding declaration is missing attribute '%0'"
-
-- id: protocol_witness_missing_differentiable_attr
-  msg: "candidate is missing attribute '%0'"
-
-- id: protocol_witness_missing_differentiable_attr_nonpublic_other_file
-  msg: "non-public %1 %2 must have explicit '%0' attribute to satisfy requirement %3 %4 (in protocol %6) because it is declared in a different file than the conformance of %5 to %6"
-
-- id: derivative_attr_expected_result_tuple
-  msg: "'@derivative(of:)' attribute requires function to return a two-element tuple; first element must have label 'value:' and second element must have label 'pullback:' or 'differential:'"
-
-- id: derivative_attr_invalid_result_tuple_value_label
-  msg: "'@derivative(of:)' attribute requires function to return a two-element tuple; first element must have label 'value:'"
-
-- id: derivative_attr_invalid_result_tuple_func_label
-  msg: "'@derivative(of:)' attribute requires function to return a two-element tuple; second element must have label 'pullback:' or 'differential:'"
-
-- id: derivative_attr_result_value_not_differentiable
-  msg: "'@derivative(of:)' attribute requires function to return a two-element tuple; first element type %0 must conform to 'Differentiable'"
-
-- id: derivative_attr_result_func_type_mismatch
-  msg: "function result's %0 type does not match %1"
-
-- id: derivative_attr_result_func_type_mismatch_note
-  msg: "%0 does not have expected type %1"
-
-- id: derivative_attr_result_func_original_note
-  msg: "%0 defined here"
-
-- id: derivative_attr_not_in_same_file_as_original
-  msg: "derivative not in the same file as the original function"
-
-- id: derivative_attr_original_stored_property_unsupported
-  msg: "cannot register derivative for stored property %0"
-
-- id: derivative_attr_class_member_dynamic_self_result_unsupported
-  msg: "cannot register derivative for class member %0 returning 'Self'"
-
-- id: derivative_attr_nonfinal_class_init_unsupported
-  msg: "cannot register derivative for 'init' in a non-final class; consider making %0 final"
-
-- id: derivative_attr_unsupported_accessor_kind
-  msg: "cannot register derivative for %0"
-
-- id: derivative_attr_class_setter_unsupported
-  msg: "cannot yet register derivative for class property or subscript setters"
-
-- id: derivative_attr_protocol_requirement_unsupported
-  msg: "cannot yet register derivative default implementation for protocol requirements"
-
-- id: derivative_attr_original_already_has_derivative
-  msg: "a derivative already exists for %0"
-
-- id: derivative_attr_duplicate_note
-  msg: "other attribute declared here"
-
-- id: derivative_attr_access_level_mismatch
-  msg: "derivative function must have same access level as original function; derivative function %2 is %select{private|fileprivate|internal|public|open}3, but original function %0 is %select{private|fileprivate|internal|public|open}1"
-
-- id: derivative_attr_fix_access
-  msg: "mark the derivative function as '%select{private|fileprivate|internal|@usableFromInline|@usableFromInline}0' to match the original function"
-
-- id: transpose_attr_invalid_linearity_parameter_or_result
-  msg: "cannot transpose with respect to original %select{result|parameter}1 '%0' that does not conform to 'Differentiable' and satisfy '%0 == %0.TangentVector'"
-
-- id: transpose_attr_overload_not_found
-  msg: "could not find function %0 with expected type %1"
-
-- id: transpose_attr_cannot_use_named_wrt_params
-  msg: "cannot use named 'wrt' parameters in '@transpose(of:)' attribute, found %0"
-
-- id: transpose_attr_wrt_self_must_be_static
-  msg: "the transpose of an instance method must be a 'static' method in the same type when 'self' is a linearity parameter"
-
-- id: transpose_attr_wrt_self_self_type_mismatch_note
-  msg: "the transpose is declared in %0 but the original function is declared in %1"
-
-- id: autodiff_attr_original_decl_ambiguous
-  msg: "referenced declaration %0 is ambiguous"
-
-- id: autodiff_attr_original_decl_ambiguous_candidate
-  msg: "candidate %0 found here"
-
-- id: autodiff_attr_original_decl_none_valid
-  msg: "referenced declaration %0 could not be resolved"
-
-- id: autodiff_attr_original_decl_invalid_kind
-  msg: "candidate %0 is not a 'func', 'init', 'subscript', or 'var' computed property declaration"
-
-- id: autodiff_attr_original_decl_missing_accessor
-  msg: "candidate %0 does not have a %1"
-
-- id: autodiff_attr_original_decl_type_mismatch
-  msg: "candidate %0 does not have %select{expected type|type equal to or less constrained than}2 %1"
-
-- id: autodiff_attr_original_decl_not_same_type_context
-  msg: "candidate %0 is not defined in the current type context"
-
-- id: autodiff_attr_original_void_result
-  msg: "cannot differentiate void function %0"
-
-- id: autodiff_attr_original_multiple_semantic_results
-  msg: "cannot differentiate functions with both an 'inout' parameter and a result"
-
-- id: autodiff_attr_result_not_differentiable
-  msg: "can only differentiate functions with results that conform to 'Differentiable', but %0 does not conform to 'Differentiable'"
-
-- id: autodiff_attr_opaque_result_type_unsupported
-  msg: "cannot differentiate functions returning opaque result types"
-
-- id: diff_function_no_parameters
-  msg: "%0 has no parameters to differentiate with respect to"
-
-- id: diff_params_clause_param_name_unknown
-  msg: "unknown parameter name %0"
-
-- id: diff_params_clause_self_instance_method_only
-  msg: "'self' parameter is only applicable to instance methods"
-
-- id: diff_params_clause_self_must_be_first
-  msg: "'self' parameter must come first in the parameter list"
-
-- id: diff_params_clause_params_not_original_order
-  msg: "parameters must be specified in original order"
-
-- id: diff_params_clause_param_index_out_of_range
-  msg: "parameter index is larger than total number of parameters"
-
-- id: diff_params_clause_no_inferred_parameters
-  msg: "no differentiation parameters could be inferred; must differentiate with respect to at least one parameter conforming to 'Differentiable'"
-
-- id: diff_params_clause_cannot_diff_wrt_inout_parameter
-  msg: "cannot differentiate with respect to 'inout' parameter (%0)"
-
-- id: diff_params_clause_param_not_differentiable
-  msg: "can only differentiate with respect to parameters that conform to 'Differentiable', but %0 does not conform to 'Differentiable'"
-
-- id: found_candidate
-  msg: "found this candidate"
-
-- id: found_candidate_type
-  msg: "found candidate with type %0"
-
-- id: no_MaxBuiltinFloatType_found
-  msg: "standard library error: _MaxBuiltinFloatType is not properly defined"
-
-- id: no_member_of_module
-  msg: "module %0 has no member named %1"
-
-- id: super_with_no_base_class
-  msg: "'super' members cannot be referenced in a root class"
-
-- id: bad_init_ref_base
-  msg: "'init' can only refer to the initializers of 'self'%select{| or 'super'}0"
-
-- id: init_delegation_outside_initializer
-  msg: "initializer delegation can only occur within an initializer"
-
-- id: init_delegates_and_chains
-  msg: "initializer cannot both delegate ('self.init') and chain to a superclass initializer ('super.init')"
-
-- id: init_delegation_or_chain
-  msg: "previous %select{delegation|chaining}0 call is here"
-
-- id: delegating_convenience_super_init
-  msg: "convenience initializer for %0 must delegate (with 'self.init') rather than chaining to a superclass initializer (with 'super.init')"
-
-- id: delegating_designated_init
-  msg: "designated initializer for %0 cannot delegate (with 'self.init'); did you mean this to be a convenience initializer?"
-
-- id: delegating_designated_init_in_extension
-  msg: "designated initializer for %0 cannot delegate (with 'self.init')"
-
-- id: delegation_here
-  msg: "delegation occurs here"
-
-- id: chain_convenience_init
-  msg: "must call a designated initializer of the superclass %0"
-
-- id: delegate_chain_nonoptional_to_optional
-  msg: "a non-failable initializer cannot %select{delegate|chain}0 to failable initializer %1 written with 'init?'"
-
-- id: init_force_unwrap
-  msg: "force potentially-failing result with '!'"
-
-- id: init_propagate_failure
-  msg: "propagate the failure with 'init?'"
-
-- id: delegate_chain_nonoptional_to_optional_try
-  msg: "a non-failable initializer cannot use 'try?' to %select{delegate|chain}0 to another initializer"
-
-- id: init_delegate_force_try
-  msg: "force potentially-failing result with 'try!'"
-
-- id: init_delegation_nested
-  msg: "%select{initializer delegation ('self.init')|initializer chaining ('super.init')}0 cannot be nested in another %select{expression|statement}1"
-
-- id: convenience_init_here
-  msg: "convenience initializer is declared here"
-
-- id: designated_init_in_extension
-  msg: "designated initializer cannot be declared in an extension of %0; did you mean this to be a convenience initializer?"
-
-- id: cfclass_designated_init_in_extension
-  msg: "designated initializer cannot be declared in an extension of %0"
-
-- id: enumstruct_convenience_init
-  msg: "delegating initializers in %0 are not marked with 'convenience'"
-
-- id: nonclass_convenience_init
-  msg: "convenience initializer not allowed in non-class type %0"
-
-- id: cfclass_convenience_init
-  msg: "convenience initializers are not supported in extensions of CF types"
-
-- id: dynamic_construct_class
-  msg: "constructing an object of class type %0 with a metatype value must use a 'required' initializer"
-
-- id: note_nonrequired_initializer
-  msg: "selected %select{non-required|implicit}0 initializer %1"
-
-- id: construct_protocol_value
-  msg: "value of type %0 is a protocol; it cannot be instantiated"
-
-- id: construct_protocol_by_name
-  msg: "protocol type %0 cannot be instantiated"
-
-- id: unknown_binop
-  msg: "operator is not a known binary operator"
-
-- id: non_associative_adjacent_operators
-  msg: "adjacent operators are in non-associative precedence group %0"
-
-- id: unordered_adjacent_operators
-  msg: "adjacent operators are in unordered precedence groups %0 and %1"
-
-- id: missing_builtin_precedence_group
-  msg: "broken standard library: missing builtin precedence group %0"
-
-- id: try_rhs
-  msg: "'%select{try|try!|try?|await}0' cannot appear to the right of a non-assignment operator"
-
-- id: try_if_rhs_noncovering
-  msg: "'%select{try|try!|try?|await}0' following conditional operator does not cover everything to its right"
-
-- id: try_assign_rhs_noncovering
-  msg: "'%select{try|try!|try?|await}0' following assignment operator does not cover everything to its right"
-
-- id: broken_bool
-  msg: "type 'Bool' is broken"
-
-- id: inject_forced_downcast
-  msg: "treating a forced downcast to %0 as optional will never produce 'nil'"
-
-- id: forced_to_conditional_downcast
-  msg: "use 'as?' to perform a conditional downcast to %0"
-
-- id: silence_inject_forced_downcast
-  msg: "add parentheses around the cast to silence this warning"
-
-- id: conditional_downcast_foreign
-  msg: "conditional downcast to CoreFoundation type %0 will always succeed"
-
-- id: note_explicitly_compare_cftypeid
-  msg: "did you mean to explicitly compare the CFTypeIDs of %0 and %1?"
-
-- id: optional_used_as_boolean
-  msg: "optional type %0 cannot be used as a boolean; test for '%select{!|=}1= nil' instead"
-
-- id: integer_used_as_boolean
-  msg: "type %0 cannot be used as a boolean; test for '%select{!|=}1= 0' instead"
-
-- id: interpolation_missing_proto
-  msg: "string interpolation requires the protocol 'ExpressibleByStringInterpolation' to be defined"
-
-- id: interpolation_broken_proto
-  msg: "protocol 'ExpressibleByStringInterpolation' is broken"
-
-- id: object_literal_broken_proto
-  msg: "object literal protocol is broken"
-
-- id: discard_expr_outside_of_assignment
-  msg: "'_' can only appear in a pattern or on the left side of an assignment"
-
-- id: discard_expr_void_result_redundant
-  msg: "using '_' to ignore the result of a Void-returning function is redundant"
-
-- id: collection_literal_heterogeneous
-  msg: "heterogeneous collection literal could only be inferred to %0; add explicit type annotation if this is intentional"
-
-- id: collection_literal_empty
-  msg: "empty collection literal requires an explicit type"
-
-- id: unresolved_member_no_inference
-  msg: "reference to member %0 cannot be resolved without a contextual type"
-
-- id: cannot_infer_base_of_unresolved_member
-  msg: "cannot infer contextual base in reference to member %0"
-
-- id: unresolved_nil_literal
-  msg: "'nil' requires a contextual type"
-
-- id: cannot_force_unwrap_nil_literal
-  msg: "'nil' literal cannot be force unwrapped"
-
-- id: type_of_expression_is_ambiguous
-  msg: "type of expression is ambiguous without more context"
-
-- id: failed_to_produce_diagnostic
-  msg: "failed to produce diagnostic for expression; please file a bug report"
-
-- id: missing_protocol
-  msg: "missing protocol %0"
-
-- id: nil_literal_broken_proto
-  msg: "protocol 'ExpressibleByNilLiteral' is broken"
-
-- id: builtin_integer_literal_broken_proto
-  msg: "protocol '_ExpressibleByBuiltinIntegerLiteral' is broken"
-
-- id: integer_literal_broken_proto
-  msg: "protocol 'ExpressibleByIntegerLiteral' is broken"
-
-- id: builtin_float_literal_broken_proto
-  msg: "protocol '_ExpressibleByBuiltinFloatLiteral' is broken"
-
-- id: float_literal_broken_proto
-  msg: "protocol 'ExpressibleByFloatLiteral' is broken"
-
-- id: builtin_boolean_literal_broken_proto
-  msg: "protocol '_ExpressibleByBuiltinBooleanLiteral' is broken"
-
-- id: boolean_literal_broken_proto
-  msg: "protocol 'ExpressibleByBooleanLiteral' is broken"
-
-- id: builtin_unicode_scalar_literal_broken_proto
-  msg: "protocol '_ExpressibleByBuiltinUnicodeScalarLiteral' is broken"
-
-- id: unicode_scalar_literal_broken_proto
-  msg: "protocol 'ExpressibleByUnicodeScalarLiteral' is broken"
-
-- id: builtin_extended_grapheme_cluster_literal_broken_proto
-  msg: "protocol '_ExpressibleByBuiltinExtendedGraphemeClusterLiteral' is broken"
-
-- id: extended_grapheme_cluster_literal_broken_proto
-  msg: "protocol 'ExpressibleByExtendedGraphemeClusterLiteral' is broken"
-
-- id: builtin_string_literal_broken_proto
-  msg: "protocol '_ExpressibleByBuiltinStringLiteral' is broken"
-
-- id: string_literal_broken_proto
-  msg: "protocol 'ExpressibleByStringLiteral' is broken"
-
-- id: should_use_dictionary_literal
-  msg: "dictionary of type %0 cannot be %select{used|initialized}1 with array literal"
-
-- id: meant_dictionary_lit
-  msg: "did you mean to use a dictionary literal instead?"
-
-- id: should_use_empty_dictionary_literal
-  msg: "use [:] to get an empty dictionary literal"
-
-- id: type_is_not_dictionary
-  msg: "contextual type %0 cannot be used with dictionary literal"
-
-- id: cannot_explicitly_specialize_generic_function
-  msg: "cannot explicitly specialize a generic function"
-
-- id: not_a_generic_definition
-  msg: "cannot specialize a non-generic definition"
-
-- id: not_a_generic_type
-  msg: "cannot specialize non-generic type %0"
-
-- id: type_parameter_count_mismatch
-  msg: "generic type %0 specialized with %select{too many|too few}3 type parameters (got %2, but expected %1)"
-
-- id: generic_type_requires_arguments
-  msg: "reference to generic type %0 requires arguments in <...>"
-
-- id: descriptive_generic_type_declared_here
-  msg: "%0 declared here"
-
-- id: use_of_void_pointer
-  msg: "Unsafe%0Pointer<Void> has been replaced by Unsafe%0RawPointer"
-
-- id: ambiguous_decl_ref
-  msg: "ambiguous use of %0"
-
-- id: ambiguous_operator_ref
-  msg: "ambiguous use of operator %0"
-
-- id: ambiguous_because_of_trailing_closure
-  msg: "%select{use an explicit argument label instead of a trailing closure|avoid using a trailing closure}0 to call %1"
-
-- id: partial_application_of_function_invalid
-  msg: "partial application of %select{'mutating' method|'super.init' initializer chain|'self.init' initializer delegation|'super' instance method with metatype base}0 is not allowed"
-
-- id: partial_application_of_function_invalid_swift4
-  msg: "partial application of %select{'mutating' method|'super.init' initializer chain|'self.init' initializer delegation|'super' instance method with metatype base}0 is not allowed; calling the function has undefined behavior and will be an error in future Swift versions"
-
-- id: self_assignment_var
-  msg: "assigning a variable to itself"
-
-- id: self_assignment_prop
-  msg: "assigning a property to itself"
-
-- id: property_use_in_closure_without_explicit_self
-  msg: "reference to property %0 in closure requires explicit use of 'self' to make capture semantics explicit"
-
-- id: method_call_in_closure_without_explicit_self
-  msg: "call to method %0 in closure requires explicit use of 'self' to make capture semantics explicit"
-
-- id: note_capture_self_explicitly
-  msg: "capture 'self' explicitly to enable implicit 'self' in this closure"
-
-- id: note_reference_self_explicitly
-  msg: "reference 'self.' explicitly"
-
-- id: note_other_self_capture
-  msg: "variable other than 'self' captured here under the name 'self' does not enable implicit 'self'"
-
-- id: note_self_captured_weakly
-  msg: "weak capture of 'self' here does not enable implicit 'self'"
-
-- id: implicit_use_of_self_in_closure
-  msg: "implicit use of 'self' in closure; use 'self.' to make capture semantics explicit"
-
-- id: recursive_accessor_reference
-  msg: "attempting to %select{access|modify}1 %0 within its own %select{getter|setter}1"
-
-- id: recursive_accessor_reference_silence
-  msg: "access 'self' explicitly to silence this warning"
-
-- id: store_in_willset
-  msg: "attempting to store to property %0 within its own willSet, which is about to be overwritten by the new value"
-
-- id: value_of_module_type
-  msg: "expected module member name after module name"
-
-- id: value_of_metatype_type
-  msg: "expected member name or constructor call after type name"
-
-- id: add_parens_to_type
-  msg: "add arguments after the type to construct a value of the type"
-
-- id: add_self_to_type
-  msg: "use '.self' to reference the type object"
-
-- id: warn_unqualified_access
-  msg: "use of %0 treated as a reference to %1 in %2 %3"
-
-- id: fix_unqualified_access_member
-  msg: "use 'self.' to silence this warning"
-
-- id: fix_unqualified_access_top_level
-  msg: "use '%0' to reference the %1"
-
-- id: fix_unqualified_access_top_level_multi
-  msg: "use '%0' to reference the %1 in module %2"
-
-- id: warn_deprecated_conditional_conformance_outer_access
-  msg: "use of %0 as reference to %1 in %2 %3 will change in future versions of Swift to reference %4 in %5 %6 which comes via a conditional conformance"
-
-- id: fix_deprecated_conditional_conformance_outer_access
-  msg: "use '%0' to continue to reference the %1"
-
-- id: unsupported_special_decl_ref
-  msg: "referencing %0 as a function value is not implemented"
-
-- id: bitcasting_away_noescape
-  msg: "'unsafeBitCast' from non-escaping function type %0 to escaping function type %1 is undefined; use 'withoutActuallyEscaping' to temporarily escape a function"
-
-- id: bitcasting_to_change_function_rep
-  msg: "'unsafeBitCast' from function type %0 to %1 changes @convention and is undefined; use an implicit conversion to change conventions"
-
-- id: bitcasting_to_downcast
-  msg: "'unsafeBitCast' from %0 to %1 can be replaced with 'unsafeDowncast'"
-
-- id: bitcasting_is_no_op
-  msg: "'unsafeBitCast' from %0 to %1 is unnecessary and can be removed"
-
-- id: bitcasting_to_change_pointer_kind
-  msg: "'unsafeBitCast' from %0 to %1 can be replaced with %2 initializer"
-
-- id: bitcasting_to_change_pointee_type
-  msg: "'unsafeBitCast' from %0 to %1 changes pointee type and may lead to undefined behavior; use the 'withMemoryRebound' method on %0 to rebind the type of memory"
-
-- id: bitcasting_to_give_type_to_raw_pointer
-  msg: "'unsafeBitCast' from %0 to %1 gives a type to a raw pointer and may lead to undefined behavior"
-
-- id: bitcast_assume_memory_rebound
-  msg: "use the 'assumingMemoryBound' method if the pointer is known to point to an existing value or array of type %0 in memory"
-
-- id: bitcast_bind_memory
-  msg: "use the 'bindMemory' method to assign type %0 to uninitialized raw memory"
-
-- id: bitcasting_for_number_bit_pattern_init
-  msg: "'unsafeBitCast' from %0 to %1 can be replaced with 'bitPattern:' initializer on %1"
-
-- id: bitcasting_for_number_bit_pattern_property
-  msg: "'unsafeBitCast' from %0 to %1 can be replaced with 'bitPattern' property on %0"
-
-- id: bitcasting_to_change_from_unsized_to_sized_int
-  msg: "'unsafeBitCast' from %0 to %1 can be replaced with %1 initializer"
-
-- id: use_of_qq_on_non_optional_value
-  msg: "left side of nil coalescing operator '??' has non-optional type %0, so the right side is never used"
-
-- id: nonoptional_compare_to_nil
-  msg: "comparing non-optional value of type %0 to 'nil' always returns %select{false|true}1"
-
-- id: optional_check_nonoptional
-  msg: "non-optional expression of type %0 used in a check for optionals"
-
-- id: optional_check_promotion
-  msg: "explicitly specified type %0 adds an additional level of optional to the initializer, making the optional check always succeed"
-
-- id: optional_pattern_match_promotion
-  msg: "pattern match introduces an implicit promotion from %0 to %1"
-
-- id: optional_to_any_coercion
-  msg: "expression implicitly coerced from %0 to %1"
-
-- id: iuo_to_any_coercion
-  msg: "coercion of implicitly unwrappable value of type %0 to %1 does not unwrap optional"
-
-- id: iuo_to_any_coercion_note
-  msg: "implicitly unwrapped %0 %1 declared here"
-
-- id: iuo_to_any_coercion_note_func_result
-  msg: "%0 %1 with implicitly unwrapped result type is declared here"
-
-- id: default_optional_to_any
-  msg: "provide a default value to avoid this warning"
-
-- id: force_optional_to_any
-  msg: "force-unwrap the value to avoid this warning"
-
-- id: silence_optional_to_any
-  msg: "explicitly cast to %0 with '%1' to silence this warning"
-
-- id: debug_description_in_string_interpolation_segment
-  msg: "string interpolation produces a debug description for %select{an optional|a function}0 value; did you mean to make this explicit?"
-
-- id: silence_debug_description_in_interpolation_segment_call
-  msg: "use 'String(describing:)' to silence this warning"
-
-- id: noescape_parameter
-  msg: "parameter %0 is implicitly non-escaping"
-
-- id: generic_parameters_always_escaping
-  msg: "generic parameters are always considered '@escaping'"
-
-- id: passing_noescape_to_escaping
-  msg: "passing non-escaping parameter %0 to function expecting an @escaping closure"
-
-- id: converting_noespace_param_to_generic_type
-  msg: "converting non-escaping parameter %0 to generic parameter %1 may allow it to escape"
-
-- id: assigning_noescape_to_escaping
-  msg: "assigning non-escaping parameter %0 to an @escaping closure"
-
-- id: general_noescape_to_escaping
-  msg: "using non-escaping parameter %0 in a context expecting an @escaping closure"
-
-- id: converting_noescape_to_type
-  msg: "converting non-escaping value to %0 may allow it to escape"
-
-- id: capture_across_type_decl
-  msg: "%0 declaration cannot close over value %1 defined in outer scope"
-
-- id: jump_out_of_defer
-  msg: "'%0' cannot transfer control out of a defer statement"
-
-- id: defer_stmt_at_block_end
-  msg: "'defer' statement at end of scope always executes immediately; replace with 'do' statement to silence this warning"
-
-- id: return_invalid_outside_func
-  msg: "return invalid outside of a func"
-
-- id: return_expr_missing
-  msg: "non-void function should return a value"
-
-- id: return_non_failable_init
-  msg: "only a failable initializer can return 'nil'"
-
-- id: make_init_failable
-  msg: "use 'init?' to make the initializer %0 failable"
-
-- id: return_init_non_nil
-  msg: "'nil' is the only return value permitted in an initializer"
-
-- id: if_always_true
-  msg: "'if' condition is always true"
-
-- id: while_always_true
-  msg: "'while' condition is always true"
-
-- id: guard_always_succeeds
-  msg: "'guard' condition is always true, body is unreachable"
-
-- id: expression_unused_closure
-  msg: "closure expression is unused"
-
-- id: expression_unused_function
-  msg: "expression resolves to an unused function"
-
-- id: expression_unused_lvalue
-  msg: "expression resolves to an unused %select{variable|property|subscript}0"
-
-- id: expression_unused_result_call
-  msg: "result of call to %0 is unused"
-
-- id: expression_unused_result_operator
-  msg: "result of operator %0 is unused"
-
-- id: expression_unused_result_unknown
-  msg: "result of call to %select{function|closure}0 returning %1 is unused"
-
-- id: expression_unused_result
-  msg: "expression of type %0 is unused"
-
-- id: expression_unused_init_result
-  msg: "result of %0 initializer is unused"
-
-- id: expression_unused_optional_try
-  msg: "result of 'try?' is unused"
-
-- id: expression_unused_selector_result
-  msg: "result of '#selector' is unused"
-
-- id: expression_unused_literal
-  msg: "%0 literal is unused"
-
-- id: assignment_lhs_not_lvalue
-  msg: "cannot assign to immutable expression of type %0"
-
-- id: assignment_lhs_is_apply_expression
-  msg: "expression is not assignable: %0"
-
-- id: assignment_lhs_is_immutable_variable
-  msg: "cannot assign to value: %0"
-
-- id: assignment_lhs_is_immutable_property
-  msg: "cannot assign to property: %0"
-
-- id: assignment_subscript_has_immutable_base
-  msg: "cannot assign through subscript: %0"
-
-- id: assignment_dynamic_property_has_immutable_base
-  msg: "cannot assign through dynamic lookup property: %0"
-
-- id: assignment_bang_has_immutable_subcomponent
-  msg: "cannot assign through '!': %0"
-
-- id: candidate_is_not_assignable
-  msg: "candidate is not assignable: %0 %1"
-
-- id: change_to_mutating
-  msg: "mark %select{method|accessor}0 'mutating' to make 'self' mutable"
-
-- id: masked_mutable_property
-  msg: "add explicit '%0' to refer to mutable %1 of %2"
-
-- id: assignment_let_property_delegating_init
-  msg: "'let' property %0 may not be initialized directly; use \"self.init(...)\" or \"self = ...\" instead"
-
-- id: label_shadowed
-  msg: "label %0 cannot be reused on an inner statement"
-
-- id: break_outside_loop
-  msg: "'break' is only allowed inside a loop, if, do, or switch"
-
-- id: unlabeled_break_outside_loop
-  msg: "unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if or do"
-
-- id: continue_outside_loop
-  msg: "'continue' is only allowed inside a loop"
-
-- id: continue_not_in_this_stmt
-  msg: "'continue' cannot be used with %0 statements"
-
-- id: unresolved_label
-  msg: "cannot find label %0 in scope"
-
-- id: unresolved_label_corrected
-  msg: "cannot find label %0 in scope; did you mean %1?"
-
-- id: foreach_sequence_does_not_conform_to_expected_protocol
-  msg: "for-in loop requires %0 to conform to %1%select{|; did you mean to unwrap optional?}2"
-
-- id: no_match_operator
-  msg: "no binary '~=' operator available for 'switch' statement"
-
-- id: fallthrough_outside_switch
-  msg: "'fallthrough' is only allowed inside a switch"
-
-- id: fallthrough_from_last_case
-  msg: "'fallthrough' without a following 'case' or 'default' block"
-
-- id: fallthrough_into_case_with_var_binding
-  msg: "'fallthrough' from a case which doesn't bind variable %0"
-
-- id: unnecessary_cast_over_optionset
-  msg: "unnecessary cast over raw value of %0"
-
-- id: mutability_mismatch_multiple_pattern_list
-  msg: "'%select{var|let}0' pattern binding must match previous '%select{var|let}1' pattern binding"
-
-- id: type_mismatch_multiple_pattern_list
-  msg: "pattern variable bound to type %0, expected type %1"
-
-- id: type_mismatch_fallthrough_pattern_list
-  msg: "pattern variable bound to type %0, fallthrough case bound to type %1"
-
-- id: unknown_case_must_be_catchall
-  msg: "'@unknown' is only supported for catch-all cases (\"case _\")"
-
-- id: unknown_case_where_clause
-  msg: "'where' cannot be used with '@unknown'"
-
-- id: unknown_case_multiple_patterns
-  msg: "'@unknown' cannot be applied to multiple patterns"
-
-- id: unknown_case_must_be_last
-  msg: "'@unknown' can only be applied to the last case in a switch"
-
-- id: where_on_one_item
-  msg: "'where' only applies to the second pattern match in this case"
-
-- id: add_where_newline
-  msg: "disambiguate by adding a line break between them if this is desired"
-
-- id: duplicate_where
-  msg: "duplicate the 'where' on both patterns to check both patterns"
-
-- id: trailing_closure_requires_parens
-  msg: "trailing closure in this context is confusable with the body of the statement; pass as a parenthesized argument to silence this warning"
-
-- id: opaque_type_var_no_init
-  msg: "property declares an opaque return type, but has no initializer expression from which to infer an underlying type"
-
-- id: opaque_type_no_underlying_type_candidates
-  msg: "function declares an opaque return type, but has no return statements in its body from which to infer an underlying type"
-
-- id: opaque_type_mismatched_underlying_type_candidates
-  msg: "function declares an opaque return type, but the return statements in its body do not have matching underlying types"
-
-- id: opaque_type_underlying_type_candidate_here
-  msg: "return statement has underlying type %0"
-
-- id: opaque_type_self_referential_underlying_type
-  msg: "function opaque return type was inferred as %0, which defines the opaque type in terms of itself"
-
-- id: opaque_type_var_no_underlying_type
-  msg: "property declares an opaque return type, but cannot infer the underlying type from its initializer expression"
-
-- id: cannot_infer_type_for_pattern
-  msg: "type annotation missing in pattern"
-
-- id: refutable_pattern_requires_initializer
-  msg: "pattern matching requires an initializer value to match against"
-
-- id: var_pattern_didnt_bind_variables
-  msg: "'%0' pattern has no effect; sub-pattern didn't bind any variables"
-
-- id: iflet_pattern_matching
-  msg: "pattern matching in a condition requires the 'case' keyword"
-
-- id: iflet_implicitly_unwraps
-  msg: "pattern matching in a condition implicitly unwraps optionals"
-
-- id: type_pattern_missing_is
-  msg: "'is' keyword required to pattern match against type name"
-
-- id: pattern_type_mismatch_context
-  msg: "type annotation does not match contextual type %0"
-
-- id: tuple_pattern_in_non_tuple_context
-  msg: "tuple pattern cannot match values of the non-tuple type %0"
-
-- id: found_one_pattern_for_several_associated_values
-  msg: "enum case '%0' has %1 associated values; matching them as a tuple is deprecated"
-
-- id: converting_tuple_into_several_associated_values
-  msg: "enum case '%0' has %1 associated values"
-
-- id: converting_several_associated_values_into_tuple
-  msg: "enum case '%0' has one associated value that is a tuple of %1 elements"
-
-- id: closure_argument_list_tuple
-  msg: "contextual closure type %0 expects %1 argument%s1, but %2 %select{were|was}3 used in closure body"
-
-- id: closure_argument_list_missing
-  msg: "contextual type for closure argument list expects %0 argument%s0, which cannot be implicitly ignored"
-
-- id: closure_tuple_parameter_destructuring
-  msg: "closure tuple parameter %0 does not support destructuring"
-
-- id: closure_tuple_parameter_destructuring_implicit
-  msg: "closure tuple parameter %0 does not support destructuring with implicit parameters"
-
-- id: single_tuple_parameter_mismatch_special
-  msg: "%0 expects a single parameter of type %1%2"
-
-- id: single_tuple_parameter_mismatch_normal
-  msg: "%0 %1 expects a single parameter of type %2%3"
-
-- id: cannot_convert_single_tuple_into_multiple_arguments
-  msg: "%0 %select{%1 |}2expects %3 separate arguments%select{|; remove extra parentheses to change tuple into separate arguments}4"
-
-- id: enum_element_pattern_assoc_values_mismatch
-  msg: "pattern with associated values does not match enum case %0"
-
-- id: enum_element_pattern_assoc_values_remove
-  msg: "remove associated values to make the pattern match"
-
-- id: tuple_pattern_length_mismatch
-  msg: "tuple pattern has the wrong length for tuple type %0"
-
-- id: tuple_pattern_label_mismatch
-  msg: "tuple pattern element label %0 must be %1"
-
-- id: enum_element_pattern_member_not_found
-  msg: "enum case %0 not found in type %1"
-
-- id: optional_element_pattern_not_valid_type
-  msg: "'?' pattern cannot match values of type %0"
-
-- id: condition_optional_element_pattern_not_valid_type
-  msg: "initializer for conditional binding must have Optional type, not %0"
-
-- id: enum_element_pattern_not_member_of_enum
-  msg: "enum case %0 is not a member of type %1"
-
-- id: ambiguous_enum_pattern_type
-  msg: "generic enum type %0 is ambiguous without explicit generic parameters when matching value of type %1"
-
-- id: type_inferred_to_undesirable_type
-  msg: "%select{variable|constant}2 %0 inferred to have type %1, which may be unexpected"
-
-- id: type_inferred_to_uninhabited_type
-  msg: "%select{variable|constant}2 %0 inferred to have type %1, which is an enum with no cases"
-
-- id: type_inferred_to_uninhabited_tuple_type
-  msg: "%select{variable|constant}2 %0 inferred to have type %1, which contains an enum with no cases"
-
-- id: add_explicit_type_annotation_to_silence
-  msg: "add an explicit type annotation to silence this warning"
-
-- id: unowned_assignment_immediate_deallocation
-  msg: "instance will be immediately deallocated because %select{variable|property}2 %0 is %1"
-
-- id: unowned_assignment_requires_strong
-  msg: "a strong reference is required to prevent the instance from being deallocated"
-
-- id: isa_collection_downcast_pattern_value_unimplemented
-  msg: "collection downcast in cast pattern is not implemented; use an explicit downcast to %0 instead"
-
-- id: try_unhandled
-  msg: "errors thrown from here are not handled"
-
-- id: throwing_call_unhandled
-  msg: "call can throw, but the error is not handled"
-
-- id: tryless_throwing_call_unhandled
-  msg: "call can throw, but it is not marked with 'try' and the error is not handled"
-
-- id: throw_in_nonthrowing_function
-  msg: "error is not handled because the enclosing function is not declared 'throws'"
-
-- id: throwing_call_in_rethrows_function
-  msg: "call can throw, but the error is not handled; a function declared 'rethrows' may only throw if its parameter does"
-
-- id: tryless_throwing_call_in_rethrows_function
-  msg: "call can throw, but it is not marked with 'try' and the error is not handled; a function declared 'rethrows' may only throw if its parameter does"
-
-- id: throw_in_rethrows_function
-  msg: "a function declared 'rethrows' may only throw if its parameter does"
-
-- id: because_rethrows_argument_throws
-  msg: "call is to 'rethrows' function, but argument function can throw"
-
-- id: because_rethrows_default_argument_throws
-  msg: "call is to 'rethrows' function, but a defaulted argument function can throw"
-
-- id: throwing_call_in_nonthrowing_autoclosure
-  msg: "call can throw, but it is executed in a non-throwing autoclosure"
-
-- id: tryless_throwing_call_in_nonthrowing_autoclosure
-  msg: "call can throw, but it is not marked with 'try' and it is executed in a non-throwing autoclosure"
-
-- id: throw_in_nonthrowing_autoclosure
-  msg: "error is not handled because it is thrown in a non-throwing autoclosure"
-
-- id: try_unhandled_in_nonexhaustive_catch
-  msg: "errors thrown from here are not handled because the enclosing catch is not exhaustive"
-
-- id: throwing_call_in_nonexhaustive_catch
-  msg: "call can throw, but the enclosing catch is not exhaustive"
-
-- id: tryless_throwing_call_in_nonexhaustive_catch
-  msg: "call can throw, but it is not marked with 'try' and the enclosing catch is not exhaustive"
-
-- id: throw_in_nonexhaustive_catch
-  msg: "error is not handled because the enclosing catch is not exhaustive"
-
-- id: throwing_call_in_illegal_context
-  msg: "call can throw, but errors cannot be thrown out of %select{<<ERROR>>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0"
-
-- id: throw_in_illegal_context
-  msg: "errors cannot be thrown out of %select{<<ERROR>>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0"
-
-- id: throwing_operator_without_try
-  msg: "operator can throw but expression is not marked with 'try'"
-
-- id: throwing_interpolation_without_try
-  msg: "interpolation can throw but is not marked with 'try'"
-
-- id: throwing_call_without_try
-  msg: "call can throw but is not marked with 'try'"
-
-- id: note_forgot_try
-  msg: "did you mean to use 'try'?"
-
-- id: note_error_to_optional
-  msg: "did you mean to handle error as optional value?"
-
-- id: note_disable_error_propagation
-  msg: "did you mean to disable error propagation?"
-
-- id: no_throw_in_try
-  msg: "no calls to throwing functions occur within 'try' expression"
-
-- id: no_throw_in_do_with_catch
-  msg: "'catch' block is unreachable because no errors are thrown in 'do' block"
-
-- id: async_call_without_await
-  msg: "call is 'async' but is not marked with 'await'"
-
-- id: async_call_without_await_in_autoclosure
-  msg: "call is 'async' in an autoclosure argument that is not marked with 'await'"
-
-- id: no_async_in_await
-  msg: "no calls to 'async' functions occur within 'await' expression"
-
-- id: async_call_in_illegal_context
-  msg: "'async' call cannot occur in %select{<<ERROR>>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0"
-
-- id: await_in_illegal_context
-  msg: "'await' operation cannot occur in %select{<<ERROR>>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0"
-
-- id: async_in_nonasync_function
-  msg: "%select{'async'|'await'}0 in %select{a function|an autoclosure}1 that does not support concurrency"
-
-- id: note_add_async_to_function
-  msg: "add 'async' to function %0 to make it asynchronous"
-
-- id: note_add_asynchandler_to_function
-  msg: "add '@asyncHandler' to function %0 to create an implicit asynchronous context"
-
-- id: not_objc_function_async
-  msg: "'async' function cannot be represented in Objective-C"
-
-- id: not_objc_function_type_async
-  msg: "'async' function types cannot be represented in Objective-C"
-
-- id: protocol_witness_async_conflict
-  msg: "candidate is %select{not |}0'async', but protocol requirement is%select{| not}0"
-
-- id: async_autoclosure_nonasync_function
-  msg: "'async' autoclosure parameter in a non-'async' function"
-
-- id: asynchandler_attr_requires_concurrency
-  msg: "'@asyncHandler' is only valid when experimental concurrency is enabled"
-
-- id: asynchandler_non_func
-  msg: "'@asyncHandler' can only be applied to functions"
-
-- id: asynchandler_returns_value
-  msg: "'@asyncHandler' function can only return 'Void'"
-
-- id: asynchandler_throws
-  msg: "'@asyncHandler' function cannot throw"
-
-- id: asynchandler_async
-  msg: "'@asyncHandler' function cannot be 'async' itself"
-
-- id: asynchandler_inout_parameter
-  msg: "'inout' parameter is not allowed in '@asyncHandler' function"
-
-- id: asynchandler_mutating
-  msg: "'@asyncHandler' function cannot be 'mutating'"
-
-- id: unsupported_recursive_struct
-  msg: "value type %0 cannot have a stored property that recursively contains it"
-
-- id: enum_non_well_founded
-  msg: "enum containing only recursive cases is impossible to instantiate"
-
-- id: recursive_enum_not_indirect
-  msg: "recursive enum %0 is not marked 'indirect'"
-
-- id: unsupported_infinitely_sized_type
-  msg: "value type %0 has infinite size"
-
-- id: note_type_cycle_starts_here
-  msg: "cycle beginning here: %0"
-
-- id: note_recursive_enum_case_here
-  msg: "recursive case here"
-
-- id: sugar_type_not_found
-  msg: "broken standard library: cannot find %select{Array|Optional|ImplicitlyUnwrappedOptional|Dictionary|Error}0 type"
-
-- id: optional_intrinsics_not_found
-  msg: "broken standard library: cannot find intrinsic operations on Optional<T>"
-
-- id: pointer_argument_intrinsics_not_found
-  msg: "broken standard library: cannot find intrinsic operations on UnsafeMutablePointer<T>"
-
-- id: array_literal_intrinsics_not_found
-  msg: "broken standard library: cannot find intrinsic operations on Array<T>"
-
-- id: class_super_access
-  msg: "class %select{must be declared %select{%select{private|fileprivate|internal|%error|%error}1|private or fileprivate}3|cannot be declared %select{in this context|fileprivate|internal|public|open}1}0 because its superclass %select{is %select{private|fileprivate|internal|'@_spi'|'@_spi'}2|uses %select{a private|a fileprivate|an internal|an '@_spi'|an '@_spi'}2 type as a generic parameter}4"
-
-- id: class_super_access_warn
-  msg: "class %select{should be declared %select{private|fileprivate|internal|%error|%error}1|should not be declared %select{in this context|fileprivate|internal|public|open}1}0 because its superclass %select{is %select{private|fileprivate|internal|'@_spi'|'@_spi'}2|uses %select{a private|a fileprivate|an internal|an '@_spi'|an '@_spi'}2 type as a generic parameter}4"
-
-- id: class_super_not_usable_from_inline
-  msg: "%select{type referenced from |}0the superclass of a '@usableFromInline' class must be '@usableFromInline' or public"
-
-- id: class_super_not_usable_from_inline_warn
-  msg: "%select{type referenced from |}0the superclass of a '@usableFromInline' class should be '@usableFromInline' or public"
-
-- id: dot_protocol_on_non_existential
-  msg: "cannot use 'Protocol' with non-protocol type %0"
-
-- id: tuple_single_element
-  msg: "cannot create a single-element tuple with an element label"
-
-- id: tuple_ellipsis
-  msg: "cannot create a variadic tuple"
-
-- id: tuple_duplicate_label
-  msg: "cannot create a tuple with a duplicate element label"
-
-- id: enum_element_ellipsis
-  msg: "variadic enum cases are not supported"
-
-- id: implicitly_unwrapped_optional_in_illegal_position_interpreted_as_optional
-  msg: "using '!' is not allowed here; treating this as '?' instead"
-
-- id: implicitly_unwrapped_optional_deprecated_in_this_position
-  msg: "using '!' here is deprecated and will be removed in a future release"
-
-- id: implicitly_unwrapped_optional_in_illegal_position
-  msg: "using '!' is not allowed here; perhaps '?' was intended?"
-
-- id: invalid_ownership_type
-  msg: "%0 may only be applied to class and class-bound protocol types, not %1"
-
-- id: invalid_ownership_protocol_type
-  msg: "%0 must not be applied to non-class-bound %1; consider adding a protocol conformance that has a class bound"
-
-- id: invalid_ownership_incompatible_class
-  msg: "%0 is incompatible with %1 references"
-
-- id: invalid_ownership_with_optional
-  msg: "%0 variable cannot have optional type"
-
-- id: invalid_ownership_not_optional
-  msg: "%0 variable should have optional type %1"
-
-- id: invalid_ownership_is_let
-  msg: "%0 must be a mutable variable, because it may change at runtime"
-
-- id: ownership_invalid_in_protocols
-  msg: "%0 cannot be applied to a property declaration in a protocol"
-
-- id: ownership_invalid_in_protocols_compat_warning
-  msg: "%0 should not be applied to a property declaration in a protocol and will be disallowed in future versions"
-
-- id: required_initializer_nonclass
-  msg: "'required' initializer in non-class type %0"
-
-- id: required_initializer_in_extension
-  msg: "'required' initializer must be declared directly in class %0 (not in an extension)"
-
-- id: required_initializer_missing
-  msg: "'required' initializer %0 must be provided by subclass of %1"
-
-- id: required_initializer_here
-  msg: "'required' initializer is declared in superclass here"
-
-- id: required_initializer_not_accessible
-  msg: "'required' initializer must be accessible wherever class %0 can be subclassed"
-
-- id: required_initializer_missing_keyword
-  msg: "'required' modifier must be present on all overrides of a required initializer"
-
-- id: required_initializer_override_wrong_keyword
-  msg: "use the 'required' modifier to override a required initializer"
-
-- id: required_initializer_override_keyword
-  msg: "'override' is implied when overriding a required initializer"
-
-- id: overridden_required_initializer_here
-  msg: "overridden required initializer is here"
-
-- id: attribute_requires_function_type
-  msg: "@%0 attribute only applies to function types"
-
-- id: unsupported_convention
-  msg: "convention '%0' not supported"
-
-- id: unreferenced_generic_parameter
-  msg: "generic parameter '%0' is not used in function signature"
-
-- id: unexpected_ctype_for_non_c_convention
-  msg: "convention '%0' does not support the 'cType' argument label, did you mean @convention(c, cType: \"%1\") or @convention(block, cType: \"%1\") instead?"
-
-- id: unable_to_parse_c_function_type
-  msg: "unable to parse '%0'; it should be a C function pointer type or a block pointer type"
-
-- id: unsupported_opaque_type
-  msg: "'some' types are only implemented for the declared type of properties and subscripts and the return type of functions"
-
-- id: opaque_type_unsupported_pattern
-  msg: "'some' type can only be declared on a single property declaration"
-
-- id: opaque_type_in_protocol_requirement
-  msg: "'some' type cannot be the return type of a protocol requirement; did you mean to add an associated type?"
-
-- id: attr_only_on_parameters_of_differentiable
-  msg: "'%0' may only be used on parameters of '@differentiable' function types"
-
-- id: differentiable_function_type_invalid_parameter
-  msg: "parameter type '%0' does not conform to 'Differentiable'%select{| and satisfy '%0 == %0.TangentVector'}1, but the enclosing function type is '@differentiable%select{|(linear)}1'%select{|; did you want to add '@noDerivative' to this parameter?}2"
-
-- id: differentiable_function_type_invalid_result
-  msg: "result type '%0' does not conform to 'Differentiable'%select{| and satisfy '%0 == %0.TangentVector'}1, but the enclosing function type is '@differentiable%select{|(linear)}1'"
-
-- id: opened_non_protocol
-  msg: "@opened cannot be applied to non-protocol type %0"
-
-- id: sil_function_ellipsis
-  msg: "SIL function types cannot be variadic"
-
-- id: sil_function_input_label
-  msg: "SIL function types cannot have labeled inputs"
-
-- id: sil_function_output_label
-  msg: "SIL function types cannot have labeled results"
-
-- id: sil_non_coro_yields
-  msg: "non-coroutine SIL function types cannot have @yield results"
-
-- id: sil_function_repeat_convention
-  msg: "repeated %select{parameter|result|callee}0 convention attribute"
-
-- id: ast_subst_function_type
-  msg: "substitutions cannot be provided on a formal function type"
-
-- id: sil_function_multiple_error_results
-  msg: "SIL function types cannot have multiple @error results"
-
-- id: unsupported_sil_convention
-  msg: "convention '%0' not supported in SIL"
-
-- id: illegal_sil_type
-  msg: "type %0 is not a legal SIL value type"
-
-- id: sil_box_arg_mismatch
-  msg: "SIL box type has wrong number of generic arguments for layout"
-
-- id: sil_metatype_without_repr
-  msg: "metatypes in SIL must have @thin, @thick, or @objc_metatype attribute"
-
-- id: sil_metatype_multiple_reprs
-  msg: "metatypes in SIL can only be one of @thin, @thick, or @objc_metatype"
-
-- id: objc_interop_disabled
-  msg: "Objective-C interoperability is disabled"
-
-- id: attr_used_without_required_module
-  msg: "%0 attribute used without importing module %1"
-
-- id: invalid_objc_decl_context
-  msg: "@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes"
-
-- id: invalid_objc_decl
-  msg: "only classes (and their extensions), protocols, methods, initializers, properties, and subscript declarations can be declared @objc"
-
-- id: invalid_objc_swift_rooted_class
-  msg: "only classes that inherit from NSObject can be declared @objc"
-
-- id: invalid_nonobjc_decl
-  msg: "only class members and extensions of classes can be declared @nonobjc"
-
-- id: invalid_nonobjc_extension
-  msg: "only extensions of classes can be declared @nonobjc"
-
-- id: objc_in_extension_context
-  msg: "members of constrained extensions cannot be declared @objc"
-
-- id: objc_in_generic_extension
-  msg: "extensions of %select{classes from generic context|generic classes}0 cannot contain '@objc' members"
-
-- id: objc_in_resilient_extension
-  msg: "'@objc' %0 in extension of subclass of %1 requires %2 %3"
-
-- id: objc_operator
-  msg: "operator methods cannot be declared @objc"
-
-- id: objc_operator_proto
-  msg: "@objc protocols must not have operator requirements"
-
-- id: objc_inference_swift3_dynamic
-  msg: "inference of '@objc' for 'dynamic' members is deprecated"
-
-- id: objc_inference_swift3_objc_derived
-  msg: "inference of '@objc' for members of Objective-C-derived classes is deprecated"
-
-- id: objc_inference_swift3_addobjc
-  msg: "add '@objc' to continue exposing an Objective-C entry point (Swift 3 behavior)"
-
-- id: objc_inference_swift3_addnonobjc
-  msg: "add '@nonobjc' to suppress the Objective-C entry point (Swift 4 behavior)"
-
-- id: objc_for_generic_class
-  msg: "generic subclasses of '@objc' classes cannot have an explicit '@objc' because they are not directly visible from Objective-C"
-
-- id: objc_for_resilient_class
-  msg: "explicit '@objc' on subclass of %0 requires %1 %2"
-
-- id: objc_getter_for_nonobjc_property
-  msg: "'@objc' getter for non-'@objc' property"
-
-- id: objc_getter_for_nonobjc_subscript
-  msg: "'@objc' getter for non-'@objc' subscript"
-
-- id: objc_setter_for_nonobjc_property
-  msg: "'@objc' setter for non-'@objc' property"
-
-- id: objc_setter_for_nonobjc_subscript
-  msg: "'@objc' setter for non-'@objc' subscript"
-
-- id: accessor_swift3_objc_inference
-  msg: "%select{%0 %1|%1}2 with '@objc' %select{getter|setter}3 depends on deprecated inference of '@objc'"
-
-- id: objc_enum_generic
-  msg: "'@objc' enum cannot be generic"
-
-- id: objc_name_req_nullary
-  msg: "'@objc' %0 must have a simple name"
-
-- id: objc_name_subscript
-  msg: "'@objc' subscript cannot have a name; did you mean to put the name on the getter or setter?"
-
-- id: objc_name_deinit
-  msg: "'@objc' deinitializer cannot have a name"
-
-- id: objc_name_func_mismatch
-  msg: "'@objc' %select{initializer|method}0 name provides %select{one argument name|names for %1 arguments}2, but %select{initializer|method}0 has %select{one parameter|%3 parameters}4%select{| (%select{|including }4the error parameter)}5"
-
-- id: objc_enum_case_req_name
-  msg: "attribute has no effect; cases within an '@objc' enum are already exposed to Objective-C"
-
-- id: objc_enum_case_req_objc_enum
-  msg: "'@objc' enum case is not allowed outside of an '@objc' enum"
-
-- id: objc_enum_case_multi
-  msg: "'@objc' enum case declaration defines multiple enum cases with the same Objective-C name"
-
-- id: objc_extension_not_class
-  msg: "'@objc' can only be applied to an extension of a class"
-
-- id: attribute_meaningless_when_nonobjc
-  msg: "'@%0' attribute is meaningless on a property that cannot be represented in Objective-C"
-
-- id: objc_invalid_on_var
-  msg: "property cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because its type cannot be represented in Objective-C"
-
-- id: objc_invalid_on_subscript
-  msg: "subscript cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because its type cannot be represented in Objective-C"
-
-- id: objc_invalid_on_static_subscript
-  msg: "%0 cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}1"
-
-- id: objc_invalid_with_generic_params
-  msg: "%0 cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}1 because it has generic parameters"
-
-- id: objc_convention_invalid
-  msg: "%0 is not representable in Objective-C, so it cannot be used with '@convention(%1)'"
-
-- id: paren_void_probably_void
-  msg: "when calling this function in Swift 4 or later, you must pass a '()' tuple; did you mean for the input type to be '()'?"
-
-- id: not_objc_empty_protocol_composition
-  msg: "'Any' is not considered '@objc'; use 'AnyObject' instead"
-
-- id: not_objc_protocol
-  msg: "protocol-constrained type containing protocol %0 cannot be represented in Objective-C"
-
-- id: not_objc_class_constraint
-  msg: "protocol-constrained type containing class %0 cannot be represented in Objective-C"
-
-- id: not_objc_error_protocol_composition
-  msg: "protocol-constrained type containing 'Error' cannot be represented in Objective-C"
-
-- id: not_objc_empty_tuple
-  msg: "empty tuple type cannot be represented in Objective-C"
-
-- id: not_objc_tuple
-  msg: "tuples cannot be represented in Objective-C"
-
-- id: not_objc_swift_class
-  msg: "classes not annotated with @objc cannot be represented in Objective-C"
-
-- id: not_objc_swift_struct
-  msg: "Swift structs cannot be represented in Objective-C"
-
-- id: not_objc_swift_enum
-  msg: "non-'@objc' enums cannot be represented in Objective-C"
-
-- id: not_objc_generic_type_param
-  msg: "generic type parameters cannot be represented in Objective-C"
-
-- id: not_objc_function_type_param
-  msg: "function types cannot be represented in Objective-C unless their parameters and returns can be"
-
-- id: not_objc_function_type_throwing
-  msg: "throwing function types cannot be represented in Objective-C"
-
-- id: objc_inferring_on_objc_protocol_member
-  msg: "inferring '@objc' because the declaration is a member of an '@objc' protocol"
-
-- id: objc_overriding_objc_decl
-  msg: "overriding '@objc' %select{property|subscript|initializer|method}0 %1 here"
-
-- id: objc_witness_objc_requirement
-  msg: "satisfying requirement for %0 %1 in protocol %2"
-
-- id: witness_swift3_objc_inference
-  msg: "use of %0 %1 to satisfy a requirement of protocol %2 depends on '@objc' inference deprecated in Swift 4"
-
-- id: no_opaque_return_type_of
-  msg: "unable to resolve type for _opaqueReturnTypeOf attribute"
-
-- id: objc_observing_accessor
-  msg: "observing accessors are not allowed to be marked @objc"
-
-- id: objc_addressor
-  msg: "addressors are not allowed to be marked @objc"
-
-- id: objc_coroutine_accessor
-  msg: "'read' and 'modify' accessors are not allowed to be marked @objc"
-
-- id: objc_invalid_on_func_variadic
-  msg: "method cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because it has a variadic parameter"
-
-- id: objc_invalid_on_func_inout
-  msg: "method cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because inout parameters cannot be represented in Objective-C"
-
-- id: objc_invalid_on_func_param_type
-  msg: "method cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}1 because the type of the parameter %0 cannot be represented in Objective-C"
-
-- id: objc_invalid_on_func_single_param_type
-  msg: "method cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because the type of the parameter cannot be represented in Objective-C"
-
-- id: objc_invalid_on_func_result_type
-  msg: "method cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because its result type cannot be represented in Objective-C"
-
-- id: objc_invalid_on_foreign_class
-  msg: "method cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because Core Foundation types are not classes in Objective-C"
-
-- id: objc_invalid_on_throwing_optional_result
-  msg: "throwing method cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because it returns a value of optional type %1; 'nil' indicates failure to Objective-C"
-
-- id: objc_invalid_on_throwing_result
-  msg: "throwing method cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because it returns a value of type %1; return 'Void' or a type that bridges to an Objective-C class"
-
-- id: objc_invalid_on_failing_init
-  msg: "a failable and throwing initializer cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0 because 'nil' indicates failure to Objective-C"
-
-- id: objc_in_objc_runtime_visible
-  msg: "%0 cannot be %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}1 because class %2 is only visible via the Objective-C runtime"
-
-- id: objc_override_method_selector_mismatch
-  msg: "Objective-C method has a different selector from the method it overrides (%0 vs. %1)"
-
-- id: objc_override_property_name_mismatch
-  msg: "Objective-C property has a different name from the property it overrides (%0 vs. %1)"
-
-- id: objc_ambiguous_inference
-  msg: "ambiguous inference of Objective-C name for %0 %1 (%2 vs %3)"
-
-- id: objc_ambiguous_inference_candidate
-  msg: "%0 (in protocol %1) provides Objective-C name %2"
-
-- id: objc_ambiguous_error_convention
-  msg: "%0 overrides or implements protocol requirements for Objective-C declarations with incompatible error argument conventions"
-
-- id: objc_ambiguous_error_convention_candidate
-  msg: "%0 provides an error argument here"
-
-- id: nonlocal_bridged_to_objc
-  msg: "conformance of %0 to %1 can only be written in module %2"
-
-- id: missing_bridging_function
-  msg: "missing '%select{_forceBridgeFromObjectiveC|_conditionallyBridgeFromObjectiveC}0'"
-
-- id: objc_redecl
-  msg: "%select{initializer %1|implicit initializer %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript getter|setter for %1|subscript setter}0 with Objective-C selector %4 conflicts with %select{initializer %3|implicit initializer %3|deinitializer|implicit deinitializer|method %3|getter for %3|subscript getter|setter for %3|subscript setter}2 with the same Objective-C selector"
-
-- id: objc_declared_here
-  msg: "%select{initializer %1|implicit initializer %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript getter|setter for %1|subscript setter}0 declared here"
-
-- id: objc_redecl_same
-  msg: "%select{initializer %1|implicit initializer %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript getter|setter for %1|subscript setter}0 with Objective-C selector %2 conflicts with previous declaration with the same Objective-C selector"
-
-- id: objc_override_other
-  msg: "%select{initializer %1|implicit initializer %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript getter|setter for %1|subscript setter}0 with Objective-C selector %4 conflicts with %select{initializer %3|implicit initializer %3|deinitializer|implicit deinitializer|method %3|getter for %3|subscript getter|setter for %3|subscript setter}2 from superclass %5 with the same Objective-C selector"
-
-- id: objc_class_method_not_permitted
-  msg: "%select{initializer %1|implicit initializer %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript getter|setter for %1|subscript setter}0 defines Objective-C class method %2, which is not permitted by Swift"
-
-- id: objc_witness_selector_mismatch
-  msg: "Objective-C method %2 provided by %select{initializer %1|implicit initializer %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript getter|setter for %1|subscript setter}0 does not match the requirement's selector (%3)"
-
-- id: objc_optional_requirement_conflict
-  msg: "Objective-C method %4 provided by %select{initializer %1|implicit initializer %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript getter|setter for %1|subscript setter}0 conflicts with optional requirement %select{initializer %3|implicit initializer %3|deinitializer|implicit deinitializer|method %3|getter for %3|subscript getter|setter for %3|subscript setter}2 in protocol %5"
-
-- id: objc_optional_requirement_swift_rename
-  msg: "rename %select{method|initializer|property|subscript}0 to match requirement %1"
-
-- id: witness_non_objc
-  msg: "non-'@objc' %select{initializer %1|implicit initializer %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript getter|setter for %1|subscript setter}0 does not satisfy requirement of '@objc' protocol %2"
-
-- id: witness_non_objc_optional
-  msg: "non-'@objc' %select{initializer %1|implicit initializer %1|deinitializer|implicit deinitializer|method %1|getter for %1|subscript getter|setter for %1|subscript setter}0 does not satisfy optional requirement of '@objc' protocol %2"
-
-- id: witness_non_objc_storage
-  msg: "non-'@objc' %select{property %1|subscript}0 does not satisfy requirement of '@objc' protocol %2"
-
-- id: witness_non_objc_storage_optional
-  msg: "non-'@objc' %select{property %1|subscript}0 does not satisfy optional requirement of '@objc' protocol %2"
-
-- id: nonobjc_not_allowed
-  msg: "declaration is %select{marked @_cdecl|marked dynamic|marked @objc|marked @IBOutlet|marked @IBAction|marked @IBSegueAction|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override|an implementation of an @objc requirement|marked @IBInspectable|marked @GKInspectable|in an @objc extension of a class (without @nonobjc)}0, and cannot be marked @nonobjc"
-
-- id: borrowed_with_objc_dynamic
-  msg: "%0 cannot be '@_borrowed' if it is '@objc dynamic'"
-
-- id: borrowed_on_objc_protocol_requirement
-  msg: "%0 cannot be '@_borrowed' if it is an @objc protocol requirement"
-
-- id: dynamic_with_transparent
-  msg: "a declaration cannot be both '@_tranparent' and 'dynamic'"
-
-- id: dynamic_replacement_accessor_type_mismatch
-  msg: "replaced accessor %0's type does not match"
-
-- id: dynamic_replacement_accessor_not_dynamic
-  msg: "replaced accessor for %0 is not marked dynamic"
-
-- id: dynamic_replacement_accessor_not_explicit
-  msg: "replaced accessor %select{get|set|_read|_modify|willSet|didSet|unsafeAddress|addressWithOwner|addressWithNativeOwner|unsafeMutableAddress|mutableAddressWithOwner|}0 for %1 is not explicitly defined"
-
-- id: dynamic_replacement_function_not_dynamic
-  msg: "replaced function %0 is not marked dynamic"
-
-- id: dynamic_replacement_function_not_found
-  msg: "replaced function %0 could not be found"
-
-- id: dynamic_replacement_accessor_not_found
-  msg: "replaced accessor for %0 could not be found"
-
-- id: dynamic_replacement_accessor_ambiguous
-  msg: "replaced accessor for %0 occurs in multiple places"
-
-- id: dynamic_replacement_accessor_ambiguous_candidate
-  msg: "candidate accessor found in module %0"
-
-- id: dynamic_replacement_function_of_type_not_found
-  msg: "replaced function %0 of type %1 could not be found"
-
-- id: dynamic_replacement_found_function_of_type
-  msg: "found function %0 of type %1"
-
-- id: dynamic_replacement_not_in_extension
-  msg: "dynamicReplacement(for:) of %0 is not defined in an extension or at the file level"
-
-- id: dynamic_replacement_must_not_be_dynamic
-  msg: "dynamicReplacement(for:) of %0 must not be dynamic itself"
-
-- id: dynamic_replacement_replaced_not_objc_dynamic
-  msg: "%0 is not marked @objc dynamic"
-
-- id: dynamic_replacement_replacement_not_objc_dynamic
-  msg: "%0 is marked @objc dynamic"
-
-- id: dynamic_replacement_replaced_constructor_is_convenience
-  msg: "replaced constructor %0 is marked as convenience"
-
-- id: dynamic_replacement_replaced_constructor_is_not_convenience
-  msg: "replaced constructor %0 is not marked as convenience"
-
-- id: non_nominal_type_eraser
-  msg: "type eraser must be a class, struct, or enum"
-
-- id: type_eraser_does_not_conform
-  msg: "type eraser %0 must conform to protocol %1"
-
-- id: type_eraser_not_accessible
-  msg: "%select{private|fileprivate|internal|public|open}0 type eraser %1 cannot have more restrictive access than protocol %2 (which is %select{private|fileprivate|internal|public|open}3)"
-
-- id: type_eraser_missing_init
-  msg: "type eraser %0 must have an initializer of the form 'init<T: %1>(erasing: T)'"
-
-- id: type_eraser_unviable_init
-  msg: "type eraser %0 has no viable initializer of the form 'init<T: %1>(erasing: T)'"
-
-- id: type_eraser_declared_here
-  msg: "type eraser declared here"
-
-- id: type_eraser_failable_init
-  msg: "'init(erasing:)' cannot be failable"
-
-- id: type_eraser_init_unsatisfied_requirements
-  msg: "'init(erasing:)' cannot have unsatisfied requirements when %0 = 'some %1'"
-
-- id: type_eraser_init_not_accessible
-  msg: "%select{private|fileprivate|internal|public|open}0 'init(erasing:)' cannot have more restrictive access than protocol %1 (which is %select{private|fileprivate|internal|public|open}2)"
-
-- id: availability_decl_unavailable
-  msg: "%select{getter for |setter for |}0%1 is unavailable%select{ in %3|}2%select{|: %4}4"
-
-- id: availability_decl_unavailable_warn
-  msg: "%select{getter for |setter for |}0%1 is unavailable%select{ in %3|}2%select{|: %4}4"
-
-- id: availability_decl_unavailable_rename
-  msg: "%select{getter for |setter for |}0%1 has been %select{renamed to|replaced by}2%select{| instance method| property}3 '%4'%select{|: %5}5"
-
-- id: availability_decl_unavailable_rename_warn
-  msg: "%select{getter for |setter for |}0%1 has been %select{renamed to|replaced by}2%select{| instance method| property}3 '%4'%select{|: %5}5"
-
-- id: availability_marked_unavailable
-  msg: "%select{getter for |setter for |}0%1 has been explicitly marked unavailable here"
-
-- id: availability_introduced_in_version
-  msg: "%select{getter for |setter for |}0%1 was introduced in %2 %3"
-
-- id: availability_obsoleted
-  msg: "%select{getter for |setter for |}0%1 was obsoleted in %2 %3"
-
-- id: availability_deprecated
-  msg: "%select{getter for |setter for |}0%1 %select{is|%select{is|was}4}2 deprecated%select{| in %3%select{| %5}4}2%select{|: %6}6"
-
-- id: availability_deprecated_rename
-  msg: "%select{getter for |setter for |}0%1 %select{is|%select{is|was}4}2 deprecated%select{| in %3%select{| %5}4}2: %select{renamed to|replaced by}6%select{| instance method| property}7 '%8'"
-
-- id: note_deprecated_rename
-  msg: "use '%0' instead"
-
-- id: availability_decl_more_than_enclosing
-  msg: "declaration cannot be more available than enclosing scope"
-
-- id: availability_decl_more_than_enclosing_enclosing_here
-  msg: "enclosing scope here"
-
-- id: availability_decl_only_version_newer
-  msg: "%0 is only available in %1 %2 or newer"
-
-- id: availability_opaque_types_only_version_newer
-  msg: "'some' return types are only available in %0 %1 or newer"
-
-- id: availability_guard_with_version_check
-  msg: "add 'if #available' version check"
-
-- id: availability_add_attribute
-  msg: "add @available attribute to enclosing %0"
-
-- id: availability_accessor_only_version_newer
-  msg: "%select{getter|setter}0 for %1 is only available in %2 %3 or newer"
-
-- id: availability_inout_accessor_only_version_newer
-  msg: "cannot pass as inout because %select{getter|setter}0 for %1 is only available in %2 %3 or newer"
-
-- id: availability_query_required_for_platform
-  msg: "condition required for target platform '%0'"
-
-- id: availability_query_useless_enclosing_scope
-  msg: "unnecessary check for '%0'; enclosing scope ensures guard will always be true"
-
-- id: availability_query_useless_enclosing_scope_here
-  msg: "enclosing scope here"
-
-- id: availability_global_script_no_potential
-  msg: "global variable cannot be marked potentially unavailable with '@available' in script mode"
-
-- id: availability_stored_property_no_potential
-  msg: "stored properties cannot be marked potentially unavailable with '@available'"
-
-- id: availability_protocol_requires_version
-  msg: "protocol %0 requires %1 to be available in %2 %3 and newer"
-
-- id: availability_protocol_requirement_here
-  msg: "protocol requirement here"
-
-- id: public_decl_needs_availability
-  msg: "public declarations should have an availability attribute when building with -require-explicit-availability"
-
-- id: availabilty_string_subscript_migration
-  msg: "subscripts returning String were obsoleted in Swift 4; explicitly construct a String from subscripted result"
-
-- id: discardable_result_on_void_never_function
-  msg: "@discardableResult declared on a function returning %select{Never|Void}0 is unnecessary"
-
-- id: fixed_layout_attr_on_internal_type
-  msg: "'@_fixed_layout' attribute can only be applied to '@usableFromInline' or public declarations, but %0 is %select{private|fileprivate|internal|%error|%error}1"
-
-- id: fixed_layout_struct
-  msg: "'@frozen' attribute is now used for fixed-layout structs"
-
-- id: frozen_attr_on_internal_type
-  msg: "'@frozen' attribute can only be applied to '@usableFromInline' or public declarations, but %0 is %select{private|fileprivate|internal|%error|%error}1"
-
-- id: usable_from_inline_attr_with_explicit_access
-  msg: "'@usableFromInline' attribute can only be applied to internal declarations, but %0 is %select{private|fileprivate|%error|public|open}1"
-
-- id: inlinable_implies_usable_from_inline
-  msg: "'@inlinable' declaration is already '@usableFromInline'"
-
-- id: usable_from_inline_attr_in_protocol
-  msg: "'@usableFromInline' attribute cannot be used in protocols"
-
-- id: local_type_in_inlinable_function
-  msg: "type %0 cannot be nested inside %select{a '@_transparent' function|an '@inlinable' function|an '@_alwaysEmitIntoClient' function|a default argument value|a property initializer in a '@frozen' type}1"
-
-- id: resilience_decl_unavailable
-  msg: "%select{%0|%0 for}4 %1 is %select{private|fileprivate|internal|'@_spi'|'@_spi'}2 and cannot be referenced from %select{a '@_transparent' function|an '@inlinable' function|an '@_alwaysEmitIntoClient' function|a default argument value|a property initializer in a '@frozen' type}3"
-
-- id: resilience_decl_unavailable_warn
-  msg: "%select{%0|%0 for}4 %1 is %select{private|fileprivate|internal|'@_spi'|'@_spi'}2 and should not be referenced from %select{a '@_transparent' function|an '@inlinable' function|an '@_alwaysEmitIntoClient' function|a default argument value|a property initializer in a '@frozen' type}3"
-
-- id: inlinable_decl_ref_from_hidden_module
-  msg: "%0 %1 cannot be used in %select{a '@_transparent' function|an '@inlinable' function|an '@_alwaysEmitIntoClient' function|a default argument value|a property initializer in a '@frozen' type}2 because %select{%3 was imported implementation-only|it is an SPI imported from %3|it is SPI}4"
-
-- id: resilience_decl_declared_here_public
-  msg: "%select{%0|%0 for}2 %1 is not public"
-
-- id: resilience_decl_declared_here
-  msg: "%select{%0|%0 for}2 %1 is not '@usableFromInline' or public"
-
-- id: class_designated_init_inlinable_resilient
-  msg: "initializer for class %0 is '%select{@_transparent|@inlinable|@_alwaysEmitIntoClient|%error}1' and must delegate to another initializer"
-
-- id: attribute_invalid_on_stored_property
-  msg: "'%0' attribute cannot be applied to stored properties"
-
-- id: inlinable_dynamic_not_supported
-  msg: "'@inlinable' attribute cannot be applied to 'dynamic' declarations"
-
-- id: inlinable_decl_not_public
-  msg: "'@inlinable' attribute can only be applied to public declarations, but %0 is %select{private|fileprivate|internal|%error|%error}1"
-
-- id: inlinable_resilient_deinit
-  msg: "deinitializer can only be '@inlinable' if the class is '@_fixed_layout'"
-
-- id: specialize_attr_nongeneric_trailing_where
-  msg: "trailing 'where' clause in '_specialize' attribute of non-generic function %0"
-
-- id: specialize_missing_where_clause
-  msg: "missing 'where' clause in '_specialize' attribute"
-
-- id: specialize_empty_where_clause
-  msg: "empty 'where' clause in '_specialize' attribute"
-
-- id: specialize_attr_non_concrete_same_type_req
-  msg: "Only concrete type same-type requirements are supported by '_specialize' attribute"
-
-- id: specialize_attr_only_generic_param_req
-  msg: "Only requirements on generic parameters are supported by '_specialize' attribute"
-
-- id: specialize_attr_only_one_concrete_same_type_req
-  msg: "Only one concrete type should be used in the same-type requirement in '_specialize' attribute"
-
-- id: specialize_attr_non_protocol_type_constraint_req
-  msg: "Only conformances to protocol types are supported by '_specialize' attribute"
-
-- id: specialize_attr_type_parameter_count_mismatch
-  msg: "%select{too many|too few}2 type parameters are specified in '_specialize' attribute (got %1, but expected %0)"
-
-- id: specialize_attr_missing_constraint
-  msg: "Missing constraint for %0 in '_specialize' attribute"
-
-- id: specialize_attr_unsupported_kind_of_req
-  msg: "Only same-type and layout requirements are supported by '_specialize' attribute"
-
-- id: pbd_never_used_stmtcond
-  msg: "value %0 was defined but never used; consider replacing with boolean test"
-
-- id: unused_setter_parameter
-  msg: "setter argument %0 was never used, but the property was accessed"
-
-- id: fixit_for_unused_setter_parameter
-  msg: "did you mean to use %0 instead of accessing the property's current value?"
-
-- id: pbd_never_used
-  msg: "initialization of %select{variable|immutable value}1 %0 was never used; consider replacing with assignment to '_' or removing it"
-
-- id: capture_never_used
-  msg: "capture %0 was never used"
-
-- id: variable_never_used
-  msg: "%select{variable|immutable value}1 %0 was never used; consider replacing with '_' or removing it"
-
-- id: immutable_value_never_used_but_assigned
-  msg: "immutable value %0 was never used; consider removing it"
-
-- id: variable_never_mutated
-  msg: "variable %0 was never mutated; consider %select{removing 'var' to make it|changing to 'let'}1 constant"
-
-- id: variable_never_read
-  msg: "variable %0 was written to, but never read"
-
-- id: observe_keypath_property_not_objc_dynamic
-  msg: "passing reference to non-'@objc dynamic' property %0 to KVO method %1 may lead to unexpected behavior or runtime trap"
-
-- id: default_magic_identifier_mismatch
-  msg: "parameter %0 with default argument '%1' passed to parameter %2, whose default argument is '%3'"
-
-- id: change_caller_default_to_match_callee
-  msg: "did you mean for parameter %0 to default to '%1'?"
-
-- id: silence_default_magic_identifier_mismatch
-  msg: "add parentheses to silence this warning"
-
-- id: debug_long_function_body
-  msg: "%0 %1 took %2ms to type-check (limit: %3ms)"
-
-- id: debug_long_closure_body
-  msg: "closure took %0ms to type-check (limit: %1ms)"
-
-- id: debug_long_expression
-  msg: "expression took %0ms to type-check (limit: %1ms)"
-
-- id: empty_switch_stmt
-  msg: "'switch' statement body must have at least one 'case' or 'default' block; do you want to add a default case?"
-
-- id: non_exhaustive_switch
-  msg: "switch must be exhaustive"
-
-- id: possibly_non_exhaustive_switch
-  msg: "the compiler is unable to check that this switch is exhaustive in reasonable time"
-
-- id: missing_several_cases
-  msg: "do you want to add %select{missing cases|a default clause}0?"
-
-- id: missing_unknown_case
-  msg: "handle unknown values using \"@unknown default\""
-
-- id: non_exhaustive_switch_drop_unknown
-  msg: "remove '@unknown' to handle remaining values"
-
-- id: missing_particular_case
-  msg: "add missing case: '%0'"
-
-- id: redundant_particular_case
-  msg: "case is already handled by previous patterns; consider removing it"
-
-- id: redundant_particular_literal_case
-  msg: "literal value is already handled by previous pattern; consider removing it"
-
-- id: redundant_particular_literal_case_here
-  msg: "first occurrence of identical literal pattern is here"
-
-- id: non_exhaustive_switch_warn
-  msg: "switch must be exhaustive"
-
-- id: non_exhaustive_switch_unknown_only
-  msg: "switch covers known cases, but %0 may have additional unknown values%select{|, possibly added in future versions}1"
-
-- id: override_nsobject_hashvalue_error
-  msg: "'NSObject.hashValue' is not overridable; did you mean to override 'NSObject.hash'?"
-
-- id: hashvalue_implementation
-  msg: "'Hashable.hashValue' is deprecated as a protocol requirement; conform type %0 to 'Hashable' by implementing 'hash(into:)' instead"
-
-- id: property_wrapper_no_value_property
-  msg: "property wrapper type %0 does not contain a non-static property named %1"
-
-- id: property_wrapper_ambiguous_value_property
-  msg: "property wrapper type %0 has multiple non-static properties named %1"
-
-- id: property_wrapper_wrong_initial_value_init
-  msg: "%0 parameter type (%1) must be the same as its 'wrappedValue' property type (%2) or an @autoclosure thereof"
-
-- id: property_wrapper_failable_init
-  msg: "property wrapper initializer %0 cannot be failable"
-
-- id: property_wrapper_type_requirement_not_accessible
-  msg: "%select{private|fileprivate|internal|public|open}0 %1 %2 cannot have more restrictive access than its enclosing property wrapper type %3 (which is %select{private|fileprivate|internal|public|open}4)"
-
-- id: property_wrapper_ambiguous_enclosing_self_subscript
-  msg: "property wrapper type %0 has multiple enclosing-self subscripts %1"
-
-- id: property_wrapper_dynamic_self_type
-  msg: "property wrapper %select{wrapped value|projected value}0 cannot have dynamic Self type"
-
-- id: property_wrapper_attribute_not_on_property
-  msg: "property wrapper attribute %0 can only be applied to a property"
-
-- id: property_wrapper_declared_here
-  msg: "property wrapper type %0 declared here"
-
-- id: property_wrapper_mutating_get_composed_to_get_only
-  msg: "property wrapper %0 with a mutating getter cannot be composed inside get-only property wrapper %1"
-
-- id: property_wrapper_local
-  msg: "property wrappers are not yet supported on local properties"
-
-- id: property_wrapper_top_level
-  msg: "property wrappers are not yet supported in top-level code"
-
-- id: property_wrapper_let
-  msg: "property wrapper can only be applied to a 'var'"
-
-- id: property_wrapper_computed
-  msg: "property wrapper cannot be applied to a computed property"
-
-- id: property_with_wrapper_conflict_attribute
-  msg: "property %0 with a wrapper cannot also be %select{lazy|@NSCopying|@NSManaged|weak|unowned|unmanaged}1"
-
-- id: property_wrapper_not_single_var
-  msg: "property wrapper can only apply to a single variable"
-
-- id: property_with_wrapper_in_bad_context
-  msg: "%select{|non-static |non-static }1property %0 declared inside %select{a protocol|an extension|an enum}1 cannot have a wrapper"
-
-- id: property_with_wrapper_overrides
-  msg: "property %0 with attached wrapper cannot override another property"
-
-- id: property_wrapper_direct_init
-  msg: "initialize the property wrapper type directly with '(...') on the attribute"
-
-- id: property_wrapper_incompatible_property
-  msg: "property type %0 does not match that of the 'wrappedValue' property of its wrapper type %1"
-
-- id: wrapped_value_mismatch
-  msg: "property type %0 does not match 'wrappedValue' type %1"
-
-- id: composed_property_wrapper_mismatch
-  msg: "composed wrapper type %0 does not match former 'wrappedValue' type %1"
-
-- id: property_wrapper_type_access
-  msg: "%select{%select{variable|constant}0|property}1 %select{must be declared %select{%select{private|fileprivate|internal|%error|%error}3|private or fileprivate}4|cannot be declared %select{in this context|fileprivate|internal|public|open}3}2 because its property wrapper type uses %select{a private|a fileprivate|an internal|%error|%error}5 type"
-
-- id: property_wrapper_type_not_usable_from_inline
-  msg: "property wrapper type referenced from a '@usableFromInline' %select{%select{variable|constant}0|property}1 must be '@usableFromInline' or public"
-
-- id: property_wrapper_wrapperValue
-  msg: "property wrapper's 'wrapperValue' property should be renamed to 'projectedValue'; use of 'wrapperValue' is deprecated"
-
-- id: property_wrapper_init_initialValue
-  msg: "property wrapper's 'init(initialValue:)' should be renamed to 'init(wrappedValue:)'; use of 'init(initialValue:)' is deprecated"
-
-- id: property_wrapper_projection_value_missing
-  msg: "could not find projection value property %0"
-
-- id: property_wrapper_missing_arg_init
-  msg: "missing argument for parameter %0 in property wrapper initializer; add 'wrappedValue' and %0 arguments in '@%1(...)'"
-
-- id: function_builder_decl
-  msg: "closure containing a declaration cannot be used with function builder %0"
-
-- id: note_function_builder_decl
-  msg: "closure containing a declaration cannot be used with function builder %0"
-
-- id: function_builder_control_flow
-  msg: "closure containing control flow statement cannot be used with function builder %0"
-
-- id: note_function_builder_control_flow
-  msg: "closure containing control flow statement cannot be used with function builder %0"
-
-- id: function_builder_attribute_not_allowed_here
-  msg: "function builder attribute %0 can only be applied to a parameter, function, or computed property"
-
-- id: function_builder_attribute_on_storage_without_getter
-  msg: "function builder attribute %0 can only be applied to a %select{subscript|property|constant|variable}1 if it defines a getter"
-
-- id: function_builder_parameter_not_of_function_type
-  msg: "function builder attribute %0 can only be applied to a parameter of function type"
-
-- id: function_builder_parameter_autoclosure
-  msg: "function builder attribute %0 cannot be applied to an autoclosure parameter"
-
-- id: function_builder_multiple
-  msg: "only one function builder attribute can be attached to a %select{declaration|parameter}0"
-
-- id: previous_function_builder_here
-  msg: "previous function builder specified here"
-
-- id: function_builder_arguments
-  msg: "function builder attributes cannot have arguments"
-
-- id: function_builder_disabled_by_return
-  msg: "application of function builder %0 disabled by explicit 'return' statement"
-
-- id: function_builder_remove_attr
-  msg: "remove the attribute to explicitly disable the function builder"
-
-- id: function_builder_remove_returns
-  msg: "remove 'return' statements to apply the function builder"
-
-- id: function_builder_infer_ambig
-  msg: "ambiguous function builder inferred for %0: %1 or %2"
-
-- id: function_builder_infer_add_return
-  msg: "add an explicit 'return' statement to not use a function builder"
-
-- id: function_builder_infer_pick_specific
-  msg: "apply function builder %0 (inferred from %select{protocol|dynamic replacement of}1 %2)"
-
-- id: function_builder_missing_limited_availability
-  msg: "function builder %0 does not implement 'buildLimitedAvailability'; this code may crash on earlier versions of the OS"
-
-- id: warn_reordering_tuple_shuffle_deprecated
-  msg: "expression shuffles the elements of this tuple; this behavior is deprecated"
-
-- id: differentiable_programming_attr_used_without_required_module
-  msg: "'@%0' attribute used without importing module %1"
-
-- id: oslog_arg_must_be_bool_literal
-  msg: "argument must be a bool literal"
-
-- id: oslog_arg_must_be_integer_literal
-  msg: "argument must be an integer literal"
-
-- id: oslog_arg_must_be_string_literal
-  msg: "argument must be a string literal"
-
-- id: oslog_arg_must_be_float_literal
-  msg: "argument must be a floating-point literal"
-
-- id: oslog_arg_must_be_metatype_literal
-  msg: "argument must be a <Type>.self"
-
-- id: oslog_arg_must_be_closure
-  msg: "argument must be a closure"
-
-- id: argument_must_be_constant
-  msg: "argument must be an expression with only literals"
-
-- id: oslog_message_must_be_string_interpolation
-  msg: "argument must be a string interpolation"
-
-- id: oslog_arg_must_be_enum_case
-  msg: "argument must be a case of enum %0"
-
-- id: oslog_arg_must_be_type_member_access
-  msg: "argument must be a static method or property of %0"
-
-- id: atomics_ordering_must_be_constant
-  msg: "ordering argument must be a static method or property of %0"
-
-- id: warning_from_clang
-  msg: "%0"
-
-- id: error_from_clang
-  msg: "%0"
-
-- id: note_from_clang
-  msg: "%0"
-
-- id: remark_from_clang
-  msg: "%0"
-
-- id: clang_cannot_build_module
-  msg: "could not build %select{C|Objective-C}0 module '%1'"
-
-- id: bridging_header_missing
-  msg: "bridging header '%0' does not exist"
-
-- id: bridging_header_error
-  msg: "failed to import bridging header '%0'"
-
-- id: could_not_rewrite_bridging_header
-  msg: "failed to serialize bridging header; target may not be debuggable outside of its original project"
-
-- id: bridging_header_pch_error
-  msg: "failed to emit precompiled header '%0' for bridging header '%1'"
-
-- id: emit_pcm_error
-  msg: "failed to emit precompiled module '%0' for module map '%1'"
-
-- id: dump_pcm_error
-  msg: "failed to dump precompiled module '%0'"
-
-- id: invalid_swift_name_method
-  msg: "too %select{few|many}0 parameters in swift_name attribute (expected %1; got %2)"
-
-- id: note_while_importing
-  msg: "while importing '%0'"
-
-- id: swift_name_protocol_static
-  msg: "swift_name cannot be used to define %select{static member|init}0 on protocol"
-
-- id: swift_name_no_prototype
-  msg: "swift_name cannot be used on a non-prototyped function declaration"
-
-- id: inconsistent_swift_name
-  msg: "inconsistent Swift name for Objective-C %select{method|property}0 '%1' in '%2' (%3 in '%4' vs. %5 in '%6')"
-
-- id: unresolvable_clang_decl
-  msg: "imported declaration '%0' could not be mapped to '%1'"
-
-- id: unresolvable_clang_decl_is_a_framework_bug
-  msg: "please report this issue to the owners of '%0'"
-
-- id: implicit_bridging_header_imported_from_module
-  msg: "implicit import of bridging header '%0' via module %1 is deprecated and will be removed in a later version of Swift"
-
-- id: bridging_module_missing
-  msg: "unable to find module '%0' for implicit conversion function '%0.%1'"
-
-- id: bridging_function_missing
-  msg: "unable to find implicit conversion function '%0.%1'"
-
-- id: bridging_function_overloaded
-  msg: "multiple definitions of implicit conversion function '%0.%1'"
-
-- id: bridging_function_not_function
-  msg: "definition of implicit conversion function '%0.%1' is not a function"
-
-- id: bridging_function_not_correct_type
-  msg: "definition of implicit conversion function '%0.%1' is not of the correct type"
-
-- id: bridging_objcbridgeable_missing
-  msg: "cannot find definition of '_ObjectiveCBridgeable' protocol"
-
-- id: bridging_objcbridgeable_broken
-  msg: "broken definition of '_ObjectiveCBridgeable' protocol: missing %0"
-
-- id: invalid_sil_builtin
-  msg: "INTERNAL ERROR: invalid use of builtin: %0"
-
-- id: could_not_find_bridge_type
-  msg: "could not find Objective-C bridge type for type %0; did you forget to import Foundation?"
-
-- id: could_not_find_pointer_pointee_property
-  msg: "could not find 'pointee' property of pointer type %0"
-
-- id: writeback_overlap_property
-  msg: "inout writeback to computed property %0 occurs in multiple arguments to call, introducing invalid aliasing"
-
-- id: writeback_overlap_subscript
-  msg: "inout writeback through subscript occurs in multiple arguments to call, introducing invalid aliasing"
-
-- id: writebackoverlap_note
-  msg: "concurrent writeback occurred here"
-
-- id: inout_argument_alias
-  msg: "inout arguments are not allowed to alias each other"
-
-- id: previous_inout_alias
-  msg: "previous aliasing argument"
-
-- id: unimplemented_generator_witnesses
-  msg: "protocol conformance emission for generator coroutines is unimplemented"
-
-- id: exclusivity_access_required
-  msg: "overlapping accesses to %0, but %select{initialization|read|modification|deinitialization}1 requires exclusive access; %select{consider copying to a local variable|consider calling MutableCollection.swapAt(_:_:)}2"
-
-- id: exclusivity_access_required_unknown_decl
-  msg: "overlapping accesses, but %select{initialization|read|modification|deinitialization}0 requires exclusive access; consider copying to a local variable"
-
-- id: exclusivity_conflicting_access
-  msg: "conflicting access is here"
-
-- id: unsupported_c_function_pointer_conversion
-  msg: "C function pointer signature %0 is not compatible with expected type %1"
-
-- id: c_function_pointer_from_function_with_context
-  msg: "a C function pointer cannot be formed from a %select{local function|closure}0 that captures %select{context|generic parameters|dynamic Self type}1"
-
-- id: objc_selector_malformed
-  msg: "the type ObjectiveC.Selector is malformed"
-
-- id: capture_before_declaration
-  msg: "closure captures %0 before it is declared"
-
-- id: capture_before_declaration_defer
-  msg: "'defer' block captures %0 before it is declared"
-
-- id: captured_value_declared_here
-  msg: "captured value declared here"
-
-- id: escaping_inout_capture
-  msg: "escaping %select{local function|closure|autoclosure}0 captures 'inout' parameter %1"
-
-- id: inout_param_defined_here
-  msg: "parameter %0 is declared 'inout'"
-
-- id: escaping_mutable_self_capture
-  msg: "escaping %select{local function|closure|autoclosure}0 captures mutating 'self' parameter"
-
-- id: escaping_noescape_param_capture
-  msg: "escaping %select{local function|closure|autoclosure}0 captures non-escaping parameter %1"
-
-- id: noescape_param_defined_here
-  msg: "parameter %0 is implicitly non-escaping"
-
-- id: escaping_noescape_var_capture
-  msg: "escaping %select{local function|closure|autoclosure}0 captures non-escaping value"
-
-- id: value_captured_here
-  msg: "captured here"
-
-- id: copy_inout_captured_by_autoclosure
-  msg: "pass a copy of %0"
-
-- id: copy_self_captured_by_autoclosure
-  msg: "pass a copy of 'self'"
-
-- id: value_captured_transitively
-  msg: "captured indirectly by this call"
-
-- id: err_noescape_param_call
-  msg: "passing a %select{|closure which captures a }1non-escaping function parameter %0 to a call to a non-escaping function parameter can allow re-entrant modification of a variable"
-
-- id: variable_defined_here
-  msg: "%select{variable|constant}0 defined here"
-
-- id: variable_used_before_initialized
-  msg: "%select{variable|constant}1 '%0' used before being initialized"
-
-- id: variable_inout_before_initialized
-  msg: "%select{variable|constant}1 '%0' passed by reference before being initialized"
-
-- id: variable_closure_use_uninit
-  msg: "%select{variable|constant}1 '%0' captured by a closure before being initialized"
-
-- id: variable_defer_use_uninit
-  msg: "%select{variable|constant}1 '%0' used in defer before being initialized"
-
-- id: self_closure_use_uninit
-  msg: "'self' captured by a closure before all members were initialized"
-
-- id: variable_addrtaken_before_initialized
-  msg: "address of %select{variable|constant}1 '%0' taken before it is initialized"
-
-- id: ivar_not_initialized_at_superinit
-  msg: "property '%0' not initialized at super.init call"
-
-- id: ivar_not_initialized_at_implicit_superinit
-  msg: "property '%0' not initialized at implicitly generated super.init call"
-
-- id: self_use_before_fully_init
-  msg: "'self' used in %select{method call|property access}1 %0 before %select{all stored properties are initialized|'super.init' call|'self.init' call}2"
-
-- id: use_of_self_before_fully_init
-  msg: "'self' used before all stored properties are initialized"
-
-- id: stored_property_not_initialized
-  msg: "'%0' not initialized"
-
-- id: selfinit_multiple_times
-  msg: "'%select{super|self}0.init' called multiple times in initializer"
-
-- id: superselfinit_not_called_before_return
-  msg: "'%select{super|self}0.init' isn't called on all paths before returning from initializer"
-
-- id: self_before_superinit
-  msg: "'self' used before 'super.init' call"
-
-- id: self_before_selfinit
-  msg: "'self' used before 'self.init' call"
-
-- id: self_before_selfinit_value_type
-  msg: "'self' used before 'self.init' call or assignment to 'self'"
-
-- id: self_inside_catch_superselfinit
-  msg: "'self' used inside 'catch' block reachable from %select{super|self}0.init call"
-
-- id: return_from_init_without_initing_stored_properties
-  msg: "return from initializer without initializing all stored properties"
-
-- id: variable_function_use_uninit
-  msg: "%select{variable|constant}1 '%0' used by function definition before being initialized"
-
-- id: struct_not_fully_initialized
-  msg: "struct '%0' must be completely initialized before a member is stored to"
-
-- id: immutable_property_already_initialized
-  msg: "immutable value '%0' may only be initialized once"
-
-- id: initial_value_provided_in_let_decl
-  msg: "initial value already provided in 'let' declaration"
-
-- id: mutation_of_property_of_immutable_value
-  msg: "cannot mutate %select{property %0|subscript}1 of immutable value '%2'"
-
-- id: using_mutating_accessor_on_immutable_value
-  msg: "mutating accessor for %select{property %0|subscript}1 may not be used on immutable value '%2'"
-
-- id: mutating_method_called_on_immutable_value
-  msg: "mutating %select{method|operator}1 %0 may not be used on immutable value '%2'"
-
-- id: immutable_value_passed_inout
-  msg: "immutable value '%0' must not be passed inout"
-
-- id: assignment_to_immutable_value
-  msg: "immutable value '%0' must not be assigned to"
-
-- id: designated_init_in_cross_module_extension
-  msg: "initializer for struct %0 must use \"self.init(...)\" or \"self = ...\"%select{| on all paths}1 because %select{it is not in module %2|the struct was imported from C}3"
-
-- id: designated_init_c_struct_fix
-  msg: "use \"self.init()\" to initialize the struct with zero values"
-
-- id: missing_return
-  msg: "missing return in a %select{function|closure}1 expected to return %0"
-
-- id: missing_return_last_expr
-  msg: "missing return in a %select{function|closure}1 expected to return %0; did you mean to return the last expression?"
-
-- id: missing_never_call
-  msg: "%select{function|closure}1 with uninhabited return type %0 is missing call to another never-returning function on all paths"
-
-- id: guard_body_must_not_fallthrough
-  msg: "'guard' body must not fall through, consider using a 'return' or 'throw' to exit the scope"
-
-- id: unreachable_code
-  msg: "will never be executed"
-
-- id: unreachable_code_uninhabited_param_note
-  msg: "'%0' is uninhabited, so this function body can never be executed"
-
-- id: unreachable_code_branch
-  msg: "condition always evaluates to %select{false|true}0"
-
-- id: call_to_noreturn_note
-  msg: "a call to a never-returning function"
-
-- id: unreachable_code_after_stmt
-  msg: "code after '%select{return|break|continue|throw}0' will never be executed"
-
-- id: unreachable_case
-  msg: "%select{case|default}0 will never be executed"
-
-- id: switch_on_a_constant
-  msg: "switch condition evaluates to a constant"
-
-- id: unreachable_code_note
-  msg: "will never be executed"
-
-- id: warn_infinite_recursive_function
-  msg: "all paths through this function will call itself"
-
-- id: circular_transparent
-  msg: "inlining 'transparent' functions forms circular loop"
-
-- id: note_while_inlining
-  msg: "while inlining here"
-
-- id: cannot_prespecialize
-  msg: "Cannot pre-specialize %0"
-
-- id: missing_prespecialization
-  msg: "Pre-specialized function %0 missing in SwiftOnoneSupport module"
-
-- id: integer_conversion_overflow
-  msg: "integer overflows when converted from %0 to %1"
-
-- id: integer_conversion_overflow_builtin_types
-  msg: "integer overflows when converted from %select{unsigned|signed}0 %1 to %select{unsigned|signed}2 %3"
-
-- id: integer_conversion_overflow_warn
-  msg: "integer overflows when converted from %0 to %1"
-
-- id: negative_integer_literal_overflow_unsigned
-  msg: "negative integer '%1' overflows when stored into unsigned type %0"
-
-- id: integer_literal_overflow
-  msg: "integer literal '%1' overflows when stored into %0"
-
-- id: integer_literal_overflow_builtin_types
-  msg: "integer literal '%2' overflows when stored into %select{unsigned|signed}0 %1"
-
-- id: integer_literal_overflow_warn
-  msg: "integer literal overflows when stored into %0"
-
-- id: arithmetic_operation_overflow
-  msg: "arithmetic operation '%0 %1 %2' (on type %3) results in an overflow"
-
-- id: arithmetic_operation_overflow_generic_type
-  msg: "arithmetic operation '%0 %1 %2' (on %select{unsigned|signed}3 %4-bit integer type) results in an overflow"
-
-- id: division_overflow
-  msg: "division '%0 %1 %2' results in an overflow"
-
-- id: division_by_zero
-  msg: "division by zero"
-
-- id: wrong_non_negative_assumption
-  msg: "assumed non-negative value '%0' is negative"
-
-- id: shifting_all_significant_bits
-  msg: "shift amount is greater than or equal to type size in bits"
-
-- id: static_report_error
-  msg: "static report error"
-
-- id: pound_assert_condition_not_constant
-  msg: "#assert condition not constant"
-
-- id: pound_assert_failure
-  msg: "%0"
-
-- id: constexpr_unknown_reason_default
-  msg: "cannot evaluate expression as constant here"
-
-- id: constexpr_unevaluable_operation
-  msg: "cannot constant evaluate operation%select{| used by this call}0"
-
-- id: constexpr_too_many_instructions
-  msg: "exceeded instruction limit: %0 when evaluating the expression at compile time"
-
-- id: constexpr_limit_exceeding_instruction
-  msg: "limit exceeded %select{here|during this call}0"
-
-- id: constexpr_loop_found_note
-  msg: "control-flow loop found during evaluation "
-
-- id: constexpr_loop_instruction
-  msg: "found loop %select{here|inside this call}0"
-
-- id: constexpr_overflow
-  msg: "integer overflow detected"
-
-- id: constexpr_overflow_operation
-  msg: "operation%select{| performed during this call}0 overflows"
-
-- id: constexpr_trap
-  msg: "%0"
-
-- id: constexpr_trap_operation
-  msg: "operation%select{| performed during this call}0 traps"
-
-- id: constexpr_invalid_operand_seen
-  msg: "operation with invalid operands encountered during evaluation"
-
-- id: constexpr_operand_invalid_here
-  msg: "operation with invalid operands encountered %select{here|during this call}0"
-
-- id: constexpr_value_unknown_at_top_level
-  msg: "cannot evaluate top-level value as constant here"
-
-- id: constexpr_multiple_writers_found_at_top_level
-  msg: "top-level value has multiple assignments"
-
-- id: constexpr_unsupported_instruction_found
-  msg: "encountered operation not supported by the evaluator: %0"
-
-- id: constexpr_unsupported_instruction_found_here
-  msg: "operation%select{| used by this call is}0 not supported by the evaluator"
-
-- id: constexpr_found_callee_with_no_body
-  msg: "encountered call to '%0' whose body is not available. Imported functions must be marked '@inlinable' to constant evaluate"
-
-- id: constexpr_callee_with_no_body
-  msg: "%select{|calls a }0function whose body is not available"
-
-- id: constexpr_found_call_with_unknown_arg
-  msg: "encountered call to '%0' where the %1 argument is not a constant"
-
-- id: constexpr_call_with_unknown_arg
-  msg: "%select{|makes a }0function call with non-constant arguments"
-
-- id: constexpr_untracked_sil_value_use_found
-  msg: "encountered use of a variable not tracked by the evaluator"
-
-- id: constexpr_untracked_sil_value_used_here
-  msg: "untracked variable used %select{here|by this call}0"
-
-- id: constexpr_unevaluable_cast_found
-  msg: "encountered an unevaluable cast"
-
-- id: constexpr_unevaluable_cast_used_here
-  msg: "unevaluable cast encountered %select{here|by this call}0"
-
-- id: constexpr_unresolvable_witness_call
-  msg: "encountered unresolvable witness method call: '%0'"
-
-- id: constexpr_no_witness_table_entry
-  msg: "cannot find witness table entry %select{for this call|for a witness-method invoked during this call}0"
-
-- id: constexpr_witness_call_with_no_conformance
-  msg: "cannot find concrete conformance %select{for this call|for a witness-method invoked during this call}0"
-
-- id: constexpr_unknown_control_flow_due_to_skip
-  msg: "branch depends on non-constant value produced by an unevaluated instructions"
-
-- id: constexpr_returned_by_unevaluated_instruction
-  msg: "result of an unevaluated instruction is not a constant"
-
-- id: constexpr_mutated_by_unevaluated_instruction
-  msg: "value mutable by an unevaluated instruction is not a constant"
-
-- id: not_constant_evaluable
-  msg: "not constant evaluable"
-
-- id: constexpr_imported_func_not_onone
-  msg: "imported constant evaluable function '%0' must be annotated '@_optimize(none)'"
-
-- id: autodiff_internal_swift_not_imported
-  msg: "Automatic differentiation internal error: the Swift module is not imported"
-
-- id: autodiff_differentiation_module_not_imported
-  msg: "Automatic differentiation requires the '_Differentiation' module to be imported"
-
-- id: autodiff_conversion_to_linear_function_not_supported
-  msg: "conversion to '@differentiable(linear)' function type is not yet supported"
-
-- id: autodiff_function_not_differentiable_error
-  msg: "function is not differentiable"
-
-- id: autodiff_expression_not_differentiable_error
-  msg: "expression is not differentiable"
-
-- id: autodiff_expression_not_differentiable_note
-  msg: "expression is not differentiable"
-
-- id: autodiff_when_differentiating_function_call
-  msg: "when differentiating this function call"
-
-- id: autodiff_when_differentiating_function_definition
-  msg: "when differentiating this function definition"
-
-- id: autodiff_implicitly_inherited_differentiable_attr_here
-  msg: "differentiability required by the corresponding protocol requirement here"
-
-- id: autodiff_jvp_control_flow_not_supported
-  msg: "forward-mode differentiation does not yet support control flow"
-
-- id: autodiff_control_flow_not_supported
-  msg: "cannot differentiate unsupported control flow"
-
-- id: autodiff_missing_return
-  msg: "missing return for differentiation"
-
-- id: autodiff_external_nondifferentiable_function
-  msg: "cannot differentiate functions that have not been marked '@differentiable' and that are defined in other files"
-
-- id: autodiff_opaque_function_not_differentiable
-  msg: "opaque non-'@differentiable' function is not differentiable"
-
-- id: autodiff_private_derivative_from_fragile
-  msg: "differentiated functions in %select{'@inlinable' functions|default arguments}0 must be marked '@differentiable' or have a public '@derivative'%select{|; this is not possible with a closure, make a top-level function instead}1"
-
-- id: autodiff_function_noderivative_parameter_not_differentiable
-  msg: "cannot differentiate with respect to a '@noDerivative' parameter"
-
-- id: autodiff_function_assoc_func_unmet_requirements
-  msg: "function call is not differentiable because generic requirements are not met: '%0'"
-
-- id: autodiff_nondifferentiable_argument
-  msg: "cannot differentiate through a non-differentiable argument; do you want to use 'withoutDerivative(at:)'?"
-
-- id: autodiff_nondifferentiable_result
-  msg: "cannot differentiate through a non-differentiable result; do you want to use 'withoutDerivative(at:)'?"
-
-- id: autodiff_protocol_member_not_differentiable
-  msg: "member is not differentiable because the corresponding protocol requirement is not '@differentiable'"
-
-- id: autodiff_class_member_not_differentiable
-  msg: "member is not differentiable because the corresponding class member is not '@differentiable'"
-
-- id: autodiff_member_subset_indices_not_differentiable
-  msg: "member is differentiable only with respect to a smaller subset of arguments"
-
-- id: autodiff_cannot_param_subset_thunk_partially_applied_orig_fn
-  msg: "cannot convert a direct method reference to a '@differentiable' function; use an explicit closure instead"
-
-- id: autodiff_cannot_differentiate_through_multiple_results
-  msg: "cannot differentiate through multiple results"
-
-- id: autodiff_cannot_differentiate_through_inout_arguments
-  msg: "cannot differentiate through 'inout' arguments"
-
-- id: autodiff_enums_unsupported
-  msg: "differentiating enum values is not yet supported"
-
-- id: autodiff_stored_property_parent_not_differentiable
-  msg: "cannot differentiate access to property '%0.%1' because '%0' does not conform to 'Differentiable'"
-
-- id: autodiff_stored_property_not_differentiable
-  msg: "cannot differentiate access to property '%0.%1' because property type %2 does not conform to 'Differentiable'"
-
-- id: autodiff_stored_property_tangent_not_struct
-  msg: "cannot differentiate access to property '%0.%1' because '%0.TangentVector' is not a struct"
-
-- id: autodiff_stored_property_no_corresponding_tangent
-  msg: "cannot differentiate access to property '%0.%1' because '%0.TangentVector' does not have a stored property named '%1'"
-
-- id: autodiff_tangent_property_wrong_type
-  msg: "cannot differentiate access to property '%0.%1' because '%0.TangentVector.%1' does not have expected type %2"
-
-- id: autodiff_tangent_property_not_stored
-  msg: "cannot differentiate access to property '%0.%1' because '%0.TangentVector.%1' is not a stored property"
-
-- id: autodiff_coroutines_not_supported
-  msg: "differentiation of coroutine calls is not yet supported"
-
-- id: autodiff_cannot_differentiate_writes_to_global_variables
-  msg: "cannot differentiate writes to global variables"
-
-- id: autodiff_cannot_differentiate_writes_to_mutable_captures
-  msg: "cannot differentiate writes to mutable captures"
-
-- id: non_physical_addressof
-  msg: "addressof only works with purely physical lvalues; use 'withUnsafePointer' or 'withUnsafeBytes' unless you're implementing 'withUnsafePointer' or 'withUnsafeBytes'"
-
-- id: non_borrowed_indirect_addressof
-  msg: "addressof only works with borrowable in-memory rvalues; use 'withUnsafePointer' or 'withUnsafeBytes' unless you're implementing 'withUnsafePointer' or 'withUnsafeBytes'"
-
-- id: opt_remark_passed
-  msg: "%0"
-
-- id: opt_remark_missed
-  msg: "%0"
-
-- id: opt_remark_note
-  msg: "%0"
-
-- id: float_to_int_overflow
-  msg: "invalid%select{| implicit}2 conversion: '%0' overflows %1"
-
-- id: negative_fp_literal_overflow_unsigned
-  msg: "negative literal '%0' cannot be converted to %select{|unsigned }2%1"
-
-- id: warning_float_trunc_overflow
-  msg: "'%0' overflows to %select{|-}2inf during conversion to %1"
-
-- id: warning_float_trunc_underflow
-  msg: "'%0' underflows and loses precision during conversion to %1"
-
-- id: warning_float_trunc_hex_inexact
-  msg: "'%0' loses precision during conversion to %1"
-
-- id: warning_float_overflows_maxbuiltin
-  msg: "'%0' overflows to %select{|-}1inf because its magnitude exceeds the limits of a float literal"
-
-- id: warning_int_to_fp_inexact
-  msg: "'%1' is not exactly representable as %0; it becomes '%2'"
-
-- id: return_before_yield
-  msg: "accessor must yield before returning"
-
-- id: multiple_yields
-  msg: "accessor must not yield more than once"
-
-- id: previous_yield
-  msg: "previous yield was here"
-
-- id: possible_return_before_yield
-  msg: "accessor must yield on all paths before returning"
-
-- id: branch_doesnt_yield
-  msg: "missing yield when the condition is %select{false|true}0"
-
-- id: named_case_doesnt_yield
-  msg: "missing yield in the %0 case"
-
-- id: case_doesnt_yield
-  msg: "missing yield in %select{this|the nil|the non-nil}0 case"
-
-- id: switch_value_case_doesnt_yield
-  msg: "missing yield in the %0 case"
-
-- id: try_branch_doesnt_yield
-  msg: "missing yield when error is %select{not |}0thrown"
-
-- id: oslog_constant_eval_trap
-  msg: "%0"
-
-- id: oslog_too_many_instructions
-  msg: "interpolated expression and arguments are too complex"
-
-- id: oslog_invalid_log_message
-  msg: "invalid log message; extending types defined in the os module is not supported"
-
-- id: oslog_const_evaluable_fun_error
-  msg: "'%0' failed evaluation"
-
-- id: oslog_non_constant_message
-  msg: "'OSLogMessage' instance passed to the log call is not a constant"
-
-- id: oslog_non_constant_interpolation
-  msg: "'OSLogInterpolation' instance passed to 'OSLogMessage.init' is not a constant"
-
-- id: oslog_property_not_constant
-  msg: "'OSLogInterpolation.%0' is not a constant"
-
-- id: oslog_message_alive_after_opts
-  msg: "string interpolation cannot be used in this context; if you are calling an os_log function, try a different overload"
-
-- id: oslog_message_explicitly_created
-  msg: "'OSLogMessage' must be  created from a string interpolation or string literal"
-
-- id: oslog_call_in_unreachable_code
-  msg: "os log call will never be executed and may have undiagnosed errors"
-
-- id: global_string_pointer_on_non_constant
-  msg: "globalStringTablePointer builtin must be used only on string literals"
-
-- id: polymorphic_builtin_passed_non_trivial_non_builtin_type
-  msg: "Argument of type %0 can not be passed as an argument to a Polymorphic builtin. Polymorphic builtins can only be passed arguments that are trivial builtin typed"
-
-- id: polymorphic_builtin_passed_type_without_static_overload
-  msg: "Static overload %0 does not exist for polymorphic builtin '%1'. Static overload implied by passing argument of type %2"
-
-- id: box_to_stack_cannot_promote_box_to_stack_due_to_escape_alloc
-  msg: "Can not promote value from heap to stack due to value escaping"
-
-- id: box_to_stack_cannot_promote_box_to_stack_due_to_escape_location
-  msg: "value escapes here"
-
-- id: no_llvm_target
-  msg: "error loading LLVM target for triple '%0': %1"
-
-- id: error_codegen_init_fail
-  msg: "cannot initialize code generation passes for target"
-
-- id: irgen_unimplemented
-  msg: "unimplemented IR generation feature %0"
-
-- id: irgen_failure
-  msg: "IR generation failure: %0"
-
-- id: type_to_verify_not_found
-  msg: "unable to find type '%0' to verify"
-
-- id: type_to_verify_ambiguous
-  msg: "type to verify '%0' is ambiguous"
-
-- id: type_to_verify_dependent
-  msg: "type to verify '%0' has unbound generic parameters"
-
-- id: too_few_output_filenames
-  msg: "too few output file names specified"
-
-- id: no_input_files_for_mt
-  msg: "no swift input files for multi-threaded compilation"
-
-- id: alignment_dynamic_type_layout_unsupported
-  msg: "@_alignment is not supported on types with dynamic layout"
-
-- id: alignment_less_than_natural
-  msg: "@_alignment cannot decrease alignment below natural alignment of %0"
-
-- id: alignment_more_than_maximum
-  msg: "@_alignment cannot increase alignment above maximum alignment of %0"
-
-- id: warning_no_such_sdk
-  msg: "no such SDK: '%0'"
-
-- id: error_no_frontend_args
-  msg: "no arguments provided to '-frontend'"
-
-- id: error_no_such_file_or_directory
-  msg: "no such file or directory: '%0'"
-
-- id: error_unsupported_target_os
-  msg: "unsupported target OS: '%0'"
-
-- id: error_unsupported_target_arch
-  msg: "unsupported target architecture: '%0'"
-
-- id: error_unsupported_opt_for_target
-  msg: "unsupported option '%0' for target '%1'"
-
-- id: warning_inferred_simulator_target
-  msg: "inferring simulator environment for target '%0'; use '-target %1' instead"
-
-- id: error_argument_not_allowed_with
-  msg: "argument '%0' is not allowed with '%1'"
-
-- id: warning_argument_not_supported_with_optimization
-  msg: "argument '%0' is not supported with optimization"
-
-- id: error_option_requires_sanitizer
-  msg: "option '%0' requires a sanitizer to be enabled. Use -sanitize= to enable a sanitizer"
-
-- id: warning_option_requires_specific_sanitizer
-  msg: "option '%0' has no effect when '%1' sanitizer is disabled. Use -sanitize=%1 to enable the sanitizer"
-
-- id: error_option_missing_required_argument
-  msg: "option '%0' is missing a required argument (%1)"
-
-- id: cannot_open_file
-  msg: "cannot open file '%0' (%1)"
-
-- id: cannot_open_serialized_file
-  msg: "cannot open file '%0' for diagnostics emission (%1)"
-
-- id: error_open_input_file
-  msg: "error opening input file '%0' (%1)"
-
-- id: error_clang_importer_create_fail
-  msg: "clang importer creation failed"
-
-- id: error_missing_arg_value
-  msg: "missing argument value for '%0', expected %1 argument(s)"
-
-- id: error_unknown_arg
-  msg: "unknown argument: '%0'"
-
-- id: error_invalid_arg_value
-  msg: "invalid value '%1' in '%0'"
-
-- id: warning_invalid_locale_code
-  msg: "unsupported locale code; supported locale codes are: '%0'"
-
-- id: warning_locale_path_not_found
-  msg: "specified localization directory '%0' does not exist, translation is disabled"
-
-- id: warning_cannot_find_locale_file
-  msg: "cannot find translations for '%0' at '%1': no such file"
-
-- id: warning_cannot_multithread_batch_mode
-  msg: "ignoring -num-threads argument; cannot multithread batch mode"
-
-- id: error_unsupported_option_argument
-  msg: "unsupported argument '%1' to option '%0'"
-
-- id: error_immediate_mode_missing_stdlib
-  msg: "could not load the swift standard library"
-
-- id: error_immediate_mode_missing_library
-  msg: "could not load %select{shared library|framework}0 '%1'"
-
-- id: error_immediate_mode_primary_file
-  msg: "immediate mode is incompatible with -primary-file"
-
-- id: error_missing_frontend_action
-  msg: "no frontend action was selected"
-
-- id: error_invalid_source_location_str
-  msg: "invalid source location string '%0'"
-
-- id: error_no_source_location_scope_map
-  msg: "-dump-scope-maps argument must be 'expanded' or a list of source locations"
-
-- id: note_valid_swift_versions
-  msg: "valid arguments to '-swift-version' are %0"
-
-- id: error_mode_cannot_emit_dependencies
-  msg: "this mode does not support emitting dependency files"
-
-- id: error_mode_cannot_emit_reference_dependencies
-  msg: "this mode does not support emitting reference dependency files"
-
-- id: error_mode_cannot_emit_swift_ranges
-  msg: "this mode does not support emitting unparsed ranges files"
-
-- id: error_mode_cannot_emit_compiled_source
-  msg: "this mode does not support emitting compiled source files"
-
-- id: error_mode_cannot_emit_header
-  msg: "this mode does not support emitting Objective-C headers"
-
-- id: error_mode_cannot_emit_loaded_module_trace
-  msg: "this mode does not support emitting the loaded module trace"
-
-- id: error_mode_cannot_emit_module
-  msg: "this mode does not support emitting modules"
-
-- id: error_mode_cannot_emit_module_doc
-  msg: "this mode does not support emitting module documentation files"
-
-- id: error_mode_cannot_emit_module_source_info
-  msg: "this mode does not support emitting module source info files"
-
-- id: error_mode_cannot_emit_interface
-  msg: "this mode does not support emitting module interface files"
-
-- id: cannot_emit_ir_skipping_function_bodies
-  msg: "-experimental-skip-non-inlinable-function-bodies does not support emitting IR"
-
-- id: emit_reference_dependencies_without_primary_file
-  msg: "ignoring -emit-reference-dependencies (requires -primary-file)"
-
-- id: emit_swift_ranges_without_primary_file
-  msg: "ignoring -emit-swift-ranges (requires -primary-file)"
-
-- id: emit_compiled_source_without_primary_file
-  msg: "ignoring -emit-compiled-source (requires -primary-file)"
-
-- id: error_bad_module_name
-  msg: "module name \"%0\" is not a valid identifier%select{|; use -module-name flag to specify an alternate name}1"
-
-- id: error_stdlib_module_name
-  msg: "module name \"%0\" is reserved for the standard library%select{|; use -module-name flag to specify an alternate name}1"
-
-- id: error_stdlib_not_found
-  msg: "unable to load standard library for target '%0'"
-
-- id: error_unable_to_load_supplementary_output_file_map
-  msg: "unable to load supplementary output file map '%0': %1"
-
-- id: error_missing_entry_in_supplementary_output_file_map
-  msg: "supplementary output file map '%0' is missing an entry for '%1' (this likely indicates a compiler issue; please file a bug report)"
-
-- id: error_repl_requires_no_input_files
-  msg: "REPL mode requires no input files"
-
-- id: error_mode_requires_one_input_file
-  msg: "this mode requires a single input file"
-
-- id: error_mode_requires_an_input_file
-  msg: "this mode requires at least one input file"
-
-- id: error_mode_requires_one_sil_multi_sib
-  msg: "this mode requires .sil for primary-file and only .sib for other inputs"
-
-- id: error_no_output_filename_specified
-  msg: "an output filename was not specified for a mode which requires an output filename"
-
-- id: error_implicit_output_file_is_directory
-  msg: "the implicit output file '%0' is a directory; explicitly specify a filename using -o"
-
-- id: error_if_any_output_files_are_specified_they_all_must_be
-  msg: "if any output files are specified, they all must be"
-
-- id: error_primary_file_not_found
-  msg: "primary file '%0' was not found in file list '%1'"
-
-- id: error_cannot_have_input_files_with_file_list
-  msg: "cannot have input files with file list"
-
-- id: error_cannot_have_primary_files_with_primary_file_list
-  msg: "cannot have primary input files with primary file list"
-
-- id: error_cannot_have_supplementary_outputs
-  msg: "cannot have '%0' with '%1'"
-
-- id: error_duplicate_input_file
-  msg: "duplicate input file '%0'"
-
-- id: repl_must_be_initialized
-  msg: "variables currently must have an initial value when entered at the top level of the REPL"
-
-- id: verify_encountered_fatal
-  msg: "fatal error encountered while in -verify mode"
-
-- id: error_parse_input_file
-  msg: "error parsing input file '%0' (%1)"
-
-- id: error_write_index_unit
-  msg: "writing index unit file: %0"
-
-- id: error_create_index_dir
-  msg: "creating index directory: %0"
-
-- id: error_write_index_record
-  msg: "writing index record file: %0"
-
-- id: error_index_failed_status_check
-  msg: "failed file status check: %0"
-
-- id: error_index_inputs_more_than_outputs
-  msg: "index output filenames do not match input source files"
-
-- id: error_wrong_number_of_arguments
-  msg: "wrong number of '%0' arguments (expected %1, got %2)"
-
-- id: error_formatting_multiple_file_ranges
-  msg: "file ranges don't support multiple input files"
-
-- id: error_formatting_invalid_range
-  msg: "file range is invalid"
-
-- id: stats_disabled
-  msg: "compiler was not built with support for collecting statistics"
-
-- id: tbd_warn_truncating_version
-  msg: "truncating %select{current|compatibility}0 version '%1' in TBD file to fit in 32-bit space used by old mach-o format"
-
-- id: tbd_err_invalid_version
-  msg: "invalid dynamic library %select{current|compatibility}0 version '%1'"
-
-- id: tbd_only_supported_in_whole_module
-  msg: "TBD generation is only supported when the whole module can be seen"
-
-- id: tbd_not_supported_with_cmo
-  msg: "Test-Based InstallAPI (TBD) is not support with cross-module-optimization"
-
-- id: linker_directives_choice_confusion
-  msg: "only one of -emit-ldadd-cfile-path and -module-installname-map-file can be specified;the c file won't be generated"
-
-- id: previous_installname_map_missing
-  msg: "cannot open previous install name map from %0"
-
-- id: previous_installname_map_corrupted
-  msg: "previous install name map from %0 is malformed"
-
-- id: explicit_swift_module_map_missing
-  msg: "cannot open explicit Swift module map from %0"
-
-- id: explicit_swift_module_map_corrupted
-  msg: "explicit Swift module map from %0 is malformed"
-
-- id: placeholder_dependency_module_map_missing
-  msg: "cannot open Swift placeholder dependency module map from %0"
-
-- id: placeholder_dependency_module_map_corrupted
-  msg: "Swift placeholder dependency module map from %0 is malformed"
-
-- id: default_previous_install_name
-  msg: "default previous install name for %0 is %1"
-
-- id: platform_previous_install_name
-  msg: "previous install name for %0 in %1 is %2"
-
-- id: unknown_platform_name
-  msg: "unkown platform name %0"
-
-- id: unknown_swift_module_name
-  msg: "cannot find Swift module with name %0"
-
-- id: cannot_find_install_name
-  msg: "cannot find previous install name for module %0 in %1"
-
-- id: symbol_in_tbd_not_in_ir
-  msg: "symbol '%0' (%1) is in TBD file, but not in generated IR"
-
-- id: symbol_in_ir_not_in_tbd
-  msg: "symbol '%0' (%1) is in generated IR file, but not in TBD file"
-
-- id: tbd_validation_failure
-  msg: "please file a radar or open a bug on bugs.swift.org with this code, and add -Xfrontend -validate-tbd-against-ir=none to squash the errors"
-
-- id: redundant_prefix_compilation_flag
-  msg: "invalid argument '-D%0'; did you provide a redundant '-D' in your build settings?"
-
-- id: invalid_conditional_compilation_flag
-  msg: "conditional compilation flags must be valid Swift identifiers (rather than '%0')"
-
-- id: cannot_assign_value_to_conditional_compilation_flag
-  msg: "conditional compilation flags do not have values in Swift; they are either present or absent (rather than '%0')"
-
-- id: framework_search_path_includes_framework_extension
-  msg: "framework search path ends in \".framework\"; add directory containing framework instead: %0"
-
-- id: error_optimization_remark_pattern
-  msg: "%0 in '%1'"
-
-- id: error_invalid_debug_prefix_map
-  msg: "invalid argument '%0' to -debug-prefix-map; it must be of the form 'original=remapped'"
-
-- id: error_invalid_coverage_prefix_map
-  msg: "invalid argument '%0' to -coverage-prefix-map; it must be of the form 'original=remapped'"
-
-- id: error_unable_to_write_swift_ranges_file
-  msg: "unable to write unparsed ranges file '$0': %1"
-
-- id: error_unable_to_write_compiled_source_file
-  msg: "unable to write compiled source file: '$0': %1"
-
-- id: invalid_vfs_overlay_file
-  msg: "invalid virtual overlay file '%0'"
-
-- id: module_interface_scoped_import_unsupported
-  msg: "scoped imports are not yet supported in module interfaces"
-
-- id: warn_unsupported_module_interface_swift_version
-  msg: "module interfaces are only supported with Swift language version 5 or later (currently using -swift-version %0)"
-
-- id: warn_unsupported_module_interface_library_evolution
-  msg: "module interfaces are only supported with -enable-library-evolution"
-
-- id: error_extracting_version_from_module_interface
-  msg: "error extracting version from module interface"
-
-- id: unsupported_version_of_module_interface
-  msg: "unsupported version of module interface '%0': '%1'"
-
-- id: error_opening_explicit_module_file
-  msg: "failed to open explicit Swift module: %0"
-
-- id: error_extracting_flags_from_module_interface
-  msg: "error extracting flags from module interface"
-
-- id: rebuilding_module_from_interface
-  msg: "rebuilding module '%0' from interface '%1'"
-
-- id: out_of_date_module_here
-  msg: "%select{compiled|cached|forwarding|prebuilt}0 module is out of date: '%1'"
-
-- id: module_interface_dependency_out_of_date
-  msg: "dependency is out of date: '%0'"
-
-- id: module_interface_dependency_missing
-  msg: "dependency is missing: '%0'"
-
-- id: compiled_module_invalid
-  msg: "unable to load compiled module '%0'"
-
-- id: compiled_module_invalid_reason
-  msg: "unable to load compiled module '%0': %1"
-
-- id: unknown_forced_module_loading_mode
-  msg: "unknown value for SWIFT_FORCE_MODULE_LOADING variable: '%0'"
-
-- id: error_creating_remark_serializer
-  msg: "error while creating remark serializer: '%0'"
-
-- id: interface_file_lock_failure
-  msg: "could not acquire lock file for module interface '%0'"
-
-- id: interface_file_lock_timed_out
-  msg: "timed out waiting to acquire lock file for module interface '%0'"
-
-- id: dependency_cascading_mismatch
-  msg: "expected %select{non-cascading|cascading}0 dependency; found %select{non-cascading|cascading}1 dependency instead"
-
-- id: potential_dependency_cascading_mismatch
-  msg: "expected %select{non-cascading|cascading}0 potential member dependency; found %select{non-cascading|cascading}1 potential member dependency instead"
-
-- id: missing_member_dependency
-  msg: "expected %select{%error|provided|member|potential member|dynamic member}0 dependency does not exist: %1"
-
-- id: unexpected_dependency
-  msg: "unexpected %0 %select{%error|%error|member|potential member|dynamic member}1 dependency: %2"
-
-- id: unexpected_provided_entity
-  msg: "unexpected provided entity: %0"
-
-- id: negative_expectation_violated
-  msg: "unexpected dependency exists: %0"
-
-- id: expectation_missing_opening_braces
-  msg: "expected {{ in expectation"
-
-- id: expectation_missing_closing_braces
-  msg: "didn't find '}}' to match '{{' in expectation"
-
-- id: module_incompatible_with_skip_function_bodies
-  msg: "module '%0' cannot be built with -experimental-skip-non-inlinable-function-bodies; this option has been automatically disabled"
-
-- id: warning_parallel_execution_not_supported
-  msg: "parallel execution not supported; falling back to serial execution"
-
-- id: error_unable_to_execute_command
-  msg: "unable to execute command: %0"
-
-- id: error_command_signalled_without_signal_number
-  msg: "%0 command failed due to signal (use -v to see invocation)"
-
-- id: error_command_signalled
-  msg: "%0 command failed due to signal %1 (use -v to see invocation)"
-
-- id: error_command_failed
-  msg: "%0 command failed with exit code %1 (use -v to see invocation)"
-
-- id: error_expected_one_frontend_job
-  msg: "unable to handle compilation, expected exactly one frontend job"
-
-- id: error_expected_frontend_command
-  msg: "expected a swift frontend command"
-
-- id: error_cannot_specify__o_for_multiple_outputs
-  msg: "cannot specify -o when generating multiple output files"
-
-- id: error_static_emit_executable_disallowed
-  msg: "-static may not be used with -emit-executable"
-
-- id: error_unable_to_load_output_file_map
-  msg: "unable to load output file map '%1': %0"
-
-- id: error_no_output_file_map_specified
-  msg: "no output file map specified"
-
-- id: error_unable_to_make_temporary_file
-  msg: "unable to make temporary file: %0"
-
-- id: error_no_input_files
-  msg: "no input files"
-
-- id: error_unexpected_input_file
-  msg: "unexpected input file: %0"
-
-- id: error_unknown_target
-  msg: "unknown target '%0'"
-
-- id: error_framework_bridging_header
-  msg: "using bridging headers with framework targets is unsupported"
-
-- id: error_bridging_header_module_interface
-  msg: "using bridging headers with module interfaces is unsupported"
-
-- id: error_i_mode
-  msg: "the flag '-i' is no longer required and has been removed; use '%0 input-filename'"
-
-- id: warning_unnecessary_repl_mode
-  msg: "unnecessary option '%0'; this is the default for '%1' with no input files"
-
-- id: error_unsupported_option
-  msg: "option '%0' is not supported by '%1'; did you mean to use '%2'?"
-
-- id: incremental_requires_output_file_map
-  msg: "ignoring -incremental (currently requires an output file map)"
-
-- id: incremental_requires_build_record_entry
-  msg: "ignoring -incremental; output file map has no master dependencies entry (\"%0\" under \"\")"
-
-- id: unable_to_open_incremental_comparison_log
-  msg: "unable to open incremental comparison log file '%0'"
-
-- id: error_os_minimum_deployment
-  msg: "Swift requires a minimum deployment target of %0"
-
-- id: error_sdk_too_old
-  msg: "Swift does not support the SDK '%0'"
-
-- id: error_ios_maximum_deployment_32
-  msg: "iOS %0 does not support 32-bit programs"
-
-- id: error_unsupported_target_variant
-  msg: "unsupported '%select{-target|-target-variant}1' value '%0'; use 'ios-macabi' instead"
-
-- id: warn_arclite_not_found_when_link_objc_runtime
-  msg: "unable to find Objective-C runtime support library 'arclite'; pass '-no-link-objc-runtime' to silence this warning"
-
-- id: warn_cannot_stat_input
-  msg: "unable to determine when '%0' was last modified: %1"
-
-- id: warn_unable_to_load_dependencies
-  msg: "unable to load dependencies file \"%0\", disabling incremental mode"
-
-- id: error_input_changed_during_build
-  msg: "input file '%0' was modified during the build"
-
-- id: error_conflicting_options
-  msg: "conflicting options '%0' and '%1'"
-
-- id: error_option_not_supported
-  msg: "'%0' is not supported with '%1'"
-
-- id: error_requirement_not_met
-  msg: "'%0' requires '%1'"
-
-- id: warn_ignore_embed_bitcode
-  msg: "ignoring -embed-bitcode since no object file is being generated"
-
-- id: warn_ignore_embed_bitcode_marker
-  msg: "ignoring -embed-bitcode-marker since no object file is being generated"
-
-- id: verify_debug_info_requires_debug_option
-  msg: "ignoring '-verify-debug-info'; no debug info is being generated"
-
-- id: verify_incremental_dependencies_needs_incremental
-  msg: "'-verify-incremental-dependencies' requires '-incremental'"
-
-- id: error_profile_missing
-  msg: "no profdata file exists at '%0'"
-
-- id: warn_opt_remark_disabled
-  msg: "Emission of optimization records has been disabled, because it requires a single compiler invocation: consider enabling the -whole-module-optimization flag"
-
-- id: warn_ignoring_batch_mode
-  msg: "ignoring '-enable-batch-mode' because '%0' was also specified"
-
-- id: warn_ignoring_wmo
-  msg: "ignoring '-wmo' because '-dump-ast' was also specified"
-
-- id: warn_ignoring_source_range_dependencies
-  msg: "ignoring '-enable-source-range-dependencies' because '%0' was also specified"
-
-- id: warn_bad_swift_ranges_header
-  msg: "ignoring '-enable-source-range-dependencies' because of bad header in '%0'"
-
-- id: warn_bad_swift_ranges_format
-  msg: "ignoring '-enable-source-range-dependencies' because of bad format '%1' in '%0'"
-
-- id: warn_use_filelists_deprecated
-  msg: "the option '-driver-use-filelists' is deprecated; use '-driver-filelist-threshold=0' instead"
-
-- id: warn_unable_to_load_swift_ranges
-  msg: "unable to load swift ranges file \"%0\", %1"
-
-- id: warn_unable_to_load_compiled_swift
-  msg: "unable to load previously compiled swift file \"%0\", %1"
-
-- id: warn_unable_to_load_primary
-  msg: "unable to load primary swift file \"%0\", %1"
-
-- id: cannot_find_migration_script
-  msg: "missing migration script from path '%0'"
-
-- id: error_darwin_static_stdlib_not_supported
-  msg: "-static-stdlib is no longer supported on Apple platforms"
-
-- id: error_darwin_only_supports_libcxx
-  msg: "The only C++ standard library supported on Apple platforms is libc++"
-
-- id: warn_drv_darwin_sdk_invalid_settings
-  msg: "SDK settings were ignored because 'SDKSettings.json' could not be parsed"
-
-- id: invalid_name
-  msg: "'%0' is not a valid name"
-
-- id: invalid_location
-  msg: "given location is not valid"
-
-- id: arity_mismatch
-  msg: "the given new name '%0' does not match the arity of the old name '%1'"
-
-- id: name_not_functionlike
-  msg: "the 'call' name usage cannot be used with a non-function-like name '%0'"
-
-- id: unresolved_location
-  msg: "cannot resolve location as name"
-
-- id: location_module_mismatch
-  msg: "given location does not belong to module '%0'"
-
-- id: value_decl_no_loc
-  msg: "value decl '%0' has no declaration location"
-
-- id: value_decl_referenced_out_of_range
-  msg: "value decl '%0' is referenced out of range"
-
-- id: multi_entry_range
-  msg: "selected range has more than one entry point"
-
-- id: orphan_loop_keyword
-  msg: "selected range contains %0 but not its target loop"
-
-- id: invalid_default_location
-  msg: "given location is not on a default statement"
-
-- id: no_parent_switch
-  msg: "cannot find enclosing switch statement"
-
-- id: no_remaining_cases
-  msg: "no remaining cases to expand"
-
-- id: mismatched_rename
-  msg: "the name at the given location cannot be renamed to '%0'"
-
-- id: no_insert_position
-  msg: "cannot find inserting position"
-
-- id: generic_sig_change
-  msg: "%0 has generic signature change from %1 to %2"
-
-- id: raw_type_change
-  msg: "%0(%1) is now %2 representable"
-
-- id: removed_decl
-  msg: "%0 has been removed%select{| (deprecated)}1"
-
-- id: moved_decl
-  msg: "%0 has been moved to %1"
-
-- id: renamed_decl
-  msg: "%0 has been renamed to %1"
-
-- id: decl_type_change
-  msg: "%0 has %1 type change from %2 to %3"
-
-- id: decl_attr_change
-  msg: "%0 changes from %1 to %2"
-
-- id: decl_new_attr
-  msg: "%0 is now %1"
-
-- id: decl_reorder
-  msg: "%0 in a non-resilient type changes position from %1 to %2"
-
-- id: decl_added
-  msg: "%0 is added to a non-resilient type"
-
-- id: var_has_fixed_order_change
-  msg: "%0 is %select{now|no longer}1 a stored property"
-
-- id: func_has_fixed_order_change
-  msg: "%0 is %select{now|no longer}1 a non-final instance function"
-
-- id: default_arg_removed
-  msg: "%0 has removed default argument from %1"
-
-- id: conformance_removed
-  msg: "%0 has removed %select{conformance to|inherited protocol}2 %1"
-
-- id: conformance_added
-  msg: "%0 has added inherited protocol %1"
-
-- id: existing_conformance_added
-  msg: "%0 has added a conformance to an existing protocol %1"
-
-- id: default_associated_type_removed
-  msg: "%0 has removed default type %1"
-
-- id: protocol_req_added
-  msg: "%0 has been added as a protocol requirement"
-
-- id: super_class_removed
-  msg: "%0 has removed its super class %1"
-
-- id: super_class_changed
-  msg: "%0 has changed its super class from %1 to %2"
-
-- id: decl_kind_changed
-  msg: "%0 has been changed to a %1"
-
-- id: optional_req_changed
-  msg: "%0 is %select{now|no longer}1 an optional requirement"
-
-- id: no_longer_open
-  msg: "%0 is no longer open for subclassing"
-
-- id: func_type_escaping_changed
-  msg: "%0 has %select{removed|added}2 @escaping in %1"
-
-- id: func_self_access_change
-  msg: "%0 has self access kind changing from %1 to %2"
-
-- id: param_ownership_change
-  msg: "%0 has %1 changing from %2 to %3"
-
-- id: type_witness_change
-  msg: "%0 has type witness type for %1 changing from %2 to %3"
-
-- id: decl_new_witness_table_entry
-  msg: "%0 now requires %select{|no}1 new witness table entry"
-
-- id: new_decl_without_intro
-  msg: "%0 is a new API without @available attribute"
-
-- id: objc_name_change
-  msg: "%0 has ObjC name change from %1 to %2"
-
-- id: desig_init_added
-  msg: "%0 has been added as a designated initializer to an open class"
-
-- id: added_invisible_designated_init
-  msg: "%0 has new designated initializers that are not visible to clients"
-
-- id: not_inheriting_convenience_inits
-  msg: "%0 no longer inherits convenience inits from its superclass"
-
-- id: enum_case_added
-  msg: "%0 has been added as a new enum case"
-
diff --git a/stdlib/cmake/modules/AddSwiftStdlib.cmake b/stdlib/cmake/modules/AddSwiftStdlib.cmake
index afaf60a..32a4214 100644
--- a/stdlib/cmake/modules/AddSwiftStdlib.cmake
+++ b/stdlib/cmake/modules/AddSwiftStdlib.cmake
@@ -298,6 +298,9 @@
     list(APPEND result "-DSWIFT_OBJC_INTEROP=0")
   endif()
 
+  # TODO(mracek): This should get turned off for non-ABI-stable environments.
+  list(APPEND result "-DSWIFT_LIBRARY_EVOLUTION=1")
+
   if(NOT SWIFT_ENABLE_COMPATIBILITY_OVERRIDES)
     list(APPEND result "-DSWIFT_RUNTIME_NO_COMPATIBILITY_OVERRIDES")
   endif()
diff --git a/stdlib/public/Darwin/Foundation/IndexPath.swift b/stdlib/public/Darwin/Foundation/IndexPath.swift
index 62b2906..5c5d89d 100644
--- a/stdlib/public/Darwin/Foundation/IndexPath.swift
+++ b/stdlib/public/Darwin/Foundation/IndexPath.swift
@@ -617,16 +617,17 @@
     
     fileprivate init(nsIndexPath: __shared ReferenceType) {
         let count = nsIndexPath.length
-        if count == 0 {
+        switch count {
+        case 0:
             _indexes = []
-        } else if count == 1 {
+        case 1:
             _indexes = .single(nsIndexPath.index(atPosition: 0))
-        } else if count == 2 {
+        case 2:
             _indexes = .pair(nsIndexPath.index(atPosition: 0), nsIndexPath.index(atPosition: 1))
-        } else {
-            var indexes = Array<Int>(repeating: 0, count: count)
-            indexes.withUnsafeMutableBufferPointer { (buffer: inout UnsafeMutableBufferPointer<Int>) -> Void in
+        default:
+            let indexes = Array<Int>(unsafeUninitializedCapacity: count) { buffer, initializedCount in
                 nsIndexPath.getIndexes(buffer.baseAddress!, range: NSRange(location: 0, length: count))
+                initializedCount = count
             }
             _indexes = .array(indexes)
         }
diff --git a/stdlib/public/Platform/winsdk.modulemap b/stdlib/public/Platform/winsdk.modulemap
index 9baba25..97acd81 100644
--- a/stdlib/public/Platform/winsdk.modulemap
+++ b/stdlib/public/Platform/winsdk.modulemap
@@ -21,6 +21,10 @@
     link "WS2_32.Lib"
   }
 
+  module WinSock {
+    header "winsock.h"
+  }
+
   module core {
     module acl {
       header "AclAPI.h"
@@ -176,9 +180,11 @@
   }
 
   module ShellAPI {
+    header "shellapi.h"
     header "Shlwapi.h"
     export *
 
+    link "shell32.lib"
     link "ShLwApi.Lib"
   }
 
@@ -206,6 +212,11 @@
     export *
   }
 
+  module WinBase {
+    header "winbase.h"
+    export *
+  }
+
   module WinCrypt {
     header "wincrypt.h"
     export *
@@ -241,5 +252,12 @@
 
     link "RpcRT4.Lib"
   }
+
+  module WinSVC {
+    header "winsvc.h"
+    export *
+
+    link "AdvAPI32.Lib"
+  }
 }
 
diff --git a/stdlib/public/Reflection/TypeLowering.cpp b/stdlib/public/Reflection/TypeLowering.cpp
index 0c15c3d..729765e 100644
--- a/stdlib/public/Reflection/TypeLowering.cpp
+++ b/stdlib/public/Reflection/TypeLowering.cpp
@@ -1034,7 +1034,10 @@
           ++WitnessTableCount;
 
           if (auto *Superclass = TC.getBuilder().lookupSuperclass(P)) {
-            auto *SuperclassTI = TC.getTypeInfo(Superclass);
+            // ObjC class info should be available in the metadata, so it's safe
+            // to not pass an external provider here. This helps preserving the
+            // layering.
+            auto *SuperclassTI = TC.getTypeInfo(Superclass, nullptr);
             if (SuperclassTI == nullptr) {
               DEBUG_LOG(fprintf(stderr, "No TypeInfo for superclass: ");
                         Superclass->dump());
@@ -1140,7 +1143,7 @@
     Invalid = true;
   }
 
-  const TypeInfo *build() {
+  const TypeInfo *build(remote::TypeInfoProvider *ExternalTypeInfo) {
     examineProtocols();
 
     if (Invalid)
@@ -1176,12 +1179,14 @@
       // Class existentials consist of a single retainable pointer
       // followed by witness tables.
       if (Refcounting == ReferenceCounting::Unknown)
-        builder.addField("object", TC.getUnknownObjectTypeRef());
+        builder.addField("object", TC.getUnknownObjectTypeRef(),
+                         ExternalTypeInfo);
       else
-        builder.addField("object", TC.getNativeObjectTypeRef());
+        builder.addField("object", TC.getNativeObjectTypeRef(),
+                         ExternalTypeInfo);
       break;
     case ExistentialTypeRepresentation::Opaque: {
-      auto *TI = TC.getTypeInfo(TC.getRawPointerTypeRef());
+      auto *TI = TC.getTypeInfo(TC.getRawPointerTypeRef(), ExternalTypeInfo);
       if (TI == nullptr) {
         DEBUG_LOG(fprintf(stderr, "No TypeInfo for RawPointer\n"));
         return nullptr;
@@ -1195,21 +1200,21 @@
                        TI->getAlignment(),
                        /*numExtraInhabitants=*/0,
                        /*bitwiseTakable=*/true);
-      builder.addField("metadata", TC.getAnyMetatypeTypeRef());
+      builder.addField("metadata", TC.getAnyMetatypeTypeRef(), ExternalTypeInfo);
       break;
     }
     case ExistentialTypeRepresentation::Error:
-      builder.addField("error", TC.getUnknownObjectTypeRef());
+      builder.addField("error", TC.getUnknownObjectTypeRef(), ExternalTypeInfo);
       break;
     }
 
     for (unsigned i = 0; i < WitnessTableCount; ++i)
-      builder.addField("wtable", TC.getRawPointerTypeRef());
+      builder.addField("wtable", TC.getRawPointerTypeRef(), ExternalTypeInfo);
 
     return builder.build();
   }
 
-  const TypeInfo *buildMetatype() {
+  const TypeInfo *buildMetatype(remote::TypeInfoProvider *ExternalTypeInfo) {
     examineProtocols();
 
     if (Invalid)
@@ -1226,9 +1231,9 @@
 
     RecordTypeInfoBuilder builder(TC, RecordKind::ExistentialMetatype);
 
-    builder.addField("metadata", TC.getAnyMetatypeTypeRef());
+    builder.addField("metadata", TC.getAnyMetatypeTypeRef(), ExternalTypeInfo);
     for (unsigned i = 0; i < WitnessTableCount; ++i)
-      builder.addField("wtable", TC.getRawPointerTypeRef());
+      builder.addField("wtable", TC.getRawPointerTypeRef(), ExternalTypeInfo);
 
     return builder.build();
   }
@@ -1285,9 +1290,10 @@
   return offset;
 }
 
-void RecordTypeInfoBuilder::addField(const std::string &Name,
-                                     const TypeRef *TR) {
-  const TypeInfo *TI = TC.getTypeInfo(TR);
+void RecordTypeInfoBuilder::addField(
+    const std::string &Name, const TypeRef *TR,
+    remote::TypeInfoProvider *ExternalTypeInfo) {
+  const TypeInfo *TI = TC.getTypeInfo(TR, ExternalTypeInfo);
   if (TI == nullptr) {
     DEBUG_LOG(fprintf(stderr, "No TypeInfo for field type: "); TR->dump());
     Invalid = true;
@@ -1394,14 +1400,13 @@
 /// Thick functions consist of a function pointer and nullable retainable
 /// context pointer. The context is modeled exactly like a native Swift
 /// class reference.
-const TypeInfo *
-TypeConverter::getThickFunctionTypeInfo() {
+const TypeInfo *TypeConverter::getThickFunctionTypeInfo() {
   if (ThickFunctionTI != nullptr)
     return ThickFunctionTI;
 
   RecordTypeInfoBuilder builder(*this, RecordKind::ThickFunction);
-  builder.addField("function", getThinFunctionTypeRef());
-  builder.addField("context", getNativeObjectTypeRef());
+  builder.addField("function", getThinFunctionTypeRef(), nullptr);
+  builder.addField("context", getNativeObjectTypeRef(), nullptr);
   ThickFunctionTI = builder.build();
 
   return ThickFunctionTI;
@@ -1758,14 +1763,14 @@
     : TC(TC), Size(0), Alignment(1), NumExtraInhabitants(0),
       BitwiseTakable(true), Invalid(false) {}
 
-  const TypeInfo *
-  build(const TypeRef *TR, RemoteRef<FieldDescriptor> FD) {
+  const TypeInfo *build(const TypeRef *TR, RemoteRef<FieldDescriptor> FD,
+                        remote::TypeInfoProvider *ExternalTypeInfo) {
     // Sort enum into payload and no-payload cases.
     unsigned NoPayloadCases = 0;
     std::vector<FieldTypeInfo> PayloadCases;
 
     std::vector<FieldTypeInfo> Fields;
-    if (!TC.getBuilder().getFieldTypeRefs(TR, FD, Fields)) {
+    if (!TC.getBuilder().getFieldTypeRefs(TR, FD, ExternalTypeInfo, Fields)) {
       Invalid = true;
       return nullptr;
     }
@@ -1777,7 +1782,7 @@
       } else {
         PayloadCases.push_back(Case);
         auto *CaseTR = getCaseTypeRef(Case);
-        auto *CaseTI = TC.getTypeInfo(CaseTR);
+        auto *CaseTI = TC.getTypeInfo(CaseTR, ExternalTypeInfo);
         addCase(Case.Name, CaseTR, CaseTI);
       }
     }
@@ -1810,7 +1815,7 @@
     } else if (PayloadCases.size() == 1) {
       // SinglePayloadEnumImplStrategy
       auto *CaseTR = getCaseTypeRef(PayloadCases[0]);
-      auto *CaseTI = TC.getTypeInfo(CaseTR);
+      auto *CaseTI = TC.getTypeInfo(CaseTR, ExternalTypeInfo);
       if (CaseTR == nullptr || CaseTI == nullptr) {
         return nullptr;
       }
@@ -1910,11 +1915,13 @@
 class LowerType
   : public TypeRefVisitor<LowerType, const TypeInfo *> {
   TypeConverter &TC;
+  remote::TypeInfoProvider *ExternalTypeInfo;
 
 public:
   using TypeRefVisitor<LowerType, const TypeInfo *>::visit;
 
-  LowerType(TypeConverter &TC) : TC(TC) {}
+  LowerType(TypeConverter &TC, remote::TypeInfoProvider *ExternalTypeInfo)
+      : TC(TC), ExternalTypeInfo(ExternalTypeInfo) {}
 
   const TypeInfo *visitBuiltinTypeRef(const BuiltinTypeRef *B) {
     /// The context field of a thick function is a Builtin.NativeObject.
@@ -1950,6 +1957,18 @@
 
       // Otherwise, we're out of luck.
       if (FD == nullptr) {
+        if (ExternalTypeInfo) {
+          // Ask the ExternalTypeInfo. It may be a Clang-imported type.
+          std::string MangledName;
+          if (auto N = dyn_cast<NominalTypeRef>(TR))
+            MangledName = N->getMangledName();
+          else if (auto BG = dyn_cast<BoundGenericTypeRef>(TR))
+            MangledName = BG->getMangledName();
+          if (!MangledName.empty())
+            if (auto *imported = ExternalTypeInfo->getTypeInfo(MangledName))
+              return imported;
+        }
+
         DEBUG_LOG(fprintf(stderr, "No TypeInfo for nominal type: "); TR->dump());
         return nullptr;
       }
@@ -1966,17 +1985,17 @@
       RecordTypeInfoBuilder builder(TC, RecordKind::Struct);
 
       std::vector<FieldTypeInfo> Fields;
-      if (!TC.getBuilder().getFieldTypeRefs(TR, FD, Fields))
+      if (!TC.getBuilder().getFieldTypeRefs(TR, FD, ExternalTypeInfo, Fields))
         return nullptr;
 
       for (auto Field : Fields)
-        builder.addField(Field.Name, Field.TR);
+        builder.addField(Field.Name, Field.TR, ExternalTypeInfo);
       return builder.build();
     }
     case FieldDescriptorKind::Enum:
     case FieldDescriptorKind::MultiPayloadEnum: {
       EnumTypeInfoBuilder builder(TC);
-      return builder.build(TR, FD);
+      return builder.build(TR, FD, ExternalTypeInfo);
     }
     case FieldDescriptorKind::ObjCClass:
       return TC.getReferenceTypeInfo(ReferenceKind::Strong,
@@ -2002,7 +2021,8 @@
   const TypeInfo *visitTupleTypeRef(const TupleTypeRef *T) {
     RecordTypeInfoBuilder builder(TC, RecordKind::Tuple);
     for (auto Element : T->getElements())
-      builder.addField("", Element);
+      // The label is not going to be relevant/harmful for looking up type info.
+      builder.addField("", Element, ExternalTypeInfo);
     return builder.build();
   }
 
@@ -2016,7 +2036,7 @@
                                      ReferenceCounting::Unknown);
     case FunctionMetadataConvention::Thin:
     case FunctionMetadataConvention::CFunctionPointer:
-      return TC.getTypeInfo(TC.getThinFunctionTypeRef());
+      return TC.getTypeInfo(TC.getThinFunctionTypeRef(), ExternalTypeInfo);
     }
 
     swift_runtime_unreachable("Unhandled FunctionMetadataConvention in switch.");
@@ -2026,7 +2046,7 @@
   visitProtocolCompositionTypeRef(const ProtocolCompositionTypeRef *PC) {
     ExistentialTypeInfoBuilder builder(TC);
     builder.addProtocolComposition(PC);
-    return builder.build();
+    return builder.build(ExternalTypeInfo);
   }
 
   const TypeInfo *visitMetatypeTypeRef(const MetatypeTypeRef *M) {
@@ -2037,7 +2057,7 @@
     case MetatypeRepresentation::Thin:
       return TC.getEmptyTypeInfo();
     case MetatypeRepresentation::Thick:
-      return TC.getTypeInfo(TC.getAnyMetatypeTypeRef());
+      return TC.getTypeInfo(TC.getAnyMetatypeTypeRef(), ExternalTypeInfo);
     }
 
     swift_runtime_unreachable("Unhandled MetatypeRepresentation in switch.");
@@ -2055,7 +2075,7 @@
       return nullptr;
     }
 
-    return builder.buildMetatype();
+    return builder.buildMetatype(ExternalTypeInfo);
   }
 
   const TypeInfo *
@@ -2102,7 +2122,7 @@
 
     if (auto *EnumTI = dyn_cast<EnumTypeInfo>(TI)) {
       if (EnumTI->isOptional() && Kind == ReferenceKind::Weak) {
-        auto *TI = TC.getTypeInfo(EnumTI->getCases()[0].TR);
+        auto *TI = TC.getTypeInfo(EnumTI->getCases()[0].TR, ExternalTypeInfo);
         return rebuildStorageTypeInfo(TI, Kind);
       }
     }
@@ -2142,7 +2162,7 @@
 
   const TypeInfo *
   visitAnyStorageTypeRef(const TypeRef *TR, ReferenceKind Kind) {
-    return rebuildStorageTypeInfo(TC.getTypeInfo(TR), Kind);
+    return rebuildStorageTypeInfo(TC.getTypeInfo(TR, ExternalTypeInfo), Kind);
   }
 
 #define REF_STORAGE(Name, name, ...) \
@@ -2170,9 +2190,11 @@
   }
 };
 
-const TypeInfo *TypeConverter::getTypeInfo(const TypeRef *TR) {
+const TypeInfo *
+TypeConverter::getTypeInfo(const TypeRef *TR,
+                           remote::TypeInfoProvider *ExternalTypeInfo) {
   // See if we already computed the result
-  auto found = Cache.find(TR);
+  auto found = Cache.find({TR, ExternalTypeInfo});
   if (found != Cache.end())
     return found->second;
 
@@ -2184,16 +2206,17 @@
   }
 
   // Compute the result and cache it
-  auto *TI = LowerType(*this).visit(TR);
-  Cache[TR] = TI;
+  auto *TI = LowerType(*this, ExternalTypeInfo).visit(TR);
+  Cache.insert({{TR, ExternalTypeInfo}, TI});
 
   RecursionCheck.erase(TR);
 
   return TI;
 }
 
-const TypeInfo *TypeConverter::getClassInstanceTypeInfo(const TypeRef *TR,
-                                                        unsigned start) {
+const TypeInfo *TypeConverter::getClassInstanceTypeInfo(
+    const TypeRef *TR, unsigned start,
+    remote::TypeInfoProvider *ExternalTypeInfo) {
   auto FD = getBuilder().getFieldTypeInfo(TR);
   if (FD == nullptr) {
     DEBUG_LOG(fprintf(stderr, "No field descriptor: "); TR->dump());
@@ -2208,7 +2231,7 @@
     RecordTypeInfoBuilder builder(*this, RecordKind::ClassInstance);
 
     std::vector<FieldTypeInfo> Fields;
-    if (!getBuilder().getFieldTypeRefs(TR, FD, Fields))
+    if (!getBuilder().getFieldTypeRefs(TR, FD, ExternalTypeInfo, Fields))
       return nullptr;
 
     // Start layout from the given instance start offset. This should
@@ -2219,7 +2242,7 @@
                      /*bitwiseTakable=*/true);
 
     for (auto Field : Fields)
-      builder.addField(Field.Name, Field.TR);
+      builder.addField(Field.Name, Field.TR, ExternalTypeInfo);
     return builder.build();
   }
   case FieldDescriptorKind::Struct:
diff --git a/stdlib/public/Reflection/TypeRef.cpp b/stdlib/public/Reflection/TypeRef.cpp
index d1ef7a6..5b5b1dd 100644
--- a/stdlib/public/Reflection/TypeRef.cpp
+++ b/stdlib/public/Reflection/TypeRef.cpp
@@ -109,8 +109,14 @@
 
   void visitTupleTypeRef(const TupleTypeRef *T) {
     printHeader("tuple");
-    for (auto element : T->getElements())
-      printRec(element);
+    T->getLabels();
+    auto Labels = T->getLabels();
+    for (auto NameElement : llvm::zip_first(Labels, T->getElements())) {
+      auto Label = std::get<0>(NameElement);
+      if (!Label.empty())
+        fprintf(file, "%s = ", Label.str().c_str());
+      printRec(std::get<1>(NameElement));
+    }
     fprintf(file, ")");
   }
 
@@ -400,6 +406,14 @@
     : public TypeRefVisitor<DemanglingForTypeRef, Demangle::NodePointer> {
   Demangle::Demangler &Dem;
 
+  /// Demangle a type and dive into the outermost Type node.
+  Demangle::NodePointer demangleAndUnwrapType(llvm::StringRef mangledName) {
+    auto node = Dem.demangleType(mangledName);
+    if (node && node->getKind() == Node::Kind::Type && node->getNumChildren())
+      node = node->getFirstChild();
+    return node;
+  }
+
 public:
   DemanglingForTypeRef(Demangle::Demangler &Dem) : Dem(Dem) {}
 
@@ -414,13 +428,32 @@
   }
 
   Demangle::NodePointer visitBuiltinTypeRef(const BuiltinTypeRef *B) {
-    return Dem.demangleType(B->getMangledName());
+    return demangleAndUnwrapType(B->getMangledName());
   }
 
   Demangle::NodePointer visitNominalTypeRef(const NominalTypeRef *N) {
-    if (auto parent = N->getParent())
-      assert(false && "not implemented");
-    return Dem.demangleType(N->getMangledName());
+    auto node = demangleAndUnwrapType(N->getMangledName());
+    if (!node || node->getNumChildren() != 2)
+      return node;
+
+    auto parent = N->getParent();
+    if (!parent)
+      return node;
+
+    // Swap in the richer parent that is stored in the NominalTypeRef
+    // instead of what is encoded in the mangled name. The mangled name's
+    // context has been "unspecialized" by NodeBuilder.
+    auto parentNode = visit(parent);
+    if (!parentNode)
+      return node;
+    if (parentNode->getKind() == Node::Kind::Type &&
+        parentNode->getNumChildren())
+      parentNode = parentNode->getFirstChild();
+
+    auto contextualizedNode = Dem.createNode(node->getKind());
+    contextualizedNode->addChild(parentNode, Dem);
+    contextualizedNode->addChild(node->getChild(1), Dem);
+    return contextualizedNode;
   }
 
   Demangle::NodePointer
@@ -459,9 +492,15 @@
   Demangle::NodePointer visitTupleTypeRef(const TupleTypeRef *T) {
     auto tuple = Dem.createNode(Node::Kind::Tuple);
 
-    for (auto element : T->getElements()) {
+    auto Labels = T->getLabels();
+    for (auto LabelElement : llvm::zip(Labels, T->getElements())) {
       auto tupleElt = Dem.createNode(Node::Kind::TupleElement);
-      tupleElt->addChild(visit(element), Dem);
+      auto Label = std::get<0>(LabelElement);
+      if (!Label.empty()) {
+        auto name = Dem.createNode(Node::Kind::TupleElementName, Label);
+        tupleElt->addChild(name, Dem);
+      }
+      tupleElt->addChild(visit(std::get<1>(LabelElement)), Dem);
       tuple->addChild(tupleElt, Dem);
     }
     return tuple;
@@ -605,7 +644,10 @@
 
   Demangle::NodePointer visitMetatypeTypeRef(const MetatypeTypeRef *M) {
     auto node = Dem.createNode(Node::Kind::Metatype);
-    assert(!M->wasAbstract() && "not implemented");
+    // FIXME: This is lossy. @objc_metatype is also abstract.
+    auto repr = Dem.createNode(Node::Kind::MetatypeRepresentation,
+                               M->wasAbstract() ? "@thick" : "@thin");
+    node->addChild(repr, Dem);
     node->addChild(visit(M->getInstanceType()), Dem);
     return node;
   }
@@ -638,7 +680,7 @@
   }
 
   Demangle::NodePointer visitForeignClassTypeRef(const ForeignClassTypeRef *F) {
-    return Dem.demangleType(F->getName());
+    return demangleAndUnwrapType(F->getName());
   }
 
   Demangle::NodePointer visitObjCClassTypeRef(const ObjCClassTypeRef *OC) {
@@ -816,7 +858,8 @@
     std::vector<const TypeRef *> Elements;
     for (auto Element : T->getElements())
       Elements.push_back(visit(Element));
-    return TupleTypeRef::create(Builder, Elements);
+    std::string Labels = T->getLabelString();
+    return TupleTypeRef::create(Builder, Elements, std::move(Labels));
   }
 
   const TypeRef *visitFunctionTypeRef(const FunctionTypeRef *F) {
@@ -901,7 +944,7 @@
   using TypeRefVisitor<TypeRefSubstitution, const TypeRef *>::visit;
 
   TypeRefSubstitution(TypeRefBuilder &Builder, GenericArgumentMap Substitutions)
-    : Builder(Builder), Substitutions(Substitutions) {}
+      : Builder(Builder), Substitutions(Substitutions) {}
 
   const TypeRef *visitBuiltinTypeRef(const BuiltinTypeRef *B) {
     return B;
@@ -929,7 +972,8 @@
     std::vector<const TypeRef *> Elements;
     for (auto Element : T->getElements())
       Elements.push_back(visit(Element));
-    return TupleTypeRef::create(Builder, Elements);
+    std::string Labels = T->getLabelString();
+    return TupleTypeRef::create(Builder, Elements, std::move(Labels));
   }
 
   const TypeRef *visitFunctionTypeRef(const FunctionTypeRef *F) {
@@ -1081,8 +1125,8 @@
   }
 };
 
-const TypeRef *
-TypeRef::subst(TypeRefBuilder &Builder, const GenericArgumentMap &Subs) const {
+const TypeRef *TypeRef::subst(TypeRefBuilder &Builder,
+                              const GenericArgumentMap &Subs) const {
   return TypeRefSubstitution(Builder, Subs).visit(this);
 }
 
diff --git a/stdlib/public/Reflection/TypeRefBuilder.cpp b/stdlib/public/Reflection/TypeRefBuilder.cpp
index d811f53..4440a97 100644
--- a/stdlib/public/Reflection/TypeRefBuilder.cpp
+++ b/stdlib/public/Reflection/TypeRefBuilder.cpp
@@ -146,8 +146,7 @@
   return nullptr;
 }
 
-const TypeRef * TypeRefBuilder::
-lookupSuperclass(const TypeRef *TR) {
+const TypeRef *TypeRefBuilder::lookupSuperclass(const TypeRef *TR) {
   const auto &FD = getFieldTypeInfo(TR);
   if (FD == nullptr)
     return nullptr;
@@ -204,8 +203,8 @@
 }
 
 bool TypeRefBuilder::getFieldTypeRefs(
-    const TypeRef *TR,
-    RemoteRef<FieldDescriptor> FD,
+    const TypeRef *TR, RemoteRef<FieldDescriptor> FD,
+    remote::TypeInfoProvider *ExternalTypeInfo,
     std::vector<FieldTypeInfo> &Fields) {
   if (FD == nullptr)
     return false;
diff --git a/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp b/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp
index b10f898..9d5afad 100644
--- a/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp
+++ b/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp
@@ -477,7 +477,7 @@
                                 swift_typeref_t OpaqueTypeRef) {
   auto Context = ContextRef->nativeContext;
   auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
-  auto TI = Context->getTypeInfo(TR);
+  auto TI = Context->getTypeInfo(TR, nullptr);
   return convertTypeInfo(TI);
 }
 
@@ -487,7 +487,7 @@
                                 unsigned Index) {
   auto Context = ContextRef->nativeContext;
   auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
-  auto *TI = Context->getTypeInfo(TR);
+  auto *TI = Context->getTypeInfo(TR, nullptr);
   return convertChild(TI, Index);
 }
 
@@ -495,7 +495,7 @@
 swift_reflection_infoForMetadata(SwiftReflectionContextRef ContextRef,
                                  uintptr_t Metadata) {
   auto Context = ContextRef->nativeContext;
-  auto *TI = Context->getMetadataTypeInfo(Metadata);
+  auto *TI = Context->getMetadataTypeInfo(Metadata, nullptr);
   return convertTypeInfo(TI);
 }
 
@@ -504,7 +504,7 @@
                                  uintptr_t Metadata,
                                  unsigned Index) {
   auto Context = ContextRef->nativeContext;
-  auto *TI = Context->getMetadataTypeInfo(Metadata);
+  auto *TI = Context->getMetadataTypeInfo(Metadata, nullptr);
   return convertChild(TI, Index);
 }
 
@@ -512,7 +512,7 @@
 swift_reflection_infoForInstance(SwiftReflectionContextRef ContextRef,
                                  uintptr_t Object) {
   auto Context = ContextRef->nativeContext;
-  auto *TI = Context->getInstanceTypeInfo(Object);
+  auto *TI = Context->getInstanceTypeInfo(Object, nullptr);
   return convertTypeInfo(TI);
 }
 
@@ -521,7 +521,7 @@
                                  uintptr_t Object,
                                  unsigned Index) {
   auto Context = ContextRef->nativeContext;
-  auto *TI = Context->getInstanceTypeInfo(Object);
+  auto *TI = Context->getInstanceTypeInfo(Object, nullptr);
   return convertChild(TI, Index);
 }
 
@@ -535,10 +535,9 @@
   auto RemoteExistentialAddress = RemoteAddress(ExistentialAddress);
   const TypeRef *InstanceTR = nullptr;
   RemoteAddress RemoteStartOfInstanceData(nullptr);
-  auto Success = Context->projectExistential(RemoteExistentialAddress,
-                                             ExistentialTR,
-                                             &InstanceTR,
-                                             &RemoteStartOfInstanceData);
+  auto Success = Context->projectExistential(
+      RemoteExistentialAddress, ExistentialTR, &InstanceTR,
+      &RemoteStartOfInstanceData, nullptr);
 
   if (Success) {
     *InstanceTypeRef = reinterpret_cast<swift_typeref_t>(InstanceTR);
@@ -555,10 +554,11 @@
   auto Context = ContextRef->nativeContext;
   auto EnumTR = reinterpret_cast<const TypeRef *>(EnumTypeRef);
   auto RemoteEnumAddress = RemoteAddress(EnumAddress);
-  if (!Context->projectEnumValue(RemoteEnumAddress, EnumTR, CaseIndex)) {
+  if (!Context->projectEnumValue(RemoteEnumAddress, EnumTR, CaseIndex,
+                                 nullptr)) {
     return false;
   }
-  auto TI = Context->getTypeInfo(EnumTR);
+  auto TI = Context->getTypeInfo(EnumTR, nullptr);
   auto *RecordTI = dyn_cast<EnumTypeInfo>(TI);
   assert(RecordTI != nullptr);
   if (static_cast<size_t>(*CaseIndex) >= RecordTI->getNumCases()) {
@@ -580,7 +580,7 @@
                                          swift_typeref_t OpaqueTypeRef) {
   auto Context = ContextRef->nativeContext;
   auto TR = reinterpret_cast<const TypeRef *>(OpaqueTypeRef);
-  auto TI = Context->getTypeInfo(TR);
+  auto TI = Context->getTypeInfo(TR, nullptr);
   if (TI == nullptr) {
     fprintf(stdout, "<null type info>\n");
   } else {
@@ -605,7 +605,7 @@
 void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
                                           uintptr_t Metadata) {
   auto Context = ContextRef->nativeContext;
-  auto TI = Context->getMetadataTypeInfo(Metadata);
+  auto TI = Context->getMetadataTypeInfo(Metadata, nullptr);
   if (TI == nullptr) {
     fprintf(stdout, "<null type info>\n");
   } else {
@@ -616,7 +616,7 @@
 void swift_reflection_dumpInfoForInstance(SwiftReflectionContextRef ContextRef,
                                           uintptr_t Object) {
   auto Context = ContextRef->nativeContext;
-  auto TI = Context->getInstanceTypeInfo(Object);
+  auto TI = Context->getInstanceTypeInfo(Object, nullptr);
   if (TI == nullptr) {
     fprintf(stdout, "%s", "<null type info>\n");
   } else {
diff --git a/stdlib/public/core/Array.swift b/stdlib/public/core/Array.swift
index 42fcd9d..fe5f0da 100644
--- a/stdlib/public/core/Array.swift
+++ b/stdlib/public/core/Array.swift
@@ -852,14 +852,14 @@
   /// `LazyMapCollection<Dictionary<String, Int>, Int>` to a simple
   /// `[String]`.
   ///
-  ///     func cacheImagesWithNames(names: [String]) {
+  ///     func cacheImages(withNames names: [String]) {
   ///         // custom image loading and caching
   ///      }
   ///
   ///     let namedHues: [String: Int] = ["Vermillion": 18, "Magenta": 302,
   ///             "Gold": 50, "Cerise": 320]
   ///     let colorNames = Array(namedHues.keys)
-  ///     cacheImagesWithNames(colorNames)
+  ///     cacheImages(withNames: colorNames)
   ///
   ///     print(colorNames)
   ///     // Prints "["Gold", "Cerise", "Magenta", "Vermillion"]"
diff --git a/stdlib/public/core/BridgingBuffer.swift b/stdlib/public/core/BridgingBuffer.swift
index c3d0613..5e6e28a 100644
--- a/stdlib/public/core/BridgingBuffer.swift
+++ b/stdlib/public/core/BridgingBuffer.swift
@@ -25,6 +25,7 @@
 internal typealias _BridgingBuffer
   = ManagedBufferPointer<_BridgingBufferHeader, AnyObject>
 
+@available(OpenBSD, unavailable, message: "malloc_size is unavailable.")
 extension ManagedBufferPointer
 where Header == _BridgingBufferHeader, Element == AnyObject {
   internal init(_ count: Int) {
diff --git a/stdlib/public/core/FloatingPoint.swift b/stdlib/public/core/FloatingPoint.swift
index fa7ce59..80b3249 100644
--- a/stdlib/public/core/FloatingPoint.swift
+++ b/stdlib/public/core/FloatingPoint.swift
@@ -1890,7 +1890,53 @@
   /// - Parameter value: A floating-point value to be converted.
   @inlinable
   public init<Source: BinaryFloatingPoint>(_ value: Source) {
-    self = Self._convert(from: value).value
+    // If two IEEE 754 binary interchange formats share the same exponent bit
+    // count and significand bit count, then they must share the same encoding
+    // for finite and infinite values.
+    switch (Source.exponentBitCount, Source.significandBitCount) {
+#if !os(macOS) && !(os(iOS) && targetEnvironment(macCatalyst))
+    case (5, 10):
+      guard #available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) else {
+        self = Self._convert(from: value).value
+        break
+      }
+      let value_ = value as? Float16 ?? Float16(
+        sign: value.sign,
+        exponentBitPattern:
+          UInt(truncatingIfNeeded: value.exponentBitPattern),
+        significandBitPattern:
+          UInt16(truncatingIfNeeded: value.significandBitPattern))
+      self = Self(Float(value_))
+#endif
+    case (8, 23):
+      let value_ = value as? Float ?? Float(
+        sign: value.sign,
+        exponentBitPattern:
+          UInt(truncatingIfNeeded: value.exponentBitPattern),
+        significandBitPattern:
+          UInt32(truncatingIfNeeded: value.significandBitPattern))
+      self = Self(value_)
+    case (11, 52):
+      let value_ = value as? Double ?? Double(
+        sign: value.sign,
+        exponentBitPattern:
+          UInt(truncatingIfNeeded: value.exponentBitPattern),
+        significandBitPattern:
+          UInt64(truncatingIfNeeded: value.significandBitPattern))
+      self = Self(value_)
+#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
+    case (15, 63):
+      let value_ = value as? Float80 ?? Float80(
+        sign: value.sign,
+        exponentBitPattern:
+          UInt(truncatingIfNeeded: value.exponentBitPattern),
+        significandBitPattern:
+          UInt64(truncatingIfNeeded: value.significandBitPattern))
+      self = Self(value_)
+#endif
+    default:
+      self = Self._convert(from: value).value
+    }
   }
 
   /// Creates a new instance from the given value, if it can be represented
diff --git a/stdlib/public/core/Integers.swift b/stdlib/public/core/Integers.swift
index 7c637c6..1b7ba77 100644
--- a/stdlib/public/core/Integers.swift
+++ b/stdlib/public/core/Integers.swift
@@ -1211,7 +1211,7 @@
   ///
   /// - Parameter rhs: The value to divide this value by.
   /// - Returns: A tuple containing the quotient and remainder of this value
-  ///   divided by `rhs`. The remainder has the same sign as `rhs`.
+  ///   divided by `rhs`. The remainder has the same sign as `lhs`.
   func quotientAndRemainder(dividingBy rhs: Self)
     -> (quotient: Self, remainder: Self)
 
diff --git a/stdlib/public/core/ManagedBuffer.swift b/stdlib/public/core/ManagedBuffer.swift
index 6248994..bb6a632 100644
--- a/stdlib/public/core/ManagedBuffer.swift
+++ b/stdlib/public/core/ManagedBuffer.swift
@@ -83,6 +83,7 @@
   /// idea to store this information in the "header" area when
   /// an instance is created.
   @inlinable
+  @available(OpenBSD, unavailable, message: "malloc_size is unavailable.")
   public final var capacity: Int {
     let storageAddr = UnsafeMutableRawPointer(Builtin.bridgeToRawPointer(self))
     let endAddr = storageAddr + _swift_stdlib_malloc_size(storageAddr)
@@ -197,6 +198,7 @@
   ///   properties.  The `deinit` of `bufferClass` must destroy its
   ///   stored `Header` and any constructed `Element`s.
   @inlinable
+  @available(OpenBSD, unavailable, message: "malloc_size is unavailable.")
   public init(
     bufferClass: AnyClass,
     minimumCapacity: Int,
@@ -329,6 +331,7 @@
   /// idea to store this information in the "header" area when
   /// an instance is created.
   @inlinable
+  @available(OpenBSD, unavailable, message: "malloc_size is unavailable.")
   public var capacity: Int {
     return (
       _capacityInBytes &- ManagedBufferPointer._elementOffset
@@ -431,6 +434,7 @@
 
   /// The actual number of bytes allocated for this object.
   @inlinable
+  @available(OpenBSD, unavailable, message: "malloc_size is unavailable.")
   internal var _capacityInBytes: Int {
     return _swift_stdlib_malloc_size(_address)
   }
diff --git a/stdlib/public/core/OutputStream.swift b/stdlib/public/core/OutputStream.swift
index 7faafba..5210110 100644
--- a/stdlib/public/core/OutputStream.swift
+++ b/stdlib/public/core/OutputStream.swift
@@ -225,10 +225,7 @@
 ///
 ///     let p = Point(x: 21, y: 30)
 ///     print(String(reflecting: p))
-///     // Prints "p: Point = {
-///     //           x = 21
-///     //           y = 30
-///     //         }"
+///     // Prints "Point(x: 21, y: 30)"
 ///
 /// After adding `CustomDebugStringConvertible` conformance by implementing the
 /// `debugDescription` property, `Point` provides its own custom debugging
@@ -236,12 +233,12 @@
 ///
 ///     extension Point: CustomDebugStringConvertible {
 ///         var debugDescription: String {
-///             return "Point(x: \(x), y: \(y))"
+///             return "(\(x), \(y))"
 ///         }
 ///     }
 ///
 ///     print(String(reflecting: p))
-///     // Prints "Point(x: 21, y: 30)"
+///     // Prints "(21, 30)"
 public protocol CustomDebugStringConvertible {
   /// A textual representation of this instance, suitable for debugging.
   ///
diff --git a/stdlib/public/core/StringObject.swift b/stdlib/public/core/StringObject.swift
index 30f3989..ebc2ce5 100644
--- a/stdlib/public/core/StringObject.swift
+++ b/stdlib/public/core/StringObject.swift
@@ -293,7 +293,7 @@
  on arm64.
 */
 extension _StringObject.Nibbles {
-  // The canonical empty sting is an empty small string
+  // The canonical empty string is an empty small string
   @inlinable @inline(__always)
   internal static var emptyString: UInt64 {
     return _StringObject.Nibbles.small(isASCII: true)
diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift
index 8576a86..40a134b 100644
--- a/stdlib/public/core/VarArgs.swift
+++ b/stdlib/public/core/VarArgs.swift
@@ -63,6 +63,17 @@
   var _cVarArgAlignment: Int { get }
 }
 
+#if !_runtime(_ObjC)
+/// Some pointers require an alternate object to be retained.  The object
+/// that is returned will be used with _cVarArgEncoding and held until
+/// the closure is complete.  This is required since autoreleased storage
+/// is not available on all platforms.
+public protocol _CVarArgObject: CVarArg {
+  /// Returns the alternate object that should be encoded.
+  var _cVarArgObject: CVarArg { get }
+}
+#endif
+
 #if arch(x86_64)
 @usableFromInline
 internal let _countGPRegisters = 6
@@ -462,6 +473,11 @@
   @usableFromInline // c-abi
   internal var storage: ContiguousArray<Int>
 
+#if !_runtime(_ObjC)
+  @usableFromInline // c-abi
+  internal var retainer = [CVarArg]()
+#endif
+
   @inlinable // c-abi
   internal init() {
     // prepare the register save area
@@ -473,6 +489,16 @@
 
   @inlinable // c-abi
   internal func append(_ arg: CVarArg) {
+#if !_runtime(_ObjC)
+    var arg = arg
+
+    // We may need to retain an object that provides a pointer value.
+    if let obj = arg as? _CVarArgObject {
+      arg = obj._cVarArgObject
+      retainer.append(arg)
+    }
+#endif
+
     var encoded = arg._cVarArgEncoding
 
 #if arch(x86_64) || arch(arm64)
@@ -560,6 +586,16 @@
 
   @inlinable // c-abi
   internal func append(_ arg: CVarArg) {
+#if !_runtime(_ObjC)
+    var arg = arg
+
+    // We may need to retain an object that provides a pointer value.
+    if let obj = arg as? _CVarArgObject {
+      arg = obj._cVarArgObject
+      retainer.append(arg)
+    }
+#endif
+
     // Write alignment padding if necessary.
     // This is needed on architectures where the ABI alignment of some
     // supported vararg type is greater than the alignment of Int, such
@@ -665,6 +701,11 @@
   @usableFromInline // c-abi
   internal var storage: UnsafeMutablePointer<Int>?
 
+#if !_runtime(_ObjC)
+  @usableFromInline // c-abi
+  internal var retainer = [CVarArg]()
+#endif
+
   internal static var alignedStorageForEmptyVaLists: Double = 0
 }
 
diff --git a/stdlib/public/runtime/DynamicCast.cpp b/stdlib/public/runtime/DynamicCast.cpp
index fa628e2..f848000 100644
--- a/stdlib/public/runtime/DynamicCast.cpp
+++ b/stdlib/public/runtime/DynamicCast.cpp
@@ -145,6 +145,9 @@
 
 // protocol _ObjectiveCBridgeable {
 struct _ObjectiveCBridgeableWitnessTable : WitnessTable {
+  #define _protocolWitnessSignedPointer(n) \
+    __ptrauth_swift_protocol_witness_function_pointer(SpecialPointerAuthDiscriminators::n##Discriminator) n
+
   static_assert(WitnessTableFirstRequirementOffset == 1,
                 "Witness table layout changed");
 
@@ -153,14 +156,14 @@
 
   // func _bridgeToObjectiveC() -> _ObjectiveCType
   SWIFT_CC(swift)
-  HeapObject *(*bridgeToObjectiveC)(
+  HeapObject *(*_protocolWitnessSignedPointer(bridgeToObjectiveC))(
                 SWIFT_CONTEXT OpaqueValue *self, const Metadata *Self,
                 const _ObjectiveCBridgeableWitnessTable *witnessTable);
 
   // class func _forceBridgeFromObjectiveC(x: _ObjectiveCType,
   //                                       inout result: Self?)
   SWIFT_CC(swift)
-  void (*forceBridgeFromObjectiveC)(
+  void (*_protocolWitnessSignedPointer(forceBridgeFromObjectiveC))(
          HeapObject *sourceValue,
          OpaqueValue *result,
          SWIFT_CONTEXT const Metadata *self,
@@ -170,7 +173,7 @@
   // class func _conditionallyBridgeFromObjectiveC(x: _ObjectiveCType,
   //                                              inout result: Self?) -> Bool
   SWIFT_CC(swift)
-  bool (*conditionallyBridgeFromObjectiveC)(
+  bool (*_protocolWitnessSignedPointer(conditionallyBridgeFromObjectiveC))(
          HeapObject *sourceValue,
          OpaqueValue *result,
          SWIFT_CONTEXT const Metadata *self,
@@ -862,6 +865,7 @@
       destFailureType, srcFailureType,
       takeOnSuccess, mayDeferChecks);
 #endif
+    SWIFT_FALLTHROUGH;
   }
   default:
     return DynamicCastResult::Failure;
diff --git a/stdlib/public/runtime/ImageInspectionMachO.cpp b/stdlib/public/runtime/ImageInspectionMachO.cpp
index 54c4d17..b233608 100644
--- a/stdlib/public/runtime/ImageInspectionMachO.cpp
+++ b/stdlib/public/runtime/ImageInspectionMachO.cpp
@@ -122,11 +122,7 @@
 
 #if OBJC_ADDLOADIMAGEFUNC_DEFINED && SWIFT_OBJC_INTEROP
 #define REGISTER_FUNC(...)                                               \
-  if (__builtin_available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)) { \
-    objc_addLoadImageFunc(__VA_ARGS__);                                  \
-  } else {                                                               \
-    _dyld_register_func_for_add_image(__VA_ARGS__);                      \
-  }
+    _dyld_register_func_for_add_image(__VA_ARGS__);
 #else
 #define REGISTER_FUNC(...) _dyld_register_func_for_add_image(__VA_ARGS__)
 #endif
diff --git a/stdlib/public/runtime/KeyPaths.cpp b/stdlib/public/runtime/KeyPaths.cpp
index faa6292..4afed3e 100644
--- a/stdlib/public/runtime/KeyPaths.cpp
+++ b/stdlib/public/runtime/KeyPaths.cpp
@@ -119,9 +119,6 @@
   YieldOnceTemporary::destroyAndDeallocateIn(buffer);
 }
 
-// The resilient offset to the start of KeyPath's class-specific data.
-extern "C" size_t MANGLE_SYM(s7KeyPathCMo);
-
 YieldOnceResult<const OpaqueValue*>
 swift::swift_readAtKeyPath(YieldOnceBuffer *buffer,
                            const OpaqueValue *root, void *keyPath) {
@@ -129,17 +126,7 @@
   // KeyPath is a native class, so we can just load its metadata directly
   // even on ObjC-interop targets.
   const Metadata *keyPathType = static_cast<HeapObject*>(keyPath)->metadata;
-
-  // To find the generic arguments, we just have to find the class-specific
-  // data section of the class; the generic arguments are always at the start
-  // of that.
-  //
-  // We use the resilient access pattern because it's easy; since we're within
-  // KeyPath's resilience domain, that's not really necessary, and it would
-  // be totally valid to hard-code an offset.
-  auto keyPathGenericArgs =
-    reinterpret_cast<const Metadata * const *>(
-      reinterpret_cast<const char*>(keyPathType) + MANGLE_SYM(s7KeyPathCMo));
+  auto keyPathGenericArgs = keyPathType->getGenericArgs();
   const Metadata *valueTy = keyPathGenericArgs[1];
 
   // Allocate the buffer.
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index a8e9f2a..56fd867 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -733,6 +733,7 @@
       auto key = MetadataCacheKey(cache.NumKeyParameters, cache.NumWitnessTables,
                                   arguments);
       auto result = cache.getOrInsert(key, MetadataRequest(MetadataState::Complete, /*isNonBlocking*/true), canonicalMetadata);
+      (void)result;
       assert(result.second.Value == canonicalMetadata);
     }
   } else {
@@ -744,6 +745,7 @@
       auto key = MetadataCacheKey(cache.NumKeyParameters, cache.NumWitnessTables,
                                   arguments);
       auto result = cache.getOrInsert(key, MetadataRequest(MetadataState::Complete, /*isNonBlocking*/true), canonicalMetadata);
+      (void)result;
       assert(result.second.Value == canonicalMetadata);
     }
   }
diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp
index c0c2f7c..fef3ff3 100644
--- a/stdlib/public/runtime/MetadataLookup.cpp
+++ b/stdlib/public/runtime/MetadataLookup.cpp
@@ -975,11 +975,13 @@
 
       str += "_gatherGenericParameters: context: ";
 
+#if !defined(SWIFT_RUNTIME_MACHO_NO_DYLD)
       SymbolInfo contextInfo;
       if (lookupSymbol(context, &contextInfo)) {
         str += contextInfo.symbolName.get();
         str += " ";
       }
+#endif
 
       char *contextStr;
       swift_asprintf(&contextStr, "%p", context);
diff --git a/stdlib/public/runtime/ReflectionMirror.mm b/stdlib/public/runtime/ReflectionMirror.mm
index 0206237..9a7b41e 100644
--- a/stdlib/public/runtime/ReflectionMirror.mm
+++ b/stdlib/public/runtime/ReflectionMirror.mm
@@ -328,8 +328,13 @@
   void *fptr;
   HeapObject *context;
 };
+#if SWIFT_LIBRARY_EVOLUTION
 SWIFT_RUNTIME_STDLIB_API SWIFT_CC(swift) swift_closure
 MANGLE_SYM(s20_playgroundPrintHookySScSgvg)();
+#else
+SWIFT_RUNTIME_STDLIB_API swift_closure
+MANGLE_SYM(s20_playgroundPrintHookySScSgvp);
+#endif
 
 static bool _shouldReportMissingReflectionMetadataWarnings() {
   // Missing metadata warnings noise up playground sessions and aren't really
@@ -339,7 +344,11 @@
   // Guesstimate whether we're in a playground by looking at the
   // _playgroundPrintHook variable in the standard library, which is set during
   // playground execution.
+  #if SWIFT_LIBRARY_EVOLUTION
   auto hook = MANGLE_SYM(s20_playgroundPrintHookySScSgvg)();
+  #else
+  auto hook = MANGLE_SYM(s20_playgroundPrintHookySScSgvp);
+  #endif
   if (hook.fptr) {
     swift_release(hook.context);
     return false;
diff --git a/stdlib/public/stubs/OptionalBridgingHelper.mm b/stdlib/public/stubs/OptionalBridgingHelper.mm
index 6145902..03fc52f 100644
--- a/stdlib/public/stubs/OptionalBridgingHelper.mm
+++ b/stdlib/public/stubs/OptionalBridgingHelper.mm
@@ -48,6 +48,7 @@
   int fmtResult = asprintf(&str, "<%s %p depth = %u>", clsName,
                                                        (void*)self,
                                                        self->depth);
+  (void)fmtResult;
   assert(fmtResult != -1 && "unable to format description of null");
   id result = swift_stdlib_NSStringFromUTF8(str, strlen(str));
   free(str);
diff --git a/test/AutoDiff/SILOptimizer/forward_mode_diagnostics.swift b/test/AutoDiff/SILOptimizer/forward_mode_diagnostics.swift
index ad21c18..3abe222 100644
--- a/test/AutoDiff/SILOptimizer/forward_mode_diagnostics.swift
+++ b/test/AutoDiff/SILOptimizer/forward_mode_diagnostics.swift
@@ -6,6 +6,7 @@
 // forward mode reaches feature parity with reverse mode.
 
 import _Differentiation
+import DifferentiationUnittest
 
 //===----------------------------------------------------------------------===//
 // Basic function
@@ -85,10 +86,8 @@
   return result
 }
 
-// FIXME(TF-984): Forward-mode crash due to unset tangent buffer.
-/*
 struct X: Differentiable {
-  var x : Float
+  var x: Float
 
   @differentiable(wrt: y)
   mutating func mutate(_ y: X) { self.x = y.x }
@@ -101,7 +100,6 @@
   x2.mutate(x1)
   return x1.x
 }
-*/
 
 
 struct Mut: Differentiable {}
@@ -240,12 +238,16 @@
   func move(along direction: TangentVector) {}
 }
 
-// FIXME(TF-984): Forward-mode crash due to unset tangent buffer.
+// SR-13464: Missing support for classes in forward-mode AD
 /*
+// xpected-error @+2 {{function is not differentiable}}
+// xpected-note @+3 {{when differentiating this function definition}}
 @differentiable
 @_silgen_name("test_class_tangent_property_wrong_type")
 func testClassTangentPropertyWrongType(_ c: ClassTangentPropertyWrongType) -> Float {
+  // xpected-warning @+1 {{variable 'tmp' was never mutated}}
   var tmp = c
+  // xpected-note @+1 {{cannot differentiate access to property 'ClassTangentPropertyWrongType.x' because 'ClassTangentPropertyWrongType.TangentVector.x' does not have expected type 'Float.TangentVector' (aka 'Float')}}
   return tmp.x
 }
 */
@@ -285,12 +287,16 @@
   func move(along direction: TangentVector) {}
 }
 
-// FIXME(TF-984): Forward-mode crash due to unset tangent buffer.
+// SR-13464: Missing support for classes in forward-mode AD
 /*
+// xpected-error @+2 {{function is not differentiable}}
+// xpected-note @+3 {{when differentiating this function definition}}
 @differentiable
 @_silgen_name("test_class_tangent_property_not_stored")
 func testClassTangentPropertyNotStored(_ c: ClassTangentPropertyNotStored) -> Float {
+  // xpected-warning @+1 {{variable 'tmp' was never mutated}}
   var tmp = c
+  // xpected-note @+1 {{cannot differentiate access to property 'ClassTangentPropertyNotStored.x' because 'ClassTangentPropertyNotStored.TangentVector.x' is not a stored property}}
   return tmp.x
 }
 */
diff --git a/test/AutoDiff/Sema/derivative_attr_type_checking.swift b/test/AutoDiff/Sema/derivative_attr_type_checking.swift
index 598dc36..451bf4d 100644
--- a/test/AutoDiff/Sema/derivative_attr_type_checking.swift
+++ b/test/AutoDiff/Sema/derivative_attr_type_checking.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %s
+// RUN: %target-swift-frontend-typecheck -enable-testing -verify -disable-availability-checking %s
 
 // Swift.AdditiveArithmetic:3:17: note: cannot yet register derivative default implementation for protocol requirements
 
diff --git a/test/AutoDiff/Sema/differentiable_attr_type_checking.swift b/test/AutoDiff/Sema/differentiable_attr_type_checking.swift
index a14090d..ac54b0b 100644
--- a/test/AutoDiff/Sema/differentiable_attr_type_checking.swift
+++ b/test/AutoDiff/Sema/differentiable_attr_type_checking.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend-typecheck -verify -disable-availability-checking %s
+// RUN: %target-swift-frontend-typecheck -enable-testing -verify -disable-availability-checking %s
 
 import _Differentiation
 
diff --git a/test/AutoDiff/Sema/transpose_attr_type_checking.swift b/test/AutoDiff/Sema/transpose_attr_type_checking.swift
index a49ff94..513e0b3 100644
--- a/test/AutoDiff/Sema/transpose_attr_type_checking.swift
+++ b/test/AutoDiff/Sema/transpose_attr_type_checking.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend-typecheck -verify %s
+// RUN: %target-swift-frontend-typecheck -enable-testing -verify %s
 
 import _Differentiation
 
diff --git a/test/AutoDiff/validation-test/forward_mode_array.swift b/test/AutoDiff/validation-test/forward_mode_array.swift
new file mode 100644
index 0000000..00b270d
--- /dev/null
+++ b/test/AutoDiff/validation-test/forward_mode_array.swift
@@ -0,0 +1,117 @@
+// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-forward-mode-differentiation)
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import DifferentiationUnittest
+
+var ForwardModeTests = TestSuite("ForwardModeDifferentiation")
+
+//===----------------------------------------------------------------------===//
+// Array methods from ArrayDifferentiation.swift
+//===----------------------------------------------------------------------===//
+
+typealias FloatArrayTan = Array<Float>.TangentVector
+
+ForwardModeTests.test("Array.+") {
+  func sumFirstThreeConcatenating(_ a: [Float], _ b: [Float]) -> Float {
+    let c = a + b
+    return c[0] + c[1] + c[2]
+  }
+
+  expectEqual(3, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1]), .init([1, 1])))
+  expectEqual(0, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([0, 0]), .init([0, 1])))
+  expectEqual(1, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([0, 1]), .init([0, 1])))
+  expectEqual(1, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 0]), .init([0, 1])))
+  expectEqual(1, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([0, 0]), .init([1, 1])))
+  expectEqual(2, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1]), .init([0, 1])))
+
+  expectEqual(
+    3,
+    differential(at: [0, 0, 0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1, 1, 1]), .init([1, 1])))
+  expectEqual(
+    3,
+    differential(at: [0, 0, 0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1, 1, 0]), .init([0, 0])))
+
+  expectEqual(
+    3,
+    differential(at: [], [0, 0, 0, 0], in: sumFirstThreeConcatenating)(.init([]), .init([1, 1, 1, 1])))
+  expectEqual(
+    0,
+    differential(at: [], [0, 0, 0, 0], in: sumFirstThreeConcatenating)(.init([]), .init([0, 0, 0, 1])))
+}
+
+ForwardModeTests.test("Array.init(repeating:count:)") {
+  @differentiable
+  func repeating(_ x: Float) -> [Float] {
+    Array(repeating: x, count: 10)
+  }
+  expectEqual(Float(10), derivative(at: .zero) { x in
+    repeating(x).differentiableReduce(0, {$0 + $1})
+  })
+  expectEqual(Float(20), differential(at: .zero, in: { x in
+    repeating(x).differentiableReduce(0, {$0 + $1})
+  })(2))
+}
+
+ForwardModeTests.test("Array.DifferentiableView.init") {
+  @differentiable
+  func constructView(_ x: [Float]) -> Array<Float>.DifferentiableView {
+    return Array<Float>.DifferentiableView(x)
+  }
+
+  let forward = differential(at: [5, 6, 7, 8], in: constructView)
+  expectEqual(
+    FloatArrayTan([1, 2, 3, 4]),
+    forward(FloatArrayTan([1, 2, 3, 4])))
+}
+
+ForwardModeTests.test("Array.DifferentiableView.base") {
+  @differentiable
+  func accessBase(_ x: Array<Float>.DifferentiableView) -> [Float] {
+    return x.base
+  }
+
+  let forward = differential(
+    at: Array<Float>.DifferentiableView([5, 6, 7, 8]),
+    in: accessBase)
+  expectEqual(
+    FloatArrayTan([1, 2, 3, 4]),
+    forward(FloatArrayTan([1, 2, 3, 4])))
+}
+
+ForwardModeTests.test("Array.differentiableMap") {
+  let x: [Float] = [1, 2, 3]
+  let tan = Array<Float>.TangentVector([1, 1, 1])
+
+  func multiplyMap(_ a: [Float]) -> [Float] {
+    return a.differentiableMap({ x in 3 * x })
+  }
+  expectEqual([3, 3, 3], differential(at: x, in: multiplyMap)(tan))
+
+  func squareMap(_ a: [Float]) -> [Float] {
+    return a.differentiableMap({ x in x * x })
+  }
+  expectEqual([2, 4, 6], differential(at: x, in: squareMap)(tan))
+}
+
+ForwardModeTests.test("Array.differentiableReduce") {
+  let x: [Float] = [1, 2, 3]
+  let tan = Array<Float>.TangentVector([1, 1, 1])
+
+  func sumReduce(_ a: [Float]) -> Float {
+    return a.differentiableReduce(0, { $0 + $1 })
+  }
+  expectEqual(1 + 1 + 1, differential(at: x, in: sumReduce)(tan))
+
+  func productReduce(_ a: [Float]) -> Float {
+    return a.differentiableReduce(1, { $0 * $1 })
+  }
+  expectEqual(x[1] * x[2] + x[0] * x[2] + x[0] * x[1], differential(at: x, in: productReduce)(tan))
+
+  func sumOfSquaresReduce(_ a: [Float]) -> Float {
+    return a.differentiableReduce(0, { $0 + $1 * $1 })
+  }
+  expectEqual(2 * x[0] + 2 * x[1] + 2 * x[2], differential(at: x, in: sumOfSquaresReduce)(tan))
+}
+
+runAllTests()
diff --git a/test/AutoDiff/validation-test/forward_mode_simd.swift b/test/AutoDiff/validation-test/forward_mode_simd.swift
new file mode 100644
index 0000000..03e600b
--- /dev/null
+++ b/test/AutoDiff/validation-test/forward_mode_simd.swift
@@ -0,0 +1,249 @@
+// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-forward-mode-differentiation)
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import DifferentiationUnittest
+
+var ForwardModeTests = TestSuite("ForwardModeDifferentiation")
+
+//===----------------------------------------------------------------------===//
+// SIMD methods from SIMDDifferentiation.swift.gyb
+// Tests replicate reverse mode tests from test/AutoDiff/stdlib/simd.swift
+//===----------------------------------------------------------------------===//
+
+ForwardModeTests.test("init(repeating:)") {
+  func foo1(x: Float) -> SIMD4<Float> {
+    return SIMD4<Float>(repeating: 2 * x)
+  }
+  let (val1, df1) = valueWithDifferential(at: 5, in: foo1)
+  expectEqual(SIMD4<Float>(10, 10, 10, 10), val1)
+  expectEqual(SIMD4<Float>(6, 6, 6, 6), df1(3))
+}
+
+ForwardModeTests.test("Identity") {
+  let a = SIMD4<Float>(1, 2, 3, 4)
+  let g = SIMD4<Float>(1, 1, 1, 1)
+
+  func foo1(x: SIMD4<Float>) -> SIMD4<Float> {
+    return x
+  }
+  let (val1, df1) = valueWithDifferential(at: a, in: foo1)
+  expectEqual(a, val1)
+  expectEqual(g, df1(.init(g)))
+}
+
+ForwardModeTests.test("Negate") {
+  let a = SIMD4<Float>(1, 2, 3, 4)
+  let g = SIMD4<Float>(1, 1, 1, 1)
+
+  func foo1(x: SIMD4<Float>) -> SIMD4<Float> {
+    return -x
+  }
+  let (val1, df1) = valueWithDifferential(at: a, in: foo1)
+  expectEqual(-a, val1)
+  expectEqual(-g, df1(.init(g)))
+}
+
+ForwardModeTests.test("subscript") {
+  let a = SIMD4<Float>(1, 2, 3, 4)
+
+  func foo1(x: SIMD4<Float>) -> Float {
+    return x[3]
+  }
+
+  let (val1, df1) = valueWithDifferential(at: a, in: foo1)
+  expectEqual(4, val1)
+  expectEqual(4, df1(a))
+}
+
+ForwardModeTests.test("Addition") {
+  let a = SIMD4<Float>(1, 2, 3, 4)
+  let g = SIMD4<Float>(1, 1, 1, 1)
+
+  // SIMD + SIMD
+  func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
+    return x + y
+  }
+  let (val1, df1) = valueWithDifferential(at: a, a, in: foo1)
+  expectEqual(SIMD4<Float>(2, 4, 6, 8), val1)
+  expectEqual(a + g, df1(a, g))
+
+  // SIMD + Scalar
+  func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
+    return x + y
+  }
+  let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
+  expectEqual(SIMD4<Float>(6, 7, 8, 9), val2)
+  expectEqual(g + 1, df2(g, 1))
+
+  // Scalar + SIMD
+  func foo3(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
+    return y + x
+  }
+  let (val3, df3) = valueWithDifferential(at: a, 5, in: foo3)
+  expectEqual(SIMD4<Float>(6, 7, 8, 9), val3)
+  expectEqual(2 + g, df3(g, 2))
+}
+
+ForwardModeTests.test("Subtraction") {
+  let a = SIMD4<Float>(1, 2, 3, 4)
+  let g = SIMD4<Float>(1, 1, 1, 1)
+
+  // SIMD - SIMD
+  func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
+    return x - y
+  }
+  let (val1, df1) = valueWithDifferential(at: a, a, in: foo1)
+  expectEqual(SIMD4<Float>(0, 0, 0, 0), val1)
+  expectEqual(g - a, df1(g, a))
+
+  // SIMD - Scalar
+  func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
+    return x - y
+  }
+  let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
+  expectEqual(SIMD4<Float>(-4, -3, -2, -1), val2)
+  expectEqual(g - 1, df2(g, 1))
+
+  // Scalar - SIMD
+  func foo3(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
+    return y - x
+  }
+  let (val3, df3) = valueWithDifferential(at: a, 5, in: foo3)
+  expectEqual(SIMD4<Float>(4, 3, 2, 1), val3)
+  expectEqual(2 - g, df3(g, 2))
+}
+
+ForwardModeTests.test("Multiplication") {
+  let a = SIMD4<Float>(1, 2, 3, 4)
+  let a2 = SIMD4<Float>(4, 3, 2, 1)
+  let g = SIMD4<Float>(1, 1, 1, 1)
+  let g2 = SIMD4<Float>(0, 2, 1, 3)
+
+  // SIMD * SIMD
+  func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
+    return x * y
+  }
+  let (val1, df1) = valueWithDifferential(at: a, a2, in: foo1)
+  expectEqual(a * a2, val1)
+  expectEqual(a * g2 + g * a2, df1(g, g2))
+
+  // SIMD * Scalar
+  func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
+    return x * y
+  }
+  let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
+  expectEqual(a * 5, val2)
+  expectEqual(a * 2 + g * 5, df2(g, 2))
+
+  // Scalar * SIMD
+  func foo3(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
+    return y * x
+  }
+  let (val3, df3) = valueWithDifferential(at: a, 5, in: foo3)
+  expectEqual(a * 5, val3)
+  expectEqual(a * 3 + g * 5, df3(g, 3))
+}
+
+ForwardModeTests.test("Division") {
+  let a = SIMD4<Float>(1, 2, 3, 4)
+  let g = SIMD4<Float>(1, 1, 1, 1)
+
+  // SIMD / SIMD
+  func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
+    return x / y
+  }
+  let (val1, df1) = valueWithDifferential(at: a, a, in: foo1)
+  expectEqual(a / a, val1)
+  expectEqual((g * a - a * g) / (a * a)/* == 0 */, df1(g, g))
+
+  // SIMD / Scalar
+  func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
+    return x / y
+  }
+  let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
+  expectEqual(a / 5, val2)
+  expectEqual((g * 5 - a * 2) / (5 * 5), df2(g, 2))
+
+  // Scalar / SIMD
+  func foo3(x: Float, y: SIMD4<Float>) -> SIMD4<Float> {
+    return x / y
+  }
+  let (val3, df3) = valueWithDifferential(at: 5, a, in: foo3)
+  expectEqual(5 / a, val3)
+  expectEqual((3 * a - 5 * g) / (a * a), df3(3, g))
+}
+
+ForwardModeTests.test("Generics") {
+  let a = SIMD3<Double>(1, 2, 3)
+  let g = SIMD3<Double>(1, 1, 1)
+
+  // FIXME(SR-13210): Fix forward-mode SIL verification error.
+  /*
+  func testInit<Scalar, SIMDType: SIMD>(x: Scalar) -> SIMDType
+    where SIMDType.Scalar == Scalar,
+          SIMDType : Differentiable,
+          Scalar : BinaryFloatingPoint & Differentiable,
+          SIMDType.TangentVector == SIMDType,
+          Scalar.TangentVector == Scalar {
+    return SIMDType.init(repeating: x)
+  }
+  func simd3Init(x: Double) -> SIMD3<Double> { testInit(x: x) }
+  let (val1, df1) = valueWithDifferential(at: 10, in: simd3Init)
+  expectEqual(SIMD3<Double>(10, 10, 10), val1)
+  expectEqual(SIMD3<Double>(5, 5, 5), df1(5))
+  */
+
+  // SIMDType + SIMDType
+  func testAddition<Scalar, SIMDType: SIMD>(lhs: SIMDType, rhs: SIMDType)
+    -> SIMDType
+    where SIMDType.Scalar == Scalar,
+          SIMDType : Differentiable,
+          SIMDType.TangentVector : SIMD,
+          Scalar : BinaryFloatingPoint,
+          SIMDType.TangentVector.Scalar : BinaryFloatingPoint {
+    return lhs + rhs
+  }
+  func simd3Add(lhs: SIMD3<Double>, rhs: SIMD3<Double>) -> SIMD3<Double> {
+    return testAddition(lhs: lhs, rhs: rhs)
+  }
+  let (val2, df2) = valueWithDifferential(at: a, a, in: simd3Add)
+  expectEqual(SIMD3<Double>(2, 4, 6), val2)
+  expectEqual(g + a, df2(g, a))
+
+  // Scalar - SIMDType
+  func testSubtraction<Scalar, SIMDType: SIMD>(lhs: Scalar, rhs: SIMDType)
+    -> SIMDType
+    where SIMDType.Scalar == Scalar,
+          SIMDType : Differentiable,
+          Scalar : BinaryFloatingPoint & Differentiable,
+          SIMDType.TangentVector == SIMDType,
+          Scalar.TangentVector == Scalar {
+    return lhs - rhs
+  }
+  func simd3Subtract(lhs: Double, rhs: SIMD3<Double>) -> SIMD3<Double> {
+    return testSubtraction(lhs: lhs, rhs: rhs)
+  }
+  let (val3, df3) = valueWithDifferential(at: 5, a, in: simd3Subtract)
+  expectEqual(SIMD3<Double>(4, 3, 2), val3)
+  expectEqual(2 - g, df3(2, g))
+
+  // SIMDType * Scalar
+  func testMultipication<Scalar, SIMDType: SIMD>(lhs: SIMDType, rhs: Scalar)
+    -> SIMDType
+    where SIMDType.Scalar == Scalar,
+      SIMDType : Differentiable,
+      Scalar : BinaryFloatingPoint & Differentiable,
+      SIMDType.TangentVector == SIMDType,
+      Scalar.TangentVector == Scalar {
+    return lhs * rhs
+  }
+  func simd3Multiply(lhs: SIMD3<Double>, rhs: Double) -> SIMD3<Double> {
+    return testMultipication(lhs: lhs, rhs: rhs)
+  }
+  let (val4, df4) = valueWithDifferential(at: a, 5, in: simd3Multiply)
+  expectEqual(SIMD3<Double>(5, 10, 15), val4)
+  expectEqual(a * 3 + g * 5 , df4(g, 3))
+}
+
+runAllTests()
diff --git a/test/AutoDiff/validation-test/forward_mode.swift b/test/AutoDiff/validation-test/forward_mode_simple.swift
similarity index 76%
rename from test/AutoDiff/validation-test/forward_mode.swift
rename to test/AutoDiff/validation-test/forward_mode_simple.swift
index c29b87f..57c85eb 100644
--- a/test/AutoDiff/validation-test/forward_mode.swift
+++ b/test/AutoDiff/validation-test/forward_mode_simple.swift
@@ -1319,352 +1319,74 @@
   expectEqual(5, forceUnwrap(Float(2)))
 }
 
-//===----------------------------------------------------------------------===//
-// Array methods from ArrayDifferentiation.swift
-//===----------------------------------------------------------------------===//
-
-typealias FloatArrayTan = Array<Float>.TangentVector
-
-ForwardModeTests.test("Array.+") {
-  func sumFirstThreeConcatenating(_ a: [Float], _ b: [Float]) -> Float {
-    let c = a + b
-    return c[0] + c[1] + c[2]
+ForwardModeTests.test("NonVariedResult") {
+  @differentiable(wrt: x)
+  func nonWrtInoutParam<T: Differentiable>(_ x: T, _ y: inout T) {
+    y = x
   }
 
-  expectEqual(3, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1]), .init([1, 1])))
-  expectEqual(0, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([0, 0]), .init([0, 1])))
-  expectEqual(1, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([0, 1]), .init([0, 1])))
-  expectEqual(1, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 0]), .init([0, 1])))
-  expectEqual(1, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([0, 0]), .init([1, 1])))
-  expectEqual(2, differential(at: [0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1]), .init([0, 1])))
-
-  expectEqual(
-    3,
-    differential(at: [0, 0, 0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1, 1, 1]), .init([1, 1])))
-  expectEqual(
-    3,
-    differential(at: [0, 0, 0, 0], [0, 0], in: sumFirstThreeConcatenating)(.init([1, 1, 1, 0]), .init([0, 0])))
-  
-  expectEqual(
-    3,
-    differential(at: [], [0, 0, 0, 0], in: sumFirstThreeConcatenating)(.init([]), .init([1, 1, 1, 1])))
-  expectEqual(
-    0,
-    differential(at: [], [0, 0, 0, 0], in: sumFirstThreeConcatenating)(.init([]), .init([0, 0, 0, 1])))
-}
-
-ForwardModeTests.test("Array.init(repeating:count:)") {
   @differentiable
-  func repeating(_ x: Float) -> [Float] {
-    Array(repeating: x, count: 10)
+  func wrtInoutParam<T: Differentiable>(_ x: T, _ y: inout T) {
+    y = x
   }
-  expectEqual(Float(10), derivative(at: .zero) { x in
-    repeating(x).differentiableReduce(0, {$0 + $1})
-  })
-  expectEqual(Float(20), differential(at: .zero, in: { x in
-    repeating(x).differentiableReduce(0, {$0 + $1})
-  })(2))
-}
 
-ForwardModeTests.test("Array.DifferentiableView.init") {
+  @differentiable(wrt: x)
+  func nonWrtInoutParamNonVaried<T: Differentiable>(_ x: T, _ y: inout T) {}
+
+  @differentiable(wrt: x)
+  func wrtInoutParamNonVaried<T: Differentiable>(_ x: T, _ y: inout T) {}
+
   @differentiable
-  func constructView(_ x: [Float]) -> Array<Float>.DifferentiableView {
-    return Array<Float>.DifferentiableView(x)
+  func variedResultTracked(_ x: Tracked<Float>) -> Tracked<Float> {
+    var result: Tracked<Float> = 0
+    nonWrtInoutParam(x, &result)
+    return result
   }
 
-  let forward = differential(at: [5, 6, 7, 8], in: constructView)
-  expectEqual(
-    FloatArrayTan([1, 2, 3, 4]),
-    forward(FloatArrayTan([1, 2, 3, 4])))
-}
-
-ForwardModeTests.test("Array.DifferentiableView.base") {
   @differentiable
-  func accessBase(_ x: Array<Float>.DifferentiableView) -> [Float] {
-    return x.base
+  func variedResultTracked2(_ x: Tracked<Float>) -> Tracked<Float> {
+    var result: Tracked<Float> = 0
+    wrtInoutParam(x, &result)
+    return result
   }
 
-  let forward = differential(
-    at: Array<Float>.DifferentiableView([5, 6, 7, 8]),
-    in: accessBase)
-  expectEqual(
-    FloatArrayTan([1, 2, 3, 4]),
-    forward(FloatArrayTan([1, 2, 3, 4])))
+  @differentiable
+  func nonVariedResultTracked(_ x: Tracked<Float>) -> Tracked<Float> {
+    var result: Tracked<Float> = 0
+    nonWrtInoutParamNonVaried(x, &result)
+    return result
+  }
+
+  @differentiable
+  func nonVariedResultTracked2(_ x: Tracked<Float>) -> Tracked<Float> {
+    // expected-warning @+1 {{variable 'result' was never mutated}}
+    var result: Tracked<Float> = 0
+    return result
+  }
+
+  @differentiable
+  func nonVariedResultTracked3(_ x: Tracked<Float>) -> Tracked<Float> {
+    return 0
+  }
+
+  @differentiable
+  func nonVariedResultTracked4(_ x: Tracked<Float>) -> Tracked<Float> {
+    var result: Tracked<Float> = 0
+    wrtInoutParamNonVaried(x, &result)
+    return result
+  }
 }
 
-ForwardModeTests.test("Array.differentiableMap") {
-  let x: [Float] = [1, 2, 3]
-  let tan = Array<Float>.TangentVector([1, 1, 1])
+ForwardModeTests.test("ApplyNonActiveIndirectResult") {
+  func identity<T: Differentiable>(_ x: T) -> T { x }
 
-  func multiplyMap(_ a: [Float]) -> [Float] {
-    return a.differentiableMap({ x in 3 * x })
+  @differentiable
+  func applyNonactiveArgumentActiveIndirectResult(_ x: Tracked<Float>) -> Tracked<Float> {
+    var y = identity(0 as Tracked<Float>)
+    y = x
+    return y
   }
-  expectEqual([3, 3, 3], differential(at: x, in: multiplyMap)(tan))
-
-  func squareMap(_ a: [Float]) -> [Float] {
-    return a.differentiableMap({ x in x * x })
-  }
-  expectEqual([2, 4, 6], differential(at: x, in: squareMap)(tan))
-}
-
-ForwardModeTests.test("Array.differentiableReduce") {
-  let x: [Float] = [1, 2, 3]
-  let tan = Array<Float>.TangentVector([1, 1, 1])
-
-  func sumReduce(_ a: [Float]) -> Float {
-    return a.differentiableReduce(0, { $0 + $1 })
-  }
-  expectEqual(1 + 1 + 1, differential(at: x, in: sumReduce)(tan))
-
-  func productReduce(_ a: [Float]) -> Float {
-    return a.differentiableReduce(1, { $0 * $1 })
-  }
-  expectEqual(x[1] * x[2] + x[0] * x[2] + x[0] * x[1], differential(at: x, in: productReduce)(tan))
-
-  func sumOfSquaresReduce(_ a: [Float]) -> Float {
-    return a.differentiableReduce(0, { $0 + $1 * $1 })
-  }
-  expectEqual(2 * x[0] + 2 * x[1] + 2 * x[2], differential(at: x, in: sumOfSquaresReduce)(tan))
-}
-
-//===----------------------------------------------------------------------===//
-// SIMD methods from SIMDDifferentiation.swift.gyb
-// Tests replicate reverse mode tests from test/AutoDiff/stdlib/simd.swift
-//===----------------------------------------------------------------------===//
-
-ForwardModeTests.test("init(repeating:)") {
-  func foo1(x: Float) -> SIMD4<Float> {
-    return SIMD4<Float>(repeating: 2 * x)
-  }
-  let (val1, df1) = valueWithDifferential(at: 5, in: foo1)
-  expectEqual(SIMD4<Float>(10, 10, 10, 10), val1)
-  expectEqual(SIMD4<Float>(6, 6, 6, 6), df1(3))
-}
-
-ForwardModeTests.test("Identity") {
-  let a = SIMD4<Float>(1, 2, 3, 4)
-  let g = SIMD4<Float>(1, 1, 1, 1)
-
-  func foo1(x: SIMD4<Float>) -> SIMD4<Float> {
-    return x
-  }
-  let (val1, df1) = valueWithDifferential(at: a, in: foo1)
-  expectEqual(a, val1)
-  expectEqual(g, df1(.init(g)))
-}
-
-ForwardModeTests.test("Negate") {
-  let a = SIMD4<Float>(1, 2, 3, 4)
-  let g = SIMD4<Float>(1, 1, 1, 1)
-
-  func foo1(x: SIMD4<Float>) -> SIMD4<Float> {
-    return -x
-  }
-  let (val1, df1) = valueWithDifferential(at: a, in: foo1)
-  expectEqual(-a, val1)
-  expectEqual(-g, df1(.init(g)))
-}
-
-ForwardModeTests.test("subscript") {
-  let a = SIMD4<Float>(1, 2, 3, 4)
-
-  func foo1(x: SIMD4<Float>) -> Float {
-    return x[3]
-  }
-
-  let (val1, df1) = valueWithDifferential(at: a, in: foo1)
-  expectEqual(4, val1)
-  expectEqual(4, df1(a))
-}
-
-ForwardModeTests.test("Addition") {
-  let a = SIMD4<Float>(1, 2, 3, 4)
-  let g = SIMD4<Float>(1, 1, 1, 1)
-
-  // SIMD + SIMD
-  func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
-    return x + y
-  }
-  let (val1, df1) = valueWithDifferential(at: a, a, in: foo1)
-  expectEqual(SIMD4<Float>(2, 4, 6, 8), val1)
-  expectEqual(a + g, df1(a, g))
-
-  // SIMD + Scalar
-  func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
-    return x + y
-  }
-  let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
-  expectEqual(SIMD4<Float>(6, 7, 8, 9), val2)
-  expectEqual(g + 1, df2(g, 1))
-
-  // Scalar + SIMD
-  func foo3(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
-    return y + x
-  }
-  let (val3, df3) = valueWithDifferential(at: a, 5, in: foo3)
-  expectEqual(SIMD4<Float>(6, 7, 8, 9), val3)
-  expectEqual(2 + g, df3(g, 2))
-}
-
-ForwardModeTests.test("Subtraction") {
-  let a = SIMD4<Float>(1, 2, 3, 4)
-  let g = SIMD4<Float>(1, 1, 1, 1)
-
-  // SIMD - SIMD
-  func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
-    return x - y
-  }
-  let (val1, df1) = valueWithDifferential(at: a, a, in: foo1)
-  expectEqual(SIMD4<Float>(0, 0, 0, 0), val1)
-  expectEqual(g - a, df1(g, a))
-
-  // SIMD - Scalar
-  func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
-    return x - y
-  }
-  let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
-  expectEqual(SIMD4<Float>(-4, -3, -2, -1), val2)
-  expectEqual(g - 1, df2(g, 1))
-
-  // Scalar - SIMD
-  func foo3(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
-    return y - x
-  }
-  let (val3, df3) = valueWithDifferential(at: a, 5, in: foo3)
-  expectEqual(SIMD4<Float>(4, 3, 2, 1), val3)
-  expectEqual(2 - g, df3(g, 2))
-}
-
-ForwardModeTests.test("Multiplication") {
-  let a = SIMD4<Float>(1, 2, 3, 4)
-  let a2 = SIMD4<Float>(4, 3, 2, 1)
-  let g = SIMD4<Float>(1, 1, 1, 1)
-  let g2 = SIMD4<Float>(0, 2, 1, 3)
-
-  // SIMD * SIMD
-  func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
-    return x * y
-  }
-  let (val1, df1) = valueWithDifferential(at: a, a2, in: foo1)
-  expectEqual(a * a2, val1)
-  expectEqual(a * g2 + g * a2, df1(g, g2))
-
-  // SIMD * Scalar
-  func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
-    return x * y
-  }
-  let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
-  expectEqual(a * 5, val2)
-  expectEqual(a * 2 + g * 5, df2(g, 2))
-
-  // Scalar * SIMD
-  func foo3(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
-    return y * x
-  }
-  let (val3, df3) = valueWithDifferential(at: a, 5, in: foo3)
-  expectEqual(a * 5, val3)
-  expectEqual(a * 3 + g * 5, df3(g, 3))
-}
-
-ForwardModeTests.test("Division") {
-  let a = SIMD4<Float>(1, 2, 3, 4)
-  let g = SIMD4<Float>(1, 1, 1, 1)
-
-  // SIMD / SIMD
-  func foo1(x: SIMD4<Float>, y: SIMD4<Float>) -> SIMD4<Float> {
-    return x / y
-  }
-  let (val1, df1) = valueWithDifferential(at: a, a, in: foo1)
-  expectEqual(a / a, val1)
-  expectEqual((g * a - a * g) / (a * a)/* == 0 */, df1(g, g))
-
-  // SIMD / Scalar
-  func foo2(x: SIMD4<Float>, y: Float) -> SIMD4<Float> {
-    return x / y
-  }
-  let (val2, df2) = valueWithDifferential(at: a, 5, in: foo2)
-  expectEqual(a / 5, val2)
-  expectEqual((g * 5 - a * 2) / (5 * 5), df2(g, 2))
-
-  // Scalar / SIMD
-  func foo3(x: Float, y: SIMD4<Float>) -> SIMD4<Float> {
-    return x / y
-  }
-  let (val3, df3) = valueWithDifferential(at: 5, a, in: foo3)
-  expectEqual(5 / a, val3)
-  expectEqual((3 * a - 5 * g) / (a * a), df3(3, g))
-}
-
-ForwardModeTests.test("Generics") {
-  let a = SIMD3<Double>(1, 2, 3)
-  let g = SIMD3<Double>(1, 1, 1)
-
-  // FIXME(SR-13210): Fix forward-mode SIL verification error.
-  /*
-  func testInit<Scalar, SIMDType: SIMD>(x: Scalar) -> SIMDType
-    where SIMDType.Scalar == Scalar,
-          SIMDType : Differentiable,
-          Scalar : BinaryFloatingPoint & Differentiable,
-          SIMDType.TangentVector == SIMDType,
-          Scalar.TangentVector == Scalar {
-    return SIMDType.init(repeating: x)
-  }
-  func simd3Init(x: Double) -> SIMD3<Double> { testInit(x: x) }
-  let (val1, df1) = valueWithDifferential(at: 10, in: simd3Init)
-  expectEqual(SIMD3<Double>(10, 10, 10), val1)
-  expectEqual(SIMD3<Double>(5, 5, 5), df1(5))
-  */
-
-  // SIMDType + SIMDType
-  func testAddition<Scalar, SIMDType: SIMD>(lhs: SIMDType, rhs: SIMDType)
-    -> SIMDType
-    where SIMDType.Scalar == Scalar,
-          SIMDType : Differentiable,
-          SIMDType.TangentVector : SIMD,
-          Scalar : BinaryFloatingPoint,
-          SIMDType.TangentVector.Scalar : BinaryFloatingPoint {
-    return lhs + rhs
-  }
-  func simd3Add(lhs: SIMD3<Double>, rhs: SIMD3<Double>) -> SIMD3<Double> {
-    return testAddition(lhs: lhs, rhs: rhs)
-  }
-  let (val2, df2) = valueWithDifferential(at: a, a, in: simd3Add)
-  expectEqual(SIMD3<Double>(2, 4, 6), val2)
-  expectEqual(g + a, df2(g, a))
-
-  // Scalar - SIMDType
-  func testSubtraction<Scalar, SIMDType: SIMD>(lhs: Scalar, rhs: SIMDType)
-    -> SIMDType
-    where SIMDType.Scalar == Scalar,
-          SIMDType : Differentiable,
-          Scalar : BinaryFloatingPoint & Differentiable,
-          SIMDType.TangentVector == SIMDType,
-          Scalar.TangentVector == Scalar {
-    return lhs - rhs
-  }
-  func simd3Subtract(lhs: Double, rhs: SIMD3<Double>) -> SIMD3<Double> {
-    return testSubtraction(lhs: lhs, rhs: rhs)
-  }
-  let (val3, df3) = valueWithDifferential(at: 5, a, in: simd3Subtract)
-  expectEqual(SIMD3<Double>(4, 3, 2), val3)
-  expectEqual(2 - g, df3(2, g))
-
-  // SIMDType * Scalar
-  func testMultipication<Scalar, SIMDType: SIMD>(lhs: SIMDType, rhs: Scalar)
-    -> SIMDType
-    where SIMDType.Scalar == Scalar,
-      SIMDType : Differentiable,
-      Scalar : BinaryFloatingPoint & Differentiable,
-      SIMDType.TangentVector == SIMDType,
-      Scalar.TangentVector == Scalar {
-    return lhs * rhs
-  }
-  func simd3Multiply(lhs: SIMD3<Double>, rhs: Double) -> SIMD3<Double> {
-    return testMultipication(lhs: lhs, rhs: rhs)
-  }
-  let (val4, df4) = valueWithDifferential(at: a, 5, in: simd3Multiply)
-  expectEqual(SIMD3<Double>(5, 10, 15), val4)
-  expectEqual(a * 3 + g * 5 , df4(g, 3))
+  expectEqual(1.0, derivative(at: 2, in: applyNonactiveArgumentActiveIndirectResult))
 }
 
 runAllTests()
diff --git a/test/AutoDiff/validation-test/optional-property.swift b/test/AutoDiff/validation-test/optional-property.swift
new file mode 100644
index 0000000..000433f
--- /dev/null
+++ b/test/AutoDiff/validation-test/optional-property.swift
@@ -0,0 +1,208 @@
+// RUN: %target-run-simple-swift
+// RUN: %target-swift-emit-sil -Xllvm -debug-only=differentiation -o /dev/null 2>&1 %s | %FileCheck %s
+// REQUIRES: executable_test
+// REQUIRES: asserts
+
+// Test differentiation of `Optional` properties.
+
+import DifferentiationUnittest
+import StdlibUnittest
+
+var OptionalTests = TestSuite("OptionalPropertyDifferentiation")
+
+// Test `Optional` struct stored properties.
+
+struct Struct: Differentiable {
+  var stored: Float
+  var optional: Float?
+
+  @differentiable
+  func method() -> Float {
+    let s: Struct
+    do {
+      let tmp = Struct(stored: stored, optional: optional)
+      let tuple = (tmp, tmp)
+      s = tuple.0
+    }
+    if let x = s.optional {
+      return x * s.stored
+    }
+    return s.stored
+  }
+}
+
+// Check active SIL instructions in representative original functions.
+// This tests SIL instruction coverage of derivative function cloners (e.g. PullbackCloner).
+
+// CHECK-LABEL: [AD] Activity info for ${{.*}}Struct{{.*}}method{{.*}} at (parameters=(0) results=(0))
+// CHECK:   [ACTIVE] {{.*}} struct_extract {{%.*}} : $Struct, #Struct.stored
+// CHECK:   [ACTIVE] {{.*}} struct_extract {{%.*}} : $Struct, #Struct.optional
+// CHECK:   [ACTIVE] {{.*}} tuple ({{%.*}} : $Struct, {{%.*}} : $Struct)
+// CHECK:   [ACTIVE] {{.*}} destructure_tuple {{%.*}} : $(Struct, Struct)
+// CHECK:   [ACTIVE] {{.*}} struct_element_addr {{%.*}} : $*Struct, #Struct.optional
+// CHECK:   [ACTIVE] {{.*}} struct_element_addr {{%.*}} : $*Struct, #Struct.stored
+// CHECK-LABEL: End activity info for ${{.*}}Struct{{.*}}method{{.*}} at (parameters=(0) results=(0))
+
+// CHECK-LABEL: [AD] Activity info for $s4null6StructV6stored8optionalACSf_SfSgtcfC at (parameters=(0 1) results=(0))
+// CHECK:   [ACTIVE]   {{%.*}} struct $Struct ({{%.*}} : $Float, {{%.*}} : $Optional<Float>)
+// CHECK-LABEL: End activity info for $s4null6StructV6stored8optionalACSf_SfSgtcfC at (parameters=(0 1) results=(0))
+
+struct StructTracked: Differentiable {
+  var stored: NonresilientTracked<Float>
+  var optional: NonresilientTracked<Float>?
+
+  @differentiable
+  func method() -> NonresilientTracked<Float> {
+    let s: StructTracked
+    do {
+      let tmp = StructTracked(stored: stored, optional: optional)
+      let tuple = (tmp, tmp)
+      s = tuple.0
+    }
+    if let x = s.optional {
+      return x * s.stored
+    }
+    return s.stored
+  }
+}
+
+struct StructGeneric<T: Differentiable>: Differentiable {
+  var stored: T
+  var optional: T?
+
+  @differentiable
+  func method() -> T {
+    let s: StructGeneric
+    do {
+      let tmp = StructGeneric(stored: stored, optional: optional)
+      let tuple = (tmp, tmp)
+      s = tuple.0
+    }
+    if let x = s.optional {
+      return x
+    }
+    return s.stored
+  }
+}
+
+OptionalTests.test("Optional struct stored properties") {
+  expectEqual(
+    valueWithGradient(at: Struct(stored: 3, optional: 4), in: { $0.method() }),
+    (12, .init(stored: 4, optional: .init(3))))
+  expectEqual(
+    valueWithGradient(at: Struct(stored: 3, optional: nil), in: { $0.method() }),
+    (3, .init(stored: 1, optional: .init(0))))
+
+  expectEqual(
+    valueWithGradient(at: StructTracked(stored: 3, optional: 4), in: { $0.method() }),
+    (12, .init(stored: 4, optional: .init(3))))
+  expectEqual(
+    valueWithGradient(at: StructTracked(stored: 3, optional: nil), in: { $0.method() }),
+    (3, .init(stored: 1, optional: .init(0))))
+
+  expectEqual(
+    valueWithGradient(at: StructGeneric<Float>(stored: 3, optional: 4), in: { $0.method() }),
+    (4, .init(stored: 0, optional: .init(1))))
+  expectEqual(
+    valueWithGradient(at: StructGeneric<Float>(stored: 3, optional: nil), in: { $0.method() }),
+    (3, .init(stored: 1, optional: .init(0))))
+}
+
+// Test `Optional` class stored properties.
+
+struct Class: Differentiable {
+  var stored: Float
+  var optional: Float?
+
+  init(stored: Float, optional: Float?) {
+    self.stored = stored
+    self.optional = optional
+  }
+
+  @differentiable
+  func method() -> Float {
+    let c: Class
+    do {
+      let tmp = Class(stored: stored, optional: optional)
+      let tuple = (tmp, tmp)
+      c = tuple.0
+    }
+    if let x = c.optional {
+      return x * c.stored
+    }
+    return c.stored
+  }
+}
+
+struct ClassTracked: Differentiable {
+  var stored: NonresilientTracked<Float>
+  var optional: NonresilientTracked<Float>?
+
+  init(stored: NonresilientTracked<Float>, optional: NonresilientTracked<Float>?) {
+    self.stored = stored
+    self.optional = optional
+  }
+
+  @differentiable
+  func method() -> NonresilientTracked<Float> {
+    let c: ClassTracked
+    do {
+      let tmp = ClassTracked(stored: stored, optional: optional)
+      let tuple = (tmp, tmp)
+      c = tuple.0
+    }
+    if let x = c.optional {
+      return x * c.stored
+    }
+    return c.stored
+  }
+}
+
+struct ClassGeneric<T: Differentiable>: Differentiable {
+  var stored: T
+  var optional: T?
+
+  init(stored: T, optional: T?) {
+    self.stored = stored
+    self.optional = optional
+  }
+
+  @differentiable
+  func method() -> T {
+    let c: ClassGeneric
+    do {
+      let tmp = ClassGeneric(stored: stored, optional: optional)
+      let tuple = (tmp, tmp)
+      c = tuple.0
+    }
+    if let x = c.optional {
+      return x
+    }
+    return c.stored
+  }
+}
+
+OptionalTests.test("Optional class stored properties") {
+  expectEqual(
+    valueWithGradient(at: Class(stored: 3, optional: 4), in: { $0.method() }),
+    (12, .init(stored: 4, optional: .init(3))))
+  expectEqual(
+    valueWithGradient(at: Class(stored: 3, optional: nil), in: { $0.method() }),
+    (3, .init(stored: 1, optional: .init(0))))
+
+  expectEqual(
+    valueWithGradient(at: ClassTracked(stored: 3, optional: 4), in: { $0.method() }),
+    (12, .init(stored: 4, optional: .init(3))))
+  expectEqual(
+    valueWithGradient(at: ClassTracked(stored: 3, optional: nil), in: { $0.method() }),
+    (3, .init(stored: 1, optional: .init(0))))
+
+  expectEqual(
+    valueWithGradient(at: ClassGeneric<Tracked<Float>>(stored: 3, optional: 4), in: { $0.method() }),
+    (4, .init(stored: 0, optional: .init(1))))
+  expectEqual(
+    valueWithGradient(at: ClassGeneric<Tracked<Float>>(stored: 3, optional: nil), in: { $0.method() }),
+    (3, .init(stored: 1, optional: .init(0))))
+}
+
+runAllTests()
diff --git a/test/AutoDiff/validation-test/optional.swift b/test/AutoDiff/validation-test/optional.swift
index 455fa09..09aa84d 100644
--- a/test/AutoDiff/validation-test/optional.swift
+++ b/test/AutoDiff/validation-test/optional.swift
@@ -1,6 +1,8 @@
 // RUN: %target-run-simple-swift
 // REQUIRES: executable_test
 
+// Test differentiation of `Optional` values and operations.
+
 import DifferentiationUnittest
 import StdlibUnittest
 
@@ -10,7 +12,6 @@
 // Basic tests.
 //===----------------------------------------------------------------------===//
 
-
 // TODO(TF-433): operator `??` lowers to an active `try_apply`.
 /*
 @differentiable
@@ -267,7 +268,7 @@
     (.init(.init(0.0)), 1.0))
 }
 
-OptionalTests.test("Var1") {
+OptionalTests.test("Optional binding: if let") {
   @differentiable
   func optional_var1(_ maybeX: Float?) -> Float {
     var maybeX = maybeX
@@ -393,7 +394,7 @@
     (.init(.init(0.0)), 1.0))
 }
 
-OptionalTests.test("Var2") {
+OptionalTests.test("Optional binding: if var") {
   @differentiable
   func optional_var2(_ maybeX: Float?) -> Float {
     if var x = maybeX {
diff --git a/test/ClangImporter/objc_async.swift b/test/ClangImporter/objc_async.swift
index 15b149a..1a30f41 100644
--- a/test/ClangImporter/objc_async.swift
+++ b/test/ClangImporter/objc_async.swift
@@ -1,16 +1,14 @@
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -I %S/Inputs/custom-modules -enable-experimental-concurrency %s -verify
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/Inputs/custom-modules -enable-experimental-concurrency %s -verify
 
 // REQUIRES: objc_interop
 import Foundation
 import ObjCConcurrency
 
-func testSlowServer(slowServer: SlowServer) async {
+func testSlowServer(slowServer: SlowServer) async throws {
   let _: Int = await slowServer.doSomethingSlow("mail")
   let _: Bool = await slowServer.checkAvailability()
-  let _: String = await slowServer.findAnswer() ?? "nope"
-  let _: String = await slowServer.findAnswerFailingly() ?? "nope"
-  // FIXME: expected-error@-2{{call can throw, but it is not marked with 'try'}}
-  // FIXME: expected-error@-2{{call can throw, but it is not marked with 'try'}}
+  let _: String = try await slowServer.findAnswer() ?? "nope"
+  let _: String = await try slowServer.findAnswerFailingly() ?? "nope"
   let _: Void = await slowServer.doSomethingFun("jump")
   let _: (Int) -> Void = slowServer.completionHandler
 }
diff --git a/test/Constraints/argument_matching.swift b/test/Constraints/argument_matching.swift
index c29b9c9..c321aa3 100644
--- a/test/Constraints/argument_matching.swift
+++ b/test/Constraints/argument_matching.swift
@@ -305,6 +305,93 @@
 variadics6(x: 1) // expected-error{{missing argument for parameter 'z' in call}}
 variadics6() // expected-error{{missing argument for parameter 'z' in call}}
 
+func variadics7(_ x: Int..., y: Int...) { }
+
+// Using multiple variadics (in order, complete)
+variadics7(1, y: 2)
+variadics7(1, 2, 3, y: 4, 5, 6)
+variadics7(1, 2, y: 2)
+variadics7(1, y: 2, 1)
+
+// multiple variadics, in order, some missing
+variadics7(y: 1)
+variadics7(1)
+variadics7(y: 4, 5, 6)
+variadics7(1, 2, 3)
+
+func variadics8(x: Int..., y: Int...) { }
+
+// multiple variadics, out of order
+variadics8(y: 1, x: 2) // expected-error {{argument 'x' must precede argument 'y'}} {{12-12=x: 2, }} {{16-22=}}
+variadics8(y: 1, 2, 3, x: 4) // expected-error {{argument 'x' must precede argument 'y'}} {{12-12=x: 4, }} {{22-28=}}
+variadics8(y: 1, x: 2, 3, 4) // expected-error {{argument 'x' must precede argument 'y'}} {{12-12=x: 2, 3, 4, }} {{16-28=}}
+variadics8(y: 1, 2, 3, x: 4, 5, 6) // expected-error {{argument 'x' must precede argument 'y'}} {{12-12=x: 4, 5, 6, }} {{22-34=}}
+
+func variadics9(_ a: Int..., b: Int, _ c: Int...) { } // expected-note {{'variadics9(_:b:_:)' declared here}}
+
+// multiple split variadics, in order, complete
+variadics9(1, b: 2, 3)
+variadics9(1, 2, 3, b: 2, 3)
+variadics9(1, b: 2, 3, 2, 1)
+variadics9(1, 2, 3, b: 2, 3, 2, 1)
+
+// multiple split variadics, in order, some missing
+variadics9(b: 2, 3)
+variadics9(1, b: 2)
+variadics9(1, 2, b: 2)
+variadics9(b: 2, 3, 2, 1)
+
+// multiple split variadics, required missing
+variadics9(1) // expected-error {{missing argument for parameter 'b' in call}}
+
+func variadics10(_ a: Int..., b: Int = 2, _ c: Int...) { }
+
+// multiple unlabeled variadics split by defaulted param, in order, complete
+variadics10(1, b: 2, 3)
+variadics10(1, 2, 3, b: 2, 3)
+variadics10(1, b: 2, 3, 2, 1)
+variadics10(1, 2, 3, b: 2, 3, 2, 1)
+
+// multiple unlabeled variadics split by defaulted param, in order, some missing
+variadics10(1, 2, 3)
+variadics10(1, 2, 3, b: 3)
+variadics10(b: 3)
+
+func variadics11(_ a: Int..., b: Bool = false, _ c: String...) { }
+
+variadics11(1, 2, 3, b: true, "hello", "world")
+variadics11(b: true, "hello", "world")
+variadics11(1, 2, 3, b: true)
+variadics11(b: true)
+variadics11()
+variadics11(1, 2, 3, "hello", "world") // expected-error 2 {{cannot convert value of type 'String' to expected argument type 'Int'}}
+
+func variadics12(a: Int..., b: Int, c: Int...) { }
+
+variadics12(a: 1, 2, 3, b: 4, c: 5, 6, 7)
+variadics12(b: 4, c: 5, 6, 7)
+variadics12(a: 1, 2, 3, b: 4)
+
+variadics12(c: 5, 6, 7, b: 4, a: 1, 2, 3) // expected-error {{incorrect argument labels in call (have 'c:_:_:b:a:_:_:', expected 'a:b:c:')}} {{13-14=a}} {{19-19=b: }} {{22-22=c: }} {{25-28=}} {{31-34=}}
+
+
+// Edge cases involving multiple trailing closures and forward matching.
+func variadics13(a: Int..., b: (()->Void)...) {}
+
+variadics13()
+variadics13(a: 1, 2, 3) {} _: {} _: {}
+variadics13() {} _: {} _: {}
+variadics13(a: 1, 2, 3)
+variadics13(a: 1, 2, 3) {}
+
+func variadics14(a: (()->Void)..., b: (()->Void)...) {} // expected-note {{'variadics14(a:b:)' declared here}}
+
+variadics14(a: {}, {}, b: {}, {})
+variadics14(a: {}, {}) {} _: {}
+variadics14 {} _: {} b: {} _: {}
+variadics14 {} b: {}
+variadics14 {} // expected-warning {{backward matching of the unlabeled trailing closure is deprecated; label the argument with 'b' to suppress this warning}}
+
 func outOfOrder(_ a : Int, b: Int) {
   outOfOrder(b: 42, 52)  // expected-error {{unnamed argument #2 must precede argument 'b'}} {{14-14=52, }} {{19-23=}}
 }
@@ -1336,6 +1423,26 @@
 d = sub2[d: d]
 d = sub2[f: d] // expected-error{{incorrect argument label in subscript (have 'f:', expected 'd:')}} {{10-11=d}}
 
+struct Sub3 {
+  subscript (a: Int..., b b: Int...) -> Int { 42 }
+}
+
+let sub3 = Sub3()
+_ = sub3[1, 2, 3, b: 4, 5, 6]
+_ = sub3[b: 4, 5, 6]
+_ = sub3[1, 2, 3]
+_ = sub3[1, c: 4] // expected-error {{incorrect argument label in subscript (have '_:c:', expected '_:b:')}}
+
+struct Sub4 {
+  subscript (a: Int..., b b: Int = 0, c: Int...) -> Int { 42 }
+}
+
+let sub4 = Sub4()
+_ = sub4[1, 2, 3, b: 2, 1, 2, 3]
+_ = sub4[1, 2, 3, b: 2]
+_ = sub4[1, 2, 3]
+_ = sub4[]
+
 // -------------------------------------------
 // Closures
 // -------------------------------------------
diff --git a/test/Constraints/async.swift b/test/Constraints/async.swift
index 756ee4e..e325ef2 100644
--- a/test/Constraints/async.swift
+++ b/test/Constraints/async.swift
@@ -7,3 +7,88 @@
   let _: () -> Void = doAsynchronously // expected-error{{cannot convert value of type '() async -> ()' to specified type '() -> Void'}}
   let _: () async -> Void = doSynchronously // expected-error{{cannot convert value of type '() -> ()' to specified type '() async -> Void'}}
 }
+
+// Overloading
+@available(swift, deprecated: 4.0, message: "synchronous is no fun")
+func overloadedSame() -> String { "synchronous" }
+
+func overloadedSame() async -> String { "asynchronous" }
+
+func overloaded() -> String { "synchronous" }
+func overloaded() async -> Double { 3.14159 }
+
+@available(swift, deprecated: 4.0, message: "synchronous is no fun")
+func overloadedOptDifference() -> String { "synchronous" }
+
+func overloadedOptDifference() async -> String? { nil }
+
+func testOverloadedSync() {
+  _ = overloadedSame() // expected-warning{{synchronous is no fun}}
+
+  let _: String? = overloadedOptDifference() // expected-warning{{synchronous is no fun}}
+
+  let _ = overloaded()
+  let fn = {
+    overloaded()
+  }
+  let _: Int = fn // expected-error{{value of type '() -> String'}}
+
+  let fn2 = {
+    print("fn2")
+    _ = overloaded()
+  }
+  let _: Int = fn2 // expected-error{{value of type '() -> ()'}}
+
+  let fn3 = {
+    await overloaded()
+  }
+  let _: Int = fn3 // expected-error{{value of type '() async -> Double'}}
+
+  let fn4 = {
+    print("fn2")
+    _ = await overloaded()
+  }
+  let _: Int = fn4 // expected-error{{value of type '() async -> ()'}}
+}
+
+func testOverloadedAsync() async {
+  _ = await overloadedSame() // no warning
+
+  let _: String? = await overloadedOptDifference() // no warning
+
+  let _ = await overloaded()
+  let _ = overloaded() // expected-error{{call is 'async' but is not marked with 'await'}}
+
+  let fn = {
+    overloaded()
+  }
+  let _: Int = fn // expected-error{{value of type '() -> String'}}
+
+  let fn2 = {
+    print("fn2")
+    _ = overloaded()
+  }
+  let _: Int = fn2 // expected-error{{value of type '() -> ()'}}
+
+  let fn3 = {
+    await overloaded()
+  }
+  let _: Int = fn3 // expected-error{{value of type '() async -> Double'}}
+
+  let fn4 = {
+    print("fn2")
+    _ = await overloaded()
+  }
+  let _: Int = fn4 // expected-error{{value of type '() async -> ()'}}
+}
+
+func takesAsyncClosure(_ closure: () async -> String) -> Int { 0 }
+func takesAsyncClosure(_ closure: () -> String) -> String { "" }
+
+func testPassAsyncClosure() {
+  let a = takesAsyncClosure { await overloadedSame() }
+  let _: Double = a // expected-error{{convert value of type 'Int'}}
+
+  let b = takesAsyncClosure { overloadedSame() } // expected-warning{{synchronous is no fun}}
+  let _: Double = b // expected-error{{convert value of type 'String'}}
+}
diff --git a/test/Constraints/casts.swift b/test/Constraints/casts.swift
index 0ea5745..c63dc73 100644
--- a/test/Constraints/casts.swift
+++ b/test/Constraints/casts.swift
@@ -252,11 +252,11 @@
 
   _ = (str ?? "") as Int // expected-error {{cannot convert value of type 'String' to type 'Int' in coercion}}
   _ = (optStr ?? "") as Int // expected-error {{cannot convert value of type 'String' to type 'Int' in coercion}}
-  _ = (optStr ?? "") as Int? // expected-error {{cannot convert value of type 'String' to type 'Int?' in coercion}}
+  _ = (optStr ?? "") as Int? // expected-error {{'String' is not convertible to 'Int?'; did you mean to use 'as!' to force downcast?}}
 
   _ = (str ^^^ "") as Int // expected-error {{cannot convert value of type 'String' to type 'Int' in coercion}}
   _ = (optStr ^^^ "") as Int // expected-error {{cannot convert value of type 'String' to type 'Int' in coercion}}
-  _ = (optStr ^^^ "") as Int? // expected-error {{cannot convert value of type 'String' to type 'Int?' in coercion}}
+  _ = (optStr ^^^ "") as Int? // expected-error {{'String' is not convertible to 'Int?'; did you mean to use 'as!' to force downcast?}}
 
   _ = ([] ?? []) as String // expected-error {{cannot convert value of type '[Any]' to type 'String' in coercion}}
   _ = ([""] ?? []) as [Int: Int] // expected-error {{cannot convert value of type '[String]' to type '[Int : Int]' in coercion}}
@@ -290,7 +290,7 @@
   // expected-note@-1 {{arguments to generic parameter 'Element' ('Int' and 'String') are expected to be equal}}
   _ = dict as [String: String] // expected-error {{cannot convert value of type '[String : Int]' to type '[String : String]' in coercion}}
   // expected-note@-1 {{arguments to generic parameter 'Value' ('Int' and 'String') are expected to be equal}}
-  _ = dict as [String: String]? // expected-error {{cannot convert value of type '[String : Int]' to type '[String : String]?' in coercion}}
+  _ = dict as [String: String]? // expected-error {{'[String : Int]' is not convertible to '[String : String]?'; did you mean to use 'as!' to force downcast?}}
   _ = (dict as [String: Int]?) as [String: Int] // expected-error {{value of optional type '[String : Int]?' must be unwrapped to a value of type '[String : Int]'}}
   // expected-note@-1 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
   // expected-note@-2 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
diff --git a/test/Constraints/function_builder_diags.swift b/test/Constraints/function_builder_diags.swift
index 89e4264..36bba54 100644
--- a/test/Constraints/function_builder_diags.swift
+++ b/test/Constraints/function_builder_diags.swift
@@ -619,6 +619,14 @@
     } // expected-error {{expected identifier after '.' expression}}
   }
 
+  @TupleBuilder var invalidCaseWithoutDot: some P {
+    switch Optional.some(1) {
+    case none: 42 // expected-error {{cannot find 'none' in scope}}
+    case .some(let x):
+      0
+    }
+  }
+
   @TupleBuilder var invalidConversion: Int { // expected-error {{cannot convert value of type 'String' to specified type 'Int'}}
     ""
   }
diff --git a/test/Constraints/one_way_solve.swift b/test/Constraints/one_way_solve.swift
index f21a37e..56c7547 100644
--- a/test/Constraints/one_way_solve.swift
+++ b/test/Constraints/one_way_solve.swift
@@ -38,9 +38,9 @@
 
   // CHECK: solving component #1
   // CHECK: Initial bindings: $T11 := Int8
-  // CHECK: found solution 0 0 0 0 0 0 0 0 2 0 0 0 0 0
+  // CHECK: found solution {{.*}} 2 0 0 0 0 0
 
-  // CHECK: composed solution 0 0 0 0 0 0 0 0 2 0 0 0 0 0
-  // CHECK-NOT: composed solution 0 0 0 0 0 0 0 0 2 0 0 0 0 0
+  // CHECK: composed solution {{.*}} 2 0 0 0 0 0
+  // CHECK-NOT: composed solution {{.*}} 2 0 0 0 0 0
   let _: Int8 = b ? Builtin.one_way(int8Or16(17)) : Builtin.one_way(int8Or16(42))
 }
diff --git a/test/Constraints/optional.swift b/test/Constraints/optional.swift
index 246abdb..352a8be 100644
--- a/test/Constraints/optional.swift
+++ b/test/Constraints/optional.swift
@@ -64,15 +64,17 @@
 }
 
 func test6<T>(_ x : T) {
-  // FIXME: this code should work; T could be Int? or Int??
-  // or something like that at runtime.  rdar://16374053
-  _ = x as? Int? // expected-error {{cannot downcast from 'T' to a more optional type 'Int?'}}
+  _ = x as? Int? // Okay.  We know nothing about T, so cannot judge.
 }
 
 class B : A { }
 
 func test7(_ x : A) {
-  _ = x as? B? // expected-error{{cannot downcast from 'A' to a more optional type 'B?'}}
+  _ = x as? B? // Okay: Injecting into an Optional
+}
+
+func test7a(_ x : B) {
+  _ = x as? A // expected-warning{{conditional cast from 'B' to 'A' always succeeds}}
 }
 
 func test8(_ x : AnyObject?) {
diff --git a/test/Constraints/rdar68155466.swift b/test/Constraints/rdar68155466.swift
new file mode 100644
index 0000000..f8c4e17
--- /dev/null
+++ b/test/Constraints/rdar68155466.swift
@@ -0,0 +1,28 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify %s
+// REQUIRES: objc_interop
+
+import Foundation
+
+@objc class A : NSObject {
+  func uniqueID() -> Int {
+    42
+  }
+}
+
+struct Loop< // expected-note {{required by generic struct 'Loop' where 'ID' = '() -> Int'}}
+  Data : RandomAccessCollection,
+  ID : Hashable,
+  Content
+> {
+  public init(
+    _ data: Data,
+    id: KeyPath<Data.Element, ID>,
+    content: @escaping (Data.Element) -> Content) {}
+}
+
+func data() -> [A] {
+  return []
+}
+
+_ = Loop(data(), id: \.uniqueID) { $0 } // expected-error {{key path cannot refer to instance method 'uniqueID()'}}
+// expected-error@-1 {{type '() -> Int' cannot conform to 'Hashable'; only concrete types such as structs, enums and classes can conform to protocols}}
diff --git a/test/Constraints/valid_pointer_conversions.swift b/test/Constraints/valid_pointer_conversions.swift
index 3a3bd9e..265083a 100644
--- a/test/Constraints/valid_pointer_conversions.swift
+++ b/test/Constraints/valid_pointer_conversions.swift
@@ -41,3 +41,8 @@
 var i = 0
 SR12382(&i) // expected-error {{cannot convert value of type 'UnsafeMutablePointer<Int>' to expected argument type 'UnsafeMutablePointer<Double>'}}
 // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Int' and 'Double') are expected to be equal}}
+
+//problem/68254165 - Bad diagnostic when using String init(decodingCString:) with an incorrect pointer type
+func rdar68254165(ptr: UnsafeMutablePointer<Int8>) {
+  _ = String(decodingCString: ptr, as: .utf8) // expected-error {{generic parameter 'Encoding' could not be inferred}}
+}
diff --git a/test/DebugInfo/Inputs/Macro.h b/test/DebugInfo/Inputs/Macro.h
index 5f43bbf..7cba013 100644
--- a/test/DebugInfo/Inputs/Macro.h
+++ b/test/DebugInfo/Inputs/Macro.h
@@ -1,6 +1,12 @@
+#ifdef __cplusplus
 #define MY_ENUM(NAME) \
-  enum NAME : int NAME; \
   enum NAME : int
+#else
+#define MY_ENUM(NAME) \
+  enum NAME : int; \
+  typedef enum NAME NAME; \
+  enum NAME : int
+#endif
 
 MY_ENUM(macro_enum) {
   zero = 0
diff --git a/test/DebugInfo/inlinescopes.swift b/test/DebugInfo/inlinescopes.swift
index 6c4a3a4..4b40340 100644
--- a/test/DebugInfo/inlinescopes.swift
+++ b/test/DebugInfo/inlinescopes.swift
@@ -6,13 +6,17 @@
 // RUN: %FileCheck %s -check-prefix=TRANSPARENT-CHECK < %t.ll
 
 // CHECK: define{{( dllexport)?}}{{( protected)?( signext)?}} i32 @main{{.*}}
-// CHECK: call swiftcc i64 @"$s4main8noinlineys5Int64VADF"(i64 %{{.*}}), !dbg ![[CALL:.*]]
+// CHECK: call swiftcc i64 @"$s4main8noinlineys5Int64VADF"(i64 %{{.*}})
+// CHECK-SAME: !dbg ![[CALL:.*]]
 // CHECK-DAG: ![[TOPLEVEL:.*]] = !DIFile(filename: "{{.*}}inlinescopes.swift"
 
 import FooBar
 
 @inline(never)
-func noinline(_ x: Int64) -> Int64 { return x }
+func use(_ x: Int64) -> Int64 { return x }
+
+@inline(never)
+func noinline(_ x: Int64) -> Int64 { return use(x) }
 
 @_transparent
 func transparent(_ x: Int64) -> Int64 { return noinline(x) }
diff --git a/test/DebugInfo/top_level_code.swift b/test/DebugInfo/top_level_code.swift
index 790f5df..6693d78 100644
--- a/test/DebugInfo/top_level_code.swift
+++ b/test/DebugInfo/top_level_code.swift
@@ -2,7 +2,7 @@
 
 func markUsed<T>(_ t: T) {}
 // CHECK: {{_?}}main:
-// CHECK-NEXT: Lfunc_begin0:
+// CHECK: Lfunc_begin0:
 // Verify that the top-level function (main) begins at line 0 and then
 // proceeds to the first line.
 // CHECK: .loc    {{[0-9]}} 0 {{[0-9]}}
diff --git a/test/DebugInfo/transparent.swift b/test/DebugInfo/transparent.swift
index 5bfd301..b951b4a 100644
--- a/test/DebugInfo/transparent.swift
+++ b/test/DebugInfo/transparent.swift
@@ -19,7 +19,6 @@
 // CHECK-SAME: !dbg ![[SP:[0-9]+]]
 // CHECK-NEXT: entry:
 // CHECK-NEXT: !dbg ![[ZERO:[0-9]+]]
-// CHECK-NEXT: !dbg ![[ZERO]]
 // CHECK-NEXT: }
 
 // CHECK: ![[FILE:[0-9]+]] = {{.*}}"<compiler-generated>"
diff --git a/test/DebugInfo/vector.swift b/test/DebugInfo/vector.swift
index d815055..f50164c 100644
--- a/test/DebugInfo/vector.swift
+++ b/test/DebugInfo/vector.swift
@@ -4,7 +4,7 @@
 // CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: ![[FLOAT:[0-9]+]], size: 64, flags: DIFlagVector, elements: ![[ELTS:[0-9]+]])
 // CHECK: ![[FLOAT]] = !DIBasicType(name: "$sBf32_D", size: 32, encoding: DW_ATE_float)
 // CHECK: ![[ELTS]] = !{![[SR:[0-9]+]]}
-// CHECK: ![[SR]] = !DISubrange(count: 2)
+// CHECK: ![[SR]] = !DISubrange(count: 2, lowerBound: 0)
 
 
 import Swift
diff --git a/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/DaemonKit.h b/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/DaemonKit.h
deleted file mode 100644
index bb28f06..0000000
--- a/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/DaemonKit.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#import <CoreDaemon.h>
-
-struct DaemonPair {
-  struct Daemon daemons[2];
-};
diff --git a/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/DaemonKit/DaemonKit.h b/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/DaemonKit/DaemonKit.h
new file mode 100644
index 0000000..7a4cc1d
--- /dev/null
+++ b/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/DaemonKit/DaemonKit.h
@@ -0,0 +1,7 @@
+#import <DaemonKit/ViolateSecondLawOfThermodynamics.h>
+
+#import <CoreDaemon.h>
+
+struct DaemonPair {
+  struct Daemon daemons[2];
+};
diff --git a/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/DaemonKit/ViolateSecondLawOfThermodynamics.h b/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/DaemonKit/ViolateSecondLawOfThermodynamics.h
new file mode 100644
index 0000000..2850f0f
--- /dev/null
+++ b/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/DaemonKit/ViolateSecondLawOfThermodynamics.h
@@ -0,0 +1,5 @@
+#import <CoreDaemon.h>
+
+struct MaxwellsDaemon {
+  Runner *doorOperation;
+};
diff --git a/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/module.modulemap b/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/module.modulemap
index d067348..6fee437 100644
--- a/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/module.modulemap
+++ b/test/Driver/Inputs/imported_modules/ComplexModuleGraph2/module.modulemap
@@ -14,7 +14,11 @@
 }
 
 module DaemonKit {
-  header "DaemonKit.h"
+  umbrella header "DaemonKit/DaemonKit.h"
+  explicit module ViolateSecondLawOfThermodynamics {
+    header "DaemonKit/ViolateSecondLawOfThermodynamics.h"
+    export *
+  }
   export *
 }
 
diff --git a/test/Driver/bad_tmpdir.swift b/test/Driver/bad_tmpdir.swift
index bf0565e..50be890 100644
--- a/test/Driver/bad_tmpdir.swift
+++ b/test/Driver/bad_tmpdir.swift
@@ -6,6 +6,9 @@
 //
 // REQUIRES: OS=macosx
 
+// SR-12362: This test is failing on master-next.
+// XFAIL: *
+
 // RUN: env TMP="%t/fake/" TMPDIR="%t/fake/" not %target-build-swift -c -driver-filelist-threshold=0 %s 2>&1 | %FileCheck -check-prefix=CHECK-SOURCES %s
 
 // CHECK-SOURCES: - unable to create list of input sources
diff --git a/test/Driver/coverage-prefix-map.swift b/test/Driver/coverage-prefix-map.swift
index fd2ff8a..c4f42d0 100644
--- a/test/Driver/coverage-prefix-map.swift
+++ b/test/Driver/coverage-prefix-map.swift
@@ -3,7 +3,7 @@
 // RUN: %target-swiftc_driver -### -coverage-prefix-map old=n=ew %s 2>&1 | %FileCheck %s -check-prefix CHECK-COMPLEX
 // RUN: %target-swiftc_driver -### -coverage-prefix-map old= %s 2>&1 | %FileCheck %s -check-prefix CHECK-EMPTY
 
-// CHECK-INVALID: error: invalid argument 'old' to -coverage-prefix-map
+// CHECK-INVALID: error: values for '-coverage-prefix-map' must be in the format 'original=remapped', but 'old' was provided
 // CHECK-SIMPLE: coverage-prefix-map old=new
 // CHECK-COMPLEX: coverage-prefix-map old=n=ew
 // CHECK-EMPTY: coverage-prefix-map old=
diff --git a/test/Driver/debug-prefix-map.swift b/test/Driver/debug-prefix-map.swift
index 3483f3f..d23e72f 100644
--- a/test/Driver/debug-prefix-map.swift
+++ b/test/Driver/debug-prefix-map.swift
@@ -3,7 +3,7 @@
 // RUN: %target-swiftc_driver -### -debug-prefix-map old=n=ew %s 2>&1 | %FileCheck %s -check-prefix CHECK-COMPLEX
 // RUN: %target-swiftc_driver -### -debug-prefix-map old= %s 2>&1 | %FileCheck %s -check-prefix CHECK-EMPTY
 
-// CHECK-INVALID: error: invalid argument 'old' to -debug-prefix-map
+// CHECK-INVALID: error: values for '-debug-prefix-map' must be in the format 'original=remapped', but 'old' was provided
 // CHECK-SIMPLE: debug-prefix-map old=new
 // CHECK-COMPLEX: debug-prefix-map old=n=ew
 // CHECK-EMPTY: debug-prefix-map old=
diff --git a/test/Driver/emit-module-summary.swift b/test/Driver/emit-module-summary.swift
new file mode 100644
index 0000000..d1fef32
--- /dev/null
+++ b/test/Driver/emit-module-summary.swift
@@ -0,0 +1,6 @@
+// RUN: %empty-directory(%t)
+// RUN: echo 'print("Hello, World!")' >%t/main.swift
+// RUN: cd %t
+
+// RUN: %target-swiftc_driver -emit-sib -emit-module-summary -emit-module-summary-path %t/main.swiftmodulesummary %t/main.swift
+// RUN: test -f %t/main.swiftmodulesummary
diff --git a/test/Driver/loaded_module_trace_directness_2.swift b/test/Driver/loaded_module_trace_directness_2.swift
index 95f0644..79e3ce2 100644
--- a/test/Driver/loaded_module_trace_directness_2.swift
+++ b/test/Driver/loaded_module_trace_directness_2.swift
@@ -114,7 +114,7 @@
   #endif
   #if V2
     import DaemonKit
-    public func noop(_: CoreDaemon.Daemon) {}
+    public func noop(_: CoreDaemon.Daemon, _: MaxwellsDaemon) {}
   #endif
   #if V3
     import CoreDaemon
diff --git a/test/Driver/verify-module-interface.swift b/test/Driver/verify-module-interface.swift
new file mode 100644
index 0000000..6f277fa
--- /dev/null
+++ b/test/Driver/verify-module-interface.swift
@@ -0,0 +1,12 @@
+// RUN: %empty-directory(%t)
+// RUN: touch %t/file-01.swift %t/file-02.swift %t/file-03.swift
+
+// RUN: %swiftc_driver -driver-print-jobs -driver-skip-execution -j 3 -emit-module -module-name foo -emit-module-interface %t/file-01.swift %t/file-02.swift %t/file-03.swift -verify-emitted-module-interface -enable-library-evolution >%t/evolution.txt
+
+// RUN: %swiftc_driver -driver-print-jobs -driver-skip-execution -j 3 -emit-module -module-name foo -emit-module-interface %t/file-01.swift %t/file-02.swift %t/file-03.swift -verify-emitted-module-interface >%t/no-evolution.txt
+
+// RUN: %FileCheck %s --check-prefix=CHECK_EVOLUTION <%t/evolution.txt
+// RUN: %FileCheck %s --check-prefix=CHECK_NO_EVOLUTION <%t/no-evolution.txt
+
+// CHECK_EVOLUTION: -typecheck-module-from-interface
+// CHECK_NO_EVOLUTION-NOT: -typecheck-module-from-interface
diff --git a/test/Frontend/emit-module-summary.swift b/test/Frontend/emit-module-summary.swift
new file mode 100644
index 0000000..7e69f23
--- /dev/null
+++ b/test/Frontend/emit-module-summary.swift
@@ -0,0 +1,10 @@
+// RUN: %empty-directory(%t)
+// RUN: echo 'print("Hello, World!")' >%t/main.swift
+// RUN: cd %t
+
+// RUN: %target-swift-frontend -emit-sib -emit-module-summary-path %t/main.swiftmodulesummary %t/main.swift
+// RUN: test -f %t/main.swiftmodulesummary
+
+// RUN: echo '"%/t/main.swift": { swiftmodulesummary: "%/t/foo.swiftmodulesummary" }' > %/t/filemap.yaml
+// RUN: %target-swift-frontend -emit-sib -supplementary-output-file-map %/t/filemap.yaml %/t/main.swift
+// RUN: test -f %t/foo.swiftmodulesummary
diff --git a/test/Generics/unbound.swift b/test/Generics/unbound.swift
index aed3469..8f57d93 100644
--- a/test/Generics/unbound.swift
+++ b/test/Generics/unbound.swift
@@ -74,3 +74,20 @@
   func bar<U>() where T: X2<U> {}
 }
 class X2<T> {}
+
+// <rdar://problem/67292528> missing check for unbound parent type
+struct Outer<K, V> {
+  struct Inner {}
+
+  struct Middle {
+    typealias Inner = Outer<K, V>.Middle
+  }
+}
+
+func makeInner() -> Outer<String, String>.Middle.Inner {
+  return .init()
+}
+
+var innerProperty: Outer.Middle.Inner = makeInner()
+// expected-error@-1 {{reference to generic type 'Outer' requires arguments in <...>}}
+
diff --git a/test/IDE/complete_ambiguous.swift b/test/IDE/complete_ambiguous.swift
new file mode 100644
index 0000000..6931abc
--- /dev/null
+++ b/test/IDE/complete_ambiguous.swift
@@ -0,0 +1,137 @@
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=SIMPLE | %FileCheck %s --check-prefix=SIMPLE
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=SIMPLE_EXTRAARG | %FileCheck %s --check-prefix=SIMPLE
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=SIMPLE_MEMBERS | %FileCheck %s --check-prefix=SIMPLE
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=RELATED | %FileCheck %s --check-prefix=RELATED
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=RELATED_EXTRAARG | %FileCheck %s --check-prefix=RELATED
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=RELATED_INERROREXPR | %FileCheck %s --check-prefix=RELATED
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=GENERIC | %FileCheck %s --check-prefix=GENERIC
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=GENERIC_MISSINGARG | %FileCheck %s --check-prefix=NORESULTS
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=CLOSURE_MISSINGARG | %FileCheck %s --check-prefix=POINT_MEMBER
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=CLOSURE_NORETURN | %FileCheck %s --check-prefix=POINT_MEMBER
+// RUN: %swift-ide-test -code-completion  -source-filename %s -code-completion-token=CLOSURE_FUNCBUILDER | %FileCheck %s --check-prefix=POINT_MEMBER
+
+struct A {
+  func doAThings() -> A { return self }
+}
+
+struct B {
+  func doBThings() {}
+}
+
+func overloadedReturn() -> A { return A() }
+func overloadedReturn() -> B { return B() }
+
+overloadedReturn().#^SIMPLE^#
+overloadedReturn(1).#^SIMPLE_EXTRAARG^#
+
+struct HasMembers {
+  func overloadedReturn() -> A { return A() }
+  func overloadedReturn() -> B { return B() }
+}
+
+HasMembers().overloadedReturn().#^SIMPLE_MEMBERS^#
+
+// SIMPLE: Begin completions, 4 items
+// SIMPLE-DAG: Keyword[self]/CurrNominal:          self[#A#]{{; name=.+$}}
+// SIMPLE-DAG: Decl[InstanceMethod]/CurrNominal:   doAThings()[#A#]{{; name=.+$}}
+// SIMPLE-DAG: Keyword[self]/CurrNominal:          self[#B#]{{; name=.+$}}
+// SIMPLE-DAG: Decl[InstanceMethod]/CurrNominal:   doBThings()[#Void#]{{; name=.+$}}
+// SIMPLE: End completions
+
+let x: A = overloadedReturn().#^RELATED^#
+let x: A = overloadedReturn(1).#^RELATED_EXTRAARG^#
+
+// RELATED: Begin completions, 4 items
+// RELATED-DAG: Keyword[self]/CurrNominal:          self[#A#]{{; name=.+$}}
+// RELATED-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Identical]: doAThings()[#A#]{{; name=.+$}}
+// RELATED-DAG: Keyword[self]/CurrNominal:          self[#B#]{{; name=.+$}}
+// RELATED-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: doBThings()[#Void#]{{; name=.+$}}
+// RELATED: End completions
+
+func takesA(_ callback: () -> A) -> B {}
+func takesB(_ item: B) {}
+
+takesB((takesA { return overloadedReturn().#^RELATED_INERROREXPR^# }).)
+
+protocol C {
+  associatedtype Element
+  func getCElem() -> Element
+}
+
+protocol D {
+  associatedtype Item
+  func getDElem() -> Item
+}
+
+struct CDStruct: C, D {
+  func getDElem() -> A { return A() }
+  func getCElem() -> B { return B() }
+}
+
+func genericReturn<T:C, U>(_ x: T) -> U where U == T.Element {
+  return x.getCElem()
+}
+func genericReturn<T:D, U>(_ x: T) -> U where U == T.Item {
+  return x.getDElem()
+}
+
+genericReturn(CDStruct()).#^GENERIC^#
+
+// GENERIC: Begin completions, 4 items
+// GENERIC-DAG: Keyword[self]/CurrNominal:          self[#B#]{{; name=.+$}}
+// GENERIC-DAG: Decl[InstanceMethod]/CurrNominal:   doBThings()[#Void#]{{; name=.+$}}
+// GENERIC-DAG: Keyword[self]/CurrNominal:          self[#A#]{{; name=.+$}}
+// GENERIC-DAG: Decl[InstanceMethod]/CurrNominal:   doAThings()[#A#]{{; name=.+$}}
+// GENERIC: End completions
+
+genericReturn().#^GENERIC_MISSINGARG^#
+
+// NORESULTS-NOT: Begin completions
+
+struct Point {
+    let x: Int
+    let y: Int
+    var magSquared: Int { return x*y }
+
+    init(_ x: Int, _ y: Int) {
+        self.x = x
+        self.y = y
+    }
+}
+
+// POINT_MEMBER: Begin completions, 4 items
+// POINT_MEMBER-DAG: Keyword[self]/CurrNominal:          self[#Point#]; name=self
+// POINT_MEMBER-DAG: Decl[InstanceVar]/CurrNominal:      x[#Int#]; name=x
+// POINT_MEMBER-DAG: Decl[InstanceVar]/CurrNominal:      y[#Int#]; name=y
+// POINT_MEMBER-DAG: Decl[InstanceVar]/CurrNominal:      magSquared[#Int#]; name=magSquared
+// POINT_MEMBER: End completions
+
+let _ = [Point(1, 4), Point(20, 2), Point(9, -4)]
+  .filter { $0.magSquared > 4 }
+  .min {
+    $0.#^CLOSURE_MISSINGARG^#
+  }
+
+protocol SomeProto {}
+func testing<T: Collection, U: SomeProto>(_ arg1: T, arg2: (T.Element) -> U) {}
+_ = testing([Point(4, 89)]) { arg in
+  arg.#^CLOSURE_NORETURN^#
+}
+
+struct Thing {
+    init(_ block: (Point) -> Void) {}
+}
+@_functionBuilder
+struct ThingBuilder {
+    static func buildBlock(_ x: Thing...) -> [Thing] { x }
+}
+func CreateThings(@ThingBuilder makeThings: () -> [Thing]) {}
+
+// FIXME: only works if the first call to Thing is passed a single expression closure
+CreateThings {
+    Thing { point in
+      point.#^CLOSURE_FUNCBUILDER^#
+    }
+    Thing { _ in }
+}
+
diff --git a/test/IDE/complete_decl_attribute.swift b/test/IDE/complete_decl_attribute.swift
index 1861cd5..23606da 100644
--- a/test/IDE/complete_decl_attribute.swift
+++ b/test/IDE/complete_decl_attribute.swift
@@ -39,6 +39,7 @@
 // AVAILABILITY1-NEXT: Keyword/None:                       macOSApplicationExtension[#Platform#]; name=macOSApplicationExtension{{$}}
 // AVAILABILITY1-NEXT: Keyword/None:                       macCatalyst[#Platform#]; name=macCatalyst
 // AVAILABILITY1-NEXT: Keyword/None:                       macCatalystApplicationExtension[#Platform#]; name=macCatalystApplicationExtension
+// AVAILABILITY1-NEXT: Keyword/None:                       OpenBSD[#Platform#]; name=OpenBSD{{$}}
 // AVAILABILITY1-NEXT: End completions
 
 @available(*, #^AVAILABILITY2^#)
diff --git a/test/IDE/complete_enum_elements.swift b/test/IDE/complete_enum_elements.swift
index 48d8b01d..a087c24 100644
--- a/test/IDE/complete_enum_elements.swift
+++ b/test/IDE/complete_enum_elements.swift
@@ -57,7 +57,7 @@
 // RUN: %FileCheck %s -check-prefix=QUX_ENUM_NO_DOT < %t.enum.txt
 
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_QUAL_DOT_1 > %t.enum.txt
-// RUN: %FileCheck %s -check-prefix=FOO_ENUM_DOT_INVALID < %t.enum.txt
+// RUN: %FileCheck %s -check-prefix=FOO_ENUM_DOT < %t.enum.txt
 
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUM_QUAL_DOT_2 > %t.enum.txt
 // RUN: %FileCheck %s -check-prefix=BAR_ENUM_DOT < %t.enum.txt
@@ -127,17 +127,6 @@
 // FOO_ENUM_DOT_CONTEXT-NEXT: Decl[StaticVar]/CurrNominal: allCases[#[FooEnum]#]{{; name=.+$}}
 // FOO_ENUM_DOT_CONTEXT-NEXT: End completions
 
-// FOO_ENUM_DOT_INVALID: Begin completions
-// FOO_ENUM_DOT_INVALID-NEXT: Keyword[self]/CurrNominal: self[#FooEnum.Type#]; name=self
-// FOO_ENUM_DOT_INVALID-NEXT: Keyword/CurrNominal: Type[#FooEnum.Type#]; name=Type
-// FOO_ENUM_DOT_INVALID-NEXT: Decl[EnumElement]/CurrNominal: Foo1[#FooEnum#]{{; name=.+$}}
-// FOO_ENUM_DOT_INVALID-NEXT: Decl[EnumElement]/CurrNominal: Foo2[#FooEnum#]{{; name=.+$}}
-// FOO_ENUM_DOT_INVALID-NEXT: Decl[StaticVar]/CurrNominal: alias1[#FooEnum#]{{; name=.+$}}
-// FOO_ENUM_DOT_INVALID-NEXT: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: hash({#(self): FooEnum#})[#(into: inout Hasher) -> Void#]{{; name=.+$}}
-// FOO_ENUM_DOT_INVALID-NEXT: Decl[TypeAlias]/CurrNominal: AllCases[#[FooEnum]#]{{; name=.+$}}
-// FOO_ENUM_DOT_INVALID-NEXT: Decl[StaticVar]/CurrNominal: allCases[#[FooEnum]#]{{; name=.+$}}
-// FOO_ENUM_DOT_INVALID-NEXT: End completions
-
 // FOO_ENUM_DOT_ELEMENTS: Begin completions, 13 items
 // FOO_ENUM_DOT_ELEMENTS-NEXT: Decl[EnumElement]/ExprSpecific/TypeRelation[Identical]: Foo1[#FooEnum#]{{; name=.+$}}
 // FOO_ENUM_DOT_ELEMENTS-NEXT: Decl[EnumElement]/ExprSpecific/TypeRelation[Identical]: Foo2[#FooEnum#]{{; name=.+$}}
@@ -224,7 +213,7 @@
 // BAR_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:      Bar10({#Int#}, {#Float#})[#BarEnum#]{{; name=.+$}}
 // BAR_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:      Bar11({#Int#}, {#(Float)#})[#BarEnum#]{{; name=.+$}}
 // BAR_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:      Bar12({#Int#}, {#(Float, Double)#})[#BarEnum#]{{; name=.+$}}
-// BAR_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: barInstanceFunc({#(self): &BarEnum#})[#() -> Void#]{{; name=.+$}}
+// BAR_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal:   barInstanceFunc({#(self): &BarEnum#})[#() -> Void#]{{; name=.+$}}
 // BAR_ENUM_DOT-NEXT: Decl[StaticVar]/CurrNominal:        staticVar[#Int#]{{; name=.+$}}
 // BAR_ENUM_DOT-NEXT: Decl[StaticMethod]/CurrNominal/TypeRelation[Invalid]: barStaticFunc()[#Void#]{{; name=.+$}}
 // BAR_ENUM_DOT-NEXT: End completions
@@ -272,7 +261,7 @@
 // BAZ_INT_ENUM_DOT-NEXT: Keyword/CurrNominal:              Type[#BazEnum<Int>.Type#]; name=Type
 // BAZ_INT_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:    Baz1[#BazEnum<Int>#]{{; name=.+$}}
 // BAZ_INT_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:    Baz2({#Int#})[#BazEnum<Int>#]{{; name=.+$}}
-// BAZ_INT_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: bazInstanceFunc({#(self): &BazEnum<Int>#})[#() -> Void#]{{; name=.+$}}
+// BAZ_INT_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: bazInstanceFunc({#(self): &BazEnum<Int>#})[#() -> Void#]{{; name=.+$}}
 // BAZ_INT_ENUM_DOT-NEXT: Decl[StaticVar]/CurrNominal:      staticVar[#Int#]{{; name=.+$}}
 // BAZ_INT_ENUM_DOT-NEXT: Decl[StaticVar]/CurrNominal:      staticVarT[#Int#]{{; name=.+$}}
 // BAZ_INT_ENUM_DOT-NEXT: Decl[StaticMethod]/CurrNominal/TypeRelation[Invalid]:   bazStaticFunc()[#Void#]{{; name=.+$}}
@@ -286,7 +275,7 @@
 // BAZ_T_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: bazInstanceFunc({#(self): &BazEnum<_>#})[#() -> Void#]{{; name=.+$}}
 // BAZ_T_ENUM_DOT-NEXT: Decl[StaticVar]/CurrNominal:      staticVar[#Int#]{{; name=.+$}}
 // BAZ_T_ENUM_DOT-NEXT: Decl[StaticVar]/CurrNominal:      staticVarT[#_#]{{; name=.+$}}
-// BAZ_T_ENUM_DOT-NEXT: Decl[StaticMethod]/CurrNominal:   bazStaticFunc()[#Void#]{{; name=.+$}}
+// BAZ_T_ENUM_DOT-NEXT: Decl[StaticMethod]/CurrNominal/TypeRelation[Invalid]:   bazStaticFunc()[#Void#]{{; name=.+$}}
 // BAZ_T_ENUM_DOT-NEXT: End completions
 
 enum QuxEnum : Int {
@@ -316,7 +305,7 @@
 // QUX_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:    Qux2[#QuxEnum#]{{; name=.+$}}
 // QUX_ENUM_DOT-NEXT: Decl[TypeAlias]/CurrNominal:      RawValue[#Int#]{{; name=.+$}}
 // QUX_ENUM_DOT-NEXT: Decl[Constructor]/CurrNominal:    init({#rawValue: Int#})[#QuxEnum?#]{{; name=.+$}}
-// QUX_ENUM_DOT-NEXT: Decl[InstanceMethod]/Super/IsSystem/TypeRelation[Invalid]: hash({#(self): QuxEnum#})[#(into: inout Hasher) -> Void#]{{; name=.+$}}
+// QUX_ENUM_DOT-NEXT: Decl[InstanceMethod]/Super/IsSystem: hash({#(self): QuxEnum#})[#(into: inout Hasher) -> Void#]{{; name=.+$}}
 // QUX_ENUM_DOT-NEXT: End completions
 
 func freeFunc() {}
diff --git a/test/IDE/complete_exception.swift b/test/IDE/complete_exception.swift
index a5cef6b..89f02c1 100644
--- a/test/IDE/complete_exception.swift
+++ b/test/IDE/complete_exception.swift
@@ -108,16 +108,16 @@
 func test003() {
   do {} catch Error4.#^CATCH2^#
 // CATCH2: Begin completions
-// CATCH2: Decl[EnumElement]/CurrNominal: E1[#Error4#]{{; name=.+$}}
-// CATCH2: Decl[EnumElement]/CurrNominal: E2({#Int32#})[#Error4#]{{; name=.+$}}
+// CATCH2: Decl[EnumElement]/CurrNominal/TypeRelation[Convertible]: E1[#Error4#]{{; name=.+$}}
+// CATCH2: Decl[EnumElement]/CurrNominal/TypeRelation[Convertible]: E2({#Int32#})[#Error4#]{{; name=.+$}}
 // CATCH2: End completions
 }
 
 func test004() {
   throw Error4.#^THROW2^#
 // THROW2: Begin completions
-// THROW2: Decl[EnumElement]/CurrNominal: E1[#Error4#]{{; name=.+$}}
-// THROW2: Decl[EnumElement]/CurrNominal: E2({#Int32#})[#Error4#]{{; name=.+$}}
+// THROW2: Decl[EnumElement]/CurrNominal/TypeRelation[Convertible]: E1[#Error4#]{{; name=.+$}}
+// THROW2: Decl[EnumElement]/CurrNominal/TypeRelation[Convertible]: E2({#Int32#})[#Error4#]{{; name=.+$}}
 // THROW2: End completions
 }
 
@@ -131,8 +131,8 @@
 func testInvalid() {
   try throw Error4.#^THROW3^#
 // THROW3: Begin completions
-// THROW3: Decl[EnumElement]/CurrNominal:      E1[#Error4#]{{; name=.+$}}
-// THROW3: Decl[EnumElement]/CurrNominal:      E2({#Int32#})[#Error4#]{{; name=.+$}}
+// THROW3: Decl[EnumElement]/CurrNominal/TypeRelation[Convertible]:      E1[#Error4#]{{; name=.+$}}
+// THROW3: Decl[EnumElement]/CurrNominal/TypeRelation[Convertible]:      E2({#Int32#})[#Error4#]{{; name=.+$}}
 // THROW3: End completions
 }
 
diff --git a/test/IDE/complete_swift_key_path_optional_root.swift b/test/IDE/complete_swift_key_path_optional_root.swift
new file mode 100644
index 0000000..c80822c
--- /dev/null
+++ b/test/IDE/complete_swift_key_path_optional_root.swift
@@ -0,0 +1,55 @@
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_INFER_DOT_OPTIONAL | %FileCheck %s -check-prefix=PERSONTYPE-INFER-DOT-OPT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_DOT_OPTIONAL | %FileCheck %s -check-prefix=PERSONTYPE-DOT-OPT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TYPE_DOT_OPTIONAL_SPACE | %FileCheck %s -check-prefix=PERSONTYPE-DOT-OPT-SPACE
+
+class Person {
+    var name: String
+    var friends: [Person] = []
+    var bestFriend: Person? = nil
+    var itself: Person { return self }
+    init(name: String) {
+        self.name = name
+    }
+    func getName() -> String { return name }
+    subscript(_ index: Int) -> Int { get { return 1} }
+}
+
+extension Optional {
+    var optMember: String { "member" }
+}
+
+let _ : KeyPath<Person?, String> = \.#^TYPE_INFER_DOT_OPTIONAL^#
+// PERSONTYPE-INFER-DOT-OPT: Begin completions, 9 items
+// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:   ?.name[#String#]; name=name
+// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:   ?.friends[#[Person]#]; name=friends
+// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:   ?.bestFriend[#Person?#]; name=bestFriend
+// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:   ?.itself[#Person#]; name=itself
+// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[Subscript]/CurrNominal:     ?[{#(index): Int#}][#Int#]; name=[index: Int]
+// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem:   unsafelyUnwrapped[#Person#]; name=unsafelyUnwrapped
+// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:            optMember[#String#]; name=optMember
+// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem:   debugDescription[#String#]; name=debugDescription
+// PERSONTYPE-INFER-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem:   customMirror[#Mirror#]; name=customMirror
+
+let _ : KeyPath<Person?, String> = \Person?.#^TYPE_DOT_OPTIONAL^#
+// PERSONTYPE-DOT-OPT: Begin completions, 9 items
+// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:   ?.name[#String#]; name=name
+// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:   ?.friends[#[Person]#]; name=friends
+// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:   ?.bestFriend[#Person?#]; name=bestFriend
+// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:   ?.itself[#Person#]; name=itself
+// PERSONTYPE-DOT-OPT-NEXT: Decl[Subscript]/CurrNominal:     ?[{#(index): Int#}][#Int#]; name=[index: Int]
+// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem:   unsafelyUnwrapped[#Person#]; name=unsafelyUnwrapped
+// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal:            optMember[#String#]; name=optMember
+// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem:   debugDescription[#String#]; name=debugDescription
+// PERSONTYPE-DOT-OPT-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem:   customMirror[#Mirror#]; name=customMirror
+
+let _ : KeyPath<Person?, String> = \Person?. #^TYPE_DOT_OPTIONAL_SPACE^#
+// PERSONTYPE-DOT-OPT-SPACE: Begin completions, 9 items
+// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/Erase[1]:   ?.name[#String#]; name=name
+// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/Erase[1]:   ?.friends[#[Person]#]; name=friends
+// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/Erase[1]:   ?.bestFriend[#Person?#]; name=bestFriend
+// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/Erase[1]:   ?.itself[#Person#]; name=itself
+// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[Subscript]/CurrNominal/Erase[1]:     ?[{#(index): Int#}][#Int#]; name=[index: Int]
+// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem:   unsafelyUnwrapped[#Person#]; name=unsafelyUnwrapped
+// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal:            optMember[#String#]; name=optMember
+// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem:   debugDescription[#String#]; name=debugDescription
+// PERSONTYPE-DOT-OPT-SPACE-NEXT: Decl[InstanceVar]/CurrNominal/IsSystem:   customMirror[#Mirror#]; name=customMirror
diff --git a/test/IDE/print_ast_tc_decls_errors.swift b/test/IDE/print_ast_tc_decls_errors.swift
index 802c10a..4127f2c 100644
--- a/test/IDE/print_ast_tc_decls_errors.swift
+++ b/test/IDE/print_ast_tc_decls_errors.swift
@@ -109,11 +109,11 @@
 //===--- Inheritance list in enums.
 //===---
 
-enum EnumWithInheritance1 : FooNonExistentProtocol {} // expected-error {{cannot find type 'FooNonExistentProtocol' in scope}} expected-error {{raw type}} expected-error {{an enum with no cases}}
+enum EnumWithInheritance1 : FooNonExistentProtocol {} // expected-error {{cannot find type 'FooNonExistentProtocol' in scope}} expected-error {{an enum with no cases}}
 // NO-TYREPR: {{^}}enum EnumWithInheritance1 : <<error type>> {{{$}}
 // TYREPR: {{^}}enum EnumWithInheritance1 : FooNonExistentProtocol {{{$}}
 
-enum EnumWithInheritance2 : FooNonExistentProtocol, BarNonExistentProtocol {} // expected-error {{cannot find type 'FooNonExistentProtocol' in scope}} expected-error {{cannot find type 'BarNonExistentProtocol' in scope}} expected-error {{raw type}} expected-error {{an enum with no cases}}
+enum EnumWithInheritance2 : FooNonExistentProtocol, BarNonExistentProtocol {} // expected-error {{cannot find type 'FooNonExistentProtocol' in scope}} expected-error {{cannot find type 'BarNonExistentProtocol' in scope}} expected-error {{an enum with no cases}}
 // NO-TYREPR: {{^}}enum EnumWithInheritance2 : <<error type>>, <<error type>> {{{$}}
 // TYREPR: {{^}}enum EnumWithInheritance2 : FooNonExistentProtocol, BarNonExistentProtocol {{{$}}
 
diff --git a/test/IDE/print_swift_module.swift b/test/IDE/print_swift_module.swift
index 63e4a9d..a54c31f 100644
--- a/test/IDE/print_swift_module.swift
+++ b/test/IDE/print_swift_module.swift
@@ -28,7 +28,9 @@
 }
 
 @_functionBuilder
-struct BridgeBuilder {}
+struct BridgeBuilder {
+    static func buildBlock(_: Any...) {}
+}
 
 public struct City {
   public init(@BridgeBuilder builder: () -> ()) {}
diff --git a/test/IRGen/Inputs/local_extern.h b/test/IRGen/Inputs/local_extern.h
new file mode 100644
index 0000000..de84f09
--- /dev/null
+++ b/test/IRGen/Inputs/local_extern.h
@@ -0,0 +1,21 @@
+static inline int _no_prior_var() {
+  extern int var;
+  return var;
+}
+
+static inline int _no_prior_func() {
+  extern int func();
+  return func();
+}
+
+static int prior_var = 1;
+static inline int _prior_var() {
+  extern int prior_var;
+  return prior_var;
+}
+
+static inline int prior_func() { return 1; }
+static inline int _prior_func() {
+  extern int prior_func();
+  return prior_func();
+}
diff --git a/test/IRGen/Inputs/opaque_result_type_private_underlying_2.swift b/test/IRGen/Inputs/opaque_result_type_private_underlying_2.swift
index 2699a34..ebabbef 100644
--- a/test/IRGen/Inputs/opaque_result_type_private_underlying_2.swift
+++ b/test/IRGen/Inputs/opaque_result_type_private_underlying_2.swift
@@ -45,3 +45,39 @@
     return PublicS()
   }
 }
+
+
+public protocol P {}
+
+private struct PrivateSome : P {}
+public func getSome() -> some P {
+  return PrivateSome()
+}
+
+@propertyWrapper
+public struct Wrapper<T> {
+  public var wrappedValue: T
+
+  public init(wrappedValue v: T) {
+    wrappedValue = v
+  }
+}
+
+public struct R<V, T: P>: P {
+  @Wrapper private var privateState = PrivateState()
+  var x: T? = nil
+
+  public init(_ v: V.Type, _ t: T) {
+    x = t
+  }
+
+  public mutating func modify() {
+    x = nil
+  }
+}
+
+private extension R {
+  struct PrivateState {
+    var x = 0
+  }
+}
diff --git a/test/IRGen/local_extern.swift b/test/IRGen/local_extern.swift
new file mode 100644
index 0000000..06c9a3d
--- /dev/null
+++ b/test/IRGen/local_extern.swift
@@ -0,0 +1,10 @@
+// RUN: %target-swift-frontend -import-objc-header %S/Inputs/local_extern.h %s -emit-ir | %FileCheck %s
+// CHECK: @var = external {{(dso_local )?}}global i32
+// CHECK: @prior_var = internal global i32
+// CHECK: declare {{(dso_local )?}}i32 @func
+// CHECK: define internal i32 @prior_func
+
+print("\(_no_prior_var())")
+print("\(_no_prior_func())")
+print("\(_prior_var())")
+print("\(_prior_func())")
diff --git a/test/IRGen/objc_local.swift b/test/IRGen/objc_local.swift
index c0d24d2..d20e087 100644
--- a/test/IRGen/objc_local.swift
+++ b/test/IRGen/objc_local.swift
@@ -1,6 +1,7 @@
 // RUN: %empty-directory(%t)
 // RUN: %build-irgen-test-overlays
 // RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) %s -emit-ir | %FileCheck %s
+// RUN: %target-swift-frontend(mock-sdk: -sdk %S/Inputs -I %t) %s -emit-ir -O | %FileCheck %s
 
 // REQUIRES: objc_interop
 
diff --git a/test/IRGen/opaque_result_type_private_underlying.swift b/test/IRGen/opaque_result_type_private_underlying.swift
index 85c975c..a1b6f72 100644
--- a/test/IRGen/opaque_result_type_private_underlying.swift
+++ b/test/IRGen/opaque_result_type_private_underlying.swift
@@ -68,3 +68,11 @@
     }
 }
 #endif
+
+public struct E<V> {
+   var body : some P {
+     var r = R(V.self, getSome())
+     r.modify()
+     return r
+   }
+}
diff --git a/test/IRGen/pic.swift b/test/IRGen/pic.swift
index 8afc50e..def763b 100644
--- a/test/IRGen/pic.swift
+++ b/test/IRGen/pic.swift
@@ -3,6 +3,7 @@
 
 // SR-12194
 // XFAIL: OS=linux-android, CPU=aarch64
+// UNSUPPORTED: OS=linux-gnu
 
 // RUN: %target-swift-frontend %s -module-name main -S -o - | %FileCheck -check-prefix=%target-cpu -check-prefix=%target-cpu-%target-sdk-name %s
 
@@ -61,10 +62,13 @@
 // armv7k:        ldr [[R_ADR]], {{\[}}[[R_ADR]]{{\]}}
 
 // arm64-LABEL: {{_?}}$s4main10use_globalSiyF:
+// arm64:        adrp [[REG3:x[0-9]+]], _$s4main6globalSivp@PAGE
 // arm64:        adrp [[REG1:x[0-9]+]], _$s4main6globalSivp@PAGE
 // arm64:        add [[REG1]], [[REG1]], _$s4main6globalSivp@PAGEOFF
+// arm64:        str [[REG3]], [sp, #16]
 // arm64:        bl _swift_beginAccess
-// arm64:        ldr [[REG2:x[0-9]+]], {{\[}}[[REG1]]{{\]}}
+// arm64:        ldr [[REG4:x[0-9]+]], [sp, #16]
+// arm64:        ldr [[REG2:x[0-9]+]], {{\[}}[[REG4]], _$s4main6globalSivp@PAGEOFF
 // arm64:        str [[REG2]], [sp]
 // arm64:        bl _swift_endAccess
 // arm64:        ldr x0, [sp]
diff --git a/test/IRGen/unused.sil b/test/IRGen/unused.sil
index e15b505..8b0d06f 100644
--- a/test/IRGen/unused.sil
+++ b/test/IRGen/unused.sil
@@ -56,7 +56,7 @@
 // CHECK-elf: @"\01l_entry_point" = private constant { i32 } { i32 trunc (i64 sub (i64 ptrtoint (i32 (i32, i8**)* @main to i64), i64 ptrtoint ({ i32 }* @"\01l_entry_point" to i64)) to i32) }, section "swift5_entry", align 4
 
 // CHECK-macho: @llvm.used = appending global [4 x i8*] [i8* bitcast (void ()* @frieda to i8*), i8* bitcast (i32 (i32, i8**)* @main to i8*), i8* bitcast ({ i32 }* @"\01l_entry_point" to i8*), i8* bitcast (i16* @__swift_reflection_version to i8*)], section "llvm.metadata", align 8
-// CHECK-elf: @llvm.used = appending global [5 x i8*] [i8* bitcast (void ()* @frieda to i8*), i8* bitcast (i32 (i32, i8**)* @main to i8*), i8* bitcast ({ i32 }* @"\01l_entry_point" to i8*), i8* bitcast (i16* @__swift_reflection_version to i8*), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @_swift1_autolink_entries, i32 0, i32 0)], section "llvm.metadata", align 8
+// CHECK-elf: @llvm.used = appending global [5 x i8*] [i8* bitcast (void ()* @frieda to i8*), i8* bitcast (i32 (i32, i8**)* @main to i8*), i8* bitcast ({ i32 }* @"\01l_entry_point" to i8*), i8* bitcast (i16* @__swift_reflection_version to i8*), i8* getelementptr inbounds ([{{[0-9]+}} x i8], [{{[0-9]+}} x i8]* @_swift1_autolink_entries, i32 0, i32 0)], section "llvm.metadata", align 8
 
 // CHECK: define linkonce_odr hidden swiftcc void @qux()
 // CHECK: define hidden swiftcc void @fred()
diff --git a/test/Incremental/Verifier/single-file-private/AnyObject.swift b/test/Incremental/Verifier/single-file-private/AnyObject.swift
index 2e80b90..ff93b85 100644
--- a/test/Incremental/Verifier/single-file-private/AnyObject.swift
+++ b/test/Incremental/Verifier/single-file-private/AnyObject.swift
@@ -25,7 +25,6 @@
 // expected-private-conformance {{Swift.CVarArg}}
 // expected-private-conformance {{Swift.CustomStringConvertible}}
 // expected-private-member {{Swift._ExpressibleByBuiltinIntegerLiteral.init}}
-// expected-private-superclass {{main.LookupFactory}}
 @objc private class LookupFactory: NSObject {
   // expected-provides {{AssignmentPrecedence}}
   // expected-provides {{IntegerLiteralType}}
diff --git a/test/Incremental/Verifier/single-file/AnyObject.swift b/test/Incremental/Verifier/single-file/AnyObject.swift
index 63a5e55..0130674 100644
--- a/test/Incremental/Verifier/single-file/AnyObject.swift
+++ b/test/Incremental/Verifier/single-file/AnyObject.swift
@@ -25,7 +25,6 @@
 // expected-private-conformance {{Swift.CVarArg}}
 // expected-private-conformance {{Swift.CustomStringConvertible}}
 // expected-cascading-member {{Swift._ExpressibleByBuiltinIntegerLiteral.init}}
-// expected-cascading-superclass {{main.LookupFactory}}
 @objc private class LookupFactory: NSObject {
   // expected-provides {{AssignmentPrecedence}}
   // expected-provides {{IntegerLiteralType}}
diff --git a/test/Interop/Cxx/operators/Inputs/member-inline.h b/test/Interop/Cxx/operators/Inputs/member-inline.h
index 8204aa0..4333f6e 100644
--- a/test/Interop/Cxx/operators/Inputs/member-inline.h
+++ b/test/Interop/Cxx/operators/Inputs/member-inline.h
@@ -3,7 +3,7 @@
 
 struct IntBox {
   int value;
-  IntBox operator+(IntBox rhs) { return IntBox{.value = value + rhs.value}; }
+  IntBox operator-(IntBox rhs) { return IntBox{.value = value - rhs.value}; }
 };
 
 #endif
diff --git a/test/Interop/Cxx/operators/member-inline-irgen.swift b/test/Interop/Cxx/operators/member-inline-irgen.swift
index 7976820..169c10d 100644
--- a/test/Interop/Cxx/operators/member-inline-irgen.swift
+++ b/test/Interop/Cxx/operators/member-inline-irgen.swift
@@ -5,7 +5,7 @@
 
 import MemberInline
 
-public func add(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs + rhs }
+public func sub(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs - rhs }
 
-// CHECK: call [[RES:i32|i64]] [[NAME:@(_ZN6IntBoxplES_|"\?\?HIntBox@@QEAA\?AU0@U0@@Z")]](%struct.IntBox* {{%[0-9]+}}, {{i32|\[1 x i32\]|i64|%struct.IntBox\* byval align 4}} {{%[0-9]+}})
+// CHECK: call [[RES:i32|i64]] [[NAME:@(_ZN6IntBoxmiES_|"\?\?GIntBox@@QEAA\?AU0@U0@@Z")]](%struct.IntBox* {{%[0-9]+}}, {{i32|\[1 x i32\]|i64|%struct.IntBox\* byval align 4}} {{%[0-9]+}})
 // CHECK: define linkonce_odr [[RES]] [[NAME]](%struct.IntBox* %this, {{i32 %rhs.coerce|\[1 x i32\] %rhs.coerce|i64 %rhs.coerce|%struct.IntBox\* byval\(%struct.IntBox\) align 4 %rhs}})
diff --git a/test/Interop/Cxx/operators/member-inline-module-interface.swift b/test/Interop/Cxx/operators/member-inline-module-interface.swift
index aef362f..b90893a 100644
--- a/test/Interop/Cxx/operators/member-inline-module-interface.swift
+++ b/test/Interop/Cxx/operators/member-inline-module-interface.swift
@@ -1,5 +1,5 @@
 // RUN: %target-swift-ide-test -print-module -module-to-print=MemberInline -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s
 
 // CHECK: struct IntBox {
-// CHECK:   static func + (lhs: inout IntBox, rhs: IntBox) -> IntBox
+// CHECK:   static func - (lhs: inout IntBox, rhs: IntBox) -> IntBox
 // CHECK: }
diff --git a/test/Interop/Cxx/operators/member-inline-silgen.swift b/test/Interop/Cxx/operators/member-inline-silgen.swift
index 96d89a4..3b88723 100644
--- a/test/Interop/Cxx/operators/member-inline-silgen.swift
+++ b/test/Interop/Cxx/operators/member-inline-silgen.swift
@@ -2,13 +2,13 @@
 
 import MemberInline
 
-public func add(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs + rhs }
+public func sub(_ lhs: inout IntBox, _ rhs: IntBox) -> IntBox { lhs - rhs }
 
 // CHECK: bb0([[SELF:%.*]] : $*IntBox, [[RHS:%.*]] : $IntBox):
 
 // CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[SELF]] : $*IntBox
-// CHECK: [[OP:%.*]] = function_ref [[NAME:@(_ZN6IntBoxplES_|\?\?HIntBox@@QEAA\?AU0@U0@@Z)]] : $@convention(c) (@inout IntBox, IntBox) -> IntBox
+// CHECK: [[OP:%.*]] = function_ref [[NAME:@(_ZN6IntBoxmiES_|\?\?GIntBox@@QEAA\?AU0@U0@@Z)]] : $@convention(c) (@inout IntBox, IntBox) -> IntBox
 // CHECK: apply [[OP]]([[SELFACCESS]], [[RHS]]) : $@convention(c) (@inout IntBox, IntBox) -> IntBox
 // CHECK: end_access [[SELFACCESS]] : $*IntBox
 
-// CHECK: sil [clang IntBox."+"] [[NAME]] : $@convention(c) (@inout IntBox, IntBox) -> IntBox
+// CHECK: sil [clang IntBox."-"] [[NAME]] : $@convention(c) (@inout IntBox, IntBox) -> IntBox
diff --git a/test/Interop/Cxx/operators/member-inline-typechecker.swift b/test/Interop/Cxx/operators/member-inline-typechecker.swift
index 635875a..3b19898 100644
--- a/test/Interop/Cxx/operators/member-inline-typechecker.swift
+++ b/test/Interop/Cxx/operators/member-inline-typechecker.swift
@@ -5,4 +5,4 @@
 var lhs = IntBox(value: 42)
 let rhs = IntBox(value: 23)
 
-let resultPlus = lhs + rhs
+let resultPlus = lhs - rhs
diff --git a/test/Interop/Cxx/operators/member-inline.swift b/test/Interop/Cxx/operators/member-inline.swift
index 0313d84..f3b1e29 100644
--- a/test/Interop/Cxx/operators/member-inline.swift
+++ b/test/Interop/Cxx/operators/member-inline.swift
@@ -14,9 +14,9 @@
   var lhs = IntBox(value: 42)
   let rhs = IntBox(value: 23)
 
-  let result = lhs + rhs
+  let result = lhs - rhs
 
-  expectEqual(65, result.value)
+  expectEqual(19, result.value)
 }
 
 runAllTests()
diff --git a/test/Interpreter/SDK/protocol_lookup_foreign.swift b/test/Interpreter/SDK/protocol_lookup_foreign.swift
index f0565dc..ae864b0 100644
--- a/test/Interpreter/SDK/protocol_lookup_foreign.swift
+++ b/test/Interpreter/SDK/protocol_lookup_foreign.swift
@@ -4,11 +4,6 @@
 // REQUIRES: objc_interop
 // REQUIRES: OS=macosx
 
-// rdar://20990451 is tracking the fix for compiling this test optimized.
-// XFAIL: swift_test_mode_optimize
-// XFAIL: swift_test_mode_optimize_size
-// XFAIL: swift_test_mode_optimize_unchecked
-
 import Foundation
 import StdlibUnittest
 
diff --git a/test/Interpreter/failable_initializers_root_class.swift b/test/Interpreter/failable_initializers_root_class.swift
new file mode 100644
index 0000000..9caa08d
--- /dev/null
+++ b/test/Interpreter/failable_initializers_root_class.swift
@@ -0,0 +1,176 @@
+// RUN: %target-run-simple-swift
+
+// REQUIRES: executable_test
+
+import StdlibUnittest
+
+
+var FailableInitTestSuite = TestSuite("FailableInit")
+
+var deinitCalled = 0
+
+func mustFail<T>(f: () -> T?) {
+  if f() != nil {
+    preconditionFailure("Didn't fail")
+  }
+}
+
+func mustSucceed<T>(f: () -> T?) {
+  if f() == nil {
+    preconditionFailure("Didn't succeed")
+  }
+}
+
+class FirstClass {
+  var x: LifetimeTracked
+
+  init?(n: Int) {
+    if n == 0 {
+      return nil
+    }
+
+    x = LifetimeTracked(0)
+
+    if n == 1 {
+      return nil
+    }
+  }
+
+  deinit {
+    deinitCalled += 1
+  }
+}
+
+FailableInitTestSuite.test("FirstClass") {
+  deinitCalled = 0
+
+  mustFail { FirstClass(n: 0) }
+  expectEqual(0, deinitCalled)
+
+  mustFail { FirstClass(n: 1) }
+  expectEqual(1, deinitCalled)
+
+  mustSucceed { FirstClass(n: 2) }
+  expectEqual(2, deinitCalled)
+}
+
+class FirstClassTrivial {
+  var x: Int
+
+  init?(n: Int) {
+    if n == 0 {
+      return nil
+    }
+
+    x = 0
+
+    if n == 1 {
+      return nil
+    }
+  }
+
+  deinit {
+    deinitCalled += 1
+  }
+}
+
+FailableInitTestSuite.test("FirstClassTrivial") {
+  deinitCalled = 0
+
+  mustFail { FirstClassTrivial(n: 0) }
+  expectEqual(0, deinitCalled)
+
+  mustFail { FirstClassTrivial(n: 1) }
+  expectEqual(1, deinitCalled)
+
+  mustSucceed { FirstClassTrivial(n: 2) }
+  expectEqual(2, deinitCalled)
+}
+
+class SecondClass {
+  var x: LifetimeTracked
+  var y: LifetimeTracked
+
+  init?(n: Int) {
+    if n == 0 {
+      return nil
+    }
+
+    x = LifetimeTracked(0)
+
+    if n == 1 {
+      return nil
+    }
+
+    y = LifetimeTracked(0)
+
+    if n == 2 {
+      return nil
+    }
+  }
+
+  deinit {
+    deinitCalled += 1
+  }
+}
+
+FailableInitTestSuite.test("SecondClass") {
+  deinitCalled = 0
+
+  mustFail { SecondClass(n: 0) }
+  expectEqual(0, deinitCalled)
+
+  mustFail { SecondClass(n: 1) }
+  expectEqual(0, deinitCalled)
+
+  mustFail { SecondClass(n: 2) }
+  expectEqual(1, deinitCalled)
+
+  mustSucceed { SecondClass(n: 3) }
+  expectEqual(2, deinitCalled)
+}
+
+class SecondClassTrivial {
+  var x: Int
+  var y: Int
+
+  init?(n: Int) {
+    if n == 0 {
+      return nil
+    }
+
+    x = 0
+
+    if n == 1 {
+      return nil
+    }
+
+    y = 0
+
+    if n == 2 {
+      return nil
+    }
+  }
+
+  deinit {
+    deinitCalled += 1
+  }
+}
+
+FailableInitTestSuite.test("SecondClassTrivial") {
+  deinitCalled = 0
+
+  mustFail { SecondClassTrivial(n: 0) }
+  expectEqual(0, deinitCalled)
+
+  mustFail { SecondClassTrivial(n: 1) }
+  expectEqual(0, deinitCalled)
+
+  mustFail { SecondClassTrivial(n: 2) }
+  expectEqual(1, deinitCalled)
+
+  mustSucceed { SecondClassTrivial(n: 3) }
+  expectEqual(2, deinitCalled)
+}
+
+runAllTests()
diff --git a/test/Interpreter/generic_ref_counts.swift b/test/Interpreter/generic_ref_counts.swift
index 44e6307..4f9a469 100644
--- a/test/Interpreter/generic_ref_counts.swift
+++ b/test/Interpreter/generic_ref_counts.swift
@@ -1,5 +1,6 @@
 // RUN: %target-run-simple-swift | %FileCheck %s
 // REQUIRES: executable_test
+// XFAIL: OS=openbsd
 
 import Swift
 
diff --git a/test/Interpreter/multiple_varargs.swift b/test/Interpreter/multiple_varargs.swift
new file mode 100644
index 0000000..372b496
--- /dev/null
+++ b/test/Interpreter/multiple_varargs.swift
@@ -0,0 +1,85 @@
+// RUN: %target-run-simple-swift | %FileCheck %s
+
+// REQUIRES: executable_test
+
+func vf(x: Int..., y: Int...) {
+	print(x, y)
+}
+
+vf(x: 1, 2, 3, y: 4, 5, 6)
+// CHECK: [1, 2, 3] [4, 5, 6]
+vf(y: 1, 2)
+// CHECK: [] [1, 2]
+vf(x: 3, 4)
+// CHECK: [3, 4] []
+
+func vf2(_ x: Int..., y: Int, _ z: Int...) {
+  print(x, y, z)
+}
+
+vf2(1, 2, 3, y: 4, 5, 6, 7)
+// CHECK: [1, 2, 3] 4 [5, 6, 7]
+vf2(y: 4, 5, 6, 7)
+// CHECK: [] 4 [5, 6, 7]
+vf2(1, 2, 3, y: 4)
+// CHECK: [1, 2, 3] 4 []
+vf2(y: 4)
+// CHECK: [] 4 []
+
+func vf3(_ x: Int..., y: Int = 42, _ z: Int...) {
+  print(x, y, z)
+}
+
+vf3(1, 2, 3, y: 4, 5, 6, 7)
+// CHECK: [1, 2, 3] 4 [5, 6, 7]
+vf3(y: 4, 5, 6, 7)
+// CHECK: [] 4 [5, 6, 7]
+vf3(1, 2, 3, y: 4)
+// CHECK: [1, 2, 3] 4 []
+vf3(y: 4)
+// CHECK: [] 4 []
+
+vf3()
+// CHECK: [] 42 []
+vf3(1, 2, 3)
+// CHECK: [1, 2, 3] 42 []
+
+func foo(a: Int..., b: Int, c: Int..., d: Int) {
+  print("one")
+}
+
+func foo(a: [Int], b: Int, c: [Int], d: Int) {
+  print("two")
+}
+
+func foo(a: Int..., b: Int, c: [Int], d: Int) {
+  print("three")
+}
+
+foo(a: 1, 2, 3, b: 4, c: 5, 6, 7, d: 8)
+// CHECK: one
+foo(a: [1, 2, 3], b: 4, c: [5, 6, 7], d: 8)
+// CHECK: two
+foo(a: 1, 2, 3, b: 4, c: [5, 6, 7], d: 8)
+// CHECK: three
+
+struct Baz {
+  init(a: Int..., b: Int...) {
+    print(a, b)
+  }
+
+  init(_ a: Int..., b: String, _ c: Int...) {
+    print(a, b, c)
+  }
+
+  subscript(a: Int..., b b: Int...) -> [Int] { a + b }
+}
+
+let baz1 = Baz(a: 1, 2, 3, b: 4, 5, 6)
+// CHECK: [1, 2, 3] [4, 5, 6]
+
+let baz2 = Baz(1, 2, 3, b: "hello, world!", 3, 2, 1)
+// CHECK: [1, 2, 3] hello, world! [3, 2, 1]
+
+print(baz1[1, 2, b: 3, 4])
+// CHECK: [1, 2, 3, 4]
diff --git a/test/ModuleInterface/ModuleCache/Inputs/sdk-build-ver.1.plist b/test/ModuleInterface/ModuleCache/Inputs/sdk-build-ver.1.plist
new file mode 100644
index 0000000..a7775b7
--- /dev/null
+++ b/test/ModuleInterface/ModuleCache/Inputs/sdk-build-ver.1.plist
@@ -0,0 +1,6 @@
+<plist version="1.0">
+<dict>
+	<key>ProductBuildVersion</key>
+	<string>11111</string>
+</dict>
+</plist>
diff --git a/test/ModuleInterface/ModuleCache/Inputs/sdk-build-ver.2.plist b/test/ModuleInterface/ModuleCache/Inputs/sdk-build-ver.2.plist
new file mode 100644
index 0000000..bfe4278
--- /dev/null
+++ b/test/ModuleInterface/ModuleCache/Inputs/sdk-build-ver.2.plist
@@ -0,0 +1,6 @@
+<plist version="1.0">
+<dict>
+	<key>ProductBuildVersion</key>
+	<string>22222</string>
+</dict>
+</plist>
diff --git a/test/ModuleInterface/ModuleCache/RebuildRemarks/out-of-date-forwarding-module.swift b/test/ModuleInterface/ModuleCache/RebuildRemarks/out-of-date-forwarding-module.swift
index 680dbb1..269314d 100644
--- a/test/ModuleInterface/ModuleCache/RebuildRemarks/out-of-date-forwarding-module.swift
+++ b/test/ModuleInterface/ModuleCache/RebuildRemarks/out-of-date-forwarding-module.swift
@@ -1,6 +1,10 @@
 // RUN: %empty-directory(%t/ModuleCache)
 // RUN: %empty-directory(%t/Build)
 // RUN: %empty-directory(%t/PrebuiltCache)
+// RUN: %empty-directory(%t/System/Library/CoreServices)
+
+// RUN: cp %S/../Inputs/sdk-build-ver.1.plist %t/System/Library/CoreServices/SystemVersion.plist
+// RUN: cp %S/../Inputs/sdk-build-ver.2.plist %t/PrebuiltCache/SystemVersion.plist
 
 // 1. Create a dummy module
 // RUN: echo 'public func publicFunction() {}' > %t/TestModule.swift
@@ -30,3 +34,4 @@
 // expected-note @-2 {{dependency is out of date}}
 // expected-note @-3 {{prebuilt module is out of date}}
 // expected-note @-4 {{dependency is out of date}}
+// expected-note @-5 {{SDK build version is '11111'; prebuilt modules were built using SDK build version: '22222'}}
diff --git a/test/NameLookup/subscript-generic-conjuction-astscope.swift b/test/NameLookup/subscript-generic-conjuction-astscope.swift
index 60cdc19..8fb1fc0 100644
--- a/test/NameLookup/subscript-generic-conjuction-astscope.swift
+++ b/test/NameLookup/subscript-generic-conjuction-astscope.swift
@@ -1,7 +1,5 @@
 // Check that ASTScope lookup works for a construction found in GRDB's Row.swift
-// RUN: %target-swift-frontend -typecheck %s -enable-astscope-lookup -warn-if-astscope-lookup 2>%t.out
-// RUN: %FileCheck %s <%t.out
-// CHECK: WARNING: TRYING Scope exclusively
+// RUN: %target-swift-frontend -typecheck %s
 
 protocol P1 {}
 protocol P2 {}
diff --git a/test/NameLookup/warn-if-astscope.swift b/test/NameLookup/warn-if-astscope.swift
deleted file mode 100644
index f101cf0..0000000
--- a/test/NameLookup/warn-if-astscope.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-// Verify the action of -warn-if-astscope-lookup
-//
-// RUN: not %target-swift-frontend -typecheck %s -enable-astscope-lookup 2>&1 |  %FileCheck %s --check-prefix=CHECK-NO-WARN
-// RUN: not %target-swift-frontend -typecheck %s -disable-astscope-lookup 2>&1 | %FileCheck %s --check-prefix=CHECK-NO-WARN
-// RUN: not %target-swift-frontend -typecheck %s -enable-astscope-lookup -warn-if-astscope-lookup 2>&1 | %FileCheck %s --check-prefix=CHECK-WARN
-// RUN: not %target-swift-frontend -typecheck %s -disable-astscope-lookup -warn-if-astscope-lookup 2>&1 | %FileCheck %s --check-prefix=CHECK-NO-WARN
-
-func foo() -> Int {
-  return bar() // create an error so the input to fileCheck isn't empty
-}
-
-// CHECK-NO-WARN-NOT: WARNING: TRYING Scope exclusively
-// CHECK-WARN: WARNING: TRYING Scope exclusively
diff --git a/test/Parse/toplevel_library_invalid.swift b/test/Parse/toplevel_library_invalid.swift
index 7b2eb68..1206a42 100644
--- a/test/Parse/toplevel_library_invalid.swift
+++ b/test/Parse/toplevel_library_invalid.swift
@@ -1,5 +1,4 @@
 // RUN: %target-typecheck-verify-swift -parse-as-library
-// RUN: %target-typecheck-verify-swift -parse-as-library -enable-astscope-lookup
 
 let x = 42
 x + x; // expected-error {{expressions are not allowed at the top level}} expected-warning {{result of operator '+' is unused}}
diff --git a/test/PrintAsObjC/async.swift b/test/PrintAsObjC/async.swift
new file mode 100644
index 0000000..bfa6913
--- /dev/null
+++ b/test/PrintAsObjC/async.swift
@@ -0,0 +1,30 @@
+// REQUIRES: objc_interop
+
+// RUN: %empty-directory(%t)
+
+// FIXME: BEGIN -enable-source-import hackaround
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift -disable-objc-attr-requires-foundation-module
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/AppKit.swift
+// FIXME: END -enable-source-import hackaround
+
+
+// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -parse-as-library %s -typecheck -I %S/Inputs/custom-modules -emit-objc-header-path %t/async.h -import-objc-header %S/../Inputs/empty.h  -enable-experimental-concurrency -typecheck
+// RUN: %FileCheck %s < %t/async.h
+// RUN: %check-in-clang -I %S/Inputs/custom-modules/ %t/async.h
+
+import Foundation
+
+// CHECK-LABEL: @interface BarClass : NSObject
+@objc @objcMembers class BarClass: NSObject {
+  // CHECK: (void)doSomethingBigWithCompletionHandler:(void (^)(NSInteger))completionHandler;
+  func doSomethingBig() async -> Int { 0 }
+
+  // CHECK: - (void)longRunningWithString:(NSString * _Nonnull)string completionHandler:(void (^)(BarClass * _Nullable, NSError * _Nullable))completionHandler;
+  func longRunning(string: String) async throws -> BarClass { return self }
+
+  // CHECK: - (void)magicTupleReturnWithCompletionHandler:(void (^)(BarClass * _Nonnull, NSInteger))completionHandler;
+  func magicTupleReturn() async -> (BarClass, Int) { return (self, 0) }
+}
+// CHECK: @end
diff --git a/test/SILGen/Inputs/replace_opaque_type_public_assoc_type_m.swift b/test/SILGen/Inputs/replace_opaque_type_public_assoc_type_m.swift
new file mode 100644
index 0000000..c2120db
--- /dev/null
+++ b/test/SILGen/Inputs/replace_opaque_type_public_assoc_type_m.swift
@@ -0,0 +1,11 @@
+public protocol Gesture {
+    associatedtype Body: Gesture
+    var body: Body { get }
+
+    associatedtype Value
+    var value: Value { get }
+}
+
+extension Gesture {
+    public var value: Body.Value { return body.value }
+}
diff --git a/test/SILGen/arguments.swift b/test/SILGen/arguments.swift
index fdd26f1..0c16ad459 100644
--- a/test/SILGen/arguments.swift
+++ b/test/SILGen/arguments.swift
@@ -82,6 +82,14 @@
 // CHECK-LABEL: sil hidden [ossa] @$ss14variadic_arg_3{{[_0-9a-zA-Z]*}}F
 // CHECK: bb0([[Y:%[0-9]+]] : $Array<Float>, [[X:%[0-9]+]] : $Int):
 
+func variadic_arg_4(_ y: Float..., x: Int...) {}
+// CHECK-LABEL: sil hidden [ossa] @$ss14variadic_arg_4{{[_0-9a-zA-Z]*}}F
+// CHECK: bb0([[Y:%[0-9]+]] : $Array<Float>, [[X:%[0-9]+]] : $Array<Int>):
+
+func variadic_arg_5(a: Int, b: Float..., c: Int, d: Int...) {}
+// CHECK-LABEL: sil hidden [ossa] @$ss14variadic_arg_5{{[_0-9a-zA-Z]*}}F
+// CHECK: bb0([[A:%[0-9]+]] : $Int, [[B:%[0-9]+]] : $Array<Float>, [[C:%[0-9]+]] : $Int, [[D:%[0-9]+]] : $Array<Int>):
+
 variadic_arg_3(x: i)
 variadic_arg_3(f, x: i)
 variadic_arg_3(f, f, f, x: i)
diff --git a/test/SILGen/local_recursion.swift b/test/SILGen/local_recursion.swift
index d408a4c..09c83bd 100644
--- a/test/SILGen/local_recursion.swift
+++ b/test/SILGen/local_recursion.swift
@@ -1,5 +1,4 @@
 // RUN: %target-swift-emit-silgen  -parse-as-library %s | %FileCheck %s
-// RUN: %target-swift-emit-silgen -enable-astscope-lookup  -parse-as-library %s | %FileCheck %s
 
 // CHECK-LABEL: sil hidden [ossa] @$s15local_recursionAA_1yySi_SitF : $@convention(thin) (Int, Int) -> () {
 // CHECK:       bb0([[X:%0]] : $Int, [[Y:%1]] : $Int):
diff --git a/test/SILGen/replace_opaque_type_public_assoc_type.swift b/test/SILGen/replace_opaque_type_public_assoc_type.swift
new file mode 100644
index 0000000..c256b32
--- /dev/null
+++ b/test/SILGen/replace_opaque_type_public_assoc_type.swift
@@ -0,0 +1,14 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -disable-availability-checking -emit-module-path %t/replace_opaque_type_public_assoc_type_m.swiftmodule %S/Inputs/replace_opaque_type_public_assoc_type_m.swift
+// RUN: %target-swift-emit-silgen -disable-availability-checking -I %t %s -verify
+
+import replace_opaque_type_public_assoc_type_m
+
+struct PiggyBack: Gesture {
+    var action: () -> Void
+
+    var body: some Gesture {
+        action()
+        return self
+    }
+}
diff --git a/test/SILGen/switch_fallthrough.swift b/test/SILGen/switch_fallthrough.swift
index 77b5c5c..4be37a1 100644
--- a/test/SILGen/switch_fallthrough.swift
+++ b/test/SILGen/switch_fallthrough.swift
@@ -165,3 +165,20 @@
   e()
 }
 
+// rdar://problem/67704651 - crash due to nested fallthrough
+func testNestedFallthrough(x: (Int, String), y: (Int, Int)) {
+  switch x {
+  case (17, let s):
+    switch y {
+    case (42, let i):
+      print("the answer")
+    default:
+      print("nope")
+    }
+    fallthrough
+  case (42, let s):
+    print("42 and \(s)")
+  default:
+    print("done")
+  }
+}
diff --git a/test/SILOptimizer/OSLogFullOptTest.swift b/test/SILOptimizer/OSLogFullOptTest.swift
index 4dbf39e..8cc72d8 100644
--- a/test/SILOptimizer/OSLogFullOptTest.swift
+++ b/test/SILOptimizer/OSLogFullOptTest.swift
@@ -126,6 +126,7 @@
     // CHECK-NEXT: bitcast %TSo7NSArrayC* %0 to i8*
     // CHECK-NEXT: tail call i8* @llvm.objc.retain
     // CHECK-NEXT: [[NSARRAY_ARG:%.+]] = tail call i8* @llvm.objc.retain
+    // CHECK: tail call %swift.refcounted* @swift_retain
     // CHECK: tail call swiftcc i1 @"${{.*}}isLoggingEnabled{{.*}}"()
     // CHECK-NEXT: br i1 {{%.*}}, label %[[ENABLED:[0-9]+]], label %[[NOT_ENABLED:[0-9]+]]
 
@@ -136,6 +137,7 @@
 
     // CHECK: [[EXIT]]:
     // CHECK-NEXT: tail call void @llvm.objc.release(i8* [[NSARRAY_ARG]])
+    // CHECK-NEXT: tail call void @swift_release
     // CHECK-NEXT: ret void
 
     // CHECK: [[ENABLED]]:
diff --git a/test/SILOptimizer/arcsequenceopts_knownsafebugs.sil b/test/SILOptimizer/arcsequenceopts_knownsafebugs.sil
new file mode 100644
index 0000000..25be828
--- /dev/null
+++ b/test/SILOptimizer/arcsequenceopts_knownsafebugs.sil
@@ -0,0 +1,205 @@
+// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=0 -arc-sequence-opts %s | %FileCheck %s
+sil_stage canonical
+
+import Builtin
+import Swift
+
+final class ChildCls {
+  var id: Int
+  init(_ i:Int)
+}
+
+struct S {
+  var child1 : ChildCls
+  var child2 : ChildCls
+  init()
+}
+
+class Cls {
+  var child1 : ChildCls
+  var child2 : ChildCls
+  init()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_subobject :
+// CHECK: bb0(%0 : $S):
+// CHECK:   retain_value %0 : $S
+// CHECK: bb2:
+// CHECK:   release_value %0 : $S
+// CHECK:   release_value %0 : $S
+// CHECK-LABEL: } // end sil function '$unmatched_rr_subobject'
+sil hidden @$unmatched_rr_subobject : $@convention(thin) (@owned S) -> () {
+bb0(%0 : $S):
+  retain_value %0 : $S
+  br bb1
+
+bb1:
+  %1 = struct_extract %0 : $S, #S.child1
+  strong_release %1 : $ChildCls
+  strong_retain %1 : $ChildCls
+  br bb2
+
+bb2:
+  release_value %0 : $S
+  release_value %0 : $S
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$matched_rr_subobject :
+// CHECK: bb0(%0 : $S):
+// CHECK-NOT:   retain_value %0 : $S
+// CHECK: bb2:
+// CHECK-NEXT:   release_value %0 : $S
+// CHECK-NEXT:   [[RET:%.*]] = tuple ()
+// CHECK-NEXT:   return [[RET]]
+// CHECK-LABEL: } // end sil function '$matched_rr_subobject'
+sil hidden @$matched_rr_subobject : $@convention(thin) (@owned S) -> () {
+bb0(%0 : $S):
+  retain_value %0 : $S
+  br bb1
+
+bb1:
+  %1 = struct_extract %0 : $S, #S.child1
+  strong_retain %1 : $ChildCls
+  strong_release %1 : $ChildCls
+  br bb2
+
+bb2:
+  release_value %0 : $S
+  release_value %0 : $S
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_aliasing :
+// CHECK: bb0(%0 : $S, %1 : $ChildCls):
+// CHECK:   retain_value %0 : $S
+// CHECK: bb2:
+// CHECK:   release_value %0 : $S
+// CHECK:   release_value %0 : $S
+// CHECK-LABEL: } // end sil function '$unmatched_rr_aliasing'
+sil hidden @$unmatched_rr_aliasing : $@convention(thin) (@owned S, ChildCls) -> () {
+bb0(%0 : $S, %1 : $ChildCls):
+  retain_value %0 : $S
+  br bb1
+
+bb1:
+  strong_release %1 : $ChildCls
+  strong_retain %1 : $ChildCls
+  br bb2
+
+bb2:
+  release_value %0 : $S
+  release_value %0 : $S
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$matched_rr_aliasing :
+// CHECK: bb0(%0 : $S, %1 : $ChildCls):
+// CHECK-NOT:   retain_value %0 : $S
+// CHECK: bb2:
+// CHECK-NEXT:   release_value %0 : $S
+// CHECK-NEXT:   [[RET:%.*]] = tuple ()
+// CHECK-NEXT:   return [[RET]]
+// CHECK-LABEL: } // end sil function '$matched_rr_aliasing'
+sil hidden @$matched_rr_aliasing : $@convention(thin) (@owned S, ChildCls) -> () {
+bb0(%0 : $S, %1 : $ChildCls):
+  retain_value %0 : $S
+  br bb1
+
+bb1:
+  strong_retain %1 : $ChildCls
+  strong_release %1 : $ChildCls
+  br bb2
+
+bb2:
+  release_value %0 : $S
+  release_value %0 : $S
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_cls_subobject :
+// CHECK: bb0(%0 : $Cls):
+// CHECK:   retain_value %0 : $Cls
+// CHECK: bb2:
+// CHECK:   release_value %0 : $Cls
+// CHECK:   release_value %0 : $Cls
+// CHECK-LABEL: } // end sil function '$unmatched_rr_cls_subobject'
+sil hidden @$unmatched_rr_cls_subobject : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  retain_value %0 : $Cls
+  br bb1
+
+bb1:
+  %1 = ref_element_addr %0 : $Cls, #Cls.child1
+  %2 = load %1 : $*ChildCls
+  strong_release %2 : $ChildCls
+  strong_retain %2 : $ChildCls
+  br bb2
+
+bb2:
+  release_value %0 : $Cls
+  release_value %0 : $Cls
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$matched_rr_cls_subobject :
+// CHECK: bb0(%0 : $Cls):
+// CHECK-NOT:   retain_value %0 : $Cls
+// CHECK: bb2:
+// CHECK-NEXT:   release_value %0 : $Cls
+// CHECK-NEXT:   [[RET:%.*]] = tuple ()
+// CHECK-NEXT:   return [[RET]]
+// CHECK-LABEL: } // end sil function '$matched_rr_cls_subobject'
+sil hidden @$matched_rr_cls_subobject : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  retain_value %0 : $Cls
+  br bb1
+
+bb1:
+  %1 = ref_element_addr %0 : $Cls, #Cls.child1
+  %2 = load %1 : $*ChildCls
+  strong_retain %2 : $ChildCls
+  strong_release %2 : $ChildCls
+  br bb2
+
+bb2:
+  release_value %0 : $Cls
+  release_value %0 : $Cls
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_subobject_nested_knownsafety :
+// CHECK: bb0(%0 : $S):
+// CHECK:   retain_value %0 : $S
+// CHECK:   retain_value %0 : $S
+// CHECK: bb2:
+// CHECK:   release_value %0 : $S
+// CHECK:   release_value %0 : $S
+// CHECK:   release_value %0 : $S
+// CHECK-LABEL: } // end sil function '$unmatched_rr_subobject_nested_knownsafety'
+sil hidden @$unmatched_rr_subobject_nested_knownsafety : $@convention(thin) (@owned S) -> () {
+bb0(%0 : $S):
+  retain_value %0 : $S
+  retain_value %0 : $S
+  br bb1
+
+bb1:
+  %1 = struct_extract %0 : $S, #S.child1
+  strong_release %1 : $ChildCls
+  strong_retain %1 : $ChildCls
+  br bb2
+
+bb2:
+  release_value %0 : $S
+  release_value %0 : $S
+  release_value %0 : $S
+  %ret = tuple()
+  return %ret : $()
+}
+
diff --git a/test/SILOptimizer/arcsequenceopts_knownsafebugs_loop.sil b/test/SILOptimizer/arcsequenceopts_knownsafebugs_loop.sil
new file mode 100644
index 0000000..2ba87e8
--- /dev/null
+++ b/test/SILOptimizer/arcsequenceopts_knownsafebugs_loop.sil
@@ -0,0 +1,323 @@
+// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=1 -arc-sequence-opts %s | %FileCheck %s
+sil_stage canonical
+
+import Builtin
+import Swift
+
+final class ChildCls {
+  var id: Int
+  init(_ i:Int)
+}
+struct S {
+  var child1 : ChildCls
+  var child2 : ChildCls
+  init()
+}
+class Cls {
+  var child1 : ChildCls
+  var child2 : ChildCls
+  init()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_loop :
+// CHECK: bb0(%0 : $Cls):
+// CHECK:   strong_retain %0 : $Cls
+// CHECK: bb2:
+// CHECK:   strong_release %0 : $Cls
+// CHECK:   strong_release %0 : $Cls
+// CHECK-LABEL: } // end sil function '$unmatched_rr_loop'
+sil hidden @$unmatched_rr_loop : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  strong_retain %0 : $Cls
+  br bb1
+  
+bb1:
+  strong_release %0 : $Cls
+  strong_retain %0 : $Cls
+  cond_br undef, bb1, bb2
+  
+bb2:
+  strong_release %0 : $Cls
+  strong_release %0 : $Cls
+  %4 = tuple()
+  return %4 : $()
+}
+
+// CHECK-LABEL: sil hidden @$matched_rr_loop :
+// CHECK: bb0(%0 : $Cls):
+// CHECK-NOT:   strong_retain %0 : $Cls
+// CHECK: bb2:
+// CHECK-NEXT:   strong_release %0 : $Cls
+// CHECK-NEXT:   [[RET:%.*]] = tuple ()
+// CHECK-NEXT:   return [[RET]]
+// CHECK-LABEL: } // end sil function '$matched_rr_loop'
+sil hidden @$matched_rr_loop : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  strong_retain %0 : $Cls
+  br bb1
+  
+bb1:
+  strong_retain %0 : $Cls
+  strong_release %0 : $Cls
+  cond_br undef, bb1, bb2
+  
+bb2:
+  strong_release %0 : $Cls
+  strong_release %0 : $Cls
+  %4 = tuple()
+  return %4 : $()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_aliasing_loop :
+// CHECK: bb0(%0 : $S, %1 : $ChildCls):
+// CHECK:   retain_value %0 : $S
+// CHECK: bb2:
+// CHECK:   release_value %0 : $S
+// CHECK:   release_value %0 : $S
+// CHECK-LABEL: } // end sil function '$unmatched_rr_aliasing_loop'
+sil hidden @$unmatched_rr_aliasing_loop : $@convention(thin) (@owned S, ChildCls) -> () {
+bb0(%0 : $S, %1 : $ChildCls):
+  retain_value %0 : $S
+  br bb1
+
+bb1:
+  strong_release %1 : $ChildCls
+  strong_retain %1 : $ChildCls
+  cond_br undef, bb1, bb2
+
+bb2:
+  release_value %0 : $S
+  release_value %0 : $S
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$matched_rr_aliasing_loop :
+// CHECK: bb0(%0 : $S, %1 : $ChildCls):
+// CHECK-NOT:   retain_value %0 : $S
+// CHECK: bb2:
+// CHECK-NEXT:   release_value %0 : $S
+// CHECK-NEXT:   [[RET:%.*]] = tuple ()
+// CHECK-NEXT:   return [[RET]]
+// CHECK-LABEL: } // end sil function '$matched_rr_aliasing_loop'
+sil hidden @$matched_rr_aliasing_loop : $@convention(thin) (@owned S, ChildCls) -> () {
+bb0(%0 : $S, %1 : $ChildCls):
+  retain_value %0 : $S
+  br bb1
+
+bb1:
+  strong_retain %1 : $ChildCls
+  strong_release %1 : $ChildCls
+  cond_br undef, bb1, bb2
+
+bb2:
+  release_value %0 : $S
+  release_value %0 : $S
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_subobject_loop :
+// CHECK: bb0(%0 : $Cls):
+// CHECK:   retain_value %0 : $Cls
+// CHECK: bb2:
+// CHECK:   release_value %0 : $Cls
+// CHECK:   release_value %0 : $Cls
+// CHECK-LABEL: } // end sil function '$unmatched_rr_subobject_loop'
+sil hidden @$unmatched_rr_subobject_loop : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  retain_value %0 : $Cls
+  br bb1
+
+bb1:
+  %1 = ref_element_addr %0 : $Cls, #Cls.child1
+  %2 = load %1 : $*ChildCls
+  strong_release %2 : $ChildCls
+  strong_retain %2 : $ChildCls
+  cond_br undef, bb1, bb2
+
+bb2:
+  release_value %0 : $Cls
+  release_value %0 : $Cls
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$matched_rr_subobject_loop :
+// CHECK: bb0(%0 : $Cls):
+// CHECK-NOT:   retain_value %0 : $Cls
+// CHECK: bb2:
+// CHECK-NEXT:   release_value %0 : $Cls
+// CHECK-NEXT:   [[RET:%.*]] = tuple ()
+// CHECK-NEXT:   return [[RET]]
+// CHECK-LABEL: } // end sil function '$matched_rr_subobject_loop'
+sil hidden @$matched_rr_subobject_loop : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  retain_value %0 : $Cls
+  br bb1
+
+bb1:
+  %1 = ref_element_addr %0 : $Cls, #Cls.child1
+  %2 = load %1 : $*ChildCls
+  strong_retain %2 : $ChildCls
+  strong_release %2 : $ChildCls
+  cond_br undef, bb1, bb2
+
+bb2:
+  release_value %0 : $Cls
+  release_value %0 : $Cls
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_subobject_nested_knownsafety_loop :
+// CHECK: bb0(%0 : $S):
+// CHECK:   retain_value %0 : $S
+// CHECK:   retain_value %0 : $S
+// CHECK: bb2:
+// CHECK:   release_value %0 : $S
+// CHECK:   release_value %0 : $S
+// CHECK:   release_value %0 : $S
+// CHECK-LABEL: } // end sil function '$unmatched_rr_subobject_nested_knownsafety_loop'
+sil hidden @$unmatched_rr_subobject_nested_knownsafety_loop : $@convention(thin) (@owned S) -> () {
+bb0(%0 : $S):
+  retain_value %0 : $S
+  retain_value %0 : $S
+  br bb1
+
+bb1:
+  %1 = struct_extract %0 : $S, #S.child1
+  strong_release %1 : $ChildCls
+  strong_retain %1 : $ChildCls
+  cond_br undef, bb1, bb2
+
+bb2:
+  release_value %0 : $S
+  release_value %0 : $S
+  release_value %0 : $S
+  %ret = tuple()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_loop_early_exit :
+// CHECK: bb1
+// CHECK:   strong_release %0 : $Cls
+// CHECK:   cond_br undef, bb3, bb2
+// CHECK: bb3:
+// CHECK:   strong_retain %0 : $Cls
+// CHECK:   cond_br undef, bb1, bb4
+// CHECK-LABEL: } // end sil function '$unmatched_rr_loop_early_exit'
+sil hidden @$unmatched_rr_loop_early_exit : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  strong_retain %0 : $Cls
+  br bb1
+  
+bb1:
+  strong_release %0 : $Cls
+  cond_br undef, bb2, bb3
+
+bb2:
+  strong_retain %0 : $Cls
+  cond_br undef, bb1, bb3
+  
+bb3:
+  strong_release %0 : $Cls
+  strong_release %0 : $Cls
+  %4 = tuple()
+  return %4 : $()
+}
+
+// This case does not get optimized by KnownSafety as well.
+// This is because the ref count state gets cleared due to non local successors while merging successors of bb1.
+// So the retain/release within the loop do not get matched. And KnownSafety outside the loop gets cleared.
+// CHECK-LABEL: sil hidden @$matched_rr_loop_early_exit :
+// CHECK: bb1
+// CHECK:   strong_retain %0 : $Cls
+// CHECK:   cond_br undef, bb3, bb2
+// CHECK: bb3:
+// CHECK:   strong_release %0 : $Cls
+// CHECK:   cond_br undef, bb1, bb4
+// CHECK-LABEL: } // end sil function '$matched_rr_loop_early_exit'
+sil hidden @$matched_rr_loop_early_exit : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  strong_retain %0 : $Cls
+  br bb1
+  
+bb1:
+  strong_retain %0 : $Cls
+  cond_br undef, bb2, bb3
+
+bb2:
+  strong_release %0 : $Cls
+  cond_br undef, bb1, bb3
+  
+bb3:
+  strong_release %0 : $Cls
+  strong_release %0 : $Cls
+  %4 = tuple()
+  return %4 : $()
+}
+
+// CHECK-LABEL: sil hidden @$unmatched_rr_loop_early_exit_allowsleaks :
+// CHECK: bb1
+// CHECK:   strong_release %0 : $Cls
+// CHECK:   cond_br undef, bb2, bb3
+// CHECK: bb2:
+// CHECK:   strong_retain %0 : $Cls
+// CHECK:   cond_br undef, bb1, bb4
+// CHECK-LABEL: } // end sil function '$unmatched_rr_loop_early_exit_allowsleaks'
+sil hidden @$unmatched_rr_loop_early_exit_allowsleaks : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  strong_retain %0 : $Cls
+  br bb1
+  
+bb1:
+  strong_release %0 : $Cls
+  cond_br undef, bb2, bb3
+
+bb2:
+  strong_retain %0 : $Cls
+  cond_br undef, bb1, bb4
+  
+bb3:
+  unreachable
+
+bb4:
+  strong_release %0 : $Cls
+  strong_release %0 : $Cls
+  %4 = tuple()
+  return %4 : $()
+}
+
+// Unlike $matched_rr_loop_early_exit this case gets optimized due to KnownSafety
+// Since AllowsLeaks is set, we do not clear ref count state on seeing the non local successor in bb1
+// CHECK-LABEL: sil hidden @$matched_rr_loop_early_exit_allowsleaks :
+// CHECK: bb1
+// CHECK-NOT:   strong_release %0 : $Cls
+// CHECK:   cond_br undef, bb2, bb3
+// CHECK: bb2:
+// CHECK-NOT:   strong_retain %0 : $Cls
+// CHECK:   cond_br undef, bb1, bb4
+// CHECK-LABEL: } // end sil function '$matched_rr_loop_early_exit_allowsleaks'
+sil hidden @$matched_rr_loop_early_exit_allowsleaks : $@convention(thin) (@owned Cls) -> () {
+bb0(%0 : $Cls):
+  strong_retain %0 : $Cls
+  br bb1
+  
+bb1:
+  strong_retain %0 : $Cls
+  cond_br undef, bb2, bb3
+
+bb2:
+  strong_release %0 : $Cls
+  cond_br undef, bb1, bb4
+  
+bb3:
+  unreachable
+
+bb4:
+  strong_release %0 : $Cls
+  strong_release %0 : $Cls
+  %4 = tuple()
+  return %4 : $()
+}
diff --git a/test/SILOptimizer/cse.sil b/test/SILOptimizer/cse.sil
index 60df4cc..dc56c78 100644
--- a/test/SILOptimizer/cse.sil
+++ b/test/SILOptimizer/cse.sil
@@ -1306,3 +1306,53 @@
   %4 = struct $Bool (%3 : $Builtin.Int1)
   return %4 : $Bool
 }
+
+struct StructWithLazyProperty {
+  var lazyProperty: Int64 { mutating get set }
+  @_hasStorage @_hasInitialValue var lazyPropertyStorage : Int64? { get set }
+}
+
+sil private [lazy_getter] [noinline] @lazy_getter : $@convention(method) (@inout StructWithLazyProperty) -> Int64 {
+bb0(%0 : $*StructWithLazyProperty):
+  %2 = struct_element_addr %0 : $*StructWithLazyProperty, #StructWithLazyProperty.lazyPropertyStorage 
+  %3 = load %2 : $*Optional<Int64>
+  switch_enum %3 : $Optional<Int64>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb2
+
+bb1(%5 : $Int64):
+  br bb3(%5 : $Int64)
+
+bb2:
+  %9 = integer_literal $Builtin.Int64, 27
+  %10 = struct $Int64 (%9 : $Builtin.Int64)
+  %12 = enum $Optional<Int64>, #Optional.some!enumelt, %10 : $Int64
+  store %12 to %2 : $*Optional<Int64>
+  br bb3(%10 : $Int64)
+
+bb3(%15 : $Int64):
+  return %15 : $Int64
+}
+
+sil @take_int : $@convention(thin) (Int64) -> ()
+
+// CHECK-LABEL: sil @dont_cse_lazy_property_of_overwritten_struct : $@convention(thin) () -> () {
+// CHECK:   [[GETTER:%[0-9]+]] = function_ref @lazy_getter
+// CHECK:   apply [[GETTER]]
+// CHECK:   apply [[GETTER]]
+// CHECK: } // end sil function 'dont_cse_lazy_property_of_overwritten_struct'
+sil @dont_cse_lazy_property_of_overwritten_struct : $@convention(thin) () -> () {
+bb0:
+  %0 = alloc_stack $StructWithLazyProperty
+  %4 = enum $Optional<Int64>, #Optional.none!enumelt
+  %5 = struct $StructWithLazyProperty (%4 : $Optional<Int64>)
+  store %5 to %0 : $*StructWithLazyProperty
+  %7 = function_ref @lazy_getter : $@convention(method) (@inout StructWithLazyProperty) -> Int64
+  %8 = apply %7(%0) : $@convention(method) (@inout StructWithLazyProperty) -> Int64
+  %9 = function_ref @take_int : $@convention(thin) (Int64) -> ()
+  %10 = apply %9(%8) : $@convention(thin) (Int64) -> ()
+  store %5 to %0 : $*StructWithLazyProperty
+  %18 = apply %7(%0) : $@convention(method) (@inout StructWithLazyProperty) -> Int64
+  %20 = apply %9(%18) : $@convention(thin) (Int64) -> ()
+  dealloc_stack %0 : $*StructWithLazyProperty
+  %22 = tuple ()
+  return %22 : $()
+}
diff --git a/test/SILOptimizer/definite_init_root_class.swift b/test/SILOptimizer/definite_init_root_class.swift
new file mode 100644
index 0000000..89d304d
--- /dev/null
+++ b/test/SILOptimizer/definite_init_root_class.swift
@@ -0,0 +1,214 @@
+// RUN: %target-swift-frontend -emit-sil %s | %FileCheck %s
+
+class OtherClass {}
+
+class FirstClass {
+  var x: OtherClass
+
+  // CHECK-LABEL: sil hidden @$s24definite_init_root_class10FirstClassC1nACSgs5Int32V_tcfc : $@convention(method) (Int32, @owned FirstClass) -> @owned Optional<FirstClass>
+  init?(n: Int32) {
+    // CHECK:   [[CONTROL:%.*]] = alloc_stack $Builtin.Int1
+    // CHECK:   [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
+    // CHECK:   store [[ZERO]] to [[CONTROL]] : $*Builtin.Int1
+
+    // CHECK:   [[ZERO:%.*]] = integer_literal $Builtin.Int32, 0
+    // CHECK:   [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
+    // CHECK:   [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[ZERO]] : $Builtin.Int32) : $Builtin.Int1
+    // CHECK:   cond_br [[CMP]], bb1, bb2
+    if n == 0 {
+      return nil
+    }
+
+    // CHECK: bb1:
+    // CHECK:   br bb5
+
+    // CHECK: bb2:
+    // CHECK:   [[METATYPE:%.*]] = metatype $@thick OtherClass.Type
+    // CHECK:   [[INIT:%.*]] = function_ref @$s24definite_init_root_class10OtherClassCACycfC : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
+    // CHECK:   [[OTHER:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
+    // CHECK:   [[X_ADDR:%.*]] = ref_element_addr %1 : $FirstClass, #FirstClass.x
+    // CHECK:   [[X_ACCESS:%.*]] = begin_access [modify] [dynamic] %15 : $*OtherClass
+    // CHECK:   [[ONE:%.*]] = integer_literal $Builtin.Int1, -1
+    // CHECK:   store [[ONE]] to [[CONTROL]] : $*Builtin.Int1
+    // CHECK:   store [[OTHER]] to [[X_ACCESS]] : $*OtherClass
+    // CHECK:   end_access [[X_ACCESS]] : $*OtherClass
+    x = OtherClass()
+
+    // CHECK:   [[ONE:%.*]] = integer_literal $Builtin.Int32, 1
+    // CHECK:   [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
+    // CHECK:   [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[ONE]] : $Builtin.Int32) : $Builtin.Int1
+    // CHECK:   cond_br [[CMP]], bb3, bb4
+    if n == 1 {
+      return nil
+    }
+
+    // CHECK: bb3:
+    // CHECK:   br bb5
+
+    // CHECK: bb4:
+    // CHECK:   [[RESULT:%.*]] = enum $Optional<FirstClass>, #Optional.some!enumelt, %1 : $FirstClass
+    // CHECK:   br bb12([[RESULT]] : $Optional<FirstClass>)
+
+    // CHECK: bb5:
+    // CHECK:   [[BIT:%.*]] = load [[CONTROL]] : $*Builtin.Int1
+    // CHECK:   cond_br [[BIT]], bb6, bb7
+
+    // CHECK: bb6:
+    // CHECK:   strong_release %1 : $FirstClass
+    // CHECK:   br bb11
+
+    // CHECK: bb7:
+    // CHECK:   [[BIT:%.*]] = load [[CONTROL]] : $*Builtin.Int1
+    // CHECK:   cond_br [[BIT]], bb8, bb9
+
+    // CHECK: bb8:
+    // CHECK:   [[X_ADDR:%.*]] = ref_element_addr %1 : $FirstClass, #FirstClass.x
+    // CHECK:   [[X_ACCESS:%.*]] = begin_access [deinit] [static] [[X_ADDR]] : $*OtherClass
+    // CHECK:   destroy_addr [[X_ACCESS]] : $*OtherClass
+    // CHECK:   end_access [[X_ACCESS]] : $*OtherClass
+    // CHECK:   br bb10
+
+    // CHECK: bb9:
+    // CHECK:   br bb10
+
+    // CHECK:   [[METATYPE:%.*]] = metatype $@thick FirstClass.Type
+    // CHECK:   dealloc_partial_ref %1 : $FirstClass, [[METATYPE]] : $@thick FirstClass.Type
+    // CHECK:   br bb11
+
+    // CHECK: bb11:
+    // CHECK:   [[NIL:%.*]] = enum $Optional<FirstClass>, #Optional.none!enumelt
+    // CHECK:   br bb12([[NIL]] : $Optional<FirstClass>)
+
+    // CHECK: bb12([[RESULT:%.*]] : $Optional<FirstClass>):
+    // CHECK:   dealloc_stack [[CONTROL]] : $*Builtin.Int1
+    // CHECK:   return [[RESULT]] : $Optional<FirstClass>
+  }
+}
+
+class SecondClass {
+  var x: OtherClass
+  var y: OtherClass
+
+  // CHECK-LABEL: sil hidden @$s24definite_init_root_class11SecondClassC1nACSgs5Int32V_tcfc : $@convention(method) (Int32, @owned SecondClass) -> @owned Optional<SecondClass> {
+  init?(n: Int32) {
+    // CHECK:   [[CONTROL:%.*]] = alloc_stack $Builtin.Int2
+    // CHECK:   [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
+    // CHECK:   store [[ZERO]] to [[CONTROL]] : $*Builtin.Int2
+
+    // CHECK:   [[ZERO:%.*]] = integer_literal $Builtin.Int32, 0
+    // CHECK:   [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
+    // CHECK:   [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[ZERO]] : $Builtin.Int32) : $Builtin.Int1
+    // CHECK:   cond_br [[CMP]], bb1, bb2
+    if n == 0 {
+      return nil
+    }
+
+    // CHECK: bb1:
+    // CHECK:   br bb7
+
+    // CHECK: bb2:
+    // CHECK:   [[METATYPE:%.*]] = metatype $@thick OtherClass.Type
+    // CHECK:   [[INIT:%.*]] = function_ref @$s24definite_init_root_class10OtherClassCACycfC : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
+    // CHECK:   [[OTHER:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
+    // CHECK:   [[X_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.x
+    // CHECK:   [[X_ACCESS:%.*]] = begin_access [modify] [dynamic] [[X_ADDR]] : $*OtherClass
+    // CHECK:   [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
+    // CHECK:   store [[ONE]] to [[CONTROL]] : $*Builtin.Int2
+    // CHECK:   store [[OTHER]] to [[X_ACCESS]] : $*OtherClass
+    // CHECK:   end_access [[X_ACCESS]] : $*OtherClass
+    x = OtherClass()
+
+    // CHECK:   [[ONE:%.*]] = integer_literal $Builtin.Int32, 1
+    // CHECK:   [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
+    // CHECK:   [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[ONE]] : $Builtin.Int32) : $Builtin.Int1
+    // CHECK:   cond_br [[CMP]], bb3, bb4
+    if n == 1 {
+      return nil
+    }
+
+    // CHECK: bb3:
+    // CHECK:   br bb7
+
+    // CHECK: bb4:
+    // CHECK:   [[METATYPE:%.*]] = metatype $@thick OtherClass.Type
+    // CHECK:   [[INIT:%.*]] = function_ref @$s24definite_init_root_class10OtherClassCACycfC : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
+    // CHECK:   [[OTHER:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
+    // CHECK:   [[Y_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.y
+    // CHECK:   [[Y_ACCESS:%.*]] = begin_access [modify] [dynamic] [[Y_ADDR]] : $*OtherClass
+    // CHECK:   [[THREE:%.*]] = integer_literal $Builtin.Int2, -1
+    // CHECK:   store [[THREE]] to [[CONTROL]] : $*Builtin.Int2
+    // CHECK:   store [[OTHER]] to [[Y_ACCESS]] : $*OtherClass
+    // CHECK:   end_access [[Y_ACCESS]] : $*OtherClass
+    y = OtherClass()
+
+    // CHECK:   [[TWO:%.*]] = integer_literal $Builtin.Int32, 2
+    // CHECK:   [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
+    // CHECK:   [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[TWO]] : $Builtin.Int32) : $Builtin.Int1
+    // CHECK:   cond_br [[CMP]], bb5, bb6
+    if n == 2 {
+      return nil
+    }
+
+    // CHECK: bb5:
+    // CHECK:   br bb7
+
+    // CHECK: bb6:
+    // CHECK:   [[RESULT:%.*]] = enum $Optional<SecondClass>, #Optional.some!enumelt, %1 : $SecondClass
+    // CHECK:   br bb17([[RESULT]] : $Optional<SecondClass>)
+
+    // CHECK: bb7:
+    // CHECK:   [[BITS:%.*]] = load [[CONTROL]] : $*Builtin.Int2
+    // CHECK:   [[THREE:%.*]] = integer_literal $Builtin.Int2, -1
+    // CHECK:   [[BIT:%.*]] = builtin "cmp_eq_Int2"([[BITS]] : $Builtin.Int2, [[THREE]] : $Builtin.Int2) : $Builtin.Int1
+    // CHECK:   cond_br [[BIT]], bb8, bb9
+
+    // CHECK: bb8:
+    // CHECK:   strong_release %1 : $SecondClass
+    // CHECK:   br bb16
+
+    // CHECK: bb9:
+    // CHECK:   [[BITS:%.*]] = load [[CONTROL]] : $*Builtin.Int2
+    // CHECK:   [[BIT:%.*]] = builtin "trunc_Int2_Int1"([[BITS]] : $Builtin.Int2) : $Builtin.Int1
+    // CHECK:   cond_br [[BIT]], bb10, bb11
+
+    // CHECK: bb10:
+    // CHECK:   [[X_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.x
+    // CHECK:   [[X_ACCESS:%.*]] = begin_access [deinit] [static] [[X_ADDR]] : $*OtherClass
+    // CHECK:   destroy_addr [[X_ACCESS]] : $*OtherClass
+    // CHECK:   end_access [[X_ACCESS]] : $*OtherClass
+    // CHECK:   br bb12
+
+    // CHECK: bb11:
+    // CHECK:   br bb12
+
+    // CHECK: bb12:
+    // CHECK:   [[BITS:%.*]] = load [[CONTROL]] : $*Builtin.Int2
+    // CHECK:   [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
+    // CHECK:   [[TMP:%.*]] = builtin "lshr_Int2"([[BITS]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) : $Builtin.Int2
+    // CHECK:   [[BIT:%.*]] = builtin "trunc_Int2_Int1"([[TMP]] : $Builtin.Int2) : $Builtin.Int1
+    // CHECK:   cond_br [[BIT]], bb13, bb14
+
+    // CHECK: bb13:
+    // CHECK:   [[Y_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.y
+    // CHECK:   [[Y_ACCESS:%.*]] = begin_access [deinit] [static] [[Y_ADDR]] : $*OtherClass
+    // CHECK:   destroy_addr [[Y_ACCESS]] : $*OtherClass
+    // CHECK:   end_access [[Y_ACCESS]] : $*OtherClass
+    // CHECK:   br bb15
+
+    // CHECK: bb14:
+    // CHECK:   br bb15
+
+    // CHECK: bb15:
+    // CHECK:   [[METATYPE:%.*]] = metatype $@thick SecondClass.Type
+    // CHECK:   dealloc_partial_ref %1 : $SecondClass, [[METATYPE]] : $@thick SecondClass.Type
+    // CHECK:   br bb16
+
+    // CHECK: bb16:
+    // CHECK:   [[NIL:%.*]] = enum $Optional<SecondClass>, #Optional.none!enumelt
+    // CHECK:   br bb17([[NIL]] : $Optional<SecondClass>)
+
+    // CHECK: bb17([[RESULT:%.*]] : $Optional<SecondClass>):
+    // CHECK:   dealloc_stack [[CONTROL]] : $*Builtin.Int2
+    // CHECK:   return [[RESULT]] : $Optional<SecondClass>
+  }
+}
diff --git a/test/SILOptimizer/floating_point_conversion.swift b/test/SILOptimizer/floating_point_conversion.swift
new file mode 100644
index 0000000..3acd361
--- /dev/null
+++ b/test/SILOptimizer/floating_point_conversion.swift
@@ -0,0 +1,47 @@
+// RUN: %target-swift-frontend -O -module-name=test -emit-sil %s | %FileCheck %s
+
+func convert<
+  T: BinaryFloatingPoint, U: BinaryFloatingPoint
+>(_ value: T, to: U.Type) -> U {
+  U(value)
+}
+
+// Check that the following functions can be optimized to concrete conversions.
+
+// CHECK-LABEL: sil @$s4test0A13DoubleToFloatySfSdF
+// CHECK:      bb0(%0 : $Double):
+// CHECK:        struct_extract %0 : $Double, #Double._value
+// CHECK-NEXT:   builtin "fptrunc_FPIEEE64_FPIEEE32"
+// CHECK-NEXT:   struct $Float
+// CHECK-NEXT:   return
+// CHECK-NEXT: } // end sil function '$s4test0A13DoubleToFloatySfSdF'
+public func testDoubleToFloat(_ x: Double) -> Float {
+  return convert(x, to: Float.self)
+}
+
+// CHECK-LABEL: sil @$s4test0A13FloatToDoubleySdSfF
+// CHECK:      bb0(%0 : $Float):
+// CHECK:        struct_extract %0 : $Float, #Float._value
+// CHECK-NEXT:   builtin "fpext_FPIEEE32_FPIEEE64"
+// CHECK-NEXT:   struct $Double
+// CHECK-NEXT:   return
+// CHECK-NEXT: } // end sil function '$s4test0A13FloatToDoubleySdSfF'
+public func testFloatToDouble(_ x: Float) -> Double {
+  return convert(x, to: Double.self)
+}
+
+// Check that the following functions can be optimized to no-ops.
+
+// CHECK-LABEL: sil @$s4test0A6DoubleyS2dF
+// CHECK:   return %0
+// CHECK: } // end sil function '$s4test0A6DoubleyS2dF'
+public func testDouble(_ x: Double) -> Double {
+  return convert(x, to: Double.self)
+}
+
+// CHECK-LABEL: sil @$s4test0A5FloatyS2fF
+// CHECK:   return %0
+// CHECK: } // end sil function '$s4test0A5FloatyS2fF'
+public func testFloat(_ x: Float) -> Float {
+  return convert(x, to: Float.self)
+}
diff --git a/test/SILOptimizer/ignore-always-inline.sil b/test/SILOptimizer/ignore-always-inline.sil
new file mode 100644
index 0000000..49d98e8
--- /dev/null
+++ b/test/SILOptimizer/ignore-always-inline.sil
@@ -0,0 +1,71 @@
+// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -dce | %FileCheck %s -check-prefix=REGULAR
+// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -dce -ignore-always-inline | %FileCheck %s -check-prefix=IGNORED
+
+sil_stage canonical
+
+// REGULAR: sil [Osize] @caller
+// IGNORED: sil [Osize] @caller
+sil [Osize] @caller : $@convention(thin) () -> () {
+bb0:
+  // REGULAR-NOT: function_ref @callee
+  // REGULAR:     function_ref @foobar
+  // IGNORED:     function_ref @callee
+  %d1 = function_ref @callee : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+sil @foobar : $@convention(thin) () -> ()
+
+// callee is "expensive" enough to not get inlined unless [always_inline] is used
+// REGULAR: sil [always_inline] [Osize] @callee
+// IGNORED: sil [always_inline] [Osize] @callee
+sil [always_inline] [Osize] @callee : $@convention(thin) () -> () {
+bb0:
+  %d1 = function_ref @foobar : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+  apply %d1() : $@convention(thin) () -> ()
+
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/SILOptimizer/lazy_property_getters.swift b/test/SILOptimizer/lazy_property_getters.swift
index e3e8b9d..2880d06 100644
--- a/test/SILOptimizer/lazy_property_getters.swift
+++ b/test/SILOptimizer/lazy_property_getters.swift
@@ -88,15 +88,18 @@
   return v
 }
 
+// This test is disabled, because for structs, it does not work yet.
+// CSE is too conservative to handle indirect getter arguments currently.
+
 // CHECK-LABEL: sil {{.*}} @$s4test0A7_structySiAA8MystructVF
-// CHECK:   [[GETTER:%[0-9]+]] = function_ref @$s4test8MystructV4lvarSivg
-// CHECK:   [[V1:%[0-9]+]] = apply [[GETTER]]({{.*}})
-// CHECK:   [[V2OPT:%[0-9]+]] = load
-// CHECK:   [[V2:%[0-9]+]] = unchecked_enum_data [[V2OPT]]
-// CHECK:   [[V1VAL:%[0-9]+]] = struct_extract [[V1]]
-// CHECK:   [[V2VAL:%[0-9]+]] = struct_extract [[V2]]
-// CHECK:   builtin "sadd{{.*}}"([[V1VAL]] {{.*}}, [[V2VAL]]
-// CHECK: } // end sil function '$s4test0A7_structySiAA8MystructVF'
+// CHECK-DISABLED:   [[GETTER:%[0-9]+]] = function_ref @$s4test8MystructV4lvarSivg
+// CHECK-DISABLED:   [[V1:%[0-9]+]] = apply [[GETTER]]({{.*}})
+// CHECK-DISABLED:   [[V2OPT:%[0-9]+]] = load
+// CHECK-DISABLED:   [[V2:%[0-9]+]] = unchecked_enum_data [[V2OPT]]
+// CHECK-DISABLED:   [[V1VAL:%[0-9]+]] = struct_extract [[V1]]
+// CHECK-DISABLED:   [[V2VAL:%[0-9]+]] = struct_extract [[V2]]
+// CHECK-DISABLED:   builtin "sadd{{.*}}"([[V1VAL]] {{.*}}, [[V2VAL]]
+// CHECK-DISABLED: } // end sil function '$s4test0A7_structySiAA8MystructVF'
 @inline(never)
 func test_struct(_ s: Mystruct) -> Int {
   var sm = s
@@ -106,6 +109,25 @@
   return v1 &+ v2
 }
 
+// CHECK-LABEL: sil {{.*}} @$s4test0A19_overwritten_structySiAA8MystructVF
+// CHECK:   [[GETTER:%[0-9]+]] = function_ref @$s4test8MystructV4lvarSivg
+// CHECK:   [[V1:%[0-9]+]] = apply [[GETTER]]({{.*}})
+// CHECK:   [[V2:%[0-9]+]] = apply [[GETTER]]({{.*}})
+// CHECK:   [[V1VAL:%[0-9]+]] = struct_extract [[V1]]
+// CHECK:   [[V2VAL:%[0-9]+]] = struct_extract [[V2]]
+// CHECK:   builtin "sadd{{.*}}"([[V1VAL]] {{.*}}, [[V2VAL]]
+// CHECK: } // end sil function '$s4test0A19_overwritten_structySiAA8MystructVF'
+@inline(never)
+func test_overwritten_struct(_ s: Mystruct) -> Int {
+  var sm = s
+  g = 42
+  let v1 = sm.lvar
+  sm = s
+  g = 43
+  let v2 = sm.lvar
+  return v1 &+ v2
+}
+
 func calltests() {
   // CHECK-OUTPUT-LABEL: test_simple
   print("test_simple")
@@ -133,6 +155,13 @@
   // CHECK-OUTPUT-NEXT:  lvar init
   // CHECK-OUTPUT-NEXT:  84
   print(test_struct(Mystruct()))
+
+  // CHECK-OUTPUT-LABEL: test_overwritten_struct
+  print("test_overwritten_struct")
+  // CHECK-OUTPUT-NEXT:  lvar init
+  // CHECK-OUTPUT-NEXT:  lvar init
+  // CHECK-OUTPUT-NEXT:  85
+  print(test_overwritten_struct(Mystruct()))
 }
 
 calltests()
diff --git a/test/SILOptimizer/opt-remark-generator.sil b/test/SILOptimizer/opt-remark-generator.sil
index b8ddadb..4e10c7f 100644
--- a/test/SILOptimizer/opt-remark-generator.sil
+++ b/test/SILOptimizer/opt-remark-generator.sil
@@ -1,15 +1,86 @@
-// RUN: %target-sil-opt -sil-opt-remark-generator -sil-remarks-missed=sil-opt-remark-gen -verify %s -o /dev/null
+// RUN: %target-sil-opt -sil-opt-remark-ignore-always-infer -optremarkgen-declless-debugvalue-use-sildebugvar-info -sil-opt-remark-generator -sil-remarks-missed=sil-opt-remark-gen -verify %s -o /dev/null
 
 sil_stage canonical
 
 import Builtin
 
-sil @foo : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+//////////////////
+// Declarations //
+//////////////////
+
+class Klass {}
+
+enum TrivialState {
+case first
+case second
+case third
+}
+
+struct StructWithOwner {
+  var owner: Klass
+  var state: TrivialState
+}
+
+struct KlassPair {
+  var lhs: Klass
+  var rhs: Klass
+}
+
+struct StructWithOwnerAndState {
+  var structWithOwner: StructWithOwner
+  var state: TrivialState
+}
+
+///////////
+// Tests //
+///////////
+
+sil @simple : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
 bb0(%0 : $Builtin.NativeObject):
-  strong_retain %0 : $Builtin.NativeObject // expected-remark {{retain of type 'Builtin.NativeObject'}}
-  retain_value %0 : $Builtin.NativeObject  // expected-remark {{retain of type 'Builtin.NativeObject'}}
+  debug_value %0 : $Builtin.NativeObject, let, name "arg"
+  strong_retain %0 : $Builtin.NativeObject  // expected-remark {{retain of type 'Builtin.NativeObject'}}
+                                            // expected-note @-2 {{of 'arg'}}
+  retain_value %0 : $Builtin.NativeObject   // expected-remark {{retain of type 'Builtin.NativeObject'}}
+                                            // expected-note @-4 {{of 'arg'}}
   strong_release %0 : $Builtin.NativeObject // expected-remark {{release of type 'Builtin.NativeObject'}}
-  release_value %0 : $Builtin.NativeObject // expected-remark {{release of type 'Builtin.NativeObject'}}
+                                            // expected-note @-6 {{of 'arg'}}
+  release_value %0 : $Builtin.NativeObject  // expected-remark {{release of type 'Builtin.NativeObject'}}
+                                            // expected-note @-8 {{of 'arg'}}
   %9999 = tuple()
   return %9999 : $()
 }
+
+sil @extract_out_singleobj_struct_subfield_1 : $@convention(thin) (@guaranteed StructWithOwner) -> Klass {
+bb0(%0 : $StructWithOwner):
+  debug_value %0 : $StructWithOwner, let, name "x"
+  %1 = struct_extract %0 : $StructWithOwner, #StructWithOwner.owner
+  strong_retain %1 : $Klass // expected-remark {{retain of type 'Klass'}}
+                                           // expected-note @-3 {{of 'x.owner'}}
+  return %1 : $Klass
+}
+
+// This case should never actually happen like this, but we should handle it in
+// a sane way by printing both notes for y and x and also make sure that we do
+// not infer .owner on y since y is on owner itself.
+sil @extract_out_singleobj_struct_subfield_multiple_debugvalue : $@convention(thin) (@guaranteed StructWithOwner) -> Klass {
+bb0(%0 : $StructWithOwner):
+  debug_value %0 : $StructWithOwner, let, name "x"
+  %1 = struct_extract %0 : $StructWithOwner, #StructWithOwner.owner
+  debug_value %1 : $Klass, let, name "y"
+  strong_retain %1 : $Klass // expected-remark {{retain of type 'Klass'}}
+                            // expected-note @-4 {{of 'x.owner'}}
+                            // expected-note @-3 {{of 'y'}}
+  return %1 : $Klass
+}
+
+// In this case, we emit the remark for x since its operand %2 is rc-identical
+// to %0 the value we found while traversing our access path.
+sil @rcidentity_based_use : $@convention(thin) (@guaranteed StructWithOwner, TrivialState) -> @owned Klass {
+bb0(%0 : $StructWithOwner, %1 : $TrivialState):
+  %2 = struct $StructWithOwnerAndState(%0 : $StructWithOwner, %1 : $TrivialState)
+  debug_value %2 : $StructWithOwnerAndState, let, name "x"
+  %3 = struct_extract %0 : $StructWithOwner, #StructWithOwner.owner
+  strong_retain %3 : $Klass // expected-remark {{retain of type 'Klass'}}
+                            // expected-note @-3 {{of 'x'}}
+  return %3 : $Klass
+}
diff --git a/test/SILOptimizer/opt-remark-generator.swift b/test/SILOptimizer/opt-remark-generator.swift
index 8c780ea..6aedcd8 100644
--- a/test/SILOptimizer/opt-remark-generator.swift
+++ b/test/SILOptimizer/opt-remark-generator.swift
@@ -90,8 +90,10 @@
                  // expected-remark @-3:16 {{release of type}}
 }
 
+// We put the retain on the return here since it is part of the result
+// convention.
 func returnKlassPairLHS(x: KlassPair) -> Klass {
-    return x.lhs // expected-remark @:14 {{retain of type 'Klass'}}
+    return x.lhs // expected-remark @:5 {{retain of type 'Klass'}}
                  // expected-note @-2:25 {{of 'x.lhs'}}
 }
 
@@ -123,7 +125,7 @@
 }
 
 func returnKlassTupleLHS(x: (Klass, Klass)) -> Klass {
-    return x.0 // expected-remark @:12 {{retain of type 'Klass'}}
+    return x.0 // expected-remark @:5 {{retain of type 'Klass'}}
                // expected-note @-2:26 {{of 'x'}}
 }
 
diff --git a/test/SILOptimizer/prune-vtables.sil b/test/SILOptimizer/prune-vtables.sil
index d72af0b..633dc9e 100644
--- a/test/SILOptimizer/prune-vtables.sil
+++ b/test/SILOptimizer/prune-vtables.sil
@@ -14,9 +14,9 @@
 sil @PrivateA_isFinal      : $@convention(method) (@guaranteed PrivateA) -> ()
 
 // NOWMO-LABEL: sil_vtable PrivateA {
-// NOWMO:         #PrivateA.noOverrides{{.*}} [nonoverridden]
+// NOWMO:         #PrivateA.noOverrides{{[^[]]*}}
 // NOWMO-NOT:     #PrivateA.yesOverrides{{.*}} [nonoverridden]
-// NOWMO:         #PrivateA.isFinal{{.*}} [nonoverridden]
+// NOWMO:         #PrivateA.isFinal{{[^[]]*}}
 
 // WMO-LABEL: sil_vtable PrivateA {
 // WMO:         #PrivateA.noOverrides{{.*}} [nonoverridden]
@@ -35,9 +35,9 @@
 sil @PrivateB_yesOverrides : $@convention(method) (@guaranteed PrivateB) -> ()
 
 // NOWMO-LABEL: sil_vtable PrivateB {
-// NOWMO:         #PrivateA.noOverrides{{.*}} [nonoverridden]
+// NOWMO:         #PrivateA.noOverrides{{[^[]]*}}
 // NOWMO-NOT:     #PrivateA.yesOverrides{{.*}} [nonoverridden]
-// NOWMO:         #PrivateA.isFinal{{.*}} [nonoverridden]
+// NOWMO:         #PrivateA.isFinal{{[^[]]*}}
 
 // WMO-LABEL: sil_vtable PrivateB {
 // WMO:         #PrivateA.noOverrides{{.*}} [nonoverridden]
@@ -62,7 +62,7 @@
 // NOWMO-LABEL: sil_vtable InternalA {
 // NOWMO-NOT:     #InternalA.noOverrides{{.*}} [nonoverridden]
 // NOWMO-NOT:     #InternalA.yesOverrides{{.*}} [nonoverridden]
-// NOWMO:         #InternalA.isFinal{{.*}} [nonoverridden]
+// NOWMO:         #InternalA.isFinal{{[^[]]*}}
 
 // WMO-LABEL: sil_vtable InternalA {
 // WMO:         #InternalA.noOverrides{{.*}} [nonoverridden]
@@ -83,7 +83,7 @@
 // NOWMO-LABEL: sil_vtable InternalB {
 // NOWMO-NOT:     #InternalA.noOverrides{{.*}} [nonoverridden]
 // NOWMO-NOT:     #InternalA.yesOverrides{{.*}} [nonoverridden]
-// NOWMO:         #InternalA.isFinal{{.*}} [nonoverridden]
+// NOWMO:         #InternalA.isFinal{{[^[]]*}}
 
 // WMO-LABEL: sil_vtable InternalB {
 // WMO:         #InternalA.noOverrides{{.*}} [nonoverridden]
@@ -108,7 +108,7 @@
 // NOWMO-LABEL: sil_vtable PublicA {
 // NOWMO-NOT:     #PublicA.noOverrides{{.*}} [nonoverridden]
 // NOWMO-NOT:     #PublicA.yesOverrides{{.*}} [nonoverridden]
-// NOWMO:         #PublicA.isFinal{{.*}} [nonoverridden]
+// NOWMO:         #PublicA.isFinal{{[^[]]*}}
 
 // WMO-LABEL: sil_vtable PublicA {
 // WMO:         #PublicA.noOverrides{{.*}} [nonoverridden]
@@ -129,7 +129,7 @@
 // NOWMO-LABEL: sil_vtable PublicB {
 // NOWMO-NOT:     #PublicA.noOverrides{{.*}} [nonoverridden]
 // NOWMO-NOT:     #PublicA.yesOverrides{{.*}} [nonoverridden]
-// NOWMO:         #PublicA.isFinal{{.*}} [nonoverridden]
+// NOWMO:         #PublicA.isFinal{{[^[]]*}}
 
 // WMO-LABEL: sil_vtable PublicB {
 // WMO:         #PublicA.noOverrides{{.*}} [nonoverridden]
@@ -154,7 +154,7 @@
 // NOWMO-LABEL: sil_vtable OpenA {
 // NOWMO-NOT:     #OpenA.noOverrides{{.*}} [nonoverridden]
 // NOWMO-NOT:     #OpenA.yesOverrides{{.*}} [nonoverridden]
-// NOWMO:         #OpenA.isFinal{{.*}} [nonoverridden]
+// NOWMO:         #OpenA.isFinal{{[^[]]*}}
 
 // WMO-LABEL: sil_vtable OpenA {
 // WMO-NOT:     #OpenA.noOverrides{{.*}} [nonoverridden]
@@ -175,7 +175,7 @@
 // NOWMO-LABEL: sil_vtable OpenB {
 // NOWMO-NOT:     #OpenA.noOverrides{{.*}} [nonoverridden]
 // NOWMO-NOT:     #OpenA.yesOverrides{{.*}} [nonoverridden]
-// NOWMO:         #OpenA.isFinal{{.*}} [nonoverridden]
+// NOWMO:         #OpenA.isFinal{{[^[]]*}}
 
 // WMO-LABEL: sil_vtable OpenB {
 // WMO-NOT:     #OpenA.noOverrides{{.*}} [nonoverridden]
diff --git a/test/SILOptimizer/semantic-arc-opts.sil b/test/SILOptimizer/semantic-arc-opts.sil
index ac0de9f..1b79ff3 100644
--- a/test/SILOptimizer/semantic-arc-opts.sil
+++ b/test/SILOptimizer/semantic-arc-opts.sil
@@ -20,12 +20,19 @@
 sil @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
 sil @get_owned_obj : $@convention(thin) () -> @owned Builtin.NativeObject
 sil @unreachable_guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> MyNever
+sil @inout_user : $@convention(thin) (@inout FakeOptional<NativeObjectPair>) -> ()
 
 struct NativeObjectPair {
   var obj1 : Builtin.NativeObject
   var obj2 : Builtin.NativeObject
 }
 
+struct FakeOptionalNativeObjectPairPair {
+  var pair1 : FakeOptional<NativeObjectPair>
+  var pair2 : FakeOptional<NativeObjectPair>
+}
+sil @inout_user2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
+
 sil @get_nativeobject_pair : $@convention(thin) () -> @owned NativeObjectPair
 
 protocol MyFakeAnyObject : Klass {
@@ -2639,3 +2646,84 @@
   inject_enum_addr %0 : $*FakeOptional<Klass>, #FakeOptional.none!enumelt
   br bb5
 }
+
+// CHECK-LABEL: sil [ossa] @destructure_with_differing_lifetimes_inout_1 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> () {
+// CHECK-NOT: load_borrow
+// CHECK: } // end sil function 'destructure_with_differing_lifetimes_inout_1'
+sil [ossa] @destructure_with_differing_lifetimes_inout_1 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> () {
+bb0(%0 : $*FakeOptionalNativeObjectPairPair):
+  %0a = struct_element_addr %0 : $*FakeOptionalNativeObjectPairPair, #FakeOptionalNativeObjectPairPair.pair1
+  %1 = load [copy] %0a : $*FakeOptional<NativeObjectPair>
+  switch_enum %1 : $FakeOptional<NativeObjectPair>, case #FakeOptional.some!enumelt: bb1, default bb2
+
+bb2(%2 : @owned $FakeOptional<NativeObjectPair>):
+  destroy_value %2 : $FakeOptional<NativeObjectPair>
+  br bbEnd
+
+bb1(%3 : @owned $NativeObjectPair):
+  (%3a, %3b) = destructure_struct %3 : $NativeObjectPair
+  cond_br undef, bb1a, bb1b
+
+bb1a:
+  destroy_value %3a : $Builtin.NativeObject
+  destroy_value %3b : $Builtin.NativeObject
+  br bbEnd
+
+bb1b:
+  destroy_value %3a : $Builtin.NativeObject
+  %f = function_ref @inout_user2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
+  apply %f(%0) : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
+  destroy_value %3b : $Builtin.NativeObject
+  br bbEnd
+
+bbEnd:
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil [ossa] @destructure_with_differing_lifetimes_inout_2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> () {
+// CHECK-NOT: load_borrow
+// CHECK: } // end sil function 'destructure_with_differing_lifetimes_inout_2'
+sil [ossa] @destructure_with_differing_lifetimes_inout_2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> () {
+bb0(%0 : $*FakeOptionalNativeObjectPairPair):
+  %0a = struct_element_addr %0 : $*FakeOptionalNativeObjectPairPair, #FakeOptionalNativeObjectPairPair.pair1
+  %1 = load [copy] %0a : $*FakeOptional<NativeObjectPair>
+  switch_enum %1 : $FakeOptional<NativeObjectPair>, case #FakeOptional.some!enumelt: bb1, default bb2
+
+bb2(%2 : @owned $FakeOptional<NativeObjectPair>):
+  destroy_value %2 : $FakeOptional<NativeObjectPair>
+  br bbEnd
+
+bb1(%3 : @owned $NativeObjectPair):
+  (%3a, %3b) = destructure_struct %3 : $NativeObjectPair
+  cond_br undef, bb1a, bb1b
+
+bb1a:
+  destroy_value %3a : $Builtin.NativeObject
+  br bb1ab
+
+bb1ab:
+  destroy_value %3b : $Builtin.NativeObject
+  br bbEnd
+
+bb1b:
+  destroy_value %3a : $Builtin.NativeObject
+  %f = function_ref @inout_user2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
+  apply %f(%0) : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
+  cond_br undef, bb1ba, bb1bb
+
+bb1ba:
+  br bb1baEnd
+
+bb1bb:
+  br bb1baEnd
+
+bb1baEnd:
+  destroy_value %3b : $Builtin.NativeObject
+  br bbEnd
+
+bbEnd:
+  %9999 = tuple()
+  return %9999 : $()
+}
+
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index 145399c..c3c8c95 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -3508,6 +3508,33 @@
   return %26 : $()
 }
 
+sil @any_to_object : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned AnyObject
+
+// CHECK-LABEL: sil @dont_crash_when_propagating_existentials
+// CHECK:   [[EM:%[0-9]+]] = init_existential_metatype %0
+// CHECK:   [[S:%[0-9]+]] = alloc_stack $Any
+// CHECK:   [[M:%[0-9]+]] = open_existential_metatype [[EM]]
+// CHECK:   [[E:%[0-9]+]] = init_existential_addr [[S]]
+// CHECK:   store [[M]] to [[E]]
+// CHECK:   apply {{%[0-9]+}}<(@opened("5F99B72C-EC40-11EA-9534-8C8590A6A134") AnyObject).Type>([[E]])
+// CHECK: } // end sil function 'dont_crash_when_propagating_existentials'
+sil @dont_crash_when_propagating_existentials : $@convention(thin) () -> @owned AnyObject {
+bb0:
+  %0 = metatype $@thick C.Type
+  %1 = init_existential_metatype %0 : $@thick C.Type, $@thick AnyObject.Type
+  %3 = alloc_stack $Any, let, name "object"
+  %4 = open_existential_metatype %1 : $@thick AnyObject.Type to $@thick (@opened("5F99B72C-EC40-11EA-9534-8C8590A6A134") AnyObject).Type
+  %5 = init_existential_addr %3 : $*Any, $(@opened("5F99B72C-EC40-11EA-9534-8C8590A6A134") AnyObject).Type
+  store %4 to %5 : $*@thick (@opened("5F99B72C-EC40-11EA-9534-8C8590A6A134") AnyObject).Type
+  %7 = open_existential_addr immutable_access %3 : $*Any to $*@opened("5F9F1B04-EC40-11EA-9534-8C8590A6A134") Any
+  %8 = function_ref @any_to_object : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned AnyObject
+  %9 = apply %8<@opened("5F9F1B04-EC40-11EA-9534-8C8590A6A134") Any>(%7) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned AnyObject
+  destroy_addr %3 : $*Any
+  dealloc_stack %3 : $*Any
+  return %9 : $AnyObject
+}
+
+
 // CHECK-LABEL: sil @remove_unused_alloc_ref
 // CHECK-NEXT: bb0
 // CHECK-NEXT: %0 = tuple ()
diff --git a/test/SILOptimizer/simplify_cfg.sil b/test/SILOptimizer/simplify_cfg.sil
index 6adb3f9..d19fb98 100644
--- a/test/SILOptimizer/simplify_cfg.sil
+++ b/test/SILOptimizer/simplify_cfg.sil
@@ -2980,6 +2980,70 @@
   br bb2(%z : $Builtin.Int1)
 }
 
+// CHECK-LABEL: sil @trivial_checked_cast_addr_br : $@convention(thin) (@guaranteed Int, @guaranteed Int) -> @owned Int
+// CHECK:   [[SRC:%.*]] = alloc_stack $Int
+// CHECK:   store %0 to [[SRC]]
+// CHECK:   [[DST:%.*]] = alloc_stack $Int
+// CHECK:   [[LD1:%.*]] = load [[SRC]]
+// CHECK:   store [[LD1]] to [[DST]]
+// CHECK:   [[LD2:%.*]] = load [[DST]]
+// CHECK:   return [[LD2]]
+// CHECK: } // end sil function 'trivial_checked_cast_addr_br'
+sil @trivial_checked_cast_addr_br : $@convention(thin) (@guaranteed Int, @guaranteed Int) -> @owned Int {
+bb0(%0 : $Int, %1 : $Int):
+  %6 = alloc_stack $Int
+  store %0 to %6 : $*Int
+  %8 = alloc_stack $Int
+  checked_cast_addr_br copy_on_success Int in %6 : $*Int to Int in %8 : $*Int, bb1, bb2
+
+bb1:
+  %10 = load %8 : $*Int
+  dealloc_stack %8 : $*Int
+  br bb3(%10 : $Int)
+
+bb2:
+  retain_value %1: $Int
+  dealloc_stack %8 : $*Int
+  br bb3(%1 : $Int)
+
+bb3(%11 : $Int):
+  dealloc_stack %6 : $*Int
+  return %11 : $Int
+}
+
+// CHECK-LABEL: sil @non_trivial_checked_cast_addr_br : $@convention(thin) (@guaranteed String, @guaranteed String) -> @owned String
+// CHECK:   [[SRC:%.*]] = alloc_stack $String
+// CHECK:   store %0 to [[SRC]]
+// CHECK:   [[DST:%.*]] = alloc_stack $String
+// CHECK:   [[TEMP:%.*]] = alloc_stack $String
+// CHECK:   copy_addr [[SRC]] to [initialization] [[TEMP]]
+// CHECK:   [[LD1:%.*]] = load [[TEMP]]
+// CHECK:   store [[LD1]] to [[DST]]
+// CHECK:   [[LD2:%.*]] = load [[DST]]
+// CHECK:   return [[LD2]]
+// CHECK: } // end sil function 'non_trivial_checked_cast_addr_br'
+sil @non_trivial_checked_cast_addr_br : $@convention(thin) (@guaranteed String, @guaranteed String) -> @owned String {
+bb0(%0 : $String, %1 : $String):
+  %6 = alloc_stack $String
+  store %0 to %6 : $*String
+  %8 = alloc_stack $String
+  checked_cast_addr_br copy_on_success String in %6 : $*String to String in %8 : $*String, bb1, bb2
+
+bb1:
+  %10 = load %8 : $*String
+  dealloc_stack %8 : $*String
+  br bb3(%10 : $String)
+
+bb2:
+  retain_value %1: $String
+  dealloc_stack %8 : $*String
+  br bb3(%1 : $String)
+
+bb3(%11 : $String):
+  dealloc_stack %6 : $*String
+  return %11 : $String
+}
+
 // CHECK-LABEL: sil @dont_hang
 // CHECK:      bb6:
 // CHECK:        integer_literal $Builtin.Int64, 1
diff --git a/test/SPI/local_spi_decls.swift b/test/SPI/local_spi_decls.swift
index 943a005..b824998 100644
--- a/test/SPI/local_spi_decls.swift
+++ b/test/SPI/local_spi_decls.swift
@@ -1,8 +1,11 @@
-// Checks for SPI declarations and limited exposability
+// Checks for SPI declarations and limited exportability.
 
 // RUN: %empty-directory(%t)
 // RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -enable-library-evolution -swift-version 5
 
+// Without -enable-library-evolution the exportability check looks at struct internal properties.
+// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -swift-version 5
+
 // SPI declarations
 @_spi(MySPI) public func spiFunc() {} // expected-note {{global function 'spiFunc()' is not '@usableFromInline' or public}}
 @_spi(+) public func invalidSPIName() {} // expected-error {{expected an SPI identifier as subject of the '@_spi' attribute}}
@@ -55,3 +58,26 @@
   public var a: SPIClass // expected-error {{cannot use class 'SPIClass' here; it is SPI}}
   public var b = SPIClass() // expected-error {{cannot use class 'SPIClass' here; it is SPI}}
 }
+
+@_spi(S)
+@usableFromInline
+func usableFromInlineFunc(_ a: SPIStruct) -> SPIStruct {
+  fatalError()
+}
+
+@_spi(S)
+public final class ClassWithUsables {
+    @usableFromInline
+    var usableFromInlineVar = SPIClass()
+
+    @usableFromInline
+    func usableFromInlineFunc(_ a: SPIStruct) -> SPIStruct {
+      fatalError()
+    }
+}
+
+@_spi(S)
+public struct NestedParent {
+    public struct Nested { }
+    let nested: Nested
+}
diff --git a/test/SPI/protocol_requirement.swift b/test/SPI/protocol_requirement.swift
index 756915e..c3b952e 100644
--- a/test/SPI/protocol_requirement.swift
+++ b/test/SPI/protocol_requirement.swift
@@ -96,3 +96,20 @@
   @_spi(Private)
   static var staticProperty: Int { get }
 }
+
+public protocol OtherProto {}
+public protocol Proto {
+  associatedtype A : Sequence where A.Element : OtherProto
+}
+
+public struct BadStruct {}
+@_spi(Horse) extension BadStruct : OtherProto {}
+public struct BadConforms : Proto { // expected-error {{cannot use conformance of 'BadStruct' to 'OtherProto' in associated type 'Self.A.Element' (inferred as 'BadStruct'); the conformance is declared as SPI}}
+  public typealias A = [BadStruct]
+}
+
+public struct OKStruct {}
+@_spi(Horse) extension OKStruct : OtherProto {}
+@_spi(Horse) public struct OKConforms : Proto {
+  public typealias A = [OKStruct]
+}
diff --git a/test/Sanitizers/symbolication-linux.swift b/test/Sanitizers/symbolication-linux.swift
new file mode 100644
index 0000000..a892bc8
--- /dev/null
+++ b/test/Sanitizers/symbolication-linux.swift
@@ -0,0 +1,37 @@
+// RUN: %target-build-swift %s -sanitize=address -g -target %sanitizers-target-triple -o %t
+// RUN: env %env-ASAN_OPTIONS=abort_on_error=0                           not %target-run %t 2>&1 | %swift-demangle | %FileCheck %s -check-prefix=OOP
+// In-process symbolication doesn't work on Linux (yet)
+// XXX: env %env-ASAN_OPTIONS=abort_on_error=0,external_symbolizer_path= not %target-run %t 2>&1 | %swift-demangle | %FileCheck %s -check-prefix=IP
+// REQUIRES: executable_test
+// REQUIRES: asan_runtime
+// REQUIRES: OS=linux-gnu
+
+// Check that Sanitizer reports are properly symbolicated on Linux, both
+// out-of-process (via `llvm-symbolizer`) and when falling back to in-process
+// symbolication.  Note that `llvm-symbolizer` does not demangle Swift symbol
+// names, so we use `swift demangle`.
+
+@inline(never)
+func foo() {
+  let x = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+  x.deallocate()
+  print(x.pointee)
+}
+
+@inline(never)
+func bar() {
+  foo()
+  print("Prevent tail call optimization")
+}
+
+bar()
+
+// Out-of-process
+// OOP:      #0 0x{{[0-9a-f]+}} in main.foo() -> () {{.*}}symbolication-linux.swift:[[@LINE-12]]
+// OOP-NEXT: #1 0x{{[0-9a-f]+}} in main.bar() -> () {{.*}}symbolication-linux.swift:[[@LINE-8]]
+// OOP-NEXT: #2 0x{{[0-9a-f]+}} in main {{.*}}symbolication-linux.swift:[[@LINE-5]]
+
+// In-process
+// IP:      #0 0x{{[0-9a-f]+}} in main.foo() -> ()+0x
+// IP-NEXT: #1 0x{{[0-9a-f]+}} in main.bar() -> ()+0x
+// IP-NEXT: #2 0x{{[0-9a-f]+}} in main+0x
diff --git a/test/Sanitizers/symbolication.swift b/test/Sanitizers/symbolication.swift
new file mode 100644
index 0000000..2fc6ea7
--- /dev/null
+++ b/test/Sanitizers/symbolication.swift
@@ -0,0 +1,37 @@
+// RUN: %target-build-swift %s -sanitize=address -g -target %sanitizers-target-triple -o %t
+// RUN: env %env-ASAN_OPTIONS=abort_on_error=0                           not %target-run %t 2>&1 | %FileCheck %s -check-prefix=OOP
+// RUN: env %env-ASAN_OPTIONS=abort_on_error=0,external_symbolizer_path= not %target-run %t 2>&1 | %FileCheck %s -check-prefix=IP
+// REQUIRES: executable_test
+// REQUIRES: asan_runtime
+// REQUIRES: VENDOR=apple
+
+// REQUIRES: rdar68353068
+
+// Check that Sanitizer reports are properly symbolicated on Apple platforms,
+// both out-of-process (via `atos`) and when falling back to in-process
+// symbolication.  Note that `atos` also demangles Swift symbol names.
+
+@inline(never)
+func foo() {
+  let x = UnsafeMutablePointer<Int>.allocate(capacity: 1)
+  x.deallocate()
+  print(x.pointee)
+}
+
+@inline(never)
+func bar() {
+  foo()
+  print("Prevent tail call optimization")
+}
+
+bar()
+
+// Out-of-process
+// OOP:      #0 0x{{[0-9a-f]+}} in foo() symbolication.swift:[[@LINE-12]]
+// OOP-NEXT: #1 0x{{[0-9a-f]+}} in bar() symbolication.swift:[[@LINE-8]]
+// OOP-NEXT: #2 0x{{[0-9a-f]+}} in main symbolication.swift:[[@LINE-5]]
+
+// In-process
+// IP:      #0 0x{{[0-9a-f]+}} in main.foo() -> ()+0x
+// IP-NEXT: #1 0x{{[0-9a-f]+}} in main.bar() -> ()+0x
+// IP-NEXT: #2 0x{{[0-9a-f]+}} in main+0x
diff --git a/test/ScanDependencies/can_import_placeholder.swift b/test/ScanDependencies/can_import_placeholder.swift
index 8c14c6b..777f283 100644
--- a/test/ScanDependencies/can_import_placeholder.swift
+++ b/test/ScanDependencies/can_import_placeholder.swift
@@ -8,16 +8,6 @@
 // RUN: echo "\"docPath\": \"%/t/inputs/SomeExternalModule.swiftdoc\"," >> %/t/inputs/map.json
 // RUN: echo "\"sourceInfoPath\": \"%/t/inputs/SomeExternalModule.swiftsourceinfo\"," >> %/t/inputs/map.json
 // RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
-// RUN: echo "}," >> %/t/inputs/map.json
-// RUN: echo "{" >> %/t/inputs/map.json
-// RUN: echo "\"moduleName\": \"Swift\"," >> %/t/inputs/map.json
-// RUN: echo "\"modulePath\": \"%/stdlib_module\"," >> %/t/inputs/map.json
-// RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
-// RUN: echo "}," >> %/t/inputs/map.json
-// RUN: echo "{" >> %/t/inputs/map.json
-// RUN: echo "\"moduleName\": \"SwiftOnoneSupport\"," >> %/t/inputs/map.json
-// RUN: echo "\"modulePath\": \"%/ononesupport_module\"," >> %/t/inputs/map.json
-// RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
 // RUN: echo "}]" >> %/t/inputs/map.json
 
 // RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4
diff --git a/test/ScanDependencies/module_deps_external.swift b/test/ScanDependencies/module_deps_external.swift
index f3b2147..4242028 100644
--- a/test/ScanDependencies/module_deps_external.swift
+++ b/test/ScanDependencies/module_deps_external.swift
@@ -8,16 +8,6 @@
 // RUN: echo "\"docPath\": \"%/t/inputs/SomeExternalModule.swiftdoc\"," >> %/t/inputs/map.json
 // RUN: echo "\"sourceInfoPath\": \"%/t/inputs/SomeExternalModule.swiftsourceinfo\"," >> %/t/inputs/map.json
 // RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
-// RUN: echo "}," >> %/t/inputs/map.json
-// RUN: echo "{" >> %/t/inputs/map.json
-// RUN: echo "\"moduleName\": \"Swift\"," >> %/t/inputs/map.json
-// RUN: echo "\"modulePath\": \"%/stdlib_module\"," >> %/t/inputs/map.json
-// RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
-// RUN: echo "}," >> %/t/inputs/map.json
-// RUN: echo "{" >> %/t/inputs/map.json
-// RUN: echo "\"moduleName\": \"SwiftOnoneSupport\"," >> %/t/inputs/map.json
-// RUN: echo "\"modulePath\": \"%/ononesupport_module\"," >> %/t/inputs/map.json
-// RUN: echo "\"isFramework\": false" >> %/t/inputs/map.json
 // RUN: echo "}]" >> %/t/inputs/map.json
 
 // RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -placeholder-dependency-module-map-file %t/inputs/map.json -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4
diff --git a/test/Sema/editor_placeholders.swift b/test/Sema/editor_placeholders.swift
index dedeb59..cf14d23 100644
--- a/test/Sema/editor_placeholders.swift
+++ b/test/Sema/editor_placeholders.swift
@@ -2,6 +2,7 @@
 
 func foo(_ x: Int) -> Int {}
 func foo(_ x: Float) -> Float {}
+func foo<T>(_ t: T) -> T {}
 
 var v = foo(<#T##x: Float##Float#>) // expected-error {{editor placeholder}}
 v = "" // expected-error {{cannot assign value of type 'String' to type 'Float'}}
@@ -36,3 +37,6 @@
   // expected-error@-1 {{editor placeholder in source file}}
   // expected-error@-2 {{ambiguous use of 'subscript(_:)'}}
 }
+
+let unboundInPlaceholder1: Array<Never> = <#T##Array#> // expected-error{{editor placeholder in source file}}
+let unboundInPlaceholder2: Array<Never> = foo(<#T##t: Array##Array<Never>#>) // expected-error{{editor placeholder in source file}}
diff --git a/test/Sema/spi-in-decls.swift b/test/Sema/spi-in-decls.swift
new file mode 100644
index 0000000..e83c88a
--- /dev/null
+++ b/test/Sema/spi-in-decls.swift
@@ -0,0 +1,307 @@
+/// SPI variant of implementation-only-import-in-decls with the "Bad"
+/// declarations defined as local SPI.
+
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -o %t/NormalLibrary.swiftmodule %S/Inputs/implementation-only-import-in-decls-public-helper.swift
+
+// RUN: %target-typecheck-verify-swift -I %t
+
+import NormalLibrary
+
+@_spi(X)
+extension NormalStruct: NormalProto {
+  public typealias Assoc = Int
+}
+@_spi(X)
+extension GenericStruct: NormalProto {
+  public typealias Assoc = Int
+}
+@_spi(X)
+extension NormalClass: NormalProto {
+  public typealias Assoc = Int
+}
+
+@_spi(X)
+public struct BadStruct {} // expected-note 27 {{type declared here}}
+@_spi(X)
+public protocol BadProto {} // expected-note 20 {{type declared here}}
+@_spi(X)
+open class BadClass {} // expected-note 2 {{type declared here}}
+
+@_spi(X)
+public struct IntLike: ExpressibleByIntegerLiteral, Equatable { // expected-note {{type declared here}}
+  public init(integerLiteral: Int) {}
+}
+
+@_spi(X)
+@propertyWrapper
+public struct BadWrapper { // expected-note {{type declared here}}
+    public var wrappedValue: Int
+    public init(wrappedValue: Int) {
+        self.wrappedValue = wrappedValue
+    }
+}
+
+// FIXME SPI precedencegroups are not yet accepted.
+//@_spi(X)
+//precedencegroup BadPrecedence {}
+
+public struct TestConformance: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+
+@usableFromInline struct TestConformanceUFI: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+
+struct TestConformanceOkay: BadProto {} // ok
+
+public class TestConformanceClass: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+public enum TestConformanceEnum: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+
+
+public struct TestGenericParams<T: BadProto> {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+
+public struct TestGenericParamsWhereClause<T> where T: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+
+public enum TestCase {
+  case x(BadStruct) // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  case y(Int, BadStruct) // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+}
+
+public func testGenericParams<T: BadProto>(_: T) {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+public func testGenericParamsWhereClause<T>(_: T) where T: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+public func testParams(_: BadStruct, _: BadProto) {}
+// expected-error@-1 {{cannot use struct 'BadStruct' here; it is SPI}}
+// expected-error@-2 {{cannot use protocol 'BadProto' here; it is SPI}}
+public func testResult() -> BadStruct? { return nil } // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+
+public struct TestSubscript {
+  public subscript<T: BadProto>(_: T) -> Int { return 0 } // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+  public subscript<T>(where _: T) -> Int where T: BadProto { return 0 } // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+  public subscript(_: BadStruct) -> Int { return 0 } // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  public subscript(_: Int) -> BadStruct? { return nil } // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+}
+
+public struct TestInit {
+  public init(_: BadStruct) {} // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  public init<T: BadProto>(_: T) {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+  public init<T>(where _: T) where T: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+}
+
+public struct TestPropertyWrapper {
+  @BadWrapper public var BadProperty: Int // expected-error {{cannot use struct 'BadWrapper' as property wrapper here; it is SPI}}
+}
+
+public protocol TestInherited: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+
+public protocol TestConstraintBase {
+  associatedtype Assoc
+}
+public protocol TestConstraint: TestConstraintBase where Assoc: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+public protocol TestConstraintEq: TestConstraintBase where Assoc == BadStruct {} // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+
+public protocol TestAssocType {
+  associatedtype Assoc: BadProto // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+}
+
+public protocol TestAssocTypeWhereClause {
+  associatedtype Assoc: Collection where Assoc.Element: BadProto // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+}
+
+public enum TestRawType: IntLike { // expected-error {{cannot use struct 'IntLike' here; it is SPI}}
+  case x = 1
+  // FIXME: expected-error@-1 {{cannot use conformance of 'IntLike' to 'Equatable' here; the conformance is declared as SPI}}
+}
+
+public class TestSubclass: BadClass { // expected-error {{cannot use class 'BadClass' here; it is SPI}}
+}
+
+public typealias TestUnderlying = BadStruct // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+public typealias TestGenericParamsAliasWhereClause<T> = T where T: BadProto // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+
+public typealias TestGenericParamsAlias<T: BadProto> = T // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+
+public var testBadType: BadStruct? = nil // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+public var testBadTypeInferred = Optional<BadStruct>.none // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+public var testBadTypePartiallyInferred: Optional = Optional<BadStruct>.none // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+public var (testBadTypeTuple1, testBadTypeTuple2): (BadStruct?, BadClass?) = (nil, nil)
+// expected-error@-1 {{cannot use struct 'BadStruct' here; it is SPI}}
+// expected-error@-2 {{cannot use class 'BadClass' here; it is SPI}}
+public var (testBadTypeTuplePartlyInferred1, testBadTypeTuplePartlyInferred2): (Optional, Optional) = (Optional<Int>.none, Optional<BadStruct>.none) // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+public var (testBadTypeTuplePartlyInferred3, testBadTypeTuplePartlyInferred4): (Optional, Optional) = (Optional<BadStruct>.none, Optional<Int>.none) // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+public var testMultipleBindings1: Int? = nil, testMultipleBindings2: BadStruct? = nil // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+public var testMultipleBindings3: BadStruct? = nil, testMultipleBindings4: Int? = nil // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+
+extension BadStruct {
+  public func testExtensionOfBadType() {}
+  public var testExtensionVarBad: Int { 0 }
+  public subscript(bad _: Int) -> Int { 0 }
+
+  func testExtensionOfOkayType() {}
+  var testExtensionVarOkay: Int { 0 }
+  subscript(okay _: Int) -> Int { 0 }
+}
+
+extension Array where Element == BadStruct { // expected-error {{cannot use struct 'BadStruct' in an extension with public or '@usableFromInline' members; it is SPI}}
+  public func testExtensionWithBadRequirement() {}
+  public var testExtensionVarBad: Int { 0 }
+  public subscript(bad _: Int) -> Int { 0 }
+}
+
+extension Array where Element == BadStruct {
+  func testExtensionWithOkayRequirement() {} // okay
+  var testExtensionVarOkay: Int { 0 } // okay
+  subscript(okay _: Int) -> Int { 0 } // okay
+}
+
+extension Int: BadProto {} // expected-error {{cannot use protocol 'BadProto' here; it is SPI}}
+struct TestExtensionConformanceOkay {}
+extension TestExtensionConformanceOkay: BadProto {} // okay
+
+public protocol TestConstrainedExtensionProto {}
+extension Array: TestConstrainedExtensionProto where Element == BadStruct { // expected-error {{cannot use struct 'BadStruct' in an extension with conditional conformances; it is SPI}}
+}
+
+
+// FIXME Support SPI precedencegroup?
+//infix operator !!!!!!: BadPrecedence
+//
+//precedencegroup TestLowerThan {
+//  lowerThan: BadPrecedence
+//}
+//precedencegroup TestHigherThan {
+//  higherThan: BadPrecedence
+//}
+
+public struct PublicStructStoredProperties {
+  public var publiclyBad: BadStruct? // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  internal var internallyBad: BadStruct? // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  private var privatelyBad: BadStruct? // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  private let letIsLikeVar = [BadStruct]() // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+
+  private var computedIsOkay: BadStruct? { return nil } // okay
+  private static var staticIsOkay: BadStruct? // okay
+  @usableFromInline internal var computedUFIIsNot: BadStruct? { return nil } // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+}
+
+@usableFromInline internal struct UFIStructStoredProperties {
+  @usableFromInline var publiclyBad: BadStruct? // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  internal var internallyBad: BadStruct? // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  private var privatelyBad: BadStruct? // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  private let letIsLikeVar = [BadStruct]() // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+
+  private var computedIsOkay: BadStruct? { return nil } // okay
+  private static var staticIsOkay: BadStruct? // okay
+  @usableFromInline internal var computedUFIIsNot: BadStruct? { return nil } // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+}
+
+public class PublicClassStoredProperties {
+  public var publiclyBad: BadStruct? // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  internal var internallyBad: BadStruct? // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  private var privatelyBad: BadStruct? // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+  private let letIsLikeVar = [BadStruct]() // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+
+  private var computedIsOkay: BadStruct? { return nil } // okay
+  private static var staticIsOkay: BadStruct? // okay
+  @usableFromInline internal var computedUFIIsNot: BadStruct? { return nil } // expected-error {{cannot use struct 'BadStruct' here; it is SPI}}
+}
+
+public typealias NormalProtoAssoc<T: NormalProto> = T.Assoc
+public func testConformanceInTypealias(_: NormalProtoAssoc<NormalStruct>) {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+public struct NormalProtoAssocHolder<T: NormalProto> {
+  public var value: T.Assoc
+}
+public func testConformanceInBoundGeneric(_: NormalProtoAssocHolder<NormalStruct>) {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+public class SubclassOfNormalClass: NormalClass {}
+
+public func testInheritedConformance(_: NormalProtoAssocHolder<SubclassOfNormalClass>) {} // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; the conformance is declared as SPI}}
+public func testSpecializedConformance(_: NormalProtoAssocHolder<GenericStruct<Int>>) {} // expected-error {{cannot use conformance of 'GenericStruct<T>' to 'NormalProto' here; the conformance is declared as SPI}}
+
+extension Array where Element == NormalProtoAssocHolder<NormalStruct> { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in an extension with public or '@usableFromInline' members; the conformance is declared as SPI}}
+  public func testConstrainedExtensionUsingBadConformance() {}
+}
+
+public struct ConditionalGenericStruct<T> {}
+extension ConditionalGenericStruct: NormalProto where T: NormalProto {
+  public typealias Assoc = Int
+}
+public func testConditionalGeneric(_: NormalProtoAssocHolder<ConditionalGenericStruct<NormalStruct>>) {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+public protocol PublicAssociatedTypeProto {
+  associatedtype Assoc: NormalProto
+  func takesAssoc(_: Assoc)
+}
+@usableFromInline protocol UFIAssociatedTypeProto {
+  associatedtype Assoc: NormalProto
+  func takesAssoc(_: Assoc)
+}
+protocol InternalAssociatedTypeProto {
+  associatedtype Assoc: NormalProto
+  func takesAssoc(_: Assoc)
+}
+
+public struct PublicInferredAssociatedTypeImpl {
+  public func takesAssoc(_: NormalStruct) {}
+}
+extension PublicInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
+extension PublicInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
+extension PublicInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
+
+@usableFromInline struct UFIInferredAssociatedTypeImpl {
+  public func takesAssoc(_: NormalStruct) {}
+}
+extension UFIInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
+extension UFIInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
+extension UFIInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
+
+struct InternalInferredAssociatedTypeImpl {
+  public func takesAssoc(_: NormalStruct) {}
+}
+extension InternalInferredAssociatedTypeImpl: PublicAssociatedTypeProto {} // okay
+extension InternalInferredAssociatedTypeImpl: UFIAssociatedTypeProto {} // okay
+extension InternalInferredAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
+
+public struct PublicExplicitAssociatedTypeImpl {
+  public typealias Assoc = NormalStruct
+  public func takesAssoc(_: NormalStruct) {}
+}
+extension PublicExplicitAssociatedTypeImpl: PublicAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
+extension PublicExplicitAssociatedTypeImpl: UFIAssociatedTypeProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
+extension PublicExplicitAssociatedTypeImpl: InternalAssociatedTypeProto {} // okay
+
+
+public protocol BaseProtoWithNoRequirement {
+  associatedtype Assoc
+  func takesAssoc(_: Assoc)
+}
+public protocol RefinedProto: BaseProtoWithNoRequirement where Assoc: NormalProto {
+}
+
+public struct RefinedProtoImpl: RefinedProto { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
+  public func takesAssoc(_: NormalStruct) {}
+}
+
+public protocol RefinedSelfProto where Self: NormalProto {}
+extension NormalStruct: RefinedSelfProto {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+public protocol RefinedSelfProtoInheritance: NormalProto {}
+extension NormalStruct: RefinedSelfProtoInheritance {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+
+public protocol SlightlyMoreComplicatedRequirement {
+  associatedtype Assoc: Collection where Assoc.Element: NormalProto
+  func takesAssoc(_: Assoc)
+}
+public struct SlightlyMoreComplicatedRequirementImpl: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'NormalStruct'); the conformance is declared as SPI}}
+  public func takesAssoc(_: [NormalStruct]) {}
+}
+public struct RequirementsHandleSubclassesToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'SubclassOfNormalClass'); the conformance is declared as SPI}}
+  public func takesAssoc(_: [SubclassOfNormalClass]) {}
+}
+
+public struct RequirementsHandleSpecializationsToo: SlightlyMoreComplicatedRequirement { // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' in associated type 'Self.Assoc.Element' (inferred as 'ConditionalGenericStruct<NormalStruct>'); the conformance is declared as SPI}}
+  public func takesAssoc(_: [ConditionalGenericStruct<NormalStruct>]) {}
+}
+
+public struct ClassConstrainedGenericArg<T: NormalClass>: PublicAssociatedTypeProto { // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' in associated type 'Self.Assoc' (inferred as 'T'); the conformance is declared as SPI}}
+  public func takesAssoc(_: T) {}
+}
diff --git a/test/Sema/spi-inlinable-conformances.swift b/test/Sema/spi-inlinable-conformances.swift
new file mode 100644
index 0000000..46333cb
--- /dev/null
+++ b/test/Sema/spi-inlinable-conformances.swift
@@ -0,0 +1,292 @@
+/// SPI variant of implementation-only-inlinable-conformances with the "Bad"
+/// declarations defined as local SPI. Also check that SPI conformances
+/// can be used within inlinable SPI decls.
+
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -o %t/NormalLibrary.swiftmodule %S/Inputs/implementation-only-import-in-decls-public-helper.swift
+
+// RUN: %target-typecheck-verify-swift -I %t
+
+import NormalLibrary
+
+@_spi(X)
+extension NormalStruct: NormalProto {
+  public typealias Assoc = Int
+}
+@_spi(X)
+extension GenericStruct: NormalProto {
+  public typealias Assoc = Int
+}
+@_spi(X)
+extension NormalClass: NormalProto {
+  public typealias Assoc = Int
+}
+
+@_spi(X)
+public struct BadStruct {}
+@_spi(X)
+public protocol BadProto {}
+@_spi(X)
+open class BadClass {}
+
+@_spi(X)
+public struct IntLike: ExpressibleByIntegerLiteral, Equatable {
+  public init(integerLiteral: Int) {}
+}
+
+@available(*, unavailable)
+public typealias X = Int
+
+public typealias NormalProtoAssoc<T: NormalProto> = T.Assoc
+@inlinable func testConformanceInTypealias() {
+  let x: NormalProtoAssoc<NormalStruct>? = nil // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  _ = x
+  _ = NormalProtoAssoc<NormalStruct>() // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPItestConformanceInTypealias() {
+  let x: NormalProtoAssoc<NormalStruct>? = nil
+  _ = x
+  _ = NormalProtoAssoc<NormalStruct>()
+}
+
+func internalConformanceInTypealias() {
+  let x: NormalProtoAssoc<NormalStruct>? = nil // okay
+  _ = x
+  _ = NormalProtoAssoc<NormalStruct>() // okay
+}
+
+public struct NormalProtoAssocHolder<T: NormalProto> {
+  public var value: T.Assoc?
+  public init() {}
+  public init(_ value: T?) {}
+}
+@inlinable func testConformanceInBoundGeneric() {
+  let x: NormalProtoAssocHolder<NormalStruct>? = nil // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  _ = x
+  // FIXME: We get this error twice: once for the TypeExpr and once for the implicit init.
+  _ = NormalProtoAssocHolder<NormalStruct>() // expected-error 2 {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  _ = NormalProtoAssocHolder(nil as NormalStruct?) // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPItestConformanceInBoundGeneric() {
+  let x: NormalProtoAssocHolder<NormalStruct>? = nil
+  _ = x
+  _ = NormalProtoAssocHolder<NormalStruct>()
+  _ = NormalProtoAssocHolder(nil as NormalStruct?)
+}
+
+func internalConformanceInBoundGeneric() {
+  let x: NormalProtoAssocHolder<NormalStruct>? = nil // okay
+  _ = x
+  _ = NormalProtoAssocHolder<NormalStruct>() // okay
+  _ = NormalProtoAssocHolder(nil as NormalStruct?) // okay
+}
+
+@inlinable func testDowncast(_ x: Any) -> Bool {
+  let normal = x is NormalProtoAssocHolder<NormalStruct> // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  let alias = x is NormalProtoAssoc<NormalStruct> // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  return normal || alias
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPItestDowncast(_ x: Any) -> Bool {
+  let normal = x is NormalProtoAssocHolder<NormalStruct>
+  let alias = x is NormalProtoAssoc<NormalStruct>
+  return normal || alias
+}
+
+func internalDowncast(_ x: Any) -> Bool {
+  let normal = x is NormalProtoAssocHolder<NormalStruct> // okay
+  let alias = x is NormalProtoAssoc<NormalStruct> // okay
+  return normal || alias
+}
+
+@inlinable func testSwitch(_ x: Any) {
+  switch x {
+  case let holder as NormalProtoAssocHolder<NormalStruct>: // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+    _ = holder
+    break
+  case is NormalProtoAssoc<NormalStruct>: // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+    break
+  default:
+    break
+  }
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPItestSwitch(_ x: Any) {
+  switch x {
+  case let holder as NormalProtoAssocHolder<NormalStruct>:
+    _ = holder
+    break
+  case is NormalProtoAssoc<NormalStruct>:
+    break
+  default:
+    break
+  }
+}
+
+func internalSwitch(_ x: Any) {
+  switch x {
+  case let holder as NormalProtoAssocHolder<NormalStruct>: // okay
+    _ = holder
+    break
+  case is NormalProtoAssoc<NormalStruct>: // okay
+    break
+  default:
+    break
+  }
+}
+
+public enum NormalProtoEnumUser<T: NormalProto> {
+  case a
+}
+
+@inlinable func testEnum() {
+  // FIXME: We get this error twice: once for the pattern and once for the implicit TypeExpr.
+  let x: NormalProtoEnumUser<NormalStruct> = .a // expected-error 2 {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  _ = x
+  // FIXME: We get this error twice: once for the TypeExpr and once for the case.
+  _ = NormalProtoEnumUser<NormalStruct>.a // expected-error 2 {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPItestEnum() {
+  let x: NormalProtoEnumUser<NormalStruct> = .a
+  _ = x
+  _ = NormalProtoEnumUser<NormalStruct>.a
+}
+
+func internalEnum() {
+  let x: NormalProtoEnumUser<NormalStruct> = .a // okay
+  _ = x
+  _ = NormalProtoEnumUser<NormalStruct>.a // okay
+}
+
+@usableFromInline func testFuncImpl<T: NormalProto>(_: T.Type) {}
+
+@inlinable func testFunc() {
+  testFuncImpl(NormalStruct.self) // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPItestFunc() {
+  testFuncImpl(NormalStruct.self)
+}
+
+func internalFunc() {
+  testFuncImpl(NormalStruct.self) // okay
+}
+
+public struct ForTestingMembers {
+  public init() {}
+  public init<T: NormalProto>(_: T.Type) {}
+
+  public subscript<T: NormalProto>(_: T.Type) -> Int {
+    get { return 0 }
+    set {}
+  }
+
+  public func method<T: NormalProto>(_: T.Type) {}
+}
+
+@inlinable func testMembers() {
+  _ = ForTestingMembers(NormalStruct.self) // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  _ = ForTestingMembers.init(NormalStruct.self) // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+  _ = ForTestingMembers()[NormalStruct.self] // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  var instance = ForTestingMembers()
+  instance[NormalStruct.self] = 1 // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+  ForTestingMembers().method(NormalStruct.self) // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPItestMembers() {
+  _ = ForTestingMembers(NormalStruct.self)
+  _ = ForTestingMembers.init(NormalStruct.self)
+
+  _ = ForTestingMembers()[NormalStruct.self]
+  var instance = ForTestingMembers()
+  instance[NormalStruct.self] = 1
+
+  ForTestingMembers().method(NormalStruct.self)
+}
+
+extension NormalProtoAssocHolder {
+  public static func testAnotherConformance<U: NormalProto>(_: U.Type) {}
+}
+
+@inlinable func testMultipleConformances() {
+  NormalProtoAssocHolder<NormalStruct>.testAnotherConformance(NormalClass.self)
+ // expected-error@-1 2 {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  // expected-error@-2 {{cannot use conformance of 'NormalClass' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPItestMultipleConformances() {
+  NormalProtoAssocHolder<NormalStruct>.testAnotherConformance(NormalClass.self)
+}
+
+@inlinable func localTypeAlias() {
+  typealias LocalUser = NormalProtoAssocHolder<NormalStruct> // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  typealias LocalGenericUser<T> = (T, NormalProtoAssocHolder<NormalStruct>) // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+  typealias LocalProtoAssoc<T: NormalProto> = T.Assoc
+  _ = LocalProtoAssoc<NormalStruct>() // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPIlocalTypeAlias() {
+  typealias LocalUser = NormalProtoAssocHolder<NormalStruct>
+  typealias LocalGenericUser<T> = (T, NormalProtoAssocHolder<NormalStruct>)
+
+  typealias LocalProtoAssoc<T: NormalProto> = T.Assoc
+  _ = LocalProtoAssoc<NormalStruct>()
+}
+
+@inlinable func localFunctions() {
+  func local(_: NormalProtoAssocHolder<NormalStruct>) {} // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  func localReturn() -> NormalProtoAssocHolder<NormalStruct> { fatalError() } // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  let _ = { (_: NormalProtoAssocHolder<NormalStruct>) in return } // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+  let _ = { () -> NormalProtoAssocHolder<NormalStruct> in fatalError() } // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPIlocalFunctions() {
+  func local(_: NormalProtoAssocHolder<NormalStruct>) {}
+  func localReturn() -> NormalProtoAssocHolder<NormalStruct> { fatalError() }
+  let _ = { (_: NormalProtoAssocHolder<NormalStruct>) in return }
+  let _ = { () -> NormalProtoAssocHolder<NormalStruct> in fatalError() }
+}
+
+@inlinable public func signatureOfInlinable(_: NormalProtoAssocHolder<NormalStruct>) {} // expected-error{{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+public func testDefaultArgument(_: Int = NormalProtoAssoc<NormalStruct>()) {} // expected-error {{cannot use conformance of 'NormalStruct' to 'NormalProto' here; the conformance is declared as SPI}}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPIsignatureOfInlinable(_: NormalProtoAssocHolder<NormalStruct>) {}
+
+@_spi(AcceptInSPI)
+public func SPItestDefaultArgument(_: Int = NormalProtoAssoc<NormalStruct>()) {}
+
+public class SubclassOfNormalClass: NormalClass {}
+
+@inlinable public func testInheritedConformance() {
+  _ = NormalProtoAssocHolder<SubclassOfNormalClass>.self // expected-error {{cannot use conformance of 'NormalClass' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+@inlinable public func testSpecializedConformance() {
+  _ = NormalProtoAssocHolder<GenericStruct<Int>>.self // expected-error {{cannot use conformance of 'GenericStruct<T>' to 'NormalProto' here; the conformance is declared as SPI}}
+}
+
+@_spi(AcceptInSPI)
+@inlinable public func SPItestInheritedConformance() {
+  _ = NormalProtoAssocHolder<SubclassOfNormalClass>.self
+}
+@_spi(AcceptInSPI)
+@inlinable public func SPItestSpecializedConformance() {
+  _ = NormalProtoAssocHolder<GenericStruct<Int>>.self
+}
diff --git a/test/Serialization/cdecl_attr.swift b/test/Serialization/cdecl_attr.swift
new file mode 100644
index 0000000..aa3975a
--- /dev/null
+++ b/test/Serialization/cdecl_attr.swift
@@ -0,0 +1,12 @@
+// RUN: %empty-directory(%t)
+// Ensure .swift -> .ll
+// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s
+
+// Ensure .swift -> .sib -> .ll
+// RUN: %target-swift-frontend -emit-sib %s -o %t/cdecl_attr.sib
+// RUN: %target-swift-frontend -emit-ir %t/cdecl_attr.sib | %FileCheck %s
+
+// CHECK: define hidden {{.*}} @foo
+
+@_cdecl("foo")
+func foo() {}
diff --git a/test/Serialization/load-target-normalization.swift b/test/Serialization/load-target-normalization.swift
index e1120d7..8a013a2 100644
--- a/test/Serialization/load-target-normalization.swift
+++ b/test/Serialization/load-target-normalization.swift
@@ -1,6 +1,9 @@
 // RUN: %empty-directory(%t/ForeignModule.swiftmodule)
 // RUN: touch %t/ForeignModule.swiftmodule/garbage-garbage-garbage.swiftmodule
 
+// SR-12363: This test crashes on master-next.
+// XFAIL: asserts
+
 // Test format: We try to import ForeignModule with architectures besides
 // garbage-garbage-garbage and check the target triple listed in the error
 // message to make sure it was normalized correctly. This works in lieu of a
diff --git a/test/SourceKit/CodeComplete/complete_annotateddescription.swift.result b/test/SourceKit/CodeComplete/complete_annotateddescription.swift.result
index 0b2862f..c5c0db7 100644
--- a/test/SourceKit/CodeComplete/complete_annotateddescription.swift.result
+++ b/test/SourceKit/CodeComplete/complete_annotateddescription.swift.result
@@ -94,7 +94,7 @@
       key.description: "<name>init</name>()",
       key.typename: "<typeid.user>MyStruct</typeid.user>",
       key.context: source.codecompletion.context.thisclass,
-      key.typerelation: source.codecompletion.typerelation.unrelated,
+      key.typerelation: source.codecompletion.typerelation.unknown,
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "s:29complete_annotateddescription8MyStructVACycfc",
       key.modulename: "complete_annotateddescription"
@@ -106,7 +106,7 @@
       key.description: "<name>labelName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>self</callarg.param>: <callarg.type><typeid.user>MyStruct</typeid.user></callarg.type></callarg>)",
       key.typename: "(label: (<attribute>@autoclosure</attribute> () -&gt; <typeid.sys>Int</typeid.sys>) -&gt; <typeid.sys>Int</typeid.sys>) -&gt; <typeid.sys>Void</typeid.sys>",
       key.context: source.codecompletion.context.thisclass,
-      key.typerelation: source.codecompletion.typerelation.unrelated,
+      key.typerelation: source.codecompletion.typerelation.unknown,
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "s:29complete_annotateddescription8MyStructV9labelName0E0yS2iyXKXE_tF",
       key.modulename: "complete_annotateddescription"
@@ -118,7 +118,7 @@
       key.description: "<name>labelNameParamName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>self</callarg.param>: <callarg.type><typeid.user>MyStruct</typeid.user></callarg.type></callarg>)",
       key.typename: "(label: (<keyword>inout</keyword> <typeid.sys>Int</typeid.sys>) <keyword>throws</keyword> -&gt; <typeid.user>MyStruct</typeid.user>) -&gt; <typeid.sys>Void</typeid.sys>",
       key.context: source.codecompletion.context.thisclass,
-      key.typerelation: source.codecompletion.typerelation.unrelated,
+      key.typerelation: source.codecompletion.typerelation.unknown,
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "s:29complete_annotateddescription8MyStructV014labelNameParamF00E0yACSizKXE_tKF",
       key.modulename: "complete_annotateddescription"
@@ -130,7 +130,7 @@
       key.description: "<name>paramName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>self</callarg.param>: <callarg.type><typeid.user>MyStruct</typeid.user></callarg.type></callarg>)",
       key.typename: "(<typeid.sys>Int</typeid.sys>) -&gt; <typeid.sys>Void</typeid.sys>",
       key.context: source.codecompletion.context.thisclass,
-      key.typerelation: source.codecompletion.typerelation.unrelated,
+      key.typerelation: source.codecompletion.typerelation.unknown,
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "s:29complete_annotateddescription8MyStructV9paramNameyySiF",
       key.modulename: "complete_annotateddescription"
@@ -142,7 +142,7 @@
       key.description: "<name>sameName</name>(<callarg><callarg.label>_</callarg.label> <callarg.param>self</callarg.param>: <callarg.type><typeid.user>MyStruct</typeid.user></callarg.type></callarg>)",
       key.typename: "(label: <typeid.sys>Int</typeid.sys>) -&gt; <typeid.sys>Void</typeid.sys>",
       key.context: source.codecompletion.context.thisclass,
-      key.typerelation: source.codecompletion.typerelation.unrelated,
+      key.typerelation: source.codecompletion.typerelation.unknown,
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "s:29complete_annotateddescription8MyStructV8sameName5labelySi_tF",
       key.modulename: "complete_annotateddescription"
diff --git a/test/SourceKit/CodeComplete/complete_checkdeps_avoid_check.swift b/test/SourceKit/CodeComplete/complete_checkdeps_avoid_check.swift
index 6b86cc9..96fe52c 100644
--- a/test/SourceKit/CodeComplete/complete_checkdeps_avoid_check.swift
+++ b/test/SourceKit/CodeComplete/complete_checkdeps_avoid_check.swift
@@ -40,7 +40,7 @@
 // RUN:   -shell -- cp -R $INPUT_DIR/ClangFW.framework_mod/* %t/Frameworks/ClangFW.framework/ == \
 // RUN:   -req=complete -pos=5:3 %s -- ${COMPILER_ARGS[@]} == \
 
-// RUN:   -req=global-config -completion-check-dependency-interval ${DEPCHECK_INTERVAL} == \
+// RUN:   -req=global-config -req-opts=completion_check_dependency_interval=${DEPCHECK_INTERVAL} == \
 // RUN:   -shell -- echo '### Checking dependencies' == \
 // RUN:   -req=complete -pos=5:3 %s -- ${COMPILER_ARGS[@]} \
 
diff --git a/test/SourceKit/CodeComplete/complete_checkdeps_bridged.swift b/test/SourceKit/CodeComplete/complete_checkdeps_bridged.swift
index 6b467da..2ea30a5 100644
--- a/test/SourceKit/CodeComplete/complete_checkdeps_bridged.swift
+++ b/test/SourceKit/CodeComplete/complete_checkdeps_bridged.swift
@@ -29,7 +29,7 @@
 // RUN: %target-swift-frontend -emit-module -module-name SwiftFW -o %t/Frameworks/SwiftFW.framework/Modules/SwiftFW.swiftmodule/%target-swiftmodule-name $INPUT_DIR/SwiftFW_src/Funcs.swift
 
 // RUN: %sourcekitd-test \
-// RUN:   -req=global-config -completion-check-dependency-interval ${DEPCHECK_INTERVAL} == \
+// RUN:   -req=global-config -req-opts=completion_check_dependency_interval=${DEPCHECK_INTERVAL} == \
 
 // RUN:   -shell -- echo "### Initial" == \
 // RUN:   -req=complete -pos=5:3 %s -- ${COMPILER_ARGS[@]} == \
diff --git a/test/SourceKit/CodeComplete/complete_checkdeps_clangmodule.swift b/test/SourceKit/CodeComplete/complete_checkdeps_clangmodule.swift
index 543d7f3..ce39008 100644
--- a/test/SourceKit/CodeComplete/complete_checkdeps_clangmodule.swift
+++ b/test/SourceKit/CodeComplete/complete_checkdeps_clangmodule.swift
@@ -29,7 +29,7 @@
 // RUN: %target-swift-frontend -emit-module -module-name SwiftFW -o %t/Frameworks/SwiftFW.framework/Modules/SwiftFW.swiftmodule/%target-swiftmodule-name $INPUT_DIR/SwiftFW_src/Funcs.swift
 
 // RUN: %sourcekitd-test \
-// RUN:   -req=global-config -completion-check-dependency-interval ${DEPCHECK_INTERVAL} == \
+// RUN:   -req=global-config -req-opts=completion_check_dependency_interval=${DEPCHECK_INTERVAL} == \
 
 // RUN:   -shell -- echo "### Initial" == \
 // RUN:   -req=complete -pos=5:3 %s -- ${COMPILER_ARGS[@]} == \
diff --git a/test/SourceKit/CodeComplete/complete_checkdeps_otherfile.swift b/test/SourceKit/CodeComplete/complete_checkdeps_otherfile.swift
index 61561ef..83f2c76 100644
--- a/test/SourceKit/CodeComplete/complete_checkdeps_otherfile.swift
+++ b/test/SourceKit/CodeComplete/complete_checkdeps_otherfile.swift
@@ -29,7 +29,7 @@
 // RUN: %target-swift-frontend -emit-module -module-name SwiftFW -o %t/Frameworks/SwiftFW.framework/Modules/SwiftFW.swiftmodule/%target-swiftmodule-name $INPUT_DIR/SwiftFW_src/Funcs.swift
 
 // RUN: %sourcekitd-test \
-// RUN:   -req=global-config -completion-check-dependency-interval ${DEPCHECK_INTERVAL} == \
+// RUN:   -req=global-config -req-opts=completion_check_dependency_interval=${DEPCHECK_INTERVAL} == \
 
 // RUN:   -shell -- echo "### Initial" == \
 // RUN:   -req=complete -pos=5:3 %s -- ${COMPILER_ARGS[@]} == \
diff --git a/test/SourceKit/CodeComplete/complete_checkdeps_ownfile.swift b/test/SourceKit/CodeComplete/complete_checkdeps_ownfile.swift
index 15233fe..13d0399 100644
--- a/test/SourceKit/CodeComplete/complete_checkdeps_ownfile.swift
+++ b/test/SourceKit/CodeComplete/complete_checkdeps_ownfile.swift
@@ -46,7 +46,7 @@
 // RUN: cp %t/State1.swift %t/test.swift
 
 // RUN: %sourcekitd-test \
-// RUN:   -req=global-config -completion-check-dependency-interval ${DEPCHECK_INTERVAL} == \
+// RUN:   -req=global-config -req-opts=completion_check_dependency_interval=${DEPCHECK_INTERVAL} == \
 
 // RUN:   -shell -- echo "### Initial" == \
 // RUN:   -req=complete -pos=5:4 %t/test.swift -- ${COMPILER_ARGS[@]} == \
diff --git a/test/SourceKit/CodeComplete/complete_checkdeps_swiftmodule.swift b/test/SourceKit/CodeComplete/complete_checkdeps_swiftmodule.swift
index 2ed5cfb..6235a5b 100644
--- a/test/SourceKit/CodeComplete/complete_checkdeps_swiftmodule.swift
+++ b/test/SourceKit/CodeComplete/complete_checkdeps_swiftmodule.swift
@@ -29,7 +29,7 @@
 // RUN: %target-swift-frontend -emit-module -module-name SwiftFW -o %t/Frameworks/SwiftFW.framework/Modules/SwiftFW.swiftmodule/%target-swiftmodule-name $INPUT_DIR/SwiftFW_src/Funcs.swift
 
 // RUN: %sourcekitd-test \
-// RUN:   -req=global-config -completion-check-dependency-interval ${DEPCHECK_INTERVAL} == \
+// RUN:   -req=global-config -req-opts=completion_check_dependency_interval=${DEPCHECK_INTERVAL} == \
 
 // RUN:   -shell -- echo "### Initial" == \
 // RUN:   -req=complete -pos=5:3 %s -- ${COMPILER_ARGS[@]} == \
diff --git a/test/SourceKit/CodeComplete/complete_checkdeps_vfs.swift b/test/SourceKit/CodeComplete/complete_checkdeps_vfs.swift
index 84753c3..af0831d 100644
--- a/test/SourceKit/CodeComplete/complete_checkdeps_vfs.swift
+++ b/test/SourceKit/CodeComplete/complete_checkdeps_vfs.swift
@@ -12,7 +12,7 @@
 // RUN: cp %S/Inputs/checkdeps/MyProject/LibraryExt.swift %t/VFS/
 
 // RUN: %sourcekitd-test \
-// RUN:   -req=global-config -completion-check-dependency-interval ${DEPCHECK_INTERVAL} == \
+// RUN:   -req=global-config -req-opts=completion_check_dependency_interval=${DEPCHECK_INTERVAL} == \
 
 // RUN:   -shell -- echo "### Initial" == \
 // RUN:   -req=complete -pos=2:9 -pass-as-sourcetext -vfs-files=%t/VFS/Main.swift=@%s,%t/VFS/Library.swift=@%S/Inputs/checkdeps/MyProject/Library.swift %t/VFS/Main.swift -- -target %target-triple %t/VFS/Main.swift %t/VFS/LibraryExt.swift %t/VFS/Library.swift == \
diff --git a/test/SourceKit/CodeComplete/complete_checkdeps_vfs_open.swift b/test/SourceKit/CodeComplete/complete_checkdeps_vfs_open.swift
index 1a8916d..ec5bd8e 100644
--- a/test/SourceKit/CodeComplete/complete_checkdeps_vfs_open.swift
+++ b/test/SourceKit/CodeComplete/complete_checkdeps_vfs_open.swift
@@ -12,7 +12,7 @@
 // RUN: cp %S/Inputs/checkdeps/MyProject/LibraryExt.swift %t/VFS/
 
 // RUN: %sourcekitd-test \
-// RUN:   -req=global-config -completion-check-dependency-interval ${DEPCHECK_INTERVAL} == \
+// RUN:   -req=global-config -req-opts=completion_check_dependency_interval=${DEPCHECK_INTERVAL} == \
 
 // RUN:   -shell -- echo "### Initial" == \
 // RUN:   -req=complete.open -pos=2:9 -pass-as-sourcetext -vfs-files=%t/VFS/Main.swift=@%s,%t/VFS/Library.swift=@%S/Inputs/checkdeps/MyProject/Library.swift %t/VFS/Main.swift -- -target %target-triple %t/VFS/Main.swift %t/VFS/LibraryExt.swift %t/VFS/Library.swift == \
diff --git a/test/SourceKit/CodeComplete/complete_docbrief_1.swift b/test/SourceKit/CodeComplete/complete_docbrief_1.swift
index 0941019..1b71266 100644
--- a/test/SourceKit/CodeComplete/complete_docbrief_1.swift
+++ b/test/SourceKit/CodeComplete/complete_docbrief_1.swift
@@ -35,7 +35,7 @@
 // CHECK-NEXT:       key.typename: "Void",
 // CHECK-NEXT:       key.doc.brief: "This is a doc comment of P.bar",
 // CHECK-NEXT:       key.context: source.codecompletion.context.superclass,
-// CHECK-NEXT:       key.typerelation: source.codecompletion.typerelation.unrelated,
+// CHECK-NEXT:       key.typerelation: source.codecompletion.typerelation.unknown,
 // CHECK-NEXT:       key.num_bytes_to_erase: 0,
 // CHECK-NEXT:       key.associated_usrs: "s:12DocBriefTest1PPAAE3baryyF",
 // CHECK-NEXT:       key.modulename: "DocBriefTest"
@@ -48,7 +48,7 @@
 // CHECK-NEXT:       key.typename: "Void",
 // CHECK-NEXT:       key.doc.brief: "This is a doc comment of P.foo",
 // CHECK-NEXT:       key.context: source.codecompletion.context.thisclass,
-// CHECK-NEXT:       key.typerelation: source.codecompletion.typerelation.unrelated,
+// CHECK-NEXT:       key.typerelation: source.codecompletion.typerelation.unknown,
 // CHECK-NEXT:       key.num_bytes_to_erase: 0,
 // CHECK-NEXT:       key.associated_usrs: "s:12DocBriefTest1SV3fooyyF s:12DocBriefTest1PP3fooyyF",
 // CHECK-NEXT:       key.modulename: "DocBriefTest"
diff --git a/test/SourceKit/CodeComplete/complete_docbrief_2.swift b/test/SourceKit/CodeComplete/complete_docbrief_2.swift
index b65f0d3..744cdec 100644
--- a/test/SourceKit/CodeComplete/complete_docbrief_2.swift
+++ b/test/SourceKit/CodeComplete/complete_docbrief_2.swift
@@ -39,7 +39,7 @@
 // CHECK-NEXT:       key.typename: "Void",
 // CHECK-NEXT:       key.doc.brief: "This is a doc comment of P.foo",
 // CHECK-NEXT:       key.context: source.codecompletion.context.thisclass,
-// CHECK-NEXT:       key.typerelation: source.codecompletion.typerelation.unrelated,
+// CHECK-NEXT:       key.typerelation: source.codecompletion.typerelation.unknown,
 // CHECK-NEXT:       key.num_bytes_to_erase: 0,
 // CHECK-NEXT:       key.associated_usrs: "s:12DocBriefUser1SV3fooyyF s:12DocBriefTest1PP3fooyyF",
 // CHECK-NEXT:       key.modulename: "DocBriefUser"
diff --git a/test/SourceKit/CodeComplete/complete_docbrief_3.swift b/test/SourceKit/CodeComplete/complete_docbrief_3.swift
index a329824..a346c86 100644
--- a/test/SourceKit/CodeComplete/complete_docbrief_3.swift
+++ b/test/SourceKit/CodeComplete/complete_docbrief_3.swift
@@ -40,7 +40,7 @@
 // CHECK-NEXT:       key.typename: "Void",
 // CHECK-NEXT:       key.doc.brief: "This is a doc comment of P.foo",
 // CHECK-NEXT:       key.context: source.codecompletion.context.thisclass,
-// CHECK-NEXT:       key.typerelation: source.codecompletion.typerelation.unrelated,
+// CHECK-NEXT:       key.typerelation: source.codecompletion.typerelation.unknown,
 // CHECK-NEXT:       key.num_bytes_to_erase: 0,
 // CHECK-NEXT:       key.associated_usrs: "s:12DocBriefTest1SV3fooyyF s:12DocBriefTest1PP3fooyyF",
 // CHECK-NEXT:       key.modulename: "DocBriefTest"
diff --git a/test/SourceKit/CodeComplete/complete_member.swift b/test/SourceKit/CodeComplete/complete_member.swift
index 3750d12..6681e6e 100644
--- a/test/SourceKit/CodeComplete/complete_member.swift
+++ b/test/SourceKit/CodeComplete/complete_member.swift
@@ -51,7 +51,7 @@
 // CHECK-OPTIONAL-NEXT:       key.description: "fooInstanceFunc1(a: Int)",
 // CHECK-OPTIONAL-NEXT:       key.typename: "Double",
 // CHECK-OPTIONAL-NEXT:       key.context: source.codecompletion.context.thisclass,
-// CHECK-OPTIONAL-NEXT:       key.typerelation: source.codecompletion.typerelation.unrelated,
+// CHECK-OPTIONAL-NEXT:       key.typerelation: source.codecompletion.typerelation.unknown,
 // CHECK-OPTIONAL-NEXT:       key.num_bytes_to_erase: 1,
 // CHECK-OPTIONAL-NEXT:       key.associated_usrs: "s:15complete_member11FooProtocolP16fooInstanceFunc1ySdSiF",
 // CHECK-OPTIONAL-NEXT:       key.modulename: "complete_member"
@@ -73,7 +73,7 @@
 // CHECK-OVERRIDE_USR-NEXT:     key.description: "foo()",
 // CHECK-OVERRIDE_USR-NEXT:     key.typename: "Void",
 // CHECK-OVERRIDE_USR-NEXT:     key.context: source.codecompletion.context.thisclass,
-// CHECK-OVERRIDE_USR-NEXT:     key.typerelation: source.codecompletion.typerelation.unrelated,
+// CHECK-OVERRIDE_USR-NEXT:     key.typerelation: source.codecompletion.typerelation.unknown,
 // CHECK-OVERRIDE_USR-NEXT:     key.num_bytes_to_erase: 0,
 // CHECK-OVERRIDE_USR-NEXT:     key.associated_usrs: "s:15complete_member7DerivedC3fooyyF s:15complete_member4BaseC3fooyyF",
 // CHECK-OVERRIDE_USR-NEXT:     key.modulename: "complete_member"
diff --git a/test/SourceKit/CodeComplete/complete_member.swift.response b/test/SourceKit/CodeComplete/complete_member.swift.response
index 12d8b87..7201bb6 100644
--- a/test/SourceKit/CodeComplete/complete_member.swift.response
+++ b/test/SourceKit/CodeComplete/complete_member.swift.response
@@ -7,7 +7,7 @@
       key.description: "fooInstanceFunc0()",
       key.typename: "Double",
       key.context: source.codecompletion.context.thisclass,
-      key.typerelation: source.codecompletion.typerelation.unrelated,
+      key.typerelation: source.codecompletion.typerelation.unknown,
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "s:15complete_member11FooProtocolP16fooInstanceFunc0SdyF",
       key.modulename: "complete_member"
@@ -19,7 +19,7 @@
       key.description: "fooInstanceFunc1(a: Int)",
       key.typename: "Double",
       key.context: source.codecompletion.context.thisclass,
-      key.typerelation: source.codecompletion.typerelation.unrelated,
+      key.typerelation: source.codecompletion.typerelation.unknown,
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "s:15complete_member11FooProtocolP16fooInstanceFunc1ySdSiF",
       key.modulename: "complete_member"
@@ -32,7 +32,7 @@
       key.typename: "Int",
       key.doc.brief: "fooInstanceVar Aaa. Bbb.",
       key.context: source.codecompletion.context.thisclass,
-      key.typerelation: source.codecompletion.typerelation.unrelated,
+      key.typerelation: source.codecompletion.typerelation.unknown,
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "s:15complete_member11FooProtocolP14fooInstanceVarSivp",
       key.modulename: "complete_member"
diff --git a/test/SourceKit/CodeComplete/complete_optionalmethod.swift.response b/test/SourceKit/CodeComplete/complete_optionalmethod.swift.response
index 9dbd9a8..682f5f5 100644
--- a/test/SourceKit/CodeComplete/complete_optionalmethod.swift.response
+++ b/test/SourceKit/CodeComplete/complete_optionalmethod.swift.response
@@ -7,7 +7,7 @@
       key.description: "optionalMethod?()",
       key.typename: "Int",
       key.context: source.codecompletion.context.thisclass,
-      key.typerelation: source.codecompletion.typerelation.unrelated,
+      key.typerelation: source.codecompletion.typerelation.unknown,
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "c:@M@complete_optionalmethod@objc(pl)Proto(im)optionalMethod",
       key.modulename: "complete_optionalmethod"
diff --git a/test/SourceKit/CodeComplete/complete_sequence.swift b/test/SourceKit/CodeComplete/complete_sequence.swift
index d65a1c2..3ad7676 100644
--- a/test/SourceKit/CodeComplete/complete_sequence.swift
+++ b/test/SourceKit/CodeComplete/complete_sequence.swift
@@ -19,8 +19,9 @@
 
 // Disabled.
 // RUN: %sourcekitd-test \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=12:11 %s -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=15:11 %s -- %s > %t.response
+// RUN:   -req=global-config -req-opts=completion_max_astcontext_reuse_count=0 ==\
+// RUN:   -req=complete -pos=12:11 %s -- %s == \
+// RUN:   -req=complete -pos=15:11 %s -- %s > %t.response
 // RUN: %FileCheck --check-prefix=RESULT_SLOW %s < %t.response
 
 // Enabled.
diff --git a/test/SourceKit/CodeComplete/complete_sequence_race.swift b/test/SourceKit/CodeComplete/complete_sequence_race.swift
index 191ee53..2876e23 100644
--- a/test/SourceKit/CodeComplete/complete_sequence_race.swift
+++ b/test/SourceKit/CodeComplete/complete_sequence_race.swift
@@ -19,21 +19,23 @@
 
 // ReuseASTContext disabled.
 // RUN: %sourcekitd-test \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=12:11 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=15:11 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=12:11 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=15:11 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=17:1 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=12:11 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=15:11 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=12:11 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=15:11 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=17:1 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=12:11 %s -async -- %s == \
-// RUN:   -req=complete -req-opts=reuseastcontext=0 -pos=15:11 %s -async -- %s
+// RUN:   -req=global-config -req-opts=completion_max_astcontext_reuse_count=0 \
+// RUN:   -req=complete -pos=12:11 %s -async -- %s == \
+// RUN:   -req=complete -pos=15:11 %s -async -- %s == \
+// RUN:   -req=complete -pos=12:11 %s -async -- %s == \
+// RUN:   -req=complete -pos=15:11 %s -async -- %s == \
+// RUN:   -req=complete -pos=17:1 %s -async -- %s == \
+// RUN:   -req=complete -pos=12:11 %s -async -- %s == \
+// RUN:   -req=complete -pos=15:11 %s -async -- %s == \
+// RUN:   -req=complete -pos=12:11 %s -async -- %s == \
+// RUN:   -req=complete -pos=15:11 %s -async -- %s == \
+// RUN:   -req=complete -pos=17:1 %s -async -- %s == \
+// RUN:   -req=complete -pos=12:11 %s -async -- %s == \
+// RUN:   -req=complete -pos=15:11 %s -async -- %s
 
 // ReuseASTContext enabled.
 // RUN: %sourcekitd-test \
+// RUN:   -req=global-config -req-opts=completion_max_astcontext_reuse_count=5 \
 // RUN:   -req=complete -pos=12:11 %s -async -- %s == \
 // RUN:   -req=complete -pos=15:11 %s -async -- %s == \
 // RUN:   -req=complete -pos=12:11 %s -async -- %s == \
diff --git a/test/SourceKit/CodeComplete/complete_without_stdlib.swift b/test/SourceKit/CodeComplete/complete_without_stdlib.swift
index 88d7923..7ece49f 100644
--- a/test/SourceKit/CodeComplete/complete_without_stdlib.swift
+++ b/test/SourceKit/CodeComplete/complete_without_stdlib.swift
@@ -10,10 +10,11 @@
 // RUN: %empty-directory(%t/sdk)
 
 // RUN: %sourcekitd-test \
+// RUN:   -req=global-config -req-opts=completion_max_astcontext_reuse_count=0 \
 // RUN:   -req=complete -pos=4:1 %s -- %s -resource-dir %t/rsrc -sdk %t/sdk | %FileCheck %s
 // RUN: %sourcekitd-test \
-// RUN:   -req=complete -req-opts=reuseastcontext=1 -pos=4:1 %s -- %s -resource-dir %t/rsrc -sdk %t/sdk == \
-// RUN:   -req=complete -req-opts=reuseastcontext=1 -pos=4:1 %s -- %s -resource-dir %t/rsrc -sdk %t/sdk | %FileCheck %s
+// RUN:   -req=complete -pos=4:1 %s -- %s -resource-dir %t/rsrc -sdk %t/sdk == \
+// RUN:   -req=complete -pos=4:1 %s -- %s -resource-dir %t/rsrc -sdk %t/sdk | %FileCheck %s
 
 // CHECK: key.results: [
 // CHECK-NOT: key.description:
diff --git a/test/SourceKit/ConformingMethods/basic.swift b/test/SourceKit/ConformingMethods/basic.swift
index 35701bd..551c533 100644
--- a/test/SourceKit/ConformingMethods/basic.swift
+++ b/test/SourceKit/ConformingMethods/basic.swift
@@ -26,9 +26,12 @@
   let _ = obj.
 }
 
-// RUN: %sourcekitd-test -req=conformingmethods -pos=26:14 -repeat-request=2 %s -req-opts=expectedtypes='$s8MyModule7Target2PD;$s8MyModule7Target1PD' -- -module-name MyModule %s > %t.response
+// RUN: %sourcekitd-test \
+// RUN:   -req=conformingmethods -pos=26:14 -repeat-request=2 %s -req-opts=expectedtypes='$s8MyModule7Target2PD;$s8MyModule7Target1PD' -- -module-name MyModule %s > %t.response
 // RUN: %diff -u %s.response %t.response
-// RUN: %sourcekitd-test -req=conformingmethods -pos=26:14 -repeat-request=2 %s -req-opts=expectedtypes='$s8MyModule7Target2PD;$s8MyModule7Target1PD',reuseastcontext=0 -- -module-name MyModule %s | %FileCheck %s --check-prefix=DISABLED
+// RUN: %sourcekitd-test \
+// RUN:   -req=global-config -req-opts=completion_max_astcontext_reuse_count=0 == \
+// RUN:   -req=conformingmethods -pos=26:14 -repeat-request=2 %s -req-opts=expectedtypes='$s8MyModule7Target2PD;$s8MyModule7Target1PD' -- -module-name MyModule %s | %FileCheck %s --check-prefix=DISABLED
 
 // DISABLED-NOT: key.reuseastcontext
 // DISABLED: key.members: [
diff --git a/test/SourceKit/CursorInfo/use-swift-source-info.swift b/test/SourceKit/CursorInfo/use-swift-source-info.swift
index 7f905f4..6130411 100644
--- a/test/SourceKit/CursorInfo/use-swift-source-info.swift
+++ b/test/SourceKit/CursorInfo/use-swift-source-info.swift
@@ -3,16 +3,19 @@
   foo()
 }
 
+// FIXME: Rmove REQUIRES rdar://problem/60096971
+// REQUIRES: rdar60096971
+
 // RUN: %empty-directory(%t)
 // RUN: echo "/// Some doc" >> %t/Foo.swift
 // RUN: echo "public func foo() { }" >> %t/Foo.swift
 // RUN: %target-swift-frontend -enable-batch-mode -emit-module -emit-module-doc -emit-module-path %t/Foo.swiftmodule %t/Foo.swift -module-name Foo -emit-module-source-info-path %t/Foo.swiftsourceinfo -emit-module-doc-path %t/Foo.swiftdoc
 //
 // Test setting optimize for ide to false
-// RUN: %sourcekitd-test -req=global-config -for-ide=0 == -req=cursor -pos=3:3 %s -- -I %t -target %target-triple %s | %FileCheck --check-prefixes=BOTH,WITH %s
+// RUN: %sourcekitd-test -req=global-config -req-opts=optimize_for_ide=0 == -req=cursor -pos=3:3 %s -- -I %t -target %target-triple %s | %FileCheck --check-prefixes=BOTH,WITH %s
 //
 // Test setting optimize for ide to true
-// RUN: %sourcekitd-test -req=global-config -for-ide=1 == -req=cursor -pos=3:3 %s -- -I %t -target %target-triple %s | %FileCheck --check-prefixes=BOTH,WITHOUT %s
+// RUN: %sourcekitd-test -req=global-config -req-opts=optimize_for_ide=1 == -req=cursor -pos=3:3 %s -- -I %t -target %target-triple %s | %FileCheck --check-prefixes=BOTH,WITHOUT %s
 //
 // Test sourcekitd-test's default global configuration request (optimize for ide is true)
 // RUN: %sourcekitd-test -req=cursor -pos=3:3 %s -- -I %t -target %target-triple %s | %FileCheck --check-prefixes=BOTH,WITHOUT %s
diff --git a/test/SourceKit/TypeContextInfo/typecontext_basic.swift b/test/SourceKit/TypeContextInfo/typecontext_basic.swift
index def196c..0eda323 100644
--- a/test/SourceKit/TypeContextInfo/typecontext_basic.swift
+++ b/test/SourceKit/TypeContextInfo/typecontext_basic.swift
@@ -25,9 +25,12 @@
   let _ = obj.foo(x: 
 }
 
-// RUN: %sourcekitd-test -req=typecontextinfo -repeat-request=2 -pos=25:22 %s -- %s > %t.response
+// RUN: %sourcekitd-test \
+// RUN:   -req=typecontextinfo -repeat-request=2 -pos=25:22 %s -- %s > %t.response
 // RUN: %diff -u %s.response %t.response
-// RUN: %sourcekitd-test -req=typecontextinfo -repeat-request=2 -pos=25:22 %s -req-opts=reuseastcontext=0 -- %s | %FileCheck %s --check-prefix=DISABLED
+// RUN: %sourcekitd-test \
+// RUN:   -req=global-config -req-opts=completion_max_astcontext_reuse_count=0 == \
+// RUN:   -req=typecontextinfo -repeat-request=2 -pos=25:22 %s -- %s | %FileCheck %s --check-prefix=DISABLED
 
 // DISABLED-NOT: key.reuseastcontext
 // DISABLED: key.results: [
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 43bd7aa..61dfcac 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -102,13 +102,15 @@
   @objc </Attribute><DeclModifier>private </DeclModifier>init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>)</ParameterClause></InitializerDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl>
   init!<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl>
   init?<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl><DeclModifier>
-  public </DeclModifier>init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause>throws <CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><DeinitializerDecl><Attribute>
+  public </DeclModifier>init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause>throws <CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl>
+  init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>..., </FunctionParameter><FunctionParameter>b: <SimpleTypeIdentifier>Double</SimpleTypeIdentifier>...</FunctionParameter>) </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><DeinitializerDecl><Attribute>
 
   @objc </Attribute>deinit <CodeBlock>{}</CodeBlock></DeinitializerDecl></MemberDeclListItem><MemberDeclListItem><DeinitializerDecl><DeclModifier>
   private </DeclModifier>deinit <CodeBlock>{}</CodeBlock></DeinitializerDecl></MemberDeclListItem><MemberDeclListItem><SubscriptDecl><DeclModifier>
 
   internal </DeclModifier>subscript<ParameterClause>(<FunctionParameter>x: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><AccessorBlock>{ <AccessorDecl>get <CodeBlock>{} </CodeBlock></AccessorDecl><AccessorDecl>set <CodeBlock>{} </CodeBlock></AccessorDecl>}</AccessorBlock></SubscriptDecl></MemberDeclListItem><MemberDeclListItem><SubscriptDecl>
-  subscript<ParameterClause>() </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></SubscriptDecl></MemberDeclListItem><MemberDeclListItem><VariableDecl>
+  subscript<ParameterClause>() </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></SubscriptDecl></MemberDeclListItem><MemberDeclListItem><SubscriptDecl>
+  subscript<ParameterClause>(<FunctionParameter>x: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>..., </FunctionParameter><FunctionParameter>y y: <SimpleTypeIdentifier>String</SimpleTypeIdentifier>...</FunctionParameter>) </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></SubscriptDecl></MemberDeclListItem><MemberDeclListItem><VariableDecl>
 
   var <PatternBinding><IdentifierPattern>x</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation><CodeBlock>{<FunctionCallExpr><IdentifierExpr>
     address </IdentifierExpr><ClosureExpr>{ <FunctionCallExpr><IdentifierExpr>fatalError</IdentifierExpr>() </FunctionCallExpr>}</ClosureExpr></FunctionCallExpr><FunctionCallExpr><IdentifierExpr>
@@ -197,7 +199,8 @@
          d _: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier><InitializerClause>= <SequenceExpr><TernaryExpr><BooleanLiteralExpr>true </BooleanLiteralExpr>? <IntegerLiteralExpr>2</IntegerLiteralExpr>: <IntegerLiteralExpr>3</IntegerLiteralExpr></TernaryExpr></SequenceExpr></InitializerClause>,</FunctionParameter><FunctionParameter><Attribute>
          @objc </Attribute>e: <SimpleTypeIdentifier>X </SimpleTypeIdentifier><InitializerClause>= <BooleanLiteralExpr>true</BooleanLiteralExpr></InitializerClause>,</FunctionParameter><FunctionParameter>
          f: <AttributedType>inout <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AttributedType>,</FunctionParameter><FunctionParameter>
-         g: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>...</FunctionParameter>) </ParameterClause>throws <ReturnClause>-> <DictionaryType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>: <SimpleTypeIdentifier>String</SimpleTypeIdentifier>] </DictionaryType></ReturnClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><FunctionDecl>
+         g: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>...,</FunctionParameter><FunctionParameter>
+         h: <SimpleTypeIdentifier>Bool</SimpleTypeIdentifier>...</FunctionParameter>) </ParameterClause>throws <ReturnClause>-> <DictionaryType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>: <SimpleTypeIdentifier>String</SimpleTypeIdentifier>] </DictionaryType></ReturnClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><FunctionDecl>
 
 func foo<FunctionSignature><ParameterClause>(<FunctionParameter>_ a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause>throws <ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><FunctionDecl>
 func foo<FunctionSignature><ParameterClause>( <FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause>rethrows <ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><StructDecl>
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index 8c4c998..6c68ff5 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -103,12 +103,14 @@
   init!(a: Int) {}
   init?(a: Int) {}
   public init(a: Int) throws {}
+  init(a: Int..., b: Double...) {}
 
   @objc deinit {}
   private deinit {}
 
   internal subscript(x: Int) -> Int { get {} set {} }
   subscript() -> Int { return 1 }
+  subscript(x: Int..., y y: String...) -> Int { return 1 }
 
   var x: Int {
     address { fatalError() }
@@ -197,7 +199,8 @@
          d _: Int = true ? 2: 3,
          @objc e: X = true,
          f: inout Int,
-         g: Int...) throws -> [Int: String] {}
+         g: Int...,
+         h: Bool...) throws -> [Int: String] {}
 
 func foo(_ a: Int) throws -> Int {}
 func foo( a: Int) rethrows -> Int {}
diff --git a/test/TypeDecoder/opaque_return_type.swift b/test/TypeDecoder/opaque_return_type.swift
index 94b139a..327e486 100644
--- a/test/TypeDecoder/opaque_return_type.swift
+++ b/test/TypeDecoder/opaque_return_type.swift
@@ -12,6 +12,12 @@
 
 func bar() -> some Sequence { return [] }
 
+struct G<T> {}
+
+extension G where T == Int {
+  var baz: some P { return 0 }
+}
+
 // DEMANGLE: $s18opaque_return_type3fooQryFQOyQo_
 // CHECK: some P
 
@@ -21,5 +27,8 @@
 // DEMANGLE: $s18opaque_return_type3barQryFQOyQo_
 // CHECK: some Sequence
 
+// DEMANGLE: $s18opaque_return_type1GVAASiRszlE3bazQrvpQOySi_Qo_
+// CHECK: some P
+
 // DEMANGLE: $s18opaque_return_type3barQryFQOyQo_7ElementSTQxD
 // CHECK: (some Sequence).Element
diff --git a/test/api-digester/breakage-allowlist.swift b/test/api-digester/breakage-allowlist.swift
new file mode 100644
index 0000000..9bb5aa7
--- /dev/null
+++ b/test/api-digester/breakage-allowlist.swift
@@ -0,0 +1,38 @@
+// REQUIRES: VENDOR=apple
+
+// RUN: %empty-directory(%t)
+// RUN: %empty-directory(%t.mod1)
+// RUN: %empty-directory(%t.mod2)
+// RUN: %empty-directory(%t.sdk)
+// RUN: %empty-directory(%t.module-cache)
+// RUN: %empty-directory(%t.baseline/ABI)
+
+// RUN: echo "public func foo() {}" > %t.mod1/Foo.swift
+// RUN: echo "public func bar() {}" > %t.mod2/Foo.swift
+
+// RUN: echo "Foo: Func foo() has been removed" > %t/incomplete-allowlist.txt
+// RUN: echo "Foo: Func foo() has been removed" > %t/complete-allowlist.txt
+// RUN: echo "Foo: Func bar() is a new API without @available attribute" >> %t/complete-allowlist.txt
+
+// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod1/Foo.swiftmodule  %t.mod1/Foo.swift -parse-as-library -enable-library-evolution -emit-module-source-info -emit-module-source-info-path %t.mod1/Foo.swiftsourceinfo -emit-module-interface-path %t.mod1/Foo.swiftinterface -module-name Foo -swift-version 5
+
+// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -emit-module -o %t.mod2/Foo.swiftmodule  %t.mod2/Foo.swift -parse-as-library -enable-library-evolution -emit-module-source-info -emit-module-source-info-path %t.mod2/Foo.swiftsourceinfo -emit-module-interface-path %t.mod2/Foo.swiftinterface -module-name Foo -swift-version 5
+
+// RUN: %api-digester -dump-sdk -module Foo -output-dir %t.baseline -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod1 -abi -use-interface-for-module Foo
+
+// RUN: %api-digester -diagnose-sdk -print-module -baseline-dir %t.baseline -module Foo -I %t.mod2 -module-cache-path %t.module-cache %clang-importer-sdk-nosource -abi -breakage-allowlist-path %t/complete-allowlist.txt -o %t/expected-diags.txt
+
+// RUN: not %api-digester -diagnose-sdk -print-module -baseline-dir %t.baseline -module Foo -I %t.mod2 -module-cache-path %t.module-cache %clang-importer-sdk-nosource -abi -compiler-style-diags
+
+// RUN: not %api-digester -diagnose-sdk -print-module -baseline-dir %t.baseline -module Foo -I %t.mod2 -module-cache-path %t.module-cache %clang-importer-sdk-nosource -abi -compiler-style-diags -breakage-allowlist-path %t/incomplete-allowlist.txt
+
+// RUN: %api-digester -diagnose-sdk -print-module -baseline-dir %t.baseline -module Foo -I %t.mod2 -module-cache-path %t.module-cache %clang-importer-sdk-nosource -abi -compiler-style-diags -breakage-allowlist-path %t/complete-allowlist.txt
+
+// RUN: not %api-digester -diagnose-sdk -print-module -baseline-dir %t.baseline -module Foo -I %t.mod2 -module-cache-path %t.module-cache %clang-importer-sdk-nosource -abi -serialize-diagnostics-path %t/serialized-diag.dia
+// RUN: ls %t/serialized-diag.dia
+
+// RUN: not %api-digester -diagnose-sdk -print-module -baseline-dir %t.baseline -module Foo -I %t.mod2 -module-cache-path %t.module-cache %clang-importer-sdk-nosource -abi -serialize-diagnostics-path %t/serialized-diag.dia -breakage-allowlist-path %t/incomplete-allowlist.txt
+// RUN: ls %t/serialized-diag.dia
+
+// RUN: %api-digester -diagnose-sdk -print-module -baseline-dir %t.baseline -module Foo -I %t.mod2 -module-cache-path %t.module-cache %clang-importer-sdk-nosource -abi -serialize-diagnostics-path %t/serialized-diag.dia -breakage-allowlist-path %t/complete-allowlist.txt
+// RUN: ls %t/serialized-diag.dia
diff --git a/test/attr/attr_cdecl_async.swift b/test/attr/attr_cdecl_async.swift
new file mode 100644
index 0000000..2cf765e
--- /dev/null
+++ b/test/attr/attr_cdecl_async.swift
@@ -0,0 +1,5 @@
+// RUN: %target-typecheck-verify-swift -enable-objc-interop -enable-experimental-concurrency
+
+@_cdecl("async") // expected-error{{@_cdecl functions cannot be asynchronous}}
+func asynchronous() async { }
+
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index 946e0c8..77848a0 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -1,6 +1,6 @@
-// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify -verify-ignore-unknown %s -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference -enable-experimental-concurrency
-// RUN: %target-swift-ide-test -skip-deinit=false -print-ast-typechecked -source-filename %s -function-definitions=true -prefer-type-repr=false -print-implicit-attrs=true -explode-pattern-binding-decls=true -disable-objc-attr-requires-foundation-module -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference -enable-experimental-concurrency | %FileCheck %s
-// RUN: not %target-swift-frontend -typecheck -dump-ast -disable-objc-attr-requires-foundation-module %s -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference -enable-experimental-concurrency > %t.ast
+// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify -verify-ignore-unknown %s -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference
+// RUN: %target-swift-ide-test -skip-deinit=false -print-ast-typechecked -source-filename %s -function-definitions=true -prefer-type-repr=false -print-implicit-attrs=true -explode-pattern-binding-decls=true -disable-objc-attr-requires-foundation-module -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference | %FileCheck %s
+// RUN: not %target-swift-frontend -typecheck -dump-ast -disable-objc-attr-requires-foundation-module %s -swift-version 4 -enable-source-import -I %S/Inputs -enable-swift3-objc-inference > %t.ast
 // RUN: %FileCheck -check-prefix CHECK-DUMP %s < %t.ast
 // REQUIRES: objc_interop
 
@@ -2381,11 +2381,3 @@
   @objc subscript<T>(foo : [T]) -> Int { return 0 }
   // expected-error@-1 {{subscript cannot be marked @objc because it has generic parameters}}
 }
-
-// async cannot be compiled with @objc.
-class Concurrency {
-  @objc func doBigJob() async -> Int { return 0 } // expected-error{{'async' function cannot be represented in Objective-C}}
-
-  @objc func takeAnAsync(_ fn: () async -> Int) { } // expected-error{{method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C}}
-  // expected-note@-1{{'async' function types cannot be represented in Objective-C}}
-}
diff --git a/test/attr/attr_objc_async.swift b/test/attr/attr_objc_async.swift
new file mode 100644
index 0000000..a3a2aad
--- /dev/null
+++ b/test/attr/attr_objc_async.swift
@@ -0,0 +1,23 @@
+// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify -verify-ignore-unknown %s -swift-version 5 -enable-source-import -I %S/Inputs -enable-experimental-concurrency
+// RUN: %target-swift-ide-test -skip-deinit=false -print-ast-typechecked -source-filename %s -function-definitions=true -prefer-type-repr=false -print-implicit-attrs=true -explode-pattern-binding-decls=true -disable-objc-attr-requires-foundation-module -swift-version 5 -enable-source-import -I %S/Inputs -enable-experimental-concurrency | %FileCheck %s
+// RUN: not %target-swift-frontend -typecheck -dump-ast -disable-objc-attr-requires-foundation-module %s -swift-version 5 -enable-source-import -I %S/Inputs -enable-experimental-concurrency > %t.ast
+// RUN: %FileCheck -check-prefix CHECK-DUMP %s < %t.ast
+// REQUIRES: objc_interop
+import Foundation
+
+// CHECK: class Concurrency
+class Concurrency {
+  // CHECK: @objc func doBigJob() async -> Int
+  // CHECK-DUMP: func_decl{{.*}}doBigJob{{.*}}foreign_async=@convention(block) (Int) -> (),completion_handler_param=0
+  @objc func doBigJob() async -> Int { return 0 }
+
+  // CHECK: @objc func doBigJobOrFail(_: Int) async throws -> (AnyObject, Int)
+  // CHECK-DUMP: func_decl{{.*}}doBigJobOrFail{{.*}}foreign_async=@convention(block) (Optional<AnyObject>, Int, Optional<Error>) -> (),completion_handler_param=1,error_param=2
+  @objc func doBigJobOrFail(_: Int) async throws -> (AnyObject, Int) { return (self, 0) }
+
+  @objc func takeAnAsync(_ fn: () async -> Int) { } // expected-error{{method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C}}
+  // expected-note@-1{{'async' function types cannot be represented in Objective-C}}
+
+  @objc class func createAsynchronously() async -> Self? { nil }
+  // expected-error@-1{{asynchronous method returning 'Self' cannot be '@objc'}}
+}
diff --git a/test/decl/async/objc.swift b/test/decl/async/objc.swift
new file mode 100644
index 0000000..96fba77
--- /dev/null
+++ b/test/decl/async/objc.swift
@@ -0,0 +1,44 @@
+// RUN: %target-swift-frontend -disable-objc-attr-requires-foundation-module -typecheck -verify %s -swift-version 5 -enable-experimental-concurrency
+// RUN: %target-swift-ide-test -skip-deinit=false -print-ast-typechecked -source-filename %s -function-definitions=true -prefer-type-repr=false -print-implicit-attrs=true -explode-pattern-binding-decls=true -disable-objc-attr-requires-foundation-module -swift-version 5 -enable-experimental-concurrency | %FileCheck %s
+// REQUIRES: objc_interop
+import Foundation
+import ObjectiveC
+
+@objc protocol P {
+  func doBigJob() async -> Int
+}
+
+// Infer @objc from protocol conformance
+// CHECK: class ConformsToP
+class ConformsToP: P {
+  // CHECK: @objc func doBigJob() async -> Int
+  func doBigJob() async -> Int { 5 }
+}
+
+// Infer @objc from superclass
+class Super {
+  @objc func longRunningRequest() async throws -> [String] { [] }
+}
+
+// CHECK: class Sub
+class Sub : Super {
+  // CHECK-NEXT: @objc override func longRunningRequest() async throws -> [String]
+  override func longRunningRequest() async throws -> [String] { [] }
+}
+
+// Check selector computation.
+@objc protocol MakeSelectors {
+  func selectorAsync() async -> Int
+  func selector(value: Int) async -> Int
+}
+
+func testSelectors() {
+  // expected-warning@+1{{use '#selector' instead of explicitly constructing a 'Selector'}}
+  _ = Selector("selectorAsyncWithCompletionHandler:")
+
+  // expected-warning@+1{{use '#selector' instead of explicitly constructing a 'Selector'}}
+  _ = Selector("selectorWithValue:completionHandler:")
+
+  _ = Selector("canary:") // expected-warning{{no method declared with Objective-C selector 'canary:'}}
+  // expected-note@-1{{wrap the selector name in parentheses to suppress this warning}}
+}
diff --git a/test/decl/enum/enumtest.swift b/test/decl/enum/enumtest.swift
index 57b8117..3f5a450 100644
--- a/test/decl/enum/enumtest.swift
+++ b/test/decl/enum/enumtest.swift
@@ -100,8 +100,7 @@
   var h = ZeroOneTwoThree(1)
   
   var i = 0 > 3 ? .none : .some(3) // expected-error {{cannot infer contextual base in reference to member 'none'}}
-  // expected-error@-1 {{cannot infer contextual base in reference to member 'some'}}
-  
+
   test3a;  // expected-error {{unused function}}
   .Zero   // expected-error {{reference to member 'Zero' cannot be resolved without a contextual type}}
   test3a   // expected-error {{unused function}}
diff --git a/test/decl/func/async.swift b/test/decl/func/async.swift
index 32165b7..beeb27c 100644
--- a/test/decl/func/async.swift
+++ b/test/decl/func/async.swift
@@ -2,7 +2,7 @@
 
 // Redeclaration checking
 func redecl1() async { } // expected-note{{previously declared here}}
-func redecl1() throws { } // expected-error{{invalid redeclaration of 'redecl1()'}}
+func redecl1() async throws { } // expected-error{{invalid redeclaration of 'redecl1()'}}
 
 // Override checking
 
diff --git a/test/decl/func/vararg.swift b/test/decl/func/vararg.swift
index 36bda36..71befae 100644
--- a/test/decl/func/vararg.swift
+++ b/test/decl/func/vararg.swift
@@ -27,7 +27,38 @@
   { (e: ExtraCrispy...) in }() // expected-error {{cannot find type 'ExtraCrispy' in scope}}
 }
 
-func twoVariadics(_ a: Int..., b: Int...) { } // expected-error{{only a single variadic parameter '...' is permitted}} {{38-41=}}
+func twoVariadics(_ a: Int..., b: Int...) { }
+func unlabeledFollowingVariadic(_ a: Int..., _ b: Int) { } // expected-error {{a parameter following a variadic parameter requires a label}}
+func unlabeledVariadicFollowingVariadic(_ a: Int..., _ b: Int...) { } // expected-error {{a parameter following a variadic parameter requires a label}}
+func unlabeledFollowingTwoVariadics(_ a: Int..., b: Int..., _ c: Int) { } // expected-error {{a parameter following a variadic parameter requires a label}}
+func splitVariadics(_ a: Int..., b: Int, _ c: String...) { }
+func splitByDefaultArgVariadics(_ a: Int..., b: Int = 0, _ c: String...) { }
+
+struct HasSubscripts {
+  subscript(a: Int...) -> Void { () }
+  subscript(a: Int..., b b: Int...) -> Void { () }
+  subscript(a: Int..., b: Int...) -> Void { () } // expected-error {{a parameter following a variadic parameter requires a label}}
+  subscript(a: Int..., b: Int) -> Void { () } // expected-error {{a parameter following a variadic parameter requires a label}}
+  subscript(a: Int..., b b: Int..., c c: Int) -> Void { () }
+  subscript(a: Int..., b b: Int..., c: Int) -> Void { () } // expected-error {{a parameter following a variadic parameter requires a label}}
+  subscript(a: Int..., c c: Int = 0, b: Int...) -> Void { () }
+  subscript(a: Int..., b: String = "hello, world!") -> Bool { false } // expected-error {{a parameter following a variadic parameter requires a label}}
+}
+
+struct HasInitializers {
+  init(a: Int...) {}
+  init(a: Int..., b: Int...) {}
+  init(a: Int..., _ b: Int...) {} // expected-error {{a parameter following a variadic parameter requires a label}}
+  init(a: Int..., c: Int = 0, _ b: Int...) {}
+}
+
+let closure = {(x: Int..., y: Int...) in } // expected-error {{no parameters may follow a variadic parameter in a closure}}
+let closure2 = {(x: Int..., y: Int) in } // expected-error {{no parameters may follow a variadic parameter in a closure}}
+let closure3 = {(x: Int..., y: Int, z: Int...) in } // expected-error {{no parameters may follow a variadic parameter in a closure}}
+let closure4 = {(x: Int...) in }
+let closure5 = {(x: Int, y: Int...) in }
+let closure6 = {(x: Int..., y z: Int) in } // expected-error {{closure cannot have keyword arguments}}
+// expected-error@-1 {{no parameters may follow a variadic parameter in a closure}}
 
 // rdar://22056861
 func f5(_ list: Any..., end: String = "") {}
diff --git a/test/decl/nested/protocol.swift b/test/decl/nested/protocol.swift
index 2d820f9..2ccc15b7 100644
--- a/test/decl/nested/protocol.swift
+++ b/test/decl/nested/protocol.swift
@@ -51,10 +51,11 @@
 }
 
 enum SillyRawEnum : SillyProtocol.InnerClass {} // expected-error {{an enum with no cases cannot declare a raw type}}
-// expected-error@-1 {{raw type}}
+// expected-error@-1 {{reference to generic type 'SillyProtocol.InnerClass' requires arguments in <...>}}
 
 protocol SillyProtocol {
   class InnerClass<T> {} // expected-error {{type 'InnerClass' cannot be nested in protocol 'SillyProtocol'}}
+  // expected-note@-1 {{generic type 'InnerClass' declared here}}
 }
 
 // N.B. Redeclaration checks don't see this case because `protocol A` is invalid.
diff --git a/test/decl/overload.swift b/test/decl/overload.swift
index 07ba5b7..b769dd0 100644
--- a/test/decl/overload.swift
+++ b/test/decl/overload.swift
@@ -79,7 +79,6 @@
 // expected-note @-1 2{{found this candidate}}
 enum mixed_redecl3a : mixed_redecl3 {} // expected-error {{'mixed_redecl3' is ambiguous for type lookup in this context}}
 // expected-error@-1 {{an enum with no cases cannot declare a raw type}}
-// expected-error@-2 {{raw type}}
 class mixed_redecl3b : mixed_redecl3 {} // expected-error {{'mixed_redecl3' is ambiguous for type lookup in this context}}
 
 class mixed_redecl4 {} // expected-note {{previously declared here}}
diff --git a/test/decl/var/function_builders.swift b/test/decl/var/function_builders.swift
index fd93eaf..b3b8605 100644
--- a/test/decl/var/function_builders.swift
+++ b/test/decl/var/function_builders.swift
@@ -7,10 +7,10 @@
 func globalBuilderFunction() -> Int { return 0 }
 
 @_functionBuilder
-struct Maker {}
+struct Maker {} // expected-error {{function builder must provide at least one static 'buildBlock' method}}
 
 @_functionBuilder
-class Inventor {}
+class Inventor {} // expected-error {{function builder must provide at least one static 'buildBlock' method}}
 
 @Maker // expected-error {{function builder attribute 'Maker' can only be applied to a parameter, function, or computed property}}
 typealias typename = Inventor
@@ -66,11 +66,11 @@
                            fn: @autoclosure () -> ()) {}
 
 @_functionBuilder
-struct GenericMaker<T> {} // expected-note {{generic type 'GenericMaker' declared here}}
+struct GenericMaker<T> {} // expected-note {{generic type 'GenericMaker' declared here}} expected-error {{function builder must provide at least one static 'buildBlock' method}}
 
 struct GenericContainer<T> {  // expected-note {{generic type 'GenericContainer' declared here}}
   @_functionBuilder
-  struct Maker {}
+  struct Maker {} // expected-error {{function builder must provide at least one static 'buildBlock' method}}
 }
 
 func makeParamUnbound(@GenericMaker // expected-error {{reference to generic type 'GenericMaker' requires arguments}}
@@ -89,7 +89,7 @@
 protocol P { }
 
 @_functionBuilder
-struct ConstrainedGenericMaker<T: P> {}
+struct ConstrainedGenericMaker<T: P> {} // expected-error {{function builder must provide at least one static 'buildBlock' method}}
 
 
 struct WithinGeneric<U> {
@@ -99,3 +99,121 @@
   func makeParamBoundInContextBad(@ConstrainedGenericMaker<U>
     fn: () -> ()) {}
 }
+
+@_functionBuilder
+struct ValidBuilder1 {
+  static func buildBlock(_ exprs: Any...) -> Int { return exprs.count }
+}
+
+protocol BuilderFuncHelper {}
+
+extension BuilderFuncHelper {
+  static func buildBlock(_ exprs: Any...) -> Int { return exprs.count }
+}
+
+@_functionBuilder
+struct ValidBuilder2: BuilderFuncHelper {}
+
+class BuilderFuncBase {
+  static func buildBlock(_ exprs: Any...) -> Int { return exprs.count }
+}
+
+@_functionBuilder
+class ValidBuilder3: BuilderFuncBase {}
+
+@_functionBuilder
+struct ValidBuilder4 {}
+extension ValidBuilder4 {
+    static func buildBlock(_ exprs: Any...) -> Int { return exprs.count }
+}
+
+@_functionBuilder
+struct ValidBuilder5 {
+    static func buildBlock() -> Int { 0 }
+}
+
+@_functionBuilder
+struct InvalidBuilder1 {} // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+
+@_functionBuilder
+struct InvalidBuilder2 { // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+  func buildBlock(_ exprs: Any...) -> Int { return exprs.count } // expected-note {{did you mean to make instance method 'buildBlock' static?}} {{3-3=static }}
+}
+
+@_functionBuilder
+struct InvalidBuilder3 { // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+  var buildBlock: (Any...) -> Int = { return $0.count } // expected-note {{potential match 'buildBlock' is not a static method}}
+}
+
+@_functionBuilder
+struct InvalidBuilder4 {} // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+extension InvalidBuilder4 {
+  func buildBlock(_ exprs: Any...) -> Int { return exprs.count } // expected-note {{did you mean to make instance method 'buildBlock' static?}} {{3-3=static }}
+}
+
+protocol InvalidBuilderHelper {}
+extension InvalidBuilderHelper {
+  func buildBlock(_ exprs: Any...) -> Int { return exprs.count } // expected-note {{potential match 'buildBlock' is not a static method}}
+}
+
+@_functionBuilder
+struct InvalidBuilder5: InvalidBuilderHelper {} // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+
+@_functionBuilder
+struct InvalidBuilder6 { // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+    static var buildBlock: Int = 0 // expected-note {{potential match 'buildBlock' is not a static method}}
+}
+
+struct Callable {
+    func callAsFunction(_ exprs: Any...) -> Int { return exprs.count }
+}
+
+@_functionBuilder
+struct InvalidBuilder7 { // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+    static var buildBlock = Callable() // expected-note {{potential match 'buildBlock' is not a static method}}
+}
+
+class BuilderVarBase {
+  static var buildBlock: (Any...) -> Int = { return $0.count } // expected-note {{potential match 'buildBlock' is not a static method}}
+}
+
+@_functionBuilder
+class InvalidBuilder8: BuilderVarBase {} // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+
+protocol BuilderVarHelper {}
+
+extension BuilderVarHelper {
+  static var buildBlock: (Any...) -> Int { { return $0.count } } // expected-note {{potential match 'buildBlock' is not a static method}}
+}
+
+@_functionBuilder
+struct InvalidBuilder9: BuilderVarHelper {} // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+
+@_functionBuilder
+struct InvalidBuilder10 { // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+  static var buildBlock: (Any...) -> Int = { return $0.count } // expected-note {{potential match 'buildBlock' is not a static method}}
+}
+
+@_functionBuilder
+enum InvalidBuilder11 { // expected-error {{function builder must provide at least one static 'buildBlock' method}}
+    case buildBlock(Any) // expected-note {{enum case 'buildBlock' cannot be used to satisfy the function builder requirement}}
+}
+
+struct S {
+  @ValidBuilder1 var v1: Int { 1 }
+  @ValidBuilder2 var v2: Int { 1 }
+  @ValidBuilder3 var v3: Int { 1 }
+  @ValidBuilder4 var v4: Int { 1 }
+  @ValidBuilder5 func v5() -> Int {}
+  @InvalidBuilder1 var i1: Int { 1 } // expected-error {{type 'InvalidBuilder1' has no member 'buildBlock'}}
+  @InvalidBuilder2 var i2: Int { 1 } // expected-error {{instance member 'buildBlock' cannot be used on type 'InvalidBuilder2'; did you mean to use a value of this type instead?}}
+  @InvalidBuilder3 var i3: Int { 1 } // expected-error {{instance member 'buildBlock' cannot be used on type 'InvalidBuilder3'; did you mean to use a value of this type instead?}}
+  @InvalidBuilder4 var i4: Int { 1 } // expected-error {{instance member 'buildBlock' cannot be used on type 'InvalidBuilder4'; did you mean to use a value of this type instead?}}
+  @InvalidBuilder5 var i5: Int { 1 } // expected-error {{instance member 'buildBlock' cannot be used on type 'InvalidBuilder5'; did you mean to use a value of this type instead?}}
+  @InvalidBuilder6 var i6: Int { 1 } // expected-error {{cannot call value of non-function type 'Int'}}
+  @InvalidBuilder7 var i7: Int { 1 }
+  @InvalidBuilder8 var i8: Int { 1 }
+  @InvalidBuilder9 var i9: Int { 1 }
+  @InvalidBuilder10 var i10: Int { 1 }
+  @InvalidBuilder11 var i11: InvalidBuilder11 { 1 }
+}
diff --git a/test/decl/var/nan_comparisons.swift b/test/decl/var/nan_comparisons.swift
new file mode 100644
index 0000000..3dc8ddf
--- /dev/null
+++ b/test/decl/var/nan_comparisons.swift
@@ -0,0 +1,31 @@
+// RUN: %target-typecheck-verify-swift
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+/////// Comparison with '.nan' static property instead of using '.isNaN' instance property ///////
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+// One side is '.nan' and the other isn't.
+// Using '==' or '!=' for comparison should suggest using '.isNaN'.
+
+let double: Double = 0.0
+_ = double == .nan // expected-warning {{comparison with '.nan' using '==' is always false, use 'double.isNaN' to check if 'double' is not a number}}
+_ = double != .nan // expected-warning {{comparison with '.nan' using '!=' is always true, use '!double.isNaN' to check if 'double' is a number}}
+_ = 0.0 == .nan // // expected-warning {{comparison with '.nan' using '==' is always false, use '0.0.isNaN' to check if '0.0' is not a number}}
+
+// One side is '.nan' and the other isn't. Using '>=', '>', '<', '<=' for comparison:
+// We can't suggest using '.isNaN' here.
+
+_ = 0.0 >= .nan // expected-warning {{comparison with '.nan' using '>=' is always false}}
+_ = .nan > 1.1 // expected-warning {{comparison with '.nan' using '>' is always false}}
+_ = .nan < 2.2 // expected-warning {{comparison with '.nan' using '<' is always false}}
+_ = 3.3 <= .nan // expected-warning {{comparison with '.nan' using '<=' is always false}}
+
+// Both sides are '.nan':
+// We can't suggest using '.isNaN' here.
+
+_ = Double.nan == Double.nan // expected-warning {{'.nan' == '.nan' is always false}}
+_ = Double.nan != Double.nan // expected-warning {{'.nan' != '.nan' is always true}}
+_ = Double.nan < Double.nan // expected-warning {{'.nan' < '.nan' is always false}}
+_ = Double.nan <= Double.nan // expected-warning {{'.nan' <= '.nan' is always false}}
+_ = Double.nan > Double.nan // expected-warning {{'.nan' > '.nan' is always false}}
+_ = Double.nan >= Double.nan // expected-warning {{'.nan' >= '.nan' is always false}}
diff --git a/test/expr/cast/as_coerce.swift b/test/expr/cast/as_coerce.swift
index 962c656..165d7b9 100644
--- a/test/expr/cast/as_coerce.swift
+++ b/test/expr/cast/as_coerce.swift
@@ -68,14 +68,16 @@
 
 var c: AnyObject = C3()
 
-if let castX = c as! C4? {} // expected-error {{cannot downcast from 'AnyObject' to a more optional type 'C4?'}}
+// XXX TODO: Constant-folding should generate an error about 'C3' not being convertible to 'C4'
+//if let castX = c as! C4? {}
 
-// Only suggest replacing 'as' with 'as!' if it would fix the error.
+// XXX TODO: Only suggest replacing 'as' with 'as!' if it would fix the error.
 C3() as C4 // expected-error {{'C3' is not convertible to 'C4'; did you mean to use 'as!' to force downcast?}} {{6-8=as!}}
 C3() as C5 // expected-error {{cannot convert value of type 'C3' to type 'C5' in coercion}}
 
 // Diagnostic shouldn't include @lvalue in type of c3.
 var c3 = C3()
+// XXX TODO: This should not suggest `as!`
 c3 as C4 // expected-error {{'C3' is not convertible to 'C4'; did you mean to use 'as!' to force downcast?}} {{4-6=as!}}
 
 // <rdar://problem/19495142> Various incorrect diagnostics for explicit type conversions
diff --git a/test/expr/delayed-ident/member_chains.swift b/test/expr/delayed-ident/member_chains.swift
index 2691574..a2684ad 100644
--- a/test/expr/delayed-ident/member_chains.swift
+++ b/test/expr/delayed-ident/member_chains.swift
@@ -344,3 +344,30 @@
 
 let _: CurriedGeneric = .createInt(CurriedGeneric())()
 let _: CurriedGeneric = .create(CurriedGeneric())(Int.self)
+
+// rdar://problem/68094328 - failed to compile unresolved member with implicit optional promotion
+func rdar68094328() {
+  struct S {
+    init(string: String) {}
+
+    var value: S {
+      get { S(string: "") }
+    }
+
+    func baz(str: String) -> S {
+      S(string: str)
+    }
+  }
+
+  class C {
+    func bar(_: S) {}
+  }
+
+  func foo<T>(_: (C) -> (T) -> Void, _: T?) {}
+
+  func test(str: String) {
+    foo(C.bar, .init(string: str)) // Ok
+    foo(C.bar, .init(string: str).value) // Ok
+    foo(C.bar, .init(string: str).baz(str: "")) // Ok
+  }
+}
diff --git a/test/expr/postfix/call/forward_trailing_closure_unresolved_member.swift b/test/expr/postfix/call/forward_trailing_closure_unresolved_member.swift
new file mode 100644
index 0000000..f651150
--- /dev/null
+++ b/test/expr/postfix/call/forward_trailing_closure_unresolved_member.swift
@@ -0,0 +1,19 @@
+// RUN: %target-swift-emit-silgen %s | %FileCheck %s
+
+// rdar://problem/67781123 - crash in SILGen
+
+struct Foo {
+  var title: String
+  var handler1: ((Int, String) -> Void)?
+  var handler2: (() -> Void)?
+}
+
+func take(foo: Foo) { }
+
+// CHECK-LABEL: sil hidden [ossa] @$s42forward_trailing_closure_unresolved_member4testyy
+func test() {
+  // CHECK: function_ref @$s42forward_trailing_closure_unresolved_member4testyyFyycfU_ : $@convention(thin) () -> ()
+  take(foo: .init(title: "") {
+      print("handler2 is called")
+    })
+}
diff --git a/test/expr/unary/async_await.swift b/test/expr/unary/async_await.swift
index 3601108..3dc31a3 100644
--- a/test/expr/unary/async_await.swift
+++ b/test/expr/unary/async_await.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -typecheck -verify %s -enable-experimental-concurrency
+// RUN: %target-swift-frontend -typecheck -verify %s -enable-experimental-concurrency -verify-syntax-tree
 
 func test1(asyncfp : () async -> Int, fp : () -> Int) async {
   _ = await asyncfp()
@@ -72,3 +72,64 @@
 
   let _: () -> Int = closure2 // expected-error{{cannot convert value of type '() async -> Int' to specified type '() -> Int'}}
 }
+
+// Nesting async and await together
+func throwingAndAsync() async throws -> Int { return 0 }
+
+enum HomeworkError : Error {
+  case dogAteIt
+}
+
+func testThrowingAndAsync() async throws {
+  _ = await try throwingAndAsync()
+  _ = try await throwingAndAsync()
+  _ = await (try throwingAndAsync())
+  _ = try (await throwingAndAsync())
+
+  // Errors
+  _ = await throwingAndAsync() // expected-error{{call can throw but is not marked with 'try'}}
+  // expected-note@-1{{did you mean to use 'try'?}}
+  // expected-note@-2{{did you mean to handle error as optional value?}}
+  // expected-note@-3{{did you mean to disable error propagation?}}
+  _ = try throwingAndAsync() // expected-error{{call is 'async' but is not marked with 'await'}}
+}
+
+func testExhaustiveDoCatch() async {
+  do {
+    _ = await try throwingAndAsync()
+  } catch {
+  }
+
+  do {
+    _ = await try throwingAndAsync()
+    // expected-error@-1{{errors thrown from here are not handled because the enclosing catch is not exhaustive}}
+  } catch let e as HomeworkError {
+  }
+
+  // Ensure that we infer 'async' through an exhaustive do-catch.
+  let fn = {
+    do {
+      _ = await try throwingAndAsync()
+    } catch {
+    }
+  }
+
+  let _: Int = fn // expected-error{{cannot convert value of type '() async -> ()'}}
+
+  // Ensure that we infer 'async' through a non-exhaustive do-catch.
+  let fn2 = {
+    do {
+      _ = await try throwingAndAsync()
+    } catch let e as HomeworkError {
+    }
+  }
+
+  let _: Int = fn2 // expected-error{{cannot convert value of type '() async throws -> ()'}}
+}
+
+// String interpolation
+func testStringInterpolation() async throws {
+  _ = "Eventually produces \(getInt())" // expected-error{{call is 'async' but is not marked with 'await'}}
+  _ = "Eventually produces \(await getInt())"
+  _ = await "Eventually produces \(getInt())"
+}
diff --git a/test/expr/unary/keypath/keypath.swift b/test/expr/unary/keypath/keypath.swift
index 326e148..08282b4 100644
--- a/test/expr/unary/keypath/keypath.swift
+++ b/test/expr/unary/keypath/keypath.swift
@@ -1012,6 +1012,11 @@
   let _ : KeyPath<String?, Int> = \.count // expected-error {{key path root inferred as optional type 'String?' must be unwrapped to refer to member 'count' of unwrapped type 'String'}}
   // expected-note@-1 {{chain the optional using '?.' to access unwrapped type member 'count'}} {{37-37=?.}}
   // expected-note@-2 {{unwrap the optional using '!.' to access unwrapped type member 'count'}} {{37-37=!.}}
+
+  let _ : KeyPath<String?, Int> = \.utf8.count 
+  // expected-error@-1 {{key path root inferred as optional type 'String?' must be unwrapped to refer to member 'utf8' of unwrapped type 'String'}}
+  // expected-note@-2 {{chain the optional using '?.' to access unwrapped type member 'utf8'}} {{37-37=?.}}
+  // expected-note@-3 {{unwrap the optional using '!.' to access unwrapped type member 'utf8'}} {{37-37=!.}}
 }
 
 func testSyntaxErrors() {
diff --git a/test/lit.cfg b/test/lit.cfg
index b35d22f..657adcf 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -427,10 +427,6 @@
 if 'syntax_parser_lib' in config.available_features:
     config.substitutions.append( ('%swift-syntax-parser-test', config.swift_syntax_parser_test) )
 # For testing on CI
-if '-enable-astscope-lookup' in config.swift_test_options:
-    config.available_features.add("enable-astscope-lookup")
-if '-disable-astscope-lookup' in config.swift_test_options:
-    config.available_features.add("disable-astscope-lookup")
 if '-disable-parser-lookup' in config.swift_test_options:
     config.available_features.add("disable-parser-lookup")
 config.substitutions.append( ('%swift-indent', config.swift_indent) )
diff --git a/test/multifile/Inputs/rdar67842221-other.swift b/test/multifile/Inputs/rdar67842221-other.swift
new file mode 100644
index 0000000..bda0e89
--- /dev/null
+++ b/test/multifile/Inputs/rdar67842221-other.swift
@@ -0,0 +1,4 @@
+let closureValue = { () -> () in
+   class DummyClass {}
+   return ()
+}()
diff --git a/test/multifile/rdar67842221.swift b/test/multifile/rdar67842221.swift
new file mode 100644
index 0000000..64bacf0
--- /dev/null
+++ b/test/multifile/rdar67842221.swift
@@ -0,0 +1,17 @@
+// Test both orderings, and single-file vs WMO
+
+// RUN: %target-swift-frontend -emit-ir -primary-file %s %S/Inputs/rdar67842221-other.swift -module-name main
+// RUN: %target-swift-frontend -emit-ir %s -primary-file %S/Inputs/rdar67842221-other.swift -module-name main
+
+// RUN: %target-swift-frontend -emit-ir -primary-file %S/Inputs/rdar67842221-other.swift %s -module-name main
+// RUN: %target-swift-frontend -emit-ir %S/Inputs/rdar67842221-other.swift -primary-file %s -module-name main
+
+// RUN: %target-swift-frontend -emit-ir %S/Inputs/rdar67842221-other.swift %s -module-name main
+// RUN: %target-swift-frontend -emit-ir %S/Inputs/rdar67842221-other.swift %s -module-name main
+
+// The closure defines a local class; we want to make sure there is no cycle
+// between computing the semantic members of the local class (which requires
+// sorting) and computing the type of the closure value
+public func force() {
+  _ = closureValue
+}
diff --git a/test/stdlib/ManagedBuffer.swift b/test/stdlib/ManagedBuffer.swift
index 24d288c..0d69197 100644
--- a/test/stdlib/ManagedBuffer.swift
+++ b/test/stdlib/ManagedBuffer.swift
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 // RUN: %target-run-simple-swift
 // REQUIRES: executable_test
+// XFAIL: OS=openbsd
 
 import StdlibUnittest
 
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 08a4083..b50cbc7 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -22,6 +22,7 @@
 add_swift_tool_subdirectory(swift-remoteast-test)
 add_swift_tool_subdirectory(swift-demangle)
 add_swift_tool_subdirectory(swift-demangle-yamldump)
+add_swift_tool_subdirectory(swift-def-to-yaml-converter)
 add_swift_tool_subdirectory(swift-serialize-diagnostics)
 add_swift_tool_subdirectory(lldb-moduleimport-test)
 add_swift_tool_subdirectory(sil-func-extractor)
diff --git a/tools/SourceKit/include/SourceKit/Core/Context.h b/tools/SourceKit/include/SourceKit/Core/Context.h
index 922c1ab..da9f190 100644
--- a/tools/SourceKit/include/SourceKit/Core/Context.h
+++ b/tools/SourceKit/include/SourceKit/Core/Context.h
@@ -31,14 +31,20 @@
 class GlobalConfig {
 public:
   struct Settings {
-    /// When true, the default compiler options and other configuration flags will be chosen to optimize for
-    /// usage from an IDE.
+    /// When true, the default compiler options and other configuration flags
+    /// will be chosen to optimize for usage from an IDE.
     ///
     /// At the time of writing this just means ignoring .swiftsourceinfo files.
     bool OptimizeForIDE = false;
 
-    /// Interval second for checking dependencies in fast code completion.
-    unsigned CompletionCheckDependencyInterval = 5;
+    struct CompletionOptions {
+
+      /// Max count of reusing ASTContext for cached code completion.
+      unsigned MaxASTContextReuseCount = 100;
+
+      /// Interval second for checking dependencies in cached code completion.
+      unsigned CheckDependencyInterval = 5;
+    } CompletionOpts;
   };
 
 private:
@@ -47,9 +53,10 @@
 
 public:
   Settings update(Optional<bool> OptimizeForIDE,
+                  Optional<unsigned> CompletionMaxASTContextReuseCount,
                   Optional<unsigned> CompletionCheckDependencyInterval);
   bool shouldOptimizeForIDE() const;
-  unsigned getCompletionCheckDependencyInterval() const;
+  Settings::CompletionOptions getCompletionOpts() const;
 };
 
 class Context {
diff --git a/tools/SourceKit/lib/Core/Context.cpp b/tools/SourceKit/lib/Core/Context.cpp
index b7899db..f73c3fe 100644
--- a/tools/SourceKit/lib/Core/Context.cpp
+++ b/tools/SourceKit/lib/Core/Context.cpp
@@ -18,12 +18,17 @@
 
 GlobalConfig::Settings
 GlobalConfig::update(Optional<bool> OptimizeForIDE,
+                     Optional<unsigned> CompletionMaxASTContextReuseCount,
                      Optional<unsigned> CompletionCheckDependencyInterval) {
   llvm::sys::ScopedLock L(Mtx);
   if (OptimizeForIDE.hasValue())
     State.OptimizeForIDE = *OptimizeForIDE;
+  if (CompletionMaxASTContextReuseCount.hasValue())
+    State.CompletionOpts.MaxASTContextReuseCount =
+        *CompletionMaxASTContextReuseCount;
   if (CompletionCheckDependencyInterval.hasValue())
-    State.CompletionCheckDependencyInterval = *CompletionCheckDependencyInterval;
+    State.CompletionOpts.CheckDependencyInterval =
+        *CompletionCheckDependencyInterval;
   return State;
 };
 
@@ -31,9 +36,10 @@
   llvm::sys::ScopedLock L(Mtx);
   return State.OptimizeForIDE;
 }
-unsigned GlobalConfig::getCompletionCheckDependencyInterval() const {
+GlobalConfig::Settings::CompletionOptions
+GlobalConfig::getCompletionOpts() const {
   llvm::sys::ScopedLock L(Mtx);
-  return State.CompletionCheckDependencyInterval;
+  return State.CompletionOpts;
 }
 
 SourceKit::Context::Context(
diff --git a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp
index c24e17a..4852a6f 100644
--- a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp
+++ b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp
@@ -157,8 +157,6 @@
   return results;
 }
 
-static StringRef copyString(llvm::BumpPtrAllocator &allocator, StringRef str);
-
 bool SourceKit::CodeCompletion::addCustomCompletions(
     CompletionSink &sink, std::vector<Completion *> &completions,
     ArrayRef<CustomCompletionInfo> customCompletions,
@@ -405,12 +403,6 @@
 // CodeCompletionOrganizer::Impl utilities
 //===----------------------------------------------------------------------===//
 
-static StringRef copyString(llvm::BumpPtrAllocator &allocator, StringRef str) {
-  char *newStr = allocator.Allocate<char>(str.size());
-  std::copy(str.begin(), str.end(), newStr);
-  return StringRef(newStr, str.size());
-}
-
 static std::unique_ptr<Group> make_group(StringRef name) {
   auto g = std::make_unique<Group>();
   g->name = name.str();
diff --git a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h
index f8f1d03..5ed5265 100644
--- a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h
+++ b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h
@@ -42,7 +42,6 @@
   bool hideLowPriority = true;
   bool hideByNameStyle = true;
   bool fuzzyMatching = true;
-  bool reuseASTContextIfPossible = true;
   bool annotatedDescription = false;
   unsigned minFuzzyLength = 2;
   unsigned showTopNonLiteralResults = 3;
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp b/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
index 06d3a91..8e8e9bf 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
@@ -121,9 +121,9 @@
     unsigned Offset, SwiftCodeCompletionConsumer &SwiftConsumer,
     ArrayRef<const char *> Args,
     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
-    bool EnableASTCaching, bool annotateDescription, std::string &Error) {
+    bool annotateDescription, std::string &Error) {
   return Lang.performCompletionLikeOperation(
-      UnresolvedInputFile, Offset, Args, FileSystem, EnableASTCaching, Error,
+      UnresolvedInputFile, Offset, Args, FileSystem, Error,
       [&](CompilerInstance &CI, bool reusingASTContext) {
         // Create a factory for code completion callbacks that will feed the
         // Consumer.
@@ -215,7 +215,6 @@
   std::string Error;
   if (!swiftCodeCompleteImpl(*this, UnresolvedInputFile, Offset, SwiftConsumer,
                              Args, fileSystem,
-                             CCOpts.reuseASTContextIfPossible,
                              CCOpts.annotatedDescription, Error)) {
     SKConsumer.failed(Error);
   }
@@ -734,7 +733,6 @@
   static UIdent KeyContextWeight("key.codecomplete.sort.contextweight");
   static UIdent KeyFuzzyWeight("key.codecomplete.sort.fuzzyweight");
   static UIdent KeyPopularityBonus("key.codecomplete.sort.popularitybonus");
-  static UIdent KeyReuseASTContext("key.codecomplete.reuseastcontext");
   static UIdent KeyAnnotatedDescription("key.codecomplete.annotateddescription");
 
   from.valueForOption(KeySortByName, to.sortByName);
@@ -760,7 +758,6 @@
   from.valueForOption(KeyPopularityBonus, to.popularityBonus);
   from.valueForOption(KeyHideByName, to.hideByNameStyle);
   from.valueForOption(KeyTopNonLiteral, to.showTopNonLiteralResults);
-  from.valueForOption(KeyReuseASTContext, to.reuseASTContextIfPossible);
   from.valueForOption(KeyAnnotatedDescription, to.annotatedDescription);
 }
 
@@ -1032,7 +1029,6 @@
     std::string error;
     if (!swiftCodeCompleteImpl(lang, buffer.get(), str.size(), swiftConsumer,
                                cargs, session->getFileSystem(),
-                               options.reuseASTContextIfPossible,
                                options.annotatedDescription, error)) {
       consumer.failed(error);
       return;
@@ -1134,7 +1130,6 @@
   // Invoke completion.
   if (!swiftCodeCompleteImpl(*this, inputBuf, offset, swiftConsumer,
                              extendedArgs, fileSystem,
-                             CCOpts.reuseASTContextIfPossible,
                              CCOpts.annotatedDescription, error)) {
     consumer.failed(error);
     return;
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftConformingMethodList.cpp b/tools/SourceKit/lib/SwiftLang/SwiftConformingMethodList.cpp
index f2814e6..176f307 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftConformingMethodList.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftConformingMethodList.cpp
@@ -26,11 +26,10 @@
 using namespace swift;
 using namespace ide;
 
-static void translateConformingMethodListOptions(OptionsDictionary &from,
-                                                 ConformingMethodList::Options &to) {
-  static UIdent KeyReuseASTContext("key.conformingmethods.reuseastcontext");
-
-  from.valueForOption(KeyReuseASTContext, to.reuseASTContextIfPossible);
+static void
+translateConformingMethodListOptions(OptionsDictionary &from,
+                                     ConformingMethodList::Options &to) {
+  // ConformingMethodList doesn't receive any options at this point.
 }
 
 static bool swiftConformingMethodListImpl(
@@ -39,9 +38,9 @@
     ArrayRef<const char *> ExpectedTypeNames,
     ide::ConformingMethodListConsumer &Consumer,
     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
-    bool EnableASTCaching, std::string &Error) {
+    std::string &Error) {
   return Lang.performCompletionLikeOperation(
-      UnresolvedInputFile, Offset, Args, FileSystem, EnableASTCaching, Error,
+      UnresolvedInputFile, Offset, Args, FileSystem, Error,
       [&](CompilerInstance &CI, bool reusingASTContext) {
         // Create a factory for code completion callbacks that will feed the
         // Consumer.
@@ -194,7 +193,7 @@
 
   if (!swiftConformingMethodListImpl(*this, UnresolvedInputFile, Offset, Args,
                                      ExpectedTypeNames, Consumer, fileSystem,
-                                     options.reuseASTContextIfPossible, error)) {
+                                     error)) {
     SKConsumer.failed(error);
   }
 }
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
index f59c9d0..0cb600d 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
@@ -674,6 +674,7 @@
   static UIdent PlatformOSXAppExt("source.availability.platform.osx_app_extension");
   static UIdent PlatformtvOSAppExt("source.availability.platform.tvos_app_extension");
   static UIdent PlatformWatchOSAppExt("source.availability.platform.watchos_app_extension");
+  static UIdent PlatformOpenBSD("source.availability.platform.openbsd");
   std::vector<const DeclAttribute*> Scratch;
 
   for (auto Attr : getDeclAttributes(D, Scratch)) {
@@ -702,6 +703,8 @@
         PlatformUID = PlatformtvOSAppExt; break;
       case PlatformKind::watchOSApplicationExtension:
         PlatformUID = PlatformWatchOSAppExt; break;
+      case PlatformKind::OpenBSD:
+        PlatformUID = PlatformOpenBSD; break;
       }
 
       AvailableAttrInfo Info;
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
index 45684f0..02b066e7 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
@@ -264,8 +264,11 @@
 static void
 configureCompletionInstance(std::shared_ptr<CompletionInstance> CompletionInst,
                             std::shared_ptr<GlobalConfig> GlobalConfig) {
-  CompletionInst->setDependencyCheckIntervalSecond(
-      GlobalConfig->getCompletionCheckDependencyInterval());
+  auto Opts = GlobalConfig->getCompletionOpts();
+  CompletionInst->setOptions({
+    Opts.MaxASTContextReuseCount,
+    Opts.CheckDependencyInterval
+  });
 }
 
 SwiftLangSupport::SwiftLangSupport(SourceKit::Context &SKCtx)
@@ -274,7 +277,7 @@
   llvm::SmallString<128> LibPath(SKCtx.getRuntimeLibPath());
   llvm::sys::path::append(LibPath, "swift");
   RuntimeResourcePath = std::string(LibPath.str());
-  DiagnosticDocumentationPath = SKCtx.getDiagnosticDocumentationPath();
+  DiagnosticDocumentationPath = SKCtx.getDiagnosticDocumentationPath().str();
 
   Stats = std::make_shared<SwiftStatistics>();
   EditorDocuments = std::make_shared<SwiftEditorDocumentFileMap>();
@@ -986,7 +989,7 @@
     llvm::MemoryBuffer *UnresolvedInputFile, unsigned Offset,
     ArrayRef<const char *> Args,
     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
-    bool EnableASTCaching, std::string &Error,
+    std::string &Error,
     llvm::function_ref<void(CompilerInstance &, bool)> Callback) {
   assert(FileSystem);
 
@@ -1042,8 +1045,7 @@
 
   return CompletionInst->performOperation(Invocation, Args, FileSystem,
                                           newBuffer.get(), Offset,
-                                          EnableASTCaching, Error,
-                                          &CIDiags, Callback);
+                                          Error, &CIDiags, Callback);
 }
 
 CloseClangModuleFiles::~CloseClangModuleFiles() {
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
index f64adc3..81f61f4 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
@@ -222,13 +222,13 @@
 
 namespace TypeContextInfo {
 struct Options {
-  bool reuseASTContextIfPossible = true;
+  // TypeContextInfo doesn't receive any options at this point.
 };
 } // namespace TypeContextInfo
 
 namespace ConformingMethodList {
 struct Options {
-  bool reuseASTContextIfPossible = true;
+  // ConformingMethodList doesn't receive any options at this point.
 };
 } // namespace ConformingMethodList
 
@@ -465,7 +465,7 @@
       llvm::MemoryBuffer *UnresolvedInputFile, unsigned Offset,
       ArrayRef<const char *> Args,
       llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
-      bool EnableASTCaching, std::string &Error,
+      std::string &Error,
       llvm::function_ref<void(swift::CompilerInstance &, bool)> Callback);
 
   //==========================================================================//
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
index bd366f9..746c13e 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
@@ -20,8 +20,9 @@
 #include "swift/AST/ASTDemangler.h"
 #include "swift/AST/ASTPrinter.h"
 #include "swift/AST/Decl.h"
+#include "swift/AST/LookupKinds.h"
+#include "swift/AST/ModuleNameLookup.h"
 #include "swift/AST/NameLookup.h"
-#include "swift/AST/NameLookupRequests.h"
 #include "swift/AST/SwiftNameTranslation.h"
 #include "swift/AST/GenericSignature.h"
 #include "swift/Basic/SourceManager.h"
@@ -484,40 +485,48 @@
 
 template <typename FnTy>
 void walkRelatedDecls(const ValueDecl *VD, const FnTy &Fn) {
-  llvm::SmallDenseMap<DeclName, unsigned, 16> NamesSeen;
-  ++NamesSeen[VD->getName()];
-  SmallVector<LookupResultEntry, 8> RelatedDecls;
-
   if (isa<ParamDecl>(VD))
     return; // Parameters don't have interesting related declarations.
 
-  // FIXME: Extract useful related declarations, overloaded functions,
-  // if VD is an initializer, we should extract other initializers etc.
-  // For now we use unqualified lookup to fetch other declarations with the same
-  // base name.
   auto &ctx = VD->getASTContext();
-  auto descriptor = UnqualifiedLookupDescriptor(DeclNameRef(VD->getBaseName()),
-                                                VD->getDeclContext());
-  auto lookup = evaluateOrDefault(ctx.evaluator,
-                                  UnqualifiedLookupRequest{descriptor}, {});
-  for (auto result : lookup) {
-    ValueDecl *RelatedVD = result.getValueDecl();
-    if (RelatedVD->getAttrs().isUnavailable(VD->getASTContext()))
+
+  llvm::SmallDenseMap<DeclName, unsigned, 16> NamesSeen;
+  ++NamesSeen[VD->getName()];
+
+
+  auto *DC = VD->getDeclContext();
+  bool typeLookup = DC->isTypeContext();
+
+  SmallVector<ValueDecl *, 4> results;
+
+  if (typeLookup) {
+    auto type = DC->getDeclaredInterfaceType();
+    if (!type->is<ErrorType>()) {
+      DC->lookupQualified(type, DeclNameRef(VD->getBaseName()),
+                          NL_QualifiedDefault, results);
+    }
+  } else {
+    namelookup::lookupInModule(DC->getModuleScopeContext(),
+                               VD->getBaseName(), results,
+                               NLKind::UnqualifiedLookup,
+                               namelookup::ResolutionKind::Overloadable,
+                               DC->getModuleScopeContext());
+  }
+
+  SmallVector<ValueDecl *, 8> RelatedDecls;
+  for (auto result : results) {
+    if (result->getAttrs().isUnavailable(ctx))
       continue;
 
-    if (RelatedVD != VD) {
-      ++NamesSeen[RelatedVD->getName()];
+    if (result != VD) {
+      ++NamesSeen[result->getName()];
       RelatedDecls.push_back(result);
     }
   }
 
   // Now provide the results along with whether the name is duplicate or not.
-  ValueDecl *OriginalBase = VD->getDeclContext()->getSelfNominalTypeDecl();
-  for (auto Related : RelatedDecls) {
-    ValueDecl *RelatedVD = Related.getValueDecl();
-    bool SameBase = Related.getBaseDecl() && Related.getBaseDecl() == OriginalBase;
-    Fn(RelatedVD, SameBase, NamesSeen[RelatedVD->getName()] > 1);
-  }
+  for (auto result : RelatedDecls)
+    Fn(result, typeLookup, NamesSeen[result->getName()] > 1);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftTypeContextInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftTypeContextInfo.cpp
index 5a7b8bd..9e857ba 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftTypeContextInfo.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftTypeContextInfo.cpp
@@ -27,9 +27,7 @@
 
 static void translateTypeContextInfoOptions(OptionsDictionary &from,
                                             TypeContextInfo::Options &to) {
-  static UIdent KeyReuseASTContext("key.typecontextinfo.reuseastcontext");
-
-  from.valueForOption(KeyReuseASTContext, to.reuseASTContextIfPossible);
+  // TypeContextInfo doesn't receive any options at this point.
 }
 
 static bool swiftTypeContextInfoImpl(
@@ -37,9 +35,9 @@
     unsigned Offset, ide::TypeContextInfoConsumer &Consumer,
     ArrayRef<const char *> Args,
     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
-    bool EnableASTCaching, std::string &Error) {
+    std::string &Error) {
   return Lang.performCompletionLikeOperation(
-      UnresolvedInputFile, Offset, Args, FileSystem, EnableASTCaching, Error,
+      UnresolvedInputFile, Offset, Args, FileSystem, Error,
       [&](CompilerInstance &CI, bool reusingASTContext) {
         // Create a factory for code completion callbacks that will feed the
         // Consumer.
@@ -168,8 +166,7 @@
   } Consumer(SKConsumer);
 
   if (!swiftTypeContextInfoImpl(*this, UnresolvedInputFile, Offset, Consumer,
-                                Args, fileSystem,
-                                options.reuseASTContextIfPossible, error)) {
+                                Args, fileSystem, error)) {
     SKConsumer.failed(error);
   }
 }
diff --git a/tools/SourceKit/tools/sourcekitd-test/Options.td b/tools/SourceKit/tools/sourcekitd-test/Options.td
index 5119a2e..522cc38 100644
--- a/tools/SourceKit/tools/sourcekitd-test/Options.td
+++ b/tools/SourceKit/tools/sourcekitd-test/Options.td
@@ -140,14 +140,6 @@
 def vfs_name : Separate<["-"], "vfs-name">,
   HelpText<"Specify a virtual filesystem name">;
 
-def optimize_for_ide : Joined<["-"], "for-ide=">,
-  HelpText<"Value for the OptimizeForIde global configuration setting">;
-
-def completion_check_dependency_interval : Separate<["-"], "completion-check-dependency-interval">,
-  HelpText<"Inteval seconds for checking dependencies in fast completion">;
-def completion_check_dependency_interval_EQ : Joined<["-"], "completion-check-dependency-interval=">,
-  Alias<completion_check_dependency_interval>;
-
 def suppress_config_request : Flag<["-"], "suppress-config-request">,
   HelpText<"Suppress the default global configuration request, that is otherwise sent before any other request (except for the global-config request itself)">;
 
diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
index ee57737..7b49e63 100644
--- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
@@ -371,29 +371,6 @@
       VFSName = InputArg->getValue();
       break;
 
-    case OPT_optimize_for_ide: {
-      bool Value;
-      if (StringRef(InputArg->getValue()).getAsInteger(10, Value)) {
-        llvm::errs() << "error: expected 0 or 1 for 'for-ide'\n";
-        return true;
-      }
-      OptimizeForIde = Value;
-      break;
-    }
-
-    case OPT_completion_check_dependency_interval: {
-      int64_t Value;
-      if (StringRef(InputArg->getValue()).getAsInteger(10, Value)) {
-        llvm::errs() << "error: expected number for inteval\n";
-        return true;
-      } else if (Value < 0) {
-        llvm::errs() << "error: completion-check-dependency-interval must be > 0\n";
-        return true;
-      }
-      CompletionCheckDependencyInterval = Value;
-      break;
-    }
-
     case OPT_suppress_config_request:
       SuppressDefaultConfigRequest = true;
       break;
diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
index b9f2b3e..925fea4 100644
--- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
@@ -538,15 +538,17 @@
 
   case SourceKitRequest::GlobalConfiguration:
     sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestGlobalConfiguration);
-    if (Opts.OptimizeForIde.hasValue())
-      sourcekitd_request_dictionary_set_int64(
-          Req, KeyOptimizeForIDE,
-          static_cast<int64_t>(Opts.OptimizeForIde.getValue()));
-    if (Opts.CompletionCheckDependencyInterval.hasValue())
-      sourcekitd_request_dictionary_set_int64(
-          Req, KeyCompletionCheckDependencyInterval,
-          static_cast<int64_t>(
-              Opts.CompletionCheckDependencyInterval.getValue()));
+
+    for (auto &Opt : Opts.RequestOptions) {
+      auto KeyValue = StringRef(Opt).split('=');
+      std::string KeyStr("key.");
+      KeyStr.append(KeyValue.first.str());
+      sourcekitd_uid_t Key = sourcekitd_uid_get_from_cstr(KeyStr.c_str());
+
+      int64_t Value = 0;
+      KeyValue.second.getAsInteger(0, Value);
+      sourcekitd_request_dictionary_set_int64(Req, Key, Value);
+    }
     break;
 
   case SourceKitRequest::ProtocolVersion:
diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
index 42f632e..d95425d 100644
--- a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
+++ b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
@@ -437,23 +437,27 @@
     ResponseBuilder RB;
     auto dict = RB.getDictionary();
 
-    Optional<bool> OptimizeForIDE;
-    int64_t EditorMode = true;
-    if (!Req.getInt64(KeyOptimizeForIDE, EditorMode, true)) {
-      OptimizeForIDE = EditorMode;
-    }
+    Optional<bool> OptimizeForIDE =
+        Req.getOptionalInt64(KeyOptimizeForIDE)
+            .map([](int64_t v) -> bool { return v; });
+    Optional<unsigned> CompletionMaxASTContextReuseCount =
+        Req.getOptionalInt64(KeyCompletionMaxASTContextReuseCount)
+            .map([](int64_t v) -> unsigned { return v; });
     Optional<unsigned> CompletionCheckDependencyInterval =
-      Req.getOptionalInt64(KeyCompletionCheckDependencyInterval)
-        .map([](int64_t v)->unsigned{return v;});
+        Req.getOptionalInt64(KeyCompletionCheckDependencyInterval)
+            .map([](int64_t v) -> unsigned { return v; });
 
-    GlobalConfig::Settings UpdatedConfig = Config->update(
-        OptimizeForIDE, CompletionCheckDependencyInterval);
+    GlobalConfig::Settings UpdatedConfig =
+        Config->update(OptimizeForIDE, CompletionMaxASTContextReuseCount,
+                       CompletionCheckDependencyInterval);
 
     getGlobalContext().getSwiftLangSupport().globalConfigurationUpdated(Config);
 
     dict.set(KeyOptimizeForIDE, UpdatedConfig.OptimizeForIDE);
+    dict.set(KeyCompletionMaxASTContextReuseCount,
+             UpdatedConfig.CompletionOpts.MaxASTContextReuseCount);
     dict.set(KeyCompletionCheckDependencyInterval,
-             UpdatedConfig.CompletionCheckDependencyInterval);
+             UpdatedConfig.CompletionOpts.CheckDependencyInterval);
 
     return Rec(RB.createResponse());
   }
diff --git a/tools/driver/modulewrap_main.cpp b/tools/driver/modulewrap_main.cpp
index 510cf5d..3ef145a 100644
--- a/tools/driver/modulewrap_main.cpp
+++ b/tools/driver/modulewrap_main.cpp
@@ -176,15 +176,15 @@
   SourceManager SrcMgr;
   TypeCheckerOptions TypeCheckOpts;
   LangOptions LangOpts;
+  ClangImporterOptions ClangImporterOpts;
   LangOpts.Target = Invocation.getTargetTriple();
   ASTContext &ASTCtx = *ASTContext::get(LangOpts, TypeCheckOpts, SearchPathOpts,
-                                        SrcMgr, Instance.getDiags());
+                                        ClangImporterOpts, SrcMgr,
+                                        Instance.getDiags());
   registerParseRequestFunctions(ASTCtx.evaluator);
   registerTypeCheckerRequestFunctions(ASTCtx.evaluator);
   
-  ClangImporterOptions ClangImporterOpts;
-  ASTCtx.addModuleLoader(ClangImporter::create(ASTCtx, ClangImporterOpts, ""),
-                         true);
+  ASTCtx.addModuleLoader(ClangImporter::create(ASTCtx, ""), true);
   ModuleDecl *M = ModuleDecl::create(ASTCtx.getIdentifier("swiftmodule"), ASTCtx);
   SILOptions SILOpts;
   std::unique_ptr<Lowering::TypeConverter> TC(new Lowering::TypeConverter(*M));
diff --git a/tools/sil-opt/SILOpt.cpp b/tools/sil-opt/SILOpt.cpp
index 490bf85..f4d2b44 100644
--- a/tools/sil-opt/SILOpt.cpp
+++ b/tools/sil-opt/SILOpt.cpp
@@ -274,6 +274,11 @@
                      llvm::cl::desc("Enable C++ interop."),
                      llvm::cl::init(false));
 
+static llvm::cl::opt<bool>
+    IgnoreAlwaysInline("ignore-always-inline",
+                       llvm::cl::desc("Ignore [always_inline] attribute."),
+                       llvm::cl::init(false));
+
 static void runCommandLineSelectedPasses(SILModule *Module,
                                          irgen::IRGenModule *IRGenMod) {
   auto &opts = Module->getOptions();
@@ -398,6 +403,7 @@
   }
 
   SILOpts.EnableSpeculativeDevirtualization = EnableSpeculativeDevirtualization;
+  SILOpts.IgnoreAlwaysInline = IgnoreAlwaysInline;
 
   serialization::ExtendedValidationInfo extendedInfo;
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
diff --git a/tools/swift-api-digester/ModuleDiagsConsumer.cpp b/tools/swift-api-digester/ModuleDiagsConsumer.cpp
index 6e4d2b9..7ded725 100644
--- a/tools/swift-api-digester/ModuleDiagsConsumer.cpp
+++ b/tools/swift-api-digester/ModuleDiagsConsumer.cpp
@@ -78,7 +78,7 @@
   case LocalDiagID::not_inheriting_convenience_inits:
     return "/* Class Inheritance Change */";
   default:
-    return StringRef();
+    return "/* Others */";
   }
 }
 }
@@ -122,3 +122,28 @@
     }
   }
 }
+
+bool swift::ide::api::
+FilteringDiagnosticConsumer::shouldProceed(const DiagnosticInfo &Info) {
+  if (allowedBreakages->empty()) {
+    return true;
+  }
+  llvm::SmallString<256> Text;
+  {
+    llvm::raw_svector_ostream Out(Text);
+    DiagnosticEngine::formatDiagnosticText(Out, Info.FormatString,
+                                           Info.FormatArgs);
+  }
+  return allowedBreakages->count(Text.str()) == 0;
+}
+
+void swift::ide::api::
+FilteringDiagnosticConsumer::handleDiagnostic(SourceManager &SM,
+                                              const DiagnosticInfo &Info) {
+  if (shouldProceed(Info)) {
+    if (Info.Kind == DiagnosticKind::Error) {
+      HasError = true;
+    }
+    subConsumer->handleDiagnostic(SM, Info);
+  }
+}
diff --git a/tools/swift-api-digester/ModuleDiagsConsumer.h b/tools/swift-api-digester/ModuleDiagsConsumer.h
index df83c80..cb23ef5 100644
--- a/tools/swift-api-digester/ModuleDiagsConsumer.h
+++ b/tools/swift-api-digester/ModuleDiagsConsumer.h
@@ -41,6 +41,30 @@
   ~ModuleDifferDiagsConsumer();
   void handleDiagnostic(SourceManager &SM, const DiagnosticInfo &Info) override;
 };
+
+class FilteringDiagnosticConsumer: public DiagnosticConsumer {
+  bool HasError = false;
+  std::unique_ptr<DiagnosticConsumer> subConsumer;
+  std::unique_ptr<llvm::StringSet<>> allowedBreakages;
+  bool shouldProceed(const DiagnosticInfo &Info);
+public:
+  FilteringDiagnosticConsumer(std::unique_ptr<DiagnosticConsumer> subConsumer,
+                              std::unique_ptr<llvm::StringSet<>> allowedBreakages):
+    subConsumer(std::move(subConsumer)),
+    allowedBreakages(std::move(allowedBreakages)) {}
+  ~FilteringDiagnosticConsumer() = default;
+
+  bool finishProcessing() override { return subConsumer->finishProcessing(); }
+  bool hasError() const { return HasError; }
+  void flush() override { subConsumer->flush(); }
+
+  void informDriverOfIncompleteBatchModeCompilation() override {
+    subConsumer->informDriverOfIncompleteBatchModeCompilation();
+  }
+
+  void handleDiagnostic(SourceManager &SM,
+                        const DiagnosticInfo &Info) override;
+};
 }
 }
 }
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index ed3c61d..e5820ca 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -26,6 +26,7 @@
 // can be reflected as source-breaking changes for API users. If they are,
 // the output of api-digester will include such changes.
 
+#include "swift/Basic/Platform.h"
 #include "swift/Frontend/PrintingDiagnosticConsumer.h"
 #include "swift/Frontend/SerializedDiagnosticConsumer.h"
 #include "swift/AST/DiagnosticsModuleDiffer.h"
@@ -264,6 +265,11 @@
                    llvm::cl::desc("Serialize diagnostics to a path"),
                    llvm::cl::cat(Category));
 
+static llvm::cl::opt<std::string>
+BreakageAllowlistPath("breakage-allowlist-path",
+                      llvm::cl::desc("An allowlist of breakages to not complain about"),
+                      llvm::cl::cat(Category));
+
 } // namespace options
 
 namespace {
@@ -2320,6 +2326,49 @@
   }
 }
 
+static int readFileLineByLine(StringRef Path, llvm::StringSet<> &Lines) {
+  auto FileBufOrErr = llvm::MemoryBuffer::getFile(Path);
+  if (!FileBufOrErr) {
+    llvm::errs() << "error opening file '" << Path << "': "
+      << FileBufOrErr.getError().message() << '\n';
+    return 1;
+  }
+
+  StringRef BufferText = FileBufOrErr.get()->getBuffer();
+  while (!BufferText.empty()) {
+    StringRef Line;
+    std::tie(Line, BufferText) = BufferText.split('\n');
+    Line = Line.trim();
+    if (Line.empty())
+      continue;
+    if (Line.startswith("// ")) // comment.
+      continue;
+    Lines.insert(Line);
+  }
+  return 0;
+}
+
+static bool readBreakageAllowlist(SDKContext &Ctx, llvm::StringSet<> &lines) {
+  if (options::BreakageAllowlistPath.empty())
+    return 0;
+  CompilerInstance instance;
+  CompilerInvocation invok;
+  invok.setModuleName("ForClangImporter");
+  if (instance.setup(invok))
+    return 1;
+  auto importer = ClangImporter::create(instance.getASTContext());
+  SmallString<128> preprocessedFilePath;
+  if (auto error = llvm::sys::fs::createTemporaryFile(
+    "breakage-allowlist-", "txt", preprocessedFilePath)) {
+    return 1;
+  }
+  if (importer->runPreprocessor(options::BreakageAllowlistPath,
+                                preprocessedFilePath.str())) {
+    return 1;
+  }
+  return readFileLineByLine(preprocessedFilePath, lines);
+}
+
 static int diagnoseModuleChange(SDKContext &Ctx, SDKNodeRoot *LeftModule,
                              SDKNodeRoot *RightModule, StringRef OutputPath,
                              llvm::StringSet<> ProtocolReqAllowlist) {
@@ -2337,9 +2386,14 @@
     OS = FileOS.get();
   }
   bool FailOnError;
-  std::unique_ptr<DiagnosticConsumer> pConsumer =
-    createDiagConsumer(*OS, FailOnError);
-
+  auto allowedBreakages = std::make_unique<llvm::StringSet<>>();
+  if (readBreakageAllowlist(Ctx, *allowedBreakages)) {
+    Ctx.getDiags().diagnose(SourceLoc(), diag::cannot_read_allowlist,
+                            options::BreakageAllowlistPath);
+  }
+  auto pConsumer = std::make_unique<FilteringDiagnosticConsumer>(
+    createDiagConsumer(*OS, FailOnError), std::move(allowedBreakages));
+  SWIFT_DEFER { pConsumer->finishProcessing(); };
   Ctx.addDiagConsumer(*pConsumer);
   Ctx.setCommonVersion(std::min(LeftModule->getJsonFormatVersion(),
                                 RightModule->getJsonFormatVersion()));
@@ -2352,7 +2406,7 @@
   // Find member hoist changes to help refine diagnostics.
   findTypeMemberDiffs(LeftModule, RightModule, Ctx.getTypeMemberDiffs());
   DiagnosisEmitter::diagnosis(LeftModule, RightModule, Ctx);
-  return FailOnError && Ctx.getDiags().hadAnyError() ? 1 : 0;
+  return FailOnError && pConsumer->hasError() ? 1 : 0;
 }
 
 static int diagnoseModuleChange(StringRef LeftPath, StringRef RightPath,
@@ -2372,9 +2426,8 @@
   LeftCollector.deSerialize(LeftPath);
   SwiftDeclCollector RightCollector(Ctx);
   RightCollector.deSerialize(RightPath);
-  diagnoseModuleChange(Ctx, LeftCollector.getSDKRoot(), RightCollector.getSDKRoot(),
-                       OutputPath, std::move(ProtocolReqAllowlist));
-  return options::CompilerStyleDiags && Ctx.getDiags().hadAnyError() ? 1 : 0;
+  return diagnoseModuleChange(Ctx, LeftCollector.getSDKRoot(),
+    RightCollector.getSDKRoot(), OutputPath, std::move(ProtocolReqAllowlist));
 }
 
 static void populateAliasChanges(NodeMap &AliasMap, DiffVector &AllItems,
@@ -2493,28 +2546,6 @@
   return 0;
 }
 
-static int readFileLineByLine(StringRef Path, llvm::StringSet<> &Lines) {
-  auto FileBufOrErr = llvm::MemoryBuffer::getFile(Path);
-  if (!FileBufOrErr) {
-    llvm::errs() << "error opening file '" << Path << "': "
-      << FileBufOrErr.getError().message() << '\n';
-    return 1;
-  }
-
-  StringRef BufferText = FileBufOrErr.get()->getBuffer();
-  while (!BufferText.empty()) {
-    StringRef Line;
-    std::tie(Line, BufferText) = BufferText.split('\n');
-    Line = Line.trim();
-    if (Line.empty())
-      continue;
-    if (Line.startswith("// ")) // comment.
-      continue;
-    Lines.insert(Line);
-  }
-  return 0;
-}
-
 // This function isn't referenced outside its translation unit, but it
 // can't use the "static" keyword because its address is used for
 // getMainExecutable (since some platforms don't support taking the
@@ -2674,7 +2705,7 @@
     Opts.ToolArgs.push_back(argv[i]);
 
   if (!options::SDK.empty()) {
-    auto Ver = getSDKVersion(options::SDK);
+    auto Ver = getSDKBuildVersion(options::SDK);
     if (!Ver.empty()) {
       Opts.ToolArgs.push_back("-sdk-version");
       Opts.ToolArgs.push_back(Ver);
@@ -2818,7 +2849,7 @@
       exit(1);
     }
     llvm::sys::path::append(OutputPath, getBaselineFilename(Triple));
-    return OutputPath.str();
+    return OutputPath.str().str();
   }
   llvm::errs() << "Unable to decide output file path\n";
   exit(1);
diff --git a/tools/swift-def-to-yaml-converter/CMakeLists.txt b/tools/swift-def-to-yaml-converter/CMakeLists.txt
new file mode 100644
index 0000000..558a737
--- /dev/null
+++ b/tools/swift-def-to-yaml-converter/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_swift_host_tool(swift-def-to-yaml-converter
+  swift-def-to-yaml-converter.cpp
+  SWIFT_COMPONENT tools
+)
+
+target_link_libraries(swift-def-to-yaml-converter PRIVATE
+  swiftLocalization)
diff --git a/tools/swift-def-to-yaml-converter/swift-def-to-yaml-converter.cpp b/tools/swift-def-to-yaml-converter/swift-def-to-yaml-converter.cpp
new file mode 100644
index 0000000..0d49088
--- /dev/null
+++ b/tools/swift-def-to-yaml-converter/swift-def-to-yaml-converter.cpp
@@ -0,0 +1,102 @@
+//===--- swift-def-to-yaml-converter.cpp ----------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+//
+// Create a YAML file from the diagnostic messages text in `.def` files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "swift/Basic/LLVMInitialize.h"
+#include "swift/Localization/LocalizationFormat.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdlib>
+#include <string>
+#include <system_error>
+
+static constexpr const char *const diagnosticID[] = {
+#define DIAG(KIND, ID, Options, Text, Signature) #ID,
+#include "swift/AST/DiagnosticsAll.def"
+};
+
+static constexpr const char *const diagnosticMessages[] = {
+#define DIAG(KIND, ID, Options, Text, Signature) Text,
+#include "swift/AST/DiagnosticsAll.def"
+};
+
+enum LocalDiagID : uint32_t {
+#define DIAG(KIND, ID, Options, Text, Signature) ID,
+#include "swift/AST/DiagnosticsAll.def"
+  NumDiags
+};
+
+namespace options {
+
+static llvm::cl::OptionCategory Category("swift-def-to-yaml-converter Options");
+
+static llvm::cl::opt<std::string>
+    OutputDirectory("output-directory",
+                    llvm::cl::desc("Directory for the output file"),
+                    llvm::cl::cat(Category));
+
+static llvm::cl::opt<std::string>
+    OutputFilename("output-filename",
+                   llvm::cl::desc("Filename for the output file"),
+                   llvm::cl::cat(Category));
+
+} // namespace options
+
+int main(int argc, char *argv[]) {
+  PROGRAM_START(argc, argv);
+
+  llvm::cl::HideUnrelatedOptions(options::Category);
+  llvm::cl::ParseCommandLineOptions(argc, argv,
+                                    "Swift `.def` to YAML Converter\n");
+
+  llvm::SmallString<128> LocalizedFilePath;
+  if (options::OutputFilename.empty()) {
+    // The default language for localization is English
+    std::string defaultLocaleCode = "en";
+    LocalizedFilePath = options::OutputDirectory;
+    llvm::sys::path::append(LocalizedFilePath, defaultLocaleCode);
+    llvm::sys::path::replace_extension(LocalizedFilePath, ".yaml");
+  } else {
+    LocalizedFilePath = options::OutputFilename;
+  }
+
+  std::error_code error;
+  llvm::raw_fd_ostream OS(LocalizedFilePath.str(), error,
+                          llvm::sys::fs::F_None);
+
+  if (OS.has_error() || error) {
+    llvm::errs() << "Error has occurred while trying to write to "
+                 << LocalizedFilePath.str()
+                 << " with error code: " << error.message() << "\n";
+    return EXIT_FAILURE;
+  }
+
+  llvm::ArrayRef<const char *> ids(diagnosticID, LocalDiagID::NumDiags);
+  llvm::ArrayRef<const char *> messages(diagnosticMessages,
+                                        LocalDiagID::NumDiags);
+
+  swift::diag::DefToYAMLConverter converter(ids, messages);
+  converter.convert(OS);
+
+  return EXIT_SUCCESS;
+}
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index 691318b..a17fba4 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -829,7 +829,7 @@
   CompletionInstance CompletionInst;
   auto isSuccess = CompletionInst.performOperation(
       Invocation, /*Args=*/{}, llvm::vfs::getRealFileSystem(), CleanFile.get(),
-      Offset, /*EnableASTCaching=*/false, Error,
+      Offset, Error,
       CodeCompletionDiagnostics ? &PrintDiags : nullptr,
       [&](CompilerInstance &CI, bool reusingASTContext) {
         assert(!reusingASTContext && "reusing AST context without enabling it");
@@ -1207,8 +1207,7 @@
     bool wasASTContextReused = false;
     bool isSuccess = CompletionInst.performOperation(
         Invocation, /*Args=*/{}, FileSystem, completionBuffer.get(), Offset,
-        /*EnableASTCaching=*/true, Error,
-        CodeCompletionDiagnostics ? &PrintDiags : nullptr,
+        Error, CodeCompletionDiagnostics ? &PrintDiags : nullptr,
         [&](CompilerInstance &CI, bool reusingASTContext) {
           // Create a CodeCompletionConsumer.
           std::unique_ptr<ide::CodeCompletionConsumer> Consumer(
diff --git a/tools/swift-llvm-opt/LLVMOpt.cpp b/tools/swift-llvm-opt/LLVMOpt.cpp
index a1db84b..bd01da6 100644
--- a/tools/swift-llvm-opt/LLVMOpt.cpp
+++ b/tools/swift-llvm-opt/LLVMOpt.cpp
@@ -36,7 +36,7 @@
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Bitcode/BitcodeWriterPass.h"
-#include "llvm/CodeGen/CommandFlags.inc"
+#include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
@@ -68,6 +68,8 @@
 
 using namespace swift;
 
+static llvm::codegen::RegisterCodeGenFlags CGF;
+
 //===----------------------------------------------------------------------===//
 //                            Option Declarations
 //===----------------------------------------------------------------------===//
@@ -96,19 +98,19 @@
     PrintStats("print-stats",
                llvm::cl::desc("Should LLVM Statistics be printed"));
 
-static cl::opt<std::string> InputFilename(cl::Positional,
-                                          cl::desc("<input file>"),
-                                          cl::init("-"),
-                                          cl::value_desc("filename"));
+static llvm::cl::opt<std::string> InputFilename(llvm::cl::Positional,
+                                          llvm::cl::desc("<input file>"),
+                                          llvm::cl::init("-"),
+                                          llvm::cl::value_desc("filename"));
 
-static cl::opt<std::string> OutputFilename("o",
-                                           cl::desc("Override output filename"),
-                                           cl::value_desc("filename"));
+static llvm::cl::opt<std::string>
+    OutputFilename("o", llvm::cl::desc("Override output filename"),
+                   llvm::cl::value_desc("filename"));
 
-static cl::opt<std::string> DefaultDataLayout(
+static llvm::cl::opt<std::string> DefaultDataLayout(
     "default-data-layout",
-    cl::desc("data layout string to use if not specified by module"),
-    cl::value_desc("layout-string"), cl::init(""));
+    llvm::cl::desc("data layout string to use if not specified by module"),
+    llvm::cl::value_desc("layout-string"), llvm::cl::init(""));
 
 //===----------------------------------------------------------------------===//
 //                               Helper Methods
@@ -117,8 +119,8 @@
 static llvm::CodeGenOpt::Level GetCodeGenOptLevel() {
   // TODO: Is this the right thing to do here?
   if (Optimized)
-    return CodeGenOpt::Default;
-  return CodeGenOpt::None;
+    return llvm::CodeGenOpt::Default;
+  return llvm::CodeGenOpt::None;
 }
 
 // Returns the TargetMachine instance or zero if no triple is provided.
@@ -126,8 +128,8 @@
 getTargetMachine(llvm::Triple TheTriple, StringRef CPUStr,
                  StringRef FeaturesStr, const llvm::TargetOptions &Options) {
   std::string Error;
-  const auto *TheTarget =
-      llvm::TargetRegistry::lookupTarget(MArch, TheTriple, Error);
+  const auto *TheTarget = llvm::TargetRegistry::lookupTarget(
+      llvm::codegen::getMArch(), TheTriple, Error);
   // Some modules don't specify a triple, and this is okay.
   if (!TheTarget) {
     return nullptr;
@@ -135,12 +137,13 @@
 
   return TheTarget->createTargetMachine(
       TheTriple.getTriple(), CPUStr, FeaturesStr, Options,
-      Optional<Reloc::Model>(RelocModel), getCodeModel(), GetCodeGenOptLevel());
+      Optional<llvm::Reloc::Model>(llvm::codegen::getExplicitRelocModel()),
+      llvm::codegen::getExplicitCodeModel(), GetCodeGenOptLevel());
 }
 
 static void dumpOutput(llvm::Module &M, llvm::raw_ostream &os) {
   // For now just always dump assembly.
-  legacy::PassManager EmitPasses;
+  llvm::legacy::PassManager EmitPasses;
   EmitPasses.add(createPrintModulePass(os));
   EmitPasses.run(M);
 }
@@ -152,11 +155,12 @@
 // without being given the address of a function in the main executable).
 void anchorForGetMainExecutable() {}
 
-static inline void addPass(legacy::PassManagerBase &PM, Pass *P) {
+static inline void addPass(llvm::legacy::PassManagerBase &PM, llvm::Pass *P) {
   // Add the pass to the pass manager...
   PM.add(P);
   if (P->getPassID() == &SwiftAAWrapperPass::ID) {
-    PM.add(createExternalAAWrapperPass([](Pass &P, Function &, AAResults &AAR) {
+    PM.add(llvm::createExternalAAWrapperPass([](llvm::Pass &P, llvm::Function &,
+                                                llvm::AAResults &AAR) {
       if (auto *WrapperPass = P.getAnalysisIfAvailable<SwiftAAWrapperPass>())
         AAR.addAAResult(WrapperPass->getResult());
     }));
@@ -164,7 +168,7 @@
 
   // If we are verifying all of the intermediate steps, add the verifier...
   if (VerifyEach)
-    PM.add(createVerifierPass());
+    PM.add(llvm::createVerifierPass());
 }
 
 static void runSpecificPasses(StringRef Binary, llvm::Module *M,
@@ -172,7 +176,7 @@
                               llvm::Triple &ModuleTriple) {
   llvm::legacy::PassManager Passes;
   llvm::TargetLibraryInfoImpl TLII(ModuleTriple);
-  Passes.add(new TargetLibraryInfoWrapperPass(TLII));
+  Passes.add(new llvm::TargetLibraryInfoWrapperPass(TLII));
 
   const llvm::DataLayout &DL = M->getDataLayout();
   if (DL.isDefault() && !DefaultDataLayout.empty()) {
@@ -180,13 +184,13 @@
   }
 
   // Add internal analysis passes from the target machine.
-  Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()
-                                                     : TargetIRAnalysis()));
+  Passes.add(createTargetTransformInfoWrapperPass(
+      TM ? TM->getTargetIRAnalysis() : llvm::TargetIRAnalysis()));
 
   if (TM) {
     // FIXME: We should dyn_cast this when supported.
-    auto &LTM = static_cast<LLVMTargetMachine &>(*TM);
-    Pass *TPC = LTM.createPassConfig(Passes);
+    auto &LTM = static_cast<llvm::LLVMTargetMachine &>(*TM);
+    llvm::Pass *TPC = LTM.createPassConfig(Passes);
     Passes.add(TPC);
   }
 
@@ -195,8 +199,9 @@
     if (PassInfo->getNormalCtor())
       P = PassInfo->getNormalCtor()();
     else
-      errs() << Binary << ": cannot create pass: " << PassInfo->getPassName()
-             << "\n";
+      llvm::errs() << Binary
+                   << ": cannot create pass: " << PassInfo->getPassName()
+                   << "\n";
     if (P) {
       addPass(Passes, P);
     }
@@ -215,7 +220,7 @@
   INITIALIZE_LLVM();
 
   // Initialize passes
-  PassRegistry &Registry = *PassRegistry::getPassRegistry();
+  llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
   initializeCore(Registry);
   initializeScalarOpts(Registry);
   initializeObjCARCOpts(Registry);
@@ -252,16 +257,16 @@
 
   // Load the input module...
   auto LLVMContext = std::make_unique<llvm::LLVMContext>();
-  std::unique_ptr<Module> M =
+  std::unique_ptr<llvm::Module> M =
       parseIRFile(InputFilename, Err, *LLVMContext.get());
 
   if (!M) {
-    Err.print(argv[0], errs());
+    Err.print(argv[0], llvm::errs());
     return 1;
   }
 
-  if (verifyModule(*M, &errs())) {
-    errs() << argv[0] << ": " << InputFilename
+  if (verifyModule(*M, &llvm::errs())) {
+    llvm::errs() << argv[0] << ": " << InputFilename
            << ": error: input module is broken!\n";
     return 1;
   }
@@ -280,18 +285,19 @@
   Out.reset(
       new llvm::ToolOutputFile(OutputFilename, EC, llvm::sys::fs::F_None));
   if (EC) {
-    errs() << EC.message() << '\n';
+    llvm::errs() << EC.message() << '\n';
     return 1;
   }
 
   llvm::Triple ModuleTriple(M->getTargetTriple());
   std::string CPUStr, FeaturesStr;
   llvm::TargetMachine *Machine = nullptr;
-  const llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
+  const llvm::TargetOptions Options =
+      llvm::codegen::InitTargetOptionsFromCodeGenFlags();
 
   if (ModuleTriple.getArch()) {
-    CPUStr = getCPUStr();
-    FeaturesStr = getFeaturesStr();
+    CPUStr = llvm::codegen::getCPUStr();
+    FeaturesStr = llvm::codegen::getFeaturesStr();
     Machine = getTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options);
   }
 
@@ -299,7 +305,7 @@
 
   // Override function attributes based on CPUStr, FeaturesStr, and command line
   // flags.
-  setFunctionAttributes(CPUStr, FeaturesStr, *M);
+  llvm::codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M);
 
   if (Optimized) {
     IRGenOptions Opts;
diff --git a/tools/swift-reflection-dump/swift-reflection-dump.cpp b/tools/swift-reflection-dump/swift-reflection-dump.cpp
index 8846f44..ab6472d 100644
--- a/tools/swift-reflection-dump/swift-reflection-dump.cpp
+++ b/tools/swift-reflection-dump/swift-reflection-dump.cpp
@@ -583,25 +583,28 @@
 using ReflectionContextOwner
   = std::unique_ptr<void, void (*)(void*)>;
 
-template<typename Runtime>
-static std::pair<ReflectionContextOwner, TypeRefBuilder &>
-makeReflectionContextForMetadataReader(
-                                   std::shared_ptr<ObjectMemoryReader> reader) {
+struct ReflectionContextHolder {
+  ReflectionContextOwner Owner;
+  TypeRefBuilder &Builder;
+  ObjectMemoryReader &Reader;
+};
+
+template <typename Runtime>
+static ReflectionContextHolder makeReflectionContextForMetadataReader(
+    std::shared_ptr<ObjectMemoryReader> reader) {
   using ReflectionContext = ReflectionContext<Runtime>;
   auto context = new ReflectionContext(reader);
   auto &builder = context->getBuilder();
   for (unsigned i = 0, e = reader->getImages().size(); i < e; ++i) {
     context->addImage(reader->getImageStartAddress(i));
   }
-  return {ReflectionContextOwner(context,
-                                 [](void *x){ delete (ReflectionContext*)x; }),
-          builder};
+  return {ReflectionContextOwner(
+              context, [](void *x) { delete (ReflectionContext *)x; }),
+          builder, *reader};
 }
-                                          
 
-static std::pair<ReflectionContextOwner, TypeRefBuilder &>
-makeReflectionContextForObjectFiles(
-                          const std::vector<const ObjectFile *> &objectFiles) {
+static ReflectionContextHolder makeReflectionContextForObjectFiles(
+    const std::vector<const ObjectFile *> &objectFiles) {
   auto Reader = std::make_shared<ObjectMemoryReader>(objectFiles);
 
   uint8_t pointerSize;
@@ -651,7 +654,7 @@
   }
   
   auto context = makeReflectionContextForObjectFiles(ObjectFiles);
-  auto &builder = context.second;
+  auto &builder = context.Builder;
 
   switch (Action) {
   case ActionType::DumpReflectionSections:
@@ -679,7 +682,7 @@
       auto TypeRef = Result.getType();
 
       TypeRef->dump(file);
-      auto *TypeInfo = builder.getTypeConverter().getTypeInfo(TypeRef);
+      auto *TypeInfo = builder.getTypeConverter().getTypeInfo(TypeRef, nullptr);
       if (TypeInfo == nullptr) {
         fprintf(file, "Invalid lowering\n");
         continue;
diff --git a/unittests/AST/TestContext.cpp b/unittests/AST/TestContext.cpp
index 7b86295..174cf90 100644
--- a/unittests/AST/TestContext.cpp
+++ b/unittests/AST/TestContext.cpp
@@ -34,8 +34,8 @@
 }
 
 TestContext::TestContext(ShouldDeclareOptionalTypes optionals)
-    : Ctx(*ASTContext::get(LangOpts, TypeCheckerOpts, SearchPathOpts, SourceMgr,
-                           Diags)) {
+    : Ctx(*ASTContext::get(LangOpts, TypeCheckerOpts, SearchPathOpts,
+                           ClangImporterOpts, SourceMgr, Diags)) {
   registerParseRequestFunctions(Ctx.evaluator);
   registerTypeCheckerRequestFunctions(Ctx.evaluator);
   auto stdlibID = Ctx.getIdentifier(STDLIB_NAME);
diff --git a/unittests/AST/TestContext.h b/unittests/AST/TestContext.h
index 46aa8d9..328f7a5 100644
--- a/unittests/AST/TestContext.h
+++ b/unittests/AST/TestContext.h
@@ -17,6 +17,8 @@
 #include "swift/Basic/LangOptions.h"
 #include "swift/Basic/SourceManager.h"
 
+#include "llvm/Support/Host.h"
+
 namespace swift {
 namespace unittest {
 
@@ -29,6 +31,7 @@
   LangOptions LangOpts;
   TypeCheckerOptions TypeCheckerOpts;
   SearchPathOptions SearchPathOpts;
+  ClangImporterOptions ClangImporterOpts;
   SourceManager SourceMgr;
   DiagnosticEngine Diags;
 
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 0aa744d..5c6daa8 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -9,6 +9,7 @@
   add_subdirectory(ClangImporter)
   add_subdirectory(Driver)
   add_subdirectory(FrontendTool)
+  add_subdirectory(Localization)
   add_subdirectory(IDE)
   add_subdirectory(Parse)
   add_subdirectory(SwiftDemangle)
diff --git a/unittests/ClangImporter/ClangImporterTests.cpp b/unittests/ClangImporter/ClangImporterTests.cpp
index e353fba..94e46f4 100644
--- a/unittests/ClangImporter/ClangImporterTests.cpp
+++ b/unittests/ClangImporter/ClangImporterTests.cpp
@@ -5,7 +5,6 @@
 #include "swift/Basic/LangOptions.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/ClangImporter/ClangImporter.h"
-#include "swift/ClangImporter/ClangImporterOptions.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
@@ -75,8 +74,9 @@
   swift::SourceManager sourceMgr;
   swift::DiagnosticEngine diags(sourceMgr);
   std::unique_ptr<ASTContext> context(
-      ASTContext::get(langOpts, typeckOpts, searchPathOpts, sourceMgr, diags));
-  auto importer = ClangImporter::create(*context, options);
+      ASTContext::get(langOpts, typeckOpts, searchPathOpts, options,
+                      sourceMgr, diags));
+  auto importer = ClangImporter::create(*context);
 
   std::string PCH = createFilename(cache, "bridging.h.pch");
   ASSERT_FALSE(importer->canReadPCH(PCH));
diff --git a/unittests/FrontendTool/ModuleLoadingTests.cpp b/unittests/FrontendTool/ModuleLoadingTests.cpp
index 7185ffe..0d80267 100644
--- a/unittests/FrontendTool/ModuleLoadingTests.cpp
+++ b/unittests/FrontendTool/ModuleLoadingTests.cpp
@@ -98,8 +98,10 @@
     LangOptions langOpts;
     langOpts.Target = llvm::Triple(llvm::sys::getDefaultTargetTriple());
     SearchPathOptions searchPathOpts;
+    ClangImporterOptions clangImpOpts;
     auto ctx =
-        ASTContext::get(langOpts, typeckOpts, searchPathOpts, sourceMgr, diags);
+        ASTContext::get(langOpts, typeckOpts, searchPathOpts, clangImpOpts,
+                        sourceMgr, diags);
 
     auto loader = ModuleInterfaceLoader::create(
         *ctx, cacheDir, prebuiltCacheDir,
diff --git a/unittests/Localization/CMakeLists.txt b/unittests/Localization/CMakeLists.txt
new file mode 100644
index 0000000..618d892
--- /dev/null
+++ b/unittests/Localization/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_swift_unittest(swiftLocalizationTests
+  DefToYAMLConverterTests.cpp
+  SerializationTests.cpp)
+
+target_link_libraries(swiftLocalizationTests
+  PRIVATE
+    swiftLocalization)
+
+target_compile_definitions(swiftLocalizationTests PRIVATE
+  SWIFTLIB_DIR=\"${SWIFTLIB_DIR}\")
diff --git a/unittests/Localization/DefToYAMLConverterTests.cpp b/unittests/Localization/DefToYAMLConverterTests.cpp
new file mode 100644
index 0000000..1683537
--- /dev/null
+++ b/unittests/Localization/DefToYAMLConverterTests.cpp
@@ -0,0 +1,80 @@
+//===--- DefToYAMLConverterTests.cpp -------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#include "LocalizationTest.h"
+#include "swift/Localization/LocalizationFormat.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+#include <cstdlib>
+#include <random>
+#include <string>
+#include <system_error>
+
+using namespace swift;
+using namespace swift::diag;
+using namespace swift::unittests;
+
+static std::string getMainExecutablePath() {
+  llvm::StringRef libPath = llvm::sys::path::parent_path(SWIFTLIB_DIR);
+  llvm::SmallString<128> MainExecutablePath(libPath);
+  llvm::sys::path::remove_filename(MainExecutablePath); // Remove /lib
+  llvm::sys::path::remove_filename(MainExecutablePath); // Remove /.
+  return std::string(MainExecutablePath);
+}
+
+static std::string getDefaultLocalizationPath() {
+  llvm::SmallString<128> DefaultDiagnosticMessagesDir(getMainExecutablePath());
+  llvm::sys::path::append(DefaultDiagnosticMessagesDir, "share", "swift",
+                          "diagnostics");
+  return std::string(DefaultDiagnosticMessagesDir);
+}
+
+TEST_F(LocalizationTest, MissingLocalizationFiles) {
+  ASSERT_TRUE(llvm::sys::fs::exists(getDefaultLocalizationPath()));
+  llvm::SmallString<128> EnglishLocalization(getDefaultLocalizationPath());
+  llvm::sys::path::append(EnglishLocalization, "en");
+  llvm::sys::path::replace_extension(EnglishLocalization, ".yaml");
+  ASSERT_TRUE(llvm::sys::fs::exists(EnglishLocalization));
+  llvm::sys::path::replace_extension(EnglishLocalization, ".db");
+  ASSERT_TRUE(llvm::sys::fs::exists(EnglishLocalization));
+}
+
+TEST_F(LocalizationTest, ConverterTestMatchDiagnosticMessagesSequentially) {
+  YAMLLocalizationProducer yaml(YAMLPath);
+  yaml.forEachAvailable([](swift::DiagID id, llvm::StringRef translation) {
+    llvm::StringRef msg = diagnosticMessages[static_cast<uint32_t>(id)];
+    ASSERT_EQ(msg, translation);
+  });
+}
+
+TEST_F(LocalizationTest, ConverterTestMatchDiagnosticMessagesRandomly) {
+  YAMLLocalizationProducer yaml(YAMLPath);
+
+  std::random_device rd;
+  std::mt19937 gen(rd());
+  std::uniform_int_distribution<> distr(50, LocalDiagID::NumDiags);
+  unsigned numberOfQueries = distr(gen);
+  while (numberOfQueries--) {
+    unsigned randomNum = RandNumber(LocalDiagID::NumDiags);
+    DiagID randomId = static_cast<DiagID>(randomNum);
+    llvm::StringRef msg = diagnosticMessages[randomNum];
+    llvm::StringRef translation = yaml.getMessageOr(randomId, "");
+    ASSERT_EQ(msg, translation);
+  }
+}
diff --git a/unittests/Localization/LocalizationTest.h b/unittests/Localization/LocalizationTest.h
new file mode 100644
index 0000000..865f9980
--- /dev/null
+++ b/unittests/Localization/LocalizationTest.h
@@ -0,0 +1,98 @@
+//===--- LocalizationTest.h - Helper for setting up locale tests -*- C++-*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LOCALIZATION_TEST_H
+#define LOCALIZATION_TEST_H
+
+#include "swift/Localization/LocalizationFormat.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+#include <random>
+#include <string>
+#include <system_error>
+
+using namespace swift::diag;
+
+namespace swift {
+namespace unittests {
+
+enum LocalDiagID : uint32_t {
+#define DIAG(KIND, ID, Options, Text, Signature) ID,
+#include "swift/AST/DiagnosticsAll.def"
+  NumDiags
+};
+
+static constexpr const char *const diagnosticID[] = {
+#define DIAG(KIND, ID, Options, Text, Signature) #ID,
+#include "swift/AST/DiagnosticsAll.def"
+};
+
+static constexpr const char *const diagnosticMessages[] = {
+#define DIAG(KIND, ID, Options, Text, Signature) Text,
+#include "swift/AST/DiagnosticsAll.def"
+};
+
+struct LocalizationTest : public ::testing::Test {
+  std::string YAMLPath;
+
+  LocalizationTest() {
+    YAMLPath = std::string(createTemporaryFile("en", "yaml"));
+  }
+
+  void SetUp() override {
+    bool failed = convertDefIntoYAML(YAMLPath);
+    assert(!failed && "failed to generate a YAML file");
+  }
+
+  static std::string createTemporaryFile(std::string prefix,
+                                         std::string suffix) {
+    llvm::SmallString<128> tempFile;
+    std::error_code error =
+        llvm::sys::fs::createTemporaryFile(prefix, suffix, tempFile);
+    assert(!error);
+    llvm::sys::RemoveFileOnSignal(tempFile);
+    return std::string(tempFile);
+  }
+
+  /// Random number in [0,n)
+  unsigned RandNumber(unsigned n) { return unsigned(rand()) % n; }
+
+protected:
+  static bool convertDefIntoYAML(std::string outputPath) {
+    std::error_code error;
+    llvm::raw_fd_ostream OS(outputPath, error, llvm::sys::fs::F_None);
+    if (OS.has_error() || error)
+      return true;
+
+    llvm::ArrayRef<const char *> ids(diagnosticID, LocalDiagID::NumDiags);
+    llvm::ArrayRef<const char *> messages(diagnosticMessages,
+                                          LocalDiagID::NumDiags);
+
+    DefToYAMLConverter converter(ids, messages);
+    converter.convert(OS);
+
+    OS.flush();
+
+    return OS.has_error();
+  }
+};
+
+} // end namespace unittests
+} // end namespace swift
+
+#endif
diff --git a/unittests/Localization/SerializationTests.cpp b/unittests/Localization/SerializationTests.cpp
new file mode 100644
index 0000000..5eea0419
--- /dev/null
+++ b/unittests/Localization/SerializationTests.cpp
@@ -0,0 +1,113 @@
+//===--- LocalizationProducerTests.cpp -------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#include "LocalizationTest.h"
+#include "swift/Localization/LocalizationFormat.h"
+#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+#include <string>
+#include <random>
+
+using namespace swift::diag;
+using namespace swift::unittests;
+
+TEST_F(LocalizationTest, TestYAMLSerialization) {
+  YAMLLocalizationProducer yaml(YAMLPath);
+
+  auto dbFile = createTemporaryFile("en", "db");
+
+  // First, let's serialize English translations
+  {
+    SerializedLocalizationWriter writer;
+
+    yaml.forEachAvailable([&writer](swift::DiagID id, llvm::StringRef translation) {
+                            writer.insert(id, translation);
+                          });
+
+    ASSERT_FALSE(writer.emit(dbFile));
+  }
+
+  // Now, let's make sure that serialized version matches "source" YAML
+  auto dbContent = llvm::MemoryBuffer::getFile(dbFile);
+  ASSERT_TRUE(dbContent);
+
+  SerializedLocalizationProducer db(std::move(dbContent.get()));
+  yaml.forEachAvailable([&db](swift::DiagID id, llvm::StringRef translation) {
+    ASSERT_EQ(translation, db.getMessageOr(id, "<no-fallback>"));
+  });
+}
+
+TEST_F(LocalizationTest, TestSerializationOfEmptyFile) {
+  auto dbFile = createTemporaryFile("by", "db");
+  SerializedLocalizationWriter writer;
+  ASSERT_FALSE(writer.emit(dbFile));
+
+  YAMLLocalizationProducer yaml(YAMLPath);
+
+  // Reading of the empty `db` file should always return default message.
+  {
+    auto dbContent = llvm::MemoryBuffer::getFile(dbFile);
+    ASSERT_TRUE(dbContent);
+
+    SerializedLocalizationProducer db(std::move(dbContent.get()));
+    yaml.forEachAvailable([&db](swift::DiagID id, llvm::StringRef translation) {
+      ASSERT_EQ("<<<default-fallback>>>",
+                db.getMessageOr(id, "<<<default-fallback>>>"));
+    });
+  }
+}
+
+TEST_F(LocalizationTest, TestSerializationWithGaps) {
+  // Initially all of the messages are included.
+  llvm::SmallBitVector includedMessages(LocalDiagID::NumDiags, true);
+
+  // Let's punch some holes in the diagnostic content.
+  for (unsigned i = 0, n = 200; i != n; ++i) {
+    unsigned position = RandNumber(LocalDiagID::NumDiags);
+    includedMessages.flip(position);
+  }
+
+  YAMLLocalizationProducer yaml(YAMLPath);
+  auto dbFile = createTemporaryFile("en", "db");
+
+  {
+    SerializedLocalizationWriter writer;
+
+    yaml.forEachAvailable([&](swift::DiagID id, llvm::StringRef translation) {
+      if (includedMessages.test((unsigned)id))
+        writer.insert(id, translation);
+    });
+
+    ASSERT_FALSE(writer.emit(dbFile));
+  }
+
+
+  {
+    auto dbContent = llvm::MemoryBuffer::getFile(dbFile);
+    ASSERT_TRUE(dbContent);
+
+    SerializedLocalizationProducer db(std::move(dbContent.get()));
+    yaml.forEachAvailable([&](swift::DiagID id, llvm::StringRef translation) {
+      auto position = (unsigned)id;
+
+      std::string expectedMessage = includedMessages.test(position)
+                                        ? std::string(translation)
+                                        : "<<<default-fallback>>>";
+
+      ASSERT_EQ(expectedMessage, db.getMessageOr(id, "<<<default-fallback>>>"));
+    });
+  }
+}
diff --git a/userdocs/diagnostics/nominal-types.md b/userdocs/diagnostics/nominal-types.md
index a4a0853..bd3c553 100644
--- a/userdocs/diagnostics/nominal-types.md
+++ b/userdocs/diagnostics/nominal-types.md
@@ -1,6 +1,9 @@
-# Nominal types
-In Swift, a type is considered a nominal type if it is named.  In other words, it has been defined by declaring the type somewhere in code. Examples of nominal types include classes, structs and enums, all of which must be declared before using them. Nominal types are an important concept in Swift because they can be extended, explicitly initialized using the `MyType()` syntax, and may conform to protocols.
+# Nominal Types
 
-In contrast, non-nominal types have none of these capabilities. A non-nominal type is any type which is not nominal. They are sometimes called "structural types" because they are usually obtained by composing other types. Examples include function types like `(Int) -> (String)`, tuple types like `(Int, String)`, metatypes like `Int.Type`, and special types like `Any` and `AnyObject`.
+In Swift, a type is considered a nominal type if it has been explicitly named by a declaration somewhere in code. Examples of nominal types include classes, structures and enumerations. Nominal types are an important concept in Swift because they may conform to protocols, be extended, and have values created using the initializer syntax `MyType()`.
 
-Whether the name of a protocol refers to a nominal or non-nominal type depends on where it appears in code. When used in a declaration or extension like `extension MyProtocol { … }`, `MyProtocol` refers to a protocol type, which is nominal. This means that it may be extended and conform to protocols. However, when written as the type of a constant or variable, `MyProtocol` instead refers to a non-nominal, existential type. As a result, code like `let value: MyProtocol = MyProtocol()` is not allowed because `MyProtocol` refers to a non-nominal type in this context and cannot be explicitly initialized.
+In contrast, non-nominal types do not have these capabilities. Many are obtained by composing other types. Examples include function types like `(Int) -> (String)`, tuple types like `(Int, String)`, metatypes like `Int.Type`, and special types like `Any` and `AnyObject`.
+
+Since a protocol is named by a declaration in code, it may conform to (in other words, refine) other protocols and it may be extended. However, when written as the type of a constant or variable such as `let value: MyProtocol`, the name refers to a distinct, non-nominal existential type that provides a "box" for a value of any concrete type that conforms to the protocol. The existential type itself does not conform to any protocols and cannot be extended, and a value cannot be created using the initializer syntax `MyProtocol()`.
+
+For more on using existential types, see [Protocols as Types](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID275) in _The Swift Programming Language_.
\ No newline at end of file
diff --git a/userdocs/diagnostics/protocol-type-non-conformance.md b/userdocs/diagnostics/protocol-type-non-conformance.md
index 47cc951..1177146 100644
--- a/userdocs/diagnostics/protocol-type-non-conformance.md
+++ b/userdocs/diagnostics/protocol-type-non-conformance.md
@@ -1,46 +1,92 @@
-# Protocol type not conforming to itself
-Protocols in Swift may be used as types. Protocols as types are sometimes called existential types.
+# Protocol Types Cannot Conform to Protocols
 
+In Swift, a protocol that does not have `Self` or associated type requirements can be used as a type. You can use a variable or constant of a protocol type, also called an __existential type__, to hold a value of any conforming type:
 
 ```swift 
-protocol P {}
+protocol Animal {
+    func makeNoise()
+    static var species: String { get }
+}
+struct Dog: Animal {
+    func makeNoise() { print("Woof") }
+    static var species: String = "Canus familiaris"
+}
+struct Cat: Animal {
+    func makeNoise() { print("Meow") }
+    static var species: String = "Felis catus"
+}
 
-struct S: P {}
-
-var s: P = S() // This creates existential type because the protocol P is used as a type
+var animal: Animal // `Animal` is used here as a type.
+animal = Dog()
+animal.makeNoise() // Prints "Woof".
+animal = Cat()
+animal.makeNoise() // Prints "Meow".
 ```
 
-However, a protocol type does not conform to protocols - not even the protocol itself. 
-Allowing existential types to conform to protocols is unsound. For protocols with static method, initializer, or associated type requirements, the implementation of these requirements cannot be accessed from the protocol type - accessing these kinds of requirements must be done using a concrete type.
-
-Let's walk through the example below:
+Notice that it is possible to invoke the method `makeNoise()` on a value of type `Animal`, just as it is possible to do so on a value of concrete type `Dog` or `Cat`. However, the static property `species` is not available for the existential type:
 
 ```swift
-protocol Word: Hashable {
-    var word: String { get }
-}
-
-struct Singular: Word {
-    var word: String
-}
-
-struct Plural: Word {
-    var word: String
-}
-
-let singularWord = Singular(word: "mango")
-let pluralWord = Plural(word: "mangoes")
-
-let wordPairDict: [Word: Word] = [singularWord: pluralWord] // Error
+print(Dog.species)    // Prints "Canus familiaris"
+print(Cat.species)    // Prints "Felis catus"
+print(Animal.species) // error: static member 'species' cannot be used...
 ```
 
-One workaround to fix this problem is to use type erasure for the protocol `Word`. Think of type erasure as a way to hide an object's type. Since `Word` is of type `Hashable`, we already have `AnyHashable` type erasure available in the standard library which we can easily use here.
+Since a type conforms to a protocol only when it satisfies _all_ of that protocol's requirements, the existential type `Animal` does not conform to the protocol `Animal` because it cannot satisfy the protocol's requirement for the static property `species`:
 
-```swift 
-// The fix
-let wordPairDict: [AnyHashable: AnyHashable] = [singularWord: pluralWord]
+```swift
+func declareAnimalSpecies<T: Animal>(_ animal: T) {
+    animal.makeNoise()
+    print("My species is known as \(T.species)")
+}
+
+let dog = Dog()
+declareAnimalSpecies(dog)
+// Prints:
+// "Woof"
+// "My species is known as Canus familiaris"
+declareAnimalSpecies(animal)
+// error: protocol type 'Animal' cannot conform to 'Animal'...
 ```
 
-# Exceptions
-`@objc` protocol type with no static requirements however do conform to its own protocol. Another exception is the `Error` Swift protocol.
+In general, any initializers, static members, and associated types required by a protocol can be used only via conforming concrete types. Although Swift allows a protocol that requires initializers or static members to be used as a type, that type _does not and cannot_ conform to the protocol itself.
 
+Currently, even if a protocol `P` requires no initializers or static members, the existential type `P` does not conform to `P` (with exceptions below). This restriction allows library authors to add such requirements (initializers or static members) to an existing protocol without breaking their users' source code.
+
+## Exceptions
+
+When used as a type, the Swift protocol `Error` conforms to itself; `@objc` protocols with no static requirements can also be used as types that conform to themselves.
+
+## Alternatives
+
+Concrete types that _do_ conform to protocols can provide functionality similar to that of existential types. For example, the standard library provides the `AnyHashable` type for `Hashable` values. Manual implementation of such __type erasure__ can require specific knowledge of the semantic requirements for each protocol involved and is beyond the scope of this discussion.
+
+In certain scenarios, you might avoid any need for manual type erasure by reworking generic APIs to use existential types instead:
+
+```swift
+func declareAnimalSpeciesDynamically(_ animal: Animal) {
+    animal.makeNoise()
+    print("My species is known as \(type(of: animal).species)")
+}
+
+declareAnimalSpeciesDynamically(animal)
+// Prints:
+// "Meow"
+// "My species is known as Felis catus"
+```
+
+(Note that there is a distinction between the _static_ type of a value as given by the generic parameter `T` and the _dynamic_ type of a value obtained by invoking `type(of:)`. For example, the static type of `animal` is `Animal`, while its dynamic type is `Cat`. Therefore, the two functions `declareAnimalSpecies(_:)` and `declareAnimalSpeciesDynamically(_:)` are not exact replacements of each other.)
+
+The same technique might be applicable to members of generic types:
+
+```swift
+// Instead of...
+struct Habitat<T: Animal> {
+    var animal: T
+}
+// ...consider:
+struct Habitat {
+    var animal: Animal
+}
+```
+
+For more on using existential types, see [Protocols as Types](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID275) in _The Swift Programming Language_.
diff --git a/userdocs/diagnostics/trailing-closure-matching.md b/userdocs/diagnostics/trailing-closure-matching.md
index d373191..f1ce7c0 100644
--- a/userdocs/diagnostics/trailing-closure-matching.md
+++ b/userdocs/diagnostics/trailing-closure-matching.md
@@ -1,102 +1,110 @@
 # Argument Matching for Trailing Closures
 
-In Swift, calling a function with one or more trailing closure arguments requires the label of the first trailing closure argument to be omitted. As a result, the compiler must consider additional context when determining which function parameter the trailing closure should satisfy.
-
-Before Swift 5.3, the compiler used a backward scanning rule to match a trailing closure to a function parameter. Starting from the end of the parameter list, it moved backwards until finding a parameter which could accept a trailing closure argument (a function type, unconstrained generic parameter, `Any`, etc.). This could sometimes lead to unexpected behavior. Consider the following example:
+Where trailing closures are used to pass one or more arguments to a function, the argument label for the first trailing closure is always omitted:
 
 ```swift
 func animate(
   withDuration duration: Double, 
   animations: () -> Void, 
   completion: (() -> Void)? = nil
-) {}
+) { /* ... */ }
 
-// OK
-animate(withDuration: 0.3, animations: { /* Animate Something */ }) {
-  // Done!
-}
-
-// error: missing argument for parameter 'animations' in call
-animate(withDuration: 0.3) {
-  // Animate Something
+animate(withDuration: 0.3) /* `animations:` is unwritten. */ {
+  // Animate something.
+} completion: {
+  // Completion handler.
 }
 ```
 
-The second call to `animate` results in a compiler error because the backward scanning rule matches the trailing closure to the `completion` parameter instead of `animations`.
-
-Beginning in Swift 5.3, the compiler uses a new, forward scanning rule to match trailing closures to function parameters. When matching function arguments to parameters, the forward scan first matches all non-trailing arguments from left-to-right. Then, it continues matching trailing closures in a left-to-right manner. This leads to more predictable and easy-to-understand behavior in many situations. With the new rule, the example above now works as expected without any modifications:
+Sometimes, an unlabeled trailing closure argument can be matched to more than one function parameter. Before Swift 5.3, the compiler would use a __backward scanning rule__ to match the unlabeled trailing closure, scanning backwards from the end of the parameter list until finding a parameter that can accept a closure argument (a function type, unconstrained generic type, `Any`, etc.):
 
 ```swift
-// Remains valid
-animate(withDuration: 0.3, animations: { /* Animate Something */ }) {
-  // Done!
-}
-
-// Also OK!
 animate(withDuration: 0.3) {
-  // Animate Something
+  // Animate something?
+  // The compiler matches this to the `completion` parameter.
 }
+// error: missing argument for parameter 'animations' in call
 ```
 
-When scanning forwards to match an unlabeled trailing closure argument, the compiler may sometimes need to "skip over" defaulted and variadic arguments. The new rule will skip any parameter that does not structurally resemble a function type. This allows writing a modified version of the above example where `withDuration` also has a default argument value:
+We encounter a compiler error in this example because the backward scanning rule matches the trailing closure to the `completion` parameter instead of the `animations` parameter, even though `completion` has a default value while `animations` does not.
+
+Swift 5.3 introduces a new __forward scanning rule__, which matches trailing closures to function parameters from left to right (after matching non-trailing arguments). This leads to more predictable and easy-to-understand behavior in many situations. With the new rule, the unlabeled closure in the example above is matched to the `animations` parameter, just as most users would expect:
+
+```swift
+animate(withDuration: 0.3) {
+  // Animate something.
+} // `completion` has the default value `nil`.
+```
+
+When scanning forwards to match an unlabeled trailing closure argument, the compiler will skip any parameter that does not __structurally resemble__ a function type and also apply a __heuristic__ to skip parameters that do not require an argument in favor of a subsequent parameter that does (see below). These rules make possible the ergonomic use of a modified version of the API given in the example above, where `withDuration` has a default value:
 
 ```swift
 func animate(
   withDuration duration: Double = 1.0, 
   animations: () -> Void, 
   completion: (() -> Void)? = nil
-) {}
+) { /* ... */ }
 
-// Allowed! The forward scanning rule skips `withDuration` because it does not
-// structurally resemble a function type.
 animate {
-  // Animate Something
+  // Animate something.
+  //
+  // The closure is not matched to `withDuration` but to `animations` because
+  // the first parameter doesn't structurally resemble a function type.
+  //
+  // If, in place of `withDuration`, there is a parameter with a default value
+  // that does structurally resemble a function type, the closure would still be
+  // matched to `animations` because it requires an argument while the first
+  // parameter does not.
 }
 ```
 
+For source compatibility in Swift 5, the compiler will attempt to apply *both* the new forward scanning rule and the old backward scanning rule when it encounters a function call with a single trailing closure. If the forward and backward scans produce *different valid* matches of arguments to parameters, the compiler will prefer the result of the backward scanning rule and produce a warning. To silence this warning, rewrite the function call to label the argument explicitly without using trailing closure syntax.
+
+## Structural Resemblance to a Function Type
+
 A parameter structurally resembles a function type if both of the following are true:
 
-- The parameter is not `inout`
-- The adjusted type of the parameter is a function type
+- the parameter is not `inout`, and
+- the __adjusted type__ of the parameter is a function type.
 
 The adjusted type of the parameter is the parameter's type as it appears in the function declaration, looking through any type aliases, and performing three additional adjustments:
 
-- If the parameter is an `@autoclosure`, using the result type of the parameter's declared (function) type, before performing the second adjustment.
-- If the parameter is variadic, looking at the base element type.
-- Removing all outer "optional" types.
+1. If the parameter is an `@autoclosure`, use the result type of the parameter's declared (function) type before performing the second adjustment.
+2. If the parameter is variadic, look at the base element type.
+3. Remove all outer "optional" types.
 
-To maintain source compatibility with code that was written before Swift 5.3, the forward scanning rule applies an additional heuristic when matching trailing closure arguments. If,
+## Heuristic for Skipping Parameters
+
+To maintain source compatibility, the forward scanning rule applies an additional heuristic when matching trailing closure arguments. If:
 
 - the parameter that would match an unlabeled trailing closure argument according to the forward scanning rule does not require an argument (because it is variadic or has a default argument), _and_
-- there are parameters _following_ that parameter that _do_ require an argument, which appear before the first parameter whose label matches that of the _next_ trailing closure (if any)
+- there are parameters _following_ that parameter that _do_ require an argument, which appear before the first parameter whose label matches that of the _next_ trailing closure (if any),
 
-then the compiler does not match the unlabeled trailing closure to that parameter. Instead, it skips it and examines the next parameter to see if that should be matched against the unlabeled trailing closure. This can be seen in the following example:
+then the compiler does not match the unlabeled trailing closure to that parameter. Instead, it examines the next parameter to see if that should be matched to the unlabeled trailing closure, as in the following example:
 
 ```swift
 func showAlert(
   message: String,
   onPresentation: (() ->  Void)? = nil,
   onDismissal: () -> Void
-) {}
+) { /* ... */ }
 
-// The unlabeled trailing closure matches `onDismissal` because `onPresentation`
-// does not require an argument, but `onDismissal` does and there are no other
-// trailing closures which could match it.
+// `onPresentation` does not require an argument, but `onDismissal` does, and
+// there is no subsequent trailing closure labeled `onDismissal`.
+// Therefore, the unlabeled trailing closure is matched to `onDismissal`.
 showAlert(message: "Hello, World!") {
-  // On dismissal action
+  // On dismissal action.
 }
 
-// The unlabeled trailing closure matches `onPresentation` because although
-// `onPresentation` does not require an argument, there are no parameters
-// following it which require an argument and appear before the parameter
-// whose label matches the next trailing closure argument (`onDismissal`).
+// Although `onPresentation` does not require an argument, there are no
+// subsequent parameters that require an argument before the parameter whose
+// label matches the next trailing closure (`onDismissal`).
+// Therefore, the unlabeled trailing closure is matched to `onPresentation`.
 showAlert(message: "Hello, World!") {
-  // On presentation action
+  // On presentation action.
 } onDismissal: {
-  // On dismissal action
+  // On dismissal action.
 }
 ```
 
-Additionally, the Swift 5 compiler will attempt to apply both the new forward scanning rule and the old backward scanning rule when it encounters a call with a single trailing closure. If the forward and backward scans produce *different* valid assignments of arguments to parameters, the compiler will prefer the result of the backward scanning rule and produce a warning.
-
 To learn more about argument matching for trailing closures, see [Swift Evolution Proposal SE-0286](https://github.com/apple/swift-evolution/blob/master/proposals/0286-forward-scan-trailing-closures.md).
diff --git a/utils/build-presets.ini b/utils/build-presets.ini
index b1fe751..18dba19 100644
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -1212,6 +1212,9 @@
 
 dash-dash
 
+# Cross compile for Apple Silicon
+cross-compile-hosts=macosx-arm64
+
 lldb-no-debugserver
 lldb-use-system-debugserver
 lldb-build-type=Release
@@ -1277,6 +1280,7 @@
 darwin-toolchain-name=%(darwin_toolchain_xctoolchain_name)s
 darwin-toolchain-version=%(darwin_toolchain_version)s
 darwin-toolchain-alias=%(darwin_toolchain_alias)s
+darwin-toolchain-require-use-os-runtime=0
 
 [preset: mixin_osx_package_test]
 build-subdir=buildbot_osx
@@ -1296,6 +1300,8 @@
 # Path to the .tar.gz package we would create.
 installable-package=%(installable_package)s
 
+[preset: mixin_osx_package,use_os_runtime]:
+darwin-toolchain-require-use-os-runtime=1
 
 [preset: buildbot_osx_package]
 mixin-preset=
@@ -1306,6 +1312,11 @@
 # SKIP LLDB TESTS (67923799)
 skip-test-lldb
 
+[preset: buildbot_osx_package,use_os_runtime]
+mixin-preset=
+    buildbot_osx_package
+    mixin_osx_package,use_os_runtime
+
 [preset: buildbot_osx_package,no_assertions]
 mixin-preset=
     mixin_osx_package_base
@@ -1315,12 +1326,20 @@
 
 no-assertions
 
+[preset: buildbot_osx_package,no_assertions,use_os_runtime]
+mixin-preset=
+    buildbot_osx_package,no_assertions
+    mixin_osx_package,use_os_runtime
 
 [preset: buildbot_osx_package,no_assertions,lto]
 mixin-preset=buildbot_osx_package,no_assertions
 
 lto
 
+[preset: buildbot_osx_package,no_assertions,lto,use_os_runtime]
+mixin-preset=
+    buildbot_osx_package,no_assertions,lto
+    mixin_osx_package,use_os_runtime
 
 [preset: buildbot_osx_package,no_assertions,no_test]
 mixin-preset=
@@ -1339,6 +1358,10 @@
 skip-test-skstresstester
 skip-test-swiftevolve
 
+[preset: buildbot_osx_package,no_assertions,no_test,use_os_runtime]
+mixin-preset=
+    buildbot_osx_package,no_assertions,no_test
+    mixin_osx_package,use_os_runtime
 
 # Debug version of the compilers, release version of the stdlib.
 [preset: buildbot_osx_package,tools=DA,stdlib=R]
@@ -1352,6 +1375,11 @@
 debug-swift
 no-swift-stdlib-assertions
 
+[preset: buildbot_osx_package,tools=DA,stdlib=R,use_os_runtime]
+mixin-preset=
+    buildbot_osx_package,tools=DA,stdlib=R
+    mixin_osx_package,use_os_runtime
+
 [preset: mixin_buildbot_osx_package,no_test]
 skip-test-swift
 skip-test-swiftpm
@@ -1370,6 +1398,14 @@
     buildbot_osx_package
     mixin_buildbot_osx_package,no_test
 
+# macOS package without test that when linked against uses the OS runtime
+# instead of the toolchain runtime.
+[preset: buildbot_osx_package,no_test,use_os_runtime]
+mixin-preset=
+    buildbot_osx_package
+    mixin_buildbot_osx_package,no_test
+    mixin_osx_package,use_os_runtime
+
 #===------------------------------------------------------------------------===#
 # LLDB build configurations
 #
diff --git a/utils/build-script b/utils/build-script
index 10ee8f7..18bbe73 100755
--- a/utils/build-script
+++ b/utils/build-script
@@ -942,8 +942,8 @@
             for product_class in impl_product_classes:
                 self._execute_install_action(host_target, product_class)
 
-        # Lipo...
-        self._execute_merged_host_lipo_action()
+        # Core Lipo...
+        self._execute_merged_host_lipo_core_action()
 
         # Non-build-script-impl products...
         # Note: currently only supports building for the host.
@@ -987,6 +987,9 @@
         for host_target in all_hosts:
             self._execute_package_action(host_target)
 
+        # Lipo...
+        self._execute_merged_host_lipo_action()
+
     def _execute_build_action(self, host_target, product_class):
         action_name = "{}-{}-build".format(host_target.name,
                                            product_class.product_name())
@@ -1013,6 +1016,9 @@
     def _execute_merged_host_lipo_action(self):
         self._execute_action("merged-hosts-lipo")
 
+    def _execute_merged_host_lipo_core_action(self):
+        self._execute_action("merged-hosts-lipo-core")
+
     def _execute_action(self, action_name):
         shell.call_without_sleeping(
             [BUILD_SCRIPT_IMPL_PATH] + self.impl_args +
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 4c4d499..19b92b5 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -114,6 +114,7 @@
     darwin-toolchain-installer-package            ""                "The path to installer pkg"
     darwin-toolchain-name                         ""                "Directory name for xctoolchain"
     darwin-toolchain-version                      ""                "Version for xctoolchain info plist and installer pkg"
+    darwin-toolchain-require-use-os-runtime       "0"               "When setting up a plist for a toolchain, require the users of the toolchain to link against the OS instead of the packaged toolchain runtime. 0 for false, 1 for true"
     darwin-xcrun-toolchain                        "default"         "the name of the toolchain to use on Darwin"
 
     ## Build Types for Components
@@ -424,6 +425,7 @@
     swift_cmake_options=()
     cmark_cmake_options=()
     lldb_cmake_options=()
+    llbuild_cmake_options=()
     SWIFT_HOST_VARIANT=
     SWIFT_HOST_VARIANT_SDK=
     SWIFT_HOST_VARIANT_ARCH=
@@ -645,6 +647,7 @@
                 -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${host})"
                 -DCMAKE_OSX_SYSROOT:PATH="${cmake_os_sysroot}"
                 -DCMAKE_OSX_DEPLOYMENT_TARGET="${cmake_osx_deployment_target}"
+                -DCMAKE_OSX_ARCHITECTURES="${architecture}"
             )
             llvm_cmake_options=(
                 -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING="${cmake_osx_deployment_target}"
@@ -654,6 +657,7 @@
                 -DCOMPILER_RT_ENABLE_TVOS:BOOL=FALSE
                 -DSANITIZER_MIN_OSX_VERSION="${cmake_osx_deployment_target}"
                 -DLLVM_ENABLE_MODULES:BOOL="$(true_false ${LLVM_ENABLE_MODULES})"
+                -DCMAKE_OSX_ARCHITECTURES="${architecture}"
             )
             if [[ $(is_llvm_lto_enabled) == "TRUE" ]]; then
                 llvm_cmake_options+=(
@@ -685,6 +689,10 @@
 
             lldb_cmake_options+=(
                 -DCMAKE_OSX_SYSROOT:PATH="${cmake_os_sysroot}"
+                -DCMAKE_OSX_ARCHITECTURES="${architecture}"
+            )
+            llbuild_cmake_options+=(
+                -DCMAKE_OSX_ARCHITECTURES="${architecture}"
             )
             ;;
     esac
@@ -1549,13 +1557,14 @@
                     # build of Swift depend on these for building and testing.
                     build_targets=(llvm-tblgen clang-resource-headers intrinsics_gen clang-tablegen-targets)
                     # If we are not performing a toolchain only build, then we
-                    # also want to include FileCheck and not for testing
+                    # also want to include FileCheck, not, llvm-nm for testing
                     # purposes.
                     if [[ ! "${BUILD_TOOLCHAIN_ONLY}" ]] ; then
                       build_targets=(
                           "${build_targets[@]}"
                           FileCheck
                           not
+                          llvm-nm
                       )
                     fi
                 fi
@@ -1578,6 +1587,8 @@
                     "${cmake_options[@]}"
                     -DCMAKE_C_FLAGS="$(llvm_c_flags ${host})"
                     -DCMAKE_CXX_FLAGS="$(llvm_c_flags ${host})"
+                    -DCMAKE_C_FLAGS_RELWITHDEBINFO="-O2 -DNDEBUG"
+                    -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-O2 -DNDEBUG"
                     -DCMAKE_BUILD_TYPE:STRING="${LLVM_BUILD_TYPE}"
                     -DLLVM_TOOL_SWIFT_BUILD:BOOL=NO
                     -DLLVM_TOOL_LLD_BUILD:BOOL=TRUE
@@ -1943,6 +1954,7 @@
                     DOTEST_EXTRA="${DOTEST_EXTRA} -L${FOUNDATION_BUILD_DIR}/Sources/Foundation"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -L${FOUNDATION_BUILD_DIR}/Sources/FoundationNetworking"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -L${FOUNDATION_BUILD_DIR}/Sources/FoundationXML"
+                    DOTEST_EXTRA="${DOTEST_EXTRA} -L${FOUNDATION_BUILD_DIR}/lib"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${LIBDISPATCH_BUILD_DIR}"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${LIBDISPATCH_BUILD_DIR}/src"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${FOUNDATION_BUILD_DIR}"
@@ -1950,6 +1962,7 @@
                     DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${FOUNDATION_BUILD_DIR}/Sources/Foundation"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${FOUNDATION_BUILD_DIR}/Sources/FoundationNetworking"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${FOUNDATION_BUILD_DIR}/Sources/FoundationXML"
+                    DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${FOUNDATION_BUILD_DIR}/lib"
                 fi
 
                 # Watchpoint testing is currently disabled: see rdar://38566150.
@@ -2022,6 +2035,7 @@
             llbuild)
                 cmake_options=(
                     "${cmake_options[@]}"
+                    "${llbuild_cmake_options[@]}"
 
                     -DCMAKE_BUILD_TYPE:STRING="${LLBUILD_BUILD_TYPE}"
                     -DCMAKE_C_COMPILER:PATH="${CLANG_BIN}/clang"
@@ -3028,11 +3042,7 @@
         local host_install_destdir="$(get_host_install_destdir ${host})"
         local host_install_prefix="$(get_host_install_prefix ${host})"
 
-        if [[ $(has_cross_compile_hosts) ]]; then
-            package_for_host="${INSTALLABLE_PACKAGE}-${host}"
-        else
-            package_for_host="${INSTALLABLE_PACKAGE}"
-        fi
+        package_for_host="${INSTALLABLE_PACKAGE}"
 
         echo "--- Creating installable package ---"
         echo "-- Package file: ${package_for_host} --"
@@ -3050,6 +3060,11 @@
           COMPATIBILITY_VERSION_DISPLAY_STRING="Xcode 8.0"
           DARWIN_TOOLCHAIN_CREATED_DATE="$(date -u +'%a %b %d %T GMT %Y')"
 
+          SWIFT_USE_DEVELOPMENT_TOOLCHAIN_RUNTIME="YES"
+          if [[ "${DARWIN_TOOLCHAIN_REQUIRE_USE_OS_RUNTIME}" -eq "1" ]]; then
+              SWIFT_USE_DEVELOPMENT_TOOLCHAIN_RUNTIME="NO"
+          fi
+
           echo "-- Removing: ${DARWIN_TOOLCHAIN_INFO_PLIST}"
           call rm -f ${DARWIN_TOOLCHAIN_INFO_PLIST}
 
@@ -3068,7 +3083,7 @@
           call ${PLISTBUDDY_BIN} -c "Add OverrideBuildSettings:SWIFT_DISABLE_REQUIRED_ARCLITE string 'YES'" "${DARWIN_TOOLCHAIN_INFO_PLIST}"
           call ${PLISTBUDDY_BIN} -c "Add OverrideBuildSettings:SWIFT_LINK_OBJC_RUNTIME string 'YES'" "${DARWIN_TOOLCHAIN_INFO_PLIST}"
           call ${PLISTBUDDY_BIN} -c "Add OverrideBuildSettings:SWIFT_DEVELOPMENT_TOOLCHAIN string 'YES'" "${DARWIN_TOOLCHAIN_INFO_PLIST}"
-          call ${PLISTBUDDY_BIN} -c "Add OverrideBuildSettings:SWIFT_USE_DEVELOPMENT_TOOLCHAIN_RUNTIME string 'YES'" "${DARWIN_TOOLCHAIN_INFO_PLIST}"
+          call ${PLISTBUDDY_BIN} -c "Add OverrideBuildSettings:SWIFT_USE_DEVELOPMENT_TOOLCHAIN_RUNTIME string '${SWIFT_USE_DEVELOPMENT_TOOLCHAIN_RUNTIME}'" "${DARWIN_TOOLCHAIN_INFO_PLIST}"
 
           call chmod a+r "${DARWIN_TOOLCHAIN_INFO_PLIST}"
 
@@ -3102,7 +3117,7 @@
             PKG_TESTS_SANDBOX_PARENT="$(build_directory swift_package_sandbox_${host} none)"
             PKG_TESTS_TEMPS="${PKG_TESTS_SANDBOX_PARENT}"/"tests"
 
-            if [[ "${host}" == "macosx-"* ]] ; then
+            if [[ "${host}" == "macosx-"* ]] || [[ "${host}" == "merged-hosts" ]]; then
                 PKG_TESTS_SANDBOX="${PKG_TESTS_SANDBOX_PARENT}"/"${TOOLCHAIN_PREFIX}"
             else # Linux
                 PKG_TESTS_SANDBOX="${PKG_TESTS_SANDBOX_PARENT}"
@@ -3116,8 +3131,11 @@
             with_pushd "${PKG_TESTS_SANDBOX_PARENT}" \
                 call tar xzf "${package_for_host}"
 
+            if python -c "import psutil" ; then
+              TIMEOUT_ARGS=--timeout=1200 # 20 minutes
+            fi
             with_pushd "${PKG_TESTS_SOURCE_DIR}" \
-                call python "${LIT_EXECUTABLE_PATH}" . -sv --param package-path="${PKG_TESTS_SANDBOX}" --param test-exec-root="${PKG_TESTS_TEMPS}" --param llvm-bin-dir="${LLVM_BIN_DIR}"
+                call python "${LIT_EXECUTABLE_PATH}" . -sv --param package-path="${PKG_TESTS_SANDBOX}" --param test-exec-root="${PKG_TESTS_TEMPS}" --param llvm-bin-dir="${LLVM_BIN_DIR}" ${TIMEOUT_ARGS}
         fi
     fi
 }
@@ -3143,7 +3161,7 @@
     # This is from multiple hosts; Which host should we say it is?
     # Let's call it 'merged-hosts' so that we can identify it.
 
-    if [[ $(should_execute_action "${mergedHost}-lipo") ]]; then
+    if [[ $(should_execute_action "${mergedHost}-lipo") || $(should_execute_action "${mergedHost}-lipo-core") ]]; then
         # Allow passing lipo with --host-lipo
         if [[ -z "${HOST_LIPO}" ]] ; then
             LIPO_PATH=$(xcrun_find_tool lipo)
@@ -3152,8 +3170,10 @@
         fi
         call "${SWIFT_SOURCE_DIR}"/utils/recursive-lipo --lipo=${LIPO_PATH} --copy-subdirs="$(get_host_install_prefix ${host})lib/swift $(get_host_install_prefix ${host})lib/swift_static" --destination="$(get_host_install_destdir ${mergedHost})" ${LIPO_SRC_DIRS[@]}
 
-        # Build and test the lipo-ed package.
-        build_and_test_installable_package ${mergedHost}
+        if [[ $(should_execute_action "${mergedHost}-lipo") ]]; then
+            # Build and test the lipo-ed package.
+            build_and_test_installable_package ${mergedHost}
+        fi
     fi
 fi
 # END
diff --git a/utils/build-toolchain b/utils/build-toolchain
index 8188482..7768339 100755
--- a/utils/build-toolchain
+++ b/utils/build-toolchain
@@ -35,6 +35,9 @@
   echo "--preset-prefix"
   echo "Customize the preset invoked by prepending a prefix"
   echo ""
+  echo "--use-os-runtime"
+  echo "Require this toolchain to link against against the OS runtime rather than the toolchains packaged runtime"
+  echo ""
 }
 
 RESULT_DIR=$PWD
@@ -46,6 +49,8 @@
 BUNDLE_PREFIX=
 PRESET_FILE_FLAGS=
 PRESET_PREFIX=
+PRESET_SUFFIX=
+
 case $(uname -s) in
   Darwin)
     SWIFT_PACKAGE=buildbot_osx_package,no_test
@@ -86,6 +91,9 @@
       shift
       PRESET_PREFIX="$1"
   ;;
+    --use-os-runtime)
+      PRESET_SUFFIX=",use_os_runtime"
+  ;;
   -h|--help)
     usage
     exit 0
@@ -133,7 +141,8 @@
 DISTCC_FLAG="${DISTCC_FLAG}"
 PRESET_FILE_FLAGS="${PRESET_FILE_FLAGS}"
 
-./utils/build-script ${DRY_RUN} ${DISTCC_FLAG} ${PRESET_FILE_FLAGS} --preset="${PRESET_PREFIX}${SWIFT_PACKAGE}" \
+./utils/build-script ${DRY_RUN} ${DISTCC_FLAG} ${PRESET_FILE_FLAGS} \
+        --preset="${PRESET_PREFIX}${SWIFT_PACKAGE}${PRESET_SUFFIX}" \
         install_destdir="${SWIFT_INSTALL_DIR}" \
         installable_package="${SWIFT_INSTALLABLE_PACKAGE}" \
         install_toolchain_dir="${SWIFT_TOOLCHAIN_DIR}" \
@@ -144,4 +153,5 @@
         darwin_toolchain_display_name_short="${DISPLAY_NAME_SHORT}" \
         darwin_toolchain_xctoolchain_name="${TOOLCHAIN_NAME}" \
         darwin_toolchain_version="${TOOLCHAIN_VERSION}" \
-        darwin_toolchain_alias="Local"
+        darwin_toolchain_alias="Local" \
+        darwin_toolchain_require_use_os_runtime="${REQUIRE_USE_OS_RUNTIME}"
diff --git a/utils/build-windows-rebranch.bat b/utils/build-windows-rebranch.bat
deleted file mode 100644
index feb14fe..0000000
--- a/utils/build-windows-rebranch.bat
+++ /dev/null
@@ -1,349 +0,0 @@
-:: build-windows.bat
-::
-:: This source file is part of the Swift.org open source project
-::
-:: Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
-:: Licensed under Apache License v2.0 with Runtime Library Exception
-::
-:: See https://swift.org/LICENSE.txt for license information
-:: See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-
-:: REQUIRED ENVIRONMENT VARIABLES
-:: This script requires to be executed inside one Visual Studio command line,
-:: in order for many of the tools and environment variables to be available.
-:: Additionally, it needs the following variables:
-:: - CMAKE_BUILD_TYPE: Kind of build: Release, RelWithDebInfo, Debug.
-:: - PYTHON_HOME: The Python installation directory.
-
-:: REQUIRED PERMISSIONS
-:: Practically, it is easier to be in the Adminstrators group to run the
-:: script, but it should be possible to execute as a normal user.
-:: The user will need permission to write files into the Windows SDK and the
-:: VisualC++ folder.
-
-:: @echo off
-
-setlocal enableextensions enabledelayedexpansion
-
-set icu_version_major=64
-set icu_version_minor=2
-set icu_version=%icu_version_major%_%icu_version_minor%
-set icu_version_dashed=%icu_version_major%-%icu_version_minor%
-
-set "exitOnError=|| (exit /b)"
-set current_directory=%~dp0
-set current_directory=%current_directory:~0,-1%
-set source_root=%current_directory%\..\..
-
-:: Resetting source_root with %CD% removes the ..\.. from the paths, and makes
-:: the output easier to read.
-cd %source_root%
-set source_root=%CD%
-
-set full_build_root=%source_root%\build
-mkdir %full_build_root%
-
-:: Use the shortest path we can for the build directory, to avoid Windows
-:: path problems as much as we can.
-subst T: /d
-subst T: %full_build_root% %exitOnError%
-set build_root=T:
-set install_directory=%build_root%\Library\Developer\Toolchains\unknown-Asserts-development.xctoolchain\usr
-
-md %build_root%\tmp
-set TMPDIR=%build_root%\tmp
-
-md %build_root%\tmp\org.llvm.clang
-set CUSTOM_CLANG_MODULE_CACHE=%build_root%\tmp\org.llvm.clang.9999
-
-md %build_root%\tmp\org.swift.package-manager
-set SWIFTPM_MODULECACHE_OVERRIDE=%build_root%\tmp\org.swift.package-manager
-
-call :clone_repositories %exitOnError%
-call :download_icu %exitOnError%
-:: TODO: Disabled until we need LLBuild/SwiftPM in this build script.
-:: call :download_sqlite3
-
-call :build_llvm %exitOnError%
-path %PATH%;%install_directory%\bin
-
-call :build_cmark %exitOnError%
-
-call :prepare_platform_modules %exitOnError%
-call :build_swift %exitOnError%
-
-call :build_lldb %exitOnError%
-
-call :build_libdispatch %exitOnError%
-
-path %source_root%\icu-%icu_version%\bin64;%install_directory%\bin;%build_root%\swift\bin;%build_root%\swift\libdispatch-prefix\bin;%PATH%;C:\Program Files\Git\usr\bin
-call :test_swift %exitOnError%
-call :test_libdispatch %exitOnError%
-
-goto :end
-endlocal
-
-:clone_repositories
-:: Clones the repositories used by the Windows build.
-:: It supposes that the swift repository is already cloned by CI.
-:: It supposes the %CD% is the source root.
-setlocal enableextensions enabledelayedexpansion
-
-git -C "%source_root%\swift" config --local core.autocrlf input
-git -C "%source_root%\swift" config --local core.symlink true
-git -C "%source_root%\swift" checkout-index --force --all
-
-git clone --depth 1 --single-branch https://github.com/apple/swift-cmark cmark %exitOnError%
-git clone --depth 1 --single-branch --branch swift/master-rebranch https://github.com/apple/llvm-project llvm-project %exitOnError%
-mklink /D "%source_root%\clang" "%source_root%\llvm-project\clang"
-mklink /D "%source_root%\llvm" "%source_root%\llvm-project\llvm"
-mklink /D "%source_root%\lld" "%source_root%\llvm-project\lld"
-mklink /D "%source_root%\lldb" "%source_root%\llvm-project\lldb"
-mklink /D "%source_root%\compiler-rt" "%source_root%\llvm-project\compiler-rt"
-mklink /D "%source_root%\libcxx" "%source_root%\llvm-project\libcxx"
-mklink /D "%source_root%\clang-tools-extra" "%source_root%\llvm-project\clang-tools-extra"
-git clone --depth 1 --single-branch https://github.com/apple/swift-corelibs-libdispatch %exitOnError%
-
-goto :eof
-endlocal
-
-
-:download_icu
-:: Downloads ICU, which will be used as a dependency for the Swift Standard
-:: Library and Foundation.
-setlocal enableextensions enabledelayedexpansion
-
-set file_name=icu4c-%icu_version%-Win64-MSVC2017.zip
-curl -L -O "https://github.com/unicode-org/icu/releases/download/release-%icu_version_dashed%/%file_name%" %exitOnError%
-:: unzip warns about the paths in the zip using slashes, which raises the
-:: errorLevel to 1. We cannot use exitOnError, and have to ignore errors.
-"C:\Program Files\Git\usr\bin\unzip.exe" -o %file_name% -d "%source_root%\icu-%icu_version%"
-exit /b 0
-
-goto :eof
-endlocal
-
-
-:download_sqlite3
-:: Downloads SQLite3, which will be used as a dependency for llbuild and
-:: Swift Package Manager.
-setlocal enableextensions enabledelayedexpansion
-
-set file_name=sqlite-amalgamation-3270200.zip
-curl -L -O "https://www.sqlite.org/2019/%file_name%" %exitOnError%
-"C:\Program Files\Git\usr\bin\unzip.exe" -o %file_name% %exitOnError%
-
-goto :eof
-endlocal
-
-
-:prepare_platform_modules
-:: Create files into the right places of the Windows SDK to the files in the
-:: swift repository, in order to consider the headers of the Windows SDK a
-:: module to compile Swift code against them.
-setlocal enableextensions enabledelayedexpansion
-
-copy /y "%source_root%\swift\stdlib\public\Platform\ucrt.modulemap" "%UniversalCRTSdkDir%\Include\%UCRTVersion%\ucrt\module.modulemap" %exitOnError%
-copy /y "%source_root%\swift\stdlib\public\Platform\winsdk.modulemap" "%UniversalCRTSdkDir%\Include\%UCRTVersion%\um\module.modulemap" %exitOnError%
-copy /y "%source_root%\swift\stdlib\public\Platform\visualc.modulemap" "%VCToolsInstallDir%\include\module.modulemap" %exitOnError%
-copy /y "%source_root%\swift\stdlib\public\Platform\visualc.apinotes" "%VCToolsInstallDir%\include\visualc.apinotes" %exitOnError%
-
-goto :eof
-endlocal
-
-
-:build_llvm
-:: Configures, builds, and installs LLVM
-setlocal enableextensions enabledelayedexpansion
-
-cmake^
-    -B "%build_root%\llvm"^
-    -G Ninja^
-    -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%^
-    -DCMAKE_C_COMPILER=cl^
-    -DCMAKE_CXX_COMPILER=cl^
-    -DCMAKE_INSTALL_PREFIX:PATH=%install_directory%^
-    -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-windows-msvc^
-    -DLLVM_ENABLE_PDB:BOOL=YES^
-    -DLLVM_ENABLE_ASSERTIONS:BOOL=YES^
-    -DLLVM_ENABLE_PROJECTS:STRING=lld;clang^
-    -DLLVM_TARGETS_TO_BUILD:STRING="AArch64;ARM;X86"^
-    -DLLVM_INCLUDE_BENCHMARKS:BOOL=NO^
-    -DLLVM_INCLUDE_DOCS:BOOL=NO^
-    -DLLVM_INCLUDE_EXAMPLES:BOOL=NO^
-    -DLLVM_INCLUDE_GO_TESTS:BOOL=NO^
-    -DLLVM_TOOL_GOLD_BUILD:BOOL=NO^
-    -DLLVM_ENABLE_OCAMLDOC:BOOL=NO^
-    -DLLVM_ENABLE_LIBXML2:BOOL=NO^
-    -DLLVM_ENABLE_ZLIB:BOOL=NO^
-    -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON^
-    -DENABLE_X86_RELAX_RELOCATIONS:BOOL=YES^
-    -DLLVM_INSTALL_BINUTILS_SYMLINKS:BOOL=YES^
-    -DLLVM_INSTALL_TOOLCHAIN_ONLY:BOOL=YES^
-    -DLLVM_TOOLCHAIN_TOOLS:STRING="addr2line;ar;c++filt;dsymutil;dwp;llvm-ar;llvm-cov;llvm-cvtres;llvm-cxxfilt;llvm-dlltool;llvm-dwp;llvm-ranlib;llvm-lib;llvm-mt;llvm-nm;llvm-objdump;llvm-pdbutil;llvm-profdata;llvm-rc;llvm-readelf;llvm-readobj;llvm-size;llvm-strip;llvm-symbolizer;llvm-undname;nm;objcopy;objdump;ranlib;readelf;size;strings"^
-    -DCLANG_TOOLS="clang;clang-format;clang-headers;clang-tidy"^
-    -DCMAKE_CXX_FLAGS:STRING="/GS- /Oy"^
-    -DCMAKE_EXE_LINKER_FLAGS:STRING=/INCREMENTAL:NO^
-    -DCMAKE_SHARED_LINKER_FLAGS:STRING=/INCREMENTAL:NO^
-    -S "%source_root%\llvm" %exitOnError%
-
-cmake --build "%build_root%\llvm" %exitOnError%
-cmake --build "%build_root%\llvm" --target install %exitOnError%
-
-goto :eof
-endlocal
-
-
-:build_cmark
-:: Configures and builds CMark
-setlocal enableextensions enabledelayedexpansion
-
-cmake^
-    -B "%build_root%\cmark"^
-    -G Ninja^
-    -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%^
-    -DCMAKE_C_COMPILER=cl^
-    -DCMAKE_CXX_COMPILER=cl^
-    -DCMAKE_CXX_FLAGS:STRING="/GS- /Oy"^
-    -DCMAKE_EXE_LINKER_FLAGS:STRING=/INCREMENTAL:NO^
-    -DCMAKE_SHARED_LINKER_FLAGS:STRING=/INCREMENTAL:NO^
-    -S "%source_root%\cmark" %exitOnError%
-
-cmake --build "%build_root%\cmark" %exitOnError%
-
-goto :eof
-endlocal
-
-
-:build_swift
-:: Configures, builds, and installs Swift and the Swift Standard Library
-setlocal enableextensions enabledelayedexpansion
-
-:: SWIFT_PARALLEL_LINK_JOBS=8 allows the build machine to use as many CPU as
-:: possible, while not exhausting the RAM.
-cmake^
-    -B "%build_root%\swift"^
-    -G Ninja^
-    -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%^
-    -DCMAKE_C_COMPILER=cl^
-    -DCMAKE_CXX_COMPILER=cl^
-    -DCMAKE_INSTALL_PREFIX:PATH=%install_directory%^
-    -DClang_DIR:PATH=%build_root%\llvm\lib\cmake\clang^
-    -DSWIFT_PATH_TO_CMARK_BUILD:PATH=%build_root%\cmark^
-    -DSWIFT_PATH_TO_CMARK_SOURCE:PATH=%source_root%\cmark^
-    -DSWIFT_PATH_TO_LIBDISPATCH_SOURCE:PATH=%source_root%\swift-corelibs-libdispatch^
-    -DLLVM_DIR:PATH=%build_root%\llvm\lib\cmake\llvm^
-    -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON^
-    -DSWIFT_INCLUDE_DOCS:BOOL=NO^
-    -DSWIFT_WINDOWS_x86_64_ICU_UC_INCLUDE:PATH=%source_root%\icu-%icu_version%\include\unicode^
-    -DSWIFT_WINDOWS_x86_64_ICU_UC:PATH=%source_root%\icu-%icu_version%\lib64\icuuc.lib^
-    -DSWIFT_WINDOWS_x86_64_ICU_I18N_INCLUDE:PATH=%source_root%\icu-%icu_version%\include^
-    -DSWIFT_WINDOWS_x86_64_ICU_I18N:PATH=%source_root%\icu-%icu_version%\lib64\icuin.lib^
-    -DSWIFT_BUILD_DYNAMIC_STDLIB:BOOL=YES^
-    -DSWIFT_BUILD_DYNAMIC_SDK_OVERLAY:BOOL=YES^
-    -DSWIFT_BUILD_STATIC_STDLIB:BOOL=NO^
-    -DSWIFT_BUILD_STATIC_SDK_OVERLAY:BOOL=NO^
-    -DLLVM_INSTALL_TOOLCHAIN_ONLY:BOOL=YES^
-    -DSWIFT_BUILD_SOURCEKIT:BOOL=YES^
-    -DSWIFT_ENABLE_SOURCEKIT_TESTS:BOOL=YES^
-    -DSWIFT_INSTALL_COMPONENTS="autolink-driver;compiler;clang-resource-dir-symlink;stdlib;sdk-overlay;editor-integration;tools;sourcekit-inproc;swift-remote-mirror;swift-remote-mirror-headers"^
-    -DSWIFT_PARALLEL_LINK_JOBS=8^
-    -DPYTHON_EXECUTABLE:PATH=%PYTHON_HOME%\python.exe^
-    -DCMAKE_CXX_FLAGS:STRING="/GS- /Oy"^
-    -DCMAKE_EXE_LINKER_FLAGS:STRING=/INCREMENTAL:NO^
-    -DCMAKE_SHARED_LINKER_FLAGS:STRING=/INCREMENTAL:NO^
-    -S "%source_root%\swift" %exitOnError%
-
-cmake --build "%build_root%\swift" %exitOnError%
-cmake --build "%build_root%\swift" --target install %exitOnError%
-
-goto :eof
-endlocal
-
-
-:test_swift
-:: Tests the Swift compiler and the Swift Standard Library
-setlocal enableextensions enabledelayedexpansion
-
-cmake --build "%build_root%\swift" --target check-swift %exitOnError%
-
-goto :eof
-endlocal
-
-
-:build_lldb
-:: Configures, builds, and installs LLDB
-setlocal enableextensions enabledelayedexpansion
-
-cmake^
-    -B "%build_root%\lldb"^
-    -G Ninja^
-    -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%^
-    -DCMAKE_C_COMPILER=cl^
-    -DCMAKE_CXX_COMPILER=cl^
-    -DCMAKE_INSTALL_PREFIX:PATH=%install_directory%^
-    -DLLVM_DIR:PATH=%build_root%\llvm\lib\cmake\llvm^
-    -DClang_DIR:PATH=%build_root%\llvm\lib\cmake\clang^
-    -DSwift_DIR:PATH=%build_root%\swift\lib\cmake\swift^
-    -DLLVM_ENABLE_ASSERTIONS:BOOL=YES^
-    -DLLDB_USE_STATIC_BINDINGS:BOOL=YES^
-    -DPYTHON_HOME:PATH=%PYTHON_HOME%^
-    -DCMAKE_CXX_FLAGS:STRING="/GS- /Oy"^
-    -DCMAKE_EXE_LINKER_FLAGS:STRING=/INCREMENTAL:NO^
-    -DCMAKE_SHARED_LINKER_FLAGS:STRING=/INCREMENTAL:NO^
-    -DLLDB_DISABLE_PYTHON=YES^
-    -DLLDB_INCLUDE_TESTS:BOOL=NO^
-    -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON^
-    -S "%source_root%\lldb" %exitOnError%
-
-cmake --build "%build_root%\lldb" %exitOnError%
-cmake --build "%build_root%\lldb" --target install %exitOnError%
-
-goto :eof
-endlocal
-
-
-:build_libdispatch
-:: Configures, builds, and installs Dispatch
-setlocal enableextensions enabledelayedexpansion
-
-cmake^
-    -B "%build_root%\swift-corelibs-libdispatch"^
-    -G Ninja^
-    -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%^
-    -DCMAKE_C_COMPILER=clang-cl^
-    -DCMAKE_CXX_COMPILER=clang-cl^
-    -DCMAKE_Swift_COMPILER=swiftc^
-    -DSwift_DIR:PATH=%build_root%\swift\lib\cmake\swift^
-    -DCMAKE_INSTALL_PREFIX:PATH=%install_directory%^
-    -DCMAKE_C_COMPILER_TARGET=x86_64-unknown-windows-msvc^
-    -DCMAKE_CXX_COMPILER_TARGET=x86_64-unknown-windows-msvc^
-    -DENABLE_SWIFT:BOOL=YES^
-    -DENABLE_TESTING:BOOL=YES^
-    -DCMAKE_C_FLAGS:STRING="${CMAKE_C_FLAGS} --target=x86_64-unknown-windows-msvc /GS- /Oy /Gw /Gy"^
-    -DCMAKE_CXX_FLAGS:STRING="${CMAKE_CXX_FLAGS} --target=x86_64-unknown-windows-msvc /GS- /Oy /Gw /Gy"^
-    -DCMAKE_EXE_LINKER_FLAGS:STRING="/INCREMENTAL:NO"^
-    -DCMAKE_SHARED_LINKER_FLAGS:STRING="/INCREMENTAL:NO"^
-    -DCMAKE_Swift_COMPILER_TARGET:STRING=x86_64-unknown-windows-msvc^
-    -DCMAKE_Swift_FLAGS:STRING="-resource-dir \"%install_directory%\lib\swift\""^
-    -DCMAKE_Swift_LINK_FLAGS:STRING="-resource-dir \"%install_directory%\lib\swift\""^
-    -S "%source_root%\swift-corelibs-libdispatch" %exitOnError%
-
-cmake --build "%build_root%\swift-corelibs-libdispatch" %exitOnError%
-cmake --build "%build_root%\swift-corelibs-libdispatch" --target install %exitOnError%
-
-goto :eof
-endlocal
-
-
-:test_libdispatch
-:: Tests libdispatch C interface
-setlocal enableextensions enabledelayedexpansion
-
-cmake --build "%build_root%\swift-corelibs-libdispatch" --target ExperimentalTest %exitOnError%
-
-goto :eof
-endlocal
-
-
-:end
diff --git a/utils/build-windows.bat b/utils/build-windows.bat
index 3c9c11e..a524e3f 100644
--- a/utils/build-windows.bat
+++ b/utils/build-windows.bat
@@ -176,6 +176,7 @@
     -DLLVM_ENABLE_OCAMLDOC:BOOL=NO^

     -DLLVM_ENABLE_LIBXML2:BOOL=NO^

     -DLLVM_ENABLE_ZLIB:BOOL=NO^

+    -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON^

     -DENABLE_X86_RELAX_RELOCATIONS:BOOL=YES^

     -DLLVM_INSTALL_BINUTILS_SYMLINKS:BOOL=YES^

     -DLLVM_INSTALL_TOOLCHAIN_ONLY:BOOL=YES^

@@ -232,6 +233,7 @@
     -DSWIFT_PATH_TO_CMARK_SOURCE:PATH=%source_root%\cmark^

     -DSWIFT_PATH_TO_LIBDISPATCH_SOURCE:PATH=%source_root%\swift-corelibs-libdispatch^

     -DLLVM_DIR:PATH=%build_root%\llvm\lib\cmake\llvm^

+    -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON^

     -DSWIFT_INCLUDE_DOCS:BOOL=NO^

     -DSWIFT_WINDOWS_x86_64_ICU_UC_INCLUDE:PATH=%source_root%\icu-%icu_version%\include\unicode^

     -DSWIFT_WINDOWS_x86_64_ICU_UC:PATH=%source_root%\icu-%icu_version%\lib64\icuuc.lib^

@@ -277,8 +279,8 @@
     -B "%build_root%\lldb"^

     -G Ninja^

     -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%^

-    -DCMAKE_C_COMPILER=clang-cl^

-    -DCMAKE_CXX_COMPILER=clang-cl^

+    -DCMAKE_C_COMPILER=cl^

+    -DCMAKE_CXX_COMPILER=cl^

     -DCMAKE_INSTALL_PREFIX:PATH=%install_directory%^

     -DLLVM_DIR:PATH=%build_root%\llvm\lib\cmake\llvm^

     -DClang_DIR:PATH=%build_root%\llvm\lib\cmake\clang^

@@ -291,6 +293,7 @@
     -DCMAKE_SHARED_LINKER_FLAGS:STRING=/INCREMENTAL:NO^

     -DLLDB_DISABLE_PYTHON=YES^

     -DLLDB_INCLUDE_TESTS:BOOL=NO^

+    -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON^

     -S "%source_root%\lldb" %exitOnError%

 

 cmake --build "%build_root%\lldb" %exitOnError%

diff --git a/utils/gyb_sourcekit_support/UIDs.py b/utils/gyb_sourcekit_support/UIDs.py
index e8d1eb9..41b5dab 100644
--- a/utils/gyb_sourcekit_support/UIDs.py
+++ b/utils/gyb_sourcekit_support/UIDs.py
@@ -181,6 +181,8 @@
     KEY('OptimizeForIDE', 'key.optimize_for_ide'),
     KEY('RequiredBystanders', 'key.required_bystanders'),
     KEY('ReusingASTContext', 'key.reusingastcontext'),
+    KEY('CompletionMaxASTContextReuseCount',
+        'key.completion_max_astcontext_reuse_count'),
     KEY('CompletionCheckDependencyInterval',
         'key.completion_check_dependency_interval'),
     KEY('AnnotatedTypename', 'key.annotated.typename'),
diff --git a/utils/swift_build_sdk_interfaces.py b/utils/swift_build_sdk_interfaces.py
index c838119..140afab 100755
--- a/utils/swift_build_sdk_interfaces.py
+++ b/utils/swift_build_sdk_interfaces.py
@@ -12,6 +12,7 @@
 import subprocess
 import sys
 import traceback
+from shutil import copyfile
 
 BARE_INTERFACE_SEARCH_PATHS = [
     "usr/lib/swift",
@@ -362,6 +363,16 @@
     fatal("Failed to get SDK version from: " + settingPath)
 
 
+def copySystemVersionFile(sdkroot, output):
+    sysInfoPath = os.path.join(sdkroot,
+                               'System/Library/CoreServices/SystemVersion.plist')
+    destInfoPath = os.path.join(output, 'SystemVersion.plist')
+    try:
+        copyfile(sysInfoPath, destInfoPath)
+    except BaseException as e:
+        print("cannot copy from " + sysInfoPath + " to " + destInfoPath + ": " + str(e))
+
+
 def main():
     global args, shared_output_lock
     parser = create_parser()
@@ -398,6 +409,10 @@
             xfails = json.load(xfails_file)
 
     make_dirs_if_needed(args.output_dir, args.dry_run)
+
+    # Copy a file containing SDK build version into the prebuilt module dir,
+    # so we can keep track of the SDK version we built from.
+    copySystemVersionFile(args.sdk, args.output_dir)
     if 'ANDROID_DATA' not in os.environ:
         shared_output_lock = multiprocessing.Lock()
         pool = multiprocessing.Pool(args.jobs, set_up_child,
diff --git a/utils/swift_build_support/swift_build_support/products/benchmarks.py b/utils/swift_build_support/swift_build_support/products/benchmarks.py
index cac1e24..b7a14ec 100644
--- a/utils/swift_build_support/swift_build_support/products/benchmarks.py
+++ b/utils/swift_build_support/swift_build_support/products/benchmarks.py
@@ -82,7 +82,9 @@
 
 
 def run_build_script_helper(host_target, product, args):
-    toolchain_path = args.install_destdir
+    toolchain_path = swiftpm.SwiftPM.get_install_destdir(args,
+                                                         host_target,
+                                                         product.build_dir)
     if platform.system() == 'Darwin':
         # The prefix is an absolute path, so concatenate without os.path.
         toolchain_path += \
diff --git a/utils/swift_build_support/swift_build_support/products/indexstoredb.py b/utils/swift_build_support/swift_build_support/products/indexstoredb.py
index 65d720c..83b4ac9 100644
--- a/utils/swift_build_support/swift_build_support/products/indexstoredb.py
+++ b/utils/swift_build_support/swift_build_support/products/indexstoredb.py
@@ -76,7 +76,12 @@
     script_path = os.path.join(
         product.source_dir, 'Utilities', 'build-script-helper.py')
 
-    toolchain_path = targets.toolchain_path(args.install_destdir,
+    install_destdir = args.install_destdir
+    if swiftpm.SwiftPM.has_cross_compile_hosts(args):
+        install_destdir = swiftpm.SwiftPM.get_install_destdir(args,
+                                                              host_target,
+                                                              product.build_dir)
+    toolchain_path = targets.toolchain_path(install_destdir,
                                             args.install_prefix)
     is_release = product.is_release()
     configuration = 'release' if is_release else 'debug'
diff --git a/utils/swift_build_support/swift_build_support/products/product.py b/utils/swift_build_support/swift_build_support/products/product.py
index 5ccfa48..ba6f673 100644
--- a/utils/swift_build_support/swift_build_support/products/product.py
+++ b/utils/swift_build_support/swift_build_support/products/product.py
@@ -11,6 +11,7 @@
 # ----------------------------------------------------------------------------
 
 import abc
+import os
 
 from .. import cmake
 from .. import targets
@@ -162,13 +163,17 @@
         """
         return is_release_variant(self.args.build_variant)
 
-    def install_toolchain_path(self):
+    def install_toolchain_path(self, host_target):
         """toolchain_path() -> string
 
         Returns the path to the toolchain that is being created as part of this
         build.
         """
-        return targets.toolchain_path(self.args.install_destdir,
+        install_destdir = self.args.install_destdir
+        if self.args.cross_compile_hosts:
+            build_root = os.path.dirname(self.build_dir)
+            install_destdir = '%s/intermediate-install/%s' % (build_root, host_target)
+        return targets.toolchain_path(install_destdir,
                                       self.args.install_prefix)
 
 
diff --git a/utils/swift_build_support/swift_build_support/products/skstresstester.py b/utils/swift_build_support/swift_build_support/products/skstresstester.py
index ae79373..0656a2b 100644
--- a/utils/swift_build_support/swift_build_support/products/skstresstester.py
+++ b/utils/swift_build_support/swift_build_support/products/skstresstester.py
@@ -50,7 +50,7 @@
     def package_name(self):
         return 'SourceKitStressTester'
 
-    def run_build_script_helper(self, action, additional_params=[]):
+    def run_build_script_helper(self, action, host_target, additional_params=[]):
         script_path = os.path.join(
             self.source_dir, 'build-script-helper.py')
 
@@ -60,7 +60,7 @@
             script_path,
             action,
             '--package-dir', self.package_name(),
-            '--toolchain', self.install_toolchain_path(),
+            '--toolchain', self.install_toolchain_path(host_target),
             '--config', configuration,
             '--build-dir', self.build_dir,
             '--multiroot-data-file', MULTIROOT_DATA_FILE_PATH,
@@ -84,20 +84,23 @@
                                "than Darwin".format(
                                    product=self.package_name()))
 
-        self.run_build_script_helper('build')
+        self.run_build_script_helper('build', host_target)
 
     def should_test(self, host_target):
         return self.args.test_skstresstester
 
     def test(self, host_target):
-        self.run_build_script_helper('test')
+        self.run_build_script_helper('test', host_target)
 
     def should_install(self, host_target):
         return self.args.install_skstresstester
 
     def install(self, host_target):
-        install_prefix = self.args.install_destdir + self.args.install_prefix
-        self.run_build_script_helper('install', [
+        install_destdir = swiftpm.SwiftPM.get_install_destdir(self.args,
+                                                              host_target,
+                                                              self.build_dir)
+        install_prefix = install_destdir + self.args.install_prefix
+        self.run_build_script_helper('install', host_target, [
             '--prefix', install_prefix
         ])
 
diff --git a/utils/swift_build_support/swift_build_support/products/swiftformat.py b/utils/swift_build_support/swift_build_support/products/swiftformat.py
index ae6323c..940ccd1 100644
--- a/utils/swift_build_support/swift_build_support/products/swiftformat.py
+++ b/utils/swift_build_support/swift_build_support/products/swiftformat.py
@@ -46,7 +46,7 @@
     def is_swiftpm_unified_build_product(cls):
         return True
 
-    def run_build_script_helper(self, action, additional_params=[]):
+    def run_build_script_helper(self, action, host_target, additional_params=[]):
         script_path = os.path.join(
             self.source_dir, 'build-script-helper.py')
 
@@ -55,7 +55,7 @@
         helper_cmd = [
             script_path,
             action,
-            '--toolchain', self.install_toolchain_path(),
+            '--toolchain', self.install_toolchain_path(host_target),
             '--configuration', configuration,
             '--build-path', self.build_dir,
             '--multiroot-data-file', MULTIROOT_DATA_FILE_PATH,
@@ -74,13 +74,13 @@
         return True
 
     def build(self, host_target):
-        self.run_build_script_helper('build')
+        self.run_build_script_helper('build', host_target)
 
     def should_test(self, host_target):
         return self.args.test_swiftformat
 
     def test(self, host_target):
-        self.run_build_script_helper('test')
+        self.run_build_script_helper('test', host_target)
 
     def should_install(self, host_target):
         return False
diff --git a/utils/swift_build_support/swift_build_support/products/swiftpm.py b/utils/swift_build_support/swift_build_support/products/swiftpm.py
index 412dc52..25e982e 100644
--- a/utils/swift_build_support/swift_build_support/products/swiftpm.py
+++ b/utils/swift_build_support/swift_build_support/products/swiftpm.py
@@ -40,7 +40,7 @@
     def run_bootstrap_script(self, action, host_target, additional_params=[]):
         script_path = os.path.join(
             self.source_dir, 'Utilities', 'bootstrap')
-        toolchain_path = self.install_toolchain_path()
+        toolchain_path = self.install_toolchain_path(host_target)
         swiftc = os.path.join(toolchain_path, "bin", "swiftc")
 
         # FIXME: We require llbuild build directory in order to build. Is
@@ -86,6 +86,12 @@
                 "--foundation-build-dir", foundation_build_dir
             ]
 
+        # Pass Cross compile host info
+        if self.has_cross_compile_hosts(self.args):
+            helper_cmd += ['--cross-compile-hosts']
+            for cross_compile_host in self.args.cross_compile_hosts:
+                helper_cmd += [cross_compile_host]
+
         helper_cmd.extend(additional_params)
 
         shell.call(helper_cmd)
@@ -108,8 +114,24 @@
     def should_install(self, host_target):
         return self.args.install_swiftpm
 
+    @classmethod
+    def has_cross_compile_hosts(self, args):
+        return args.cross_compile_hosts
+
+    @classmethod
+    def get_install_destdir(self, args, host_target, build_dir):
+        install_destdir = args.install_destdir
+        if self.has_cross_compile_hosts(args):
+            build_root = os.path.dirname(build_dir)
+            install_destdir = '%s/intermediate-install/%s' % (build_root, host_target)
+        return install_destdir
+
     def install(self, host_target):
-        install_prefix = self.args.install_destdir + self.args.install_prefix
+        install_destdir = self.get_install_destdir(self.args,
+                                                   host_target,
+                                                   self.build_dir)
+        install_prefix = install_destdir + self.args.install_prefix
+
         self.run_bootstrap_script('install', host_target, [
             '--prefix', install_prefix
         ])
diff --git a/utils/swift_build_support/swift_build_support/products/swiftsyntax.py b/utils/swift_build_support/swift_build_support/products/swiftsyntax.py
index 9dd6a84..00cdef0 100644
--- a/utils/swift_build_support/swift_build_support/products/swiftsyntax.py
+++ b/utils/swift_build_support/swift_build_support/products/swiftsyntax.py
@@ -55,7 +55,7 @@
             script_path,
             '--build-dir', self.build_dir,
             '--multiroot-data-file', MULTIROOT_DATA_FILE_PATH,
-            '--toolchain', self.install_toolchain_path(),
+            '--toolchain', self.install_toolchain_path(target),
             '--filecheck-exec', os.path.join(llvm_build_dir, 'bin',
                                              'FileCheck'),
         ]
diff --git a/validation-test/Reflection/existentials.swift b/validation-test/Reflection/existentials.swift
index ce17f8f..ea8b445 100644
--- a/validation-test/Reflection/existentials.swift
+++ b/validation-test/Reflection/existentials.swift
@@ -281,17 +281,17 @@
 struct S : Composition {}
 func getComposition() -> P & Q { return S() }
 reflect(any: getComposition())
-// CHECK-64: Mangled name: $s12existentials1PP_AA1QPp
+// CHECK-64: Mangled name: $s12existentials1P_AA1Qp
 // CHECK-64: Demangled name: existentials.P & existentials.Q
-// CHECK-32: Mangled name: $s12existentials1PP_AA1QPp
+// CHECK-32: Mangled name: $s12existentials1P_AA1Qp
 // CHECK-32: Demangled name: existentials.P & existentials.Q
 
 // Metatype:
 reflect(any: Int.self)
-// CHECK-64: Mangled name: $sSim
-// CHECK-64: Demangled name: Swift.Int.Type
-// CHECK-32: Mangled name: $sSim
-// CHECK-32: Demangled name: Swift.Int.Type
+// CHECK-64: Mangled name: $sSiXMt
+// CHECK-64: Demangled name: @thin Swift.Int.Type
+// CHECK-32: Mangled name: $sSiXMt
+// CHECK-32: Demangled name: @thin Swift.Int.Type
 
 protocol WithType {
   associatedtype T