Merge pull request #20557 from brentdax/this-is-why-swift-is-a-memory-safe-language

Fix lookupDirect() use-after-scope bugs
diff --git a/.flake8 b/.flake8
index d3728e2..24e50cd 100644
--- a/.flake8
+++ b/.flake8
@@ -1,5 +1,5 @@
 [flake8]
-ignore = W291
+ignore = W291 W504
 filename = *.py,
            ./utils/80+-check,
            ./utils/backtrace-check,
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a94065a..1187d4d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,39 @@
 Swift 5.0
 ---------
 
+* [SR-7139][]:
+
+  Exclusive memory access is now enforced at runtime by default in
+  optimized (`-O`/`-Osize`) builds. Programs that violate exclusivity will
+  trap at runtime with an "overlapping access" diagnostic
+  message. This can be disabled via a command line flag:
+  `-enforce-exclusivity=unchecked`, but doing so may result in undefined
+  behavior.
+
+  Runtime violations of exclusivity typically result from
+  simultaneous access of class properties, global variables (including
+  variables in top-level code), or variables captured by escaping
+  closures.
+
+* [SE-0216][]:
+
+  The `@dynamicCallable` attribute enables nominal types to be "callable" via a
+  simple syntactic sugar. The primary use case is dynamic language
+  interoperability.
+
+  Toy example:
+
+  ```swift
+  @dynamicCallable
+  struct ToyCallable {
+    func dynamicallyCall(withArguments: [Int]) {}
+    func dynamicallyCall(withKeywordArguments: KeyValuePairs<String, Int>) {}
+  }
+  let x = ToyCallable()
+  x(1, 2, 3) // desugars to `x.dynamicallyCall(withArguments: [1, 2, 3])`
+  x(label: 1, 2) // desugars to `x.dynamicallyCall(withKeywordArguments: ["label": 1, "": 2])`
+  ```
+
 * [SR-7251][]:
 
   In Swift 5 mode, attempting to declare a static property with the same name as a
@@ -7259,6 +7292,7 @@
 [SE-0224]: <https://github.com/apple/swift-evolution/blob/master/proposals/0224-ifswift-lessthan-operator.md>
 [SE-0225]: <https://github.com/apple/swift-evolution/blob/master/proposals/0225-binaryinteger-iseven-isodd-ismultiple.md>
 [SE-0226]: <https://github.com/apple/swift-evolution/blob/master/proposals/0226-package-manager-target-based-dep-resolution.md>
+[SE-0227]: <https://github.com/apple/swift-evolution/blob/master/proposals/0227-identity-keypath.md>
 
 [SR-106]: <https://bugs.swift.org/browse/SR-106>
 [SR-419]: <https://bugs.swift.org/browse/SR-419>
@@ -7270,4 +7304,5 @@
 [SR-2394]: <https://bugs.swift.org/browse/SR-2394>
 [SR-2608]: <https://bugs.swift.org/browse/SR-2608>
 [SR-4248]: <https://bugs.swift.org/browse/SR-4248>
+[SR-7139]: <https://bugs.swift.org/browse/SR-7139>
 [SR-7251]: <https://bugs.swift.org/browse/SR-7251>
diff --git a/benchmark/scripts/Benchmark_Driver b/benchmark/scripts/Benchmark_Driver
index 3e9cf0f..6e9af97 100755
--- a/benchmark/scripts/Benchmark_Driver
+++ b/benchmark/scripts/Benchmark_Driver
@@ -343,7 +343,7 @@
         setup, ratio = BenchmarkDoctor._setup_overhead(measurements)
         setup = 0 if ratio < 0.05 else setup
         runtime = min(
-            [(result.min - correction) for i_series in
+            [(result.samples.min - correction) for i_series in
              [BenchmarkDoctor._select(measurements, num_iters=i)
               for correction in [(setup / i) for i in [1, 2]]
               ] for result in i_series])
@@ -367,7 +367,8 @@
     def _setup_overhead(measurements):
         select = BenchmarkDoctor._select
         ti1, ti2 = [float(min(mins)) for mins in
-                    [[result.min for result in i_series] for i_series in
+                    [[result.samples.min for result in i_series]
+                     for i_series in
                      [select(measurements, num_iters=i) for i in [1, 2]]]]
         setup = int(round(2.0 * (ti1 - ti2)))
         ratio = (setup / ti1) if ti1 > 0 else 0
@@ -439,8 +440,9 @@
         Returns a dictionary with benchmark name and `PerformanceTestResult`s.
         """
         self.log.debug('Calibrating num-samples for {0}:'.format(benchmark))
-        r = self.driver.run(benchmark, num_samples=3, num_iters=1)  # calibrate
-        num_samples = self._adjusted_1s_samples(r.min)
+        r = self.driver.run(benchmark, num_samples=3, num_iters=1,
+                            verbose=True)  # calibrate
+        num_samples = self._adjusted_1s_samples(r.samples.min)
 
         def capped(s):
             return min(s, 2048)
@@ -449,7 +451,7 @@
         opts = opts if isinstance(opts, list) else [opts]
         self.log.debug(
             'Runtime {0} μs yields {1} adjusted samples per second.'.format(
-                r.min, num_samples))
+                r.samples.min, num_samples))
         self.log.debug(
             'Measuring {0}, 5 x i1 ({1} samples), 5 x i2 ({2} samples)'.format(
                 benchmark, run_args[0][0], run_args[1][0]))
diff --git a/benchmark/scripts/Benchmark_RuntimeLeaksRunner.in b/benchmark/scripts/Benchmark_RuntimeLeaksRunner.in
index 008d4ff..2a7dd0d 100644
--- a/benchmark/scripts/Benchmark_RuntimeLeaksRunner.in
+++ b/benchmark/scripts/Benchmark_RuntimeLeaksRunner.in
@@ -151,9 +151,9 @@
 
 if __name__ == "__main__":
     args = parse_args()
-    l = LeaksRunnerBenchmarkDriver(
+    driver = LeaksRunnerBenchmarkDriver(
         SWIFT_BIN_DIR, XFAIL_LIST, args.num_samples, args.num_iters)
-    if l.run(args.filter):
+    if driver.run(args.filter):
         sys.exit(0)
     else:
         sys.exit(-1)
diff --git a/benchmark/scripts/test_Benchmark_Driver.py b/benchmark/scripts/test_Benchmark_Driver.py
index f3adeb6..4ff7c32 100644
--- a/benchmark/scripts/test_Benchmark_Driver.py
+++ b/benchmark/scripts/test_Benchmark_Driver.py
@@ -423,7 +423,7 @@
 
 def _PTR(min=700, mem_pages=1000, setup=None):
     """Create PerformanceTestResult Stub."""
-    return Stub(min=min, mem_pages=mem_pages, setup=setup)
+    return Stub(samples=Stub(min=min), mem_pages=mem_pages, setup=setup)
 
 
 def _run(test, num_samples=None, num_iters=None, verbose=None,
@@ -483,7 +483,8 @@
         """
         driver = BenchmarkDriverMock(tests=['B1'], responses=([
             # calibration run, returns a stand-in for PerformanceTestResult
-            (_run('B1', num_samples=3, num_iters=1), _PTR(min=300))] +
+            (_run('B1', num_samples=3, num_iters=1,
+                  verbose=True), _PTR(min=300))] +
             # 5x i1 series, with 300 μs runtime its possible to take 4098
             # samples/s, but it should be capped at 2k
             ([(_run('B1', num_samples=2048, num_iters=1,
diff --git a/benchmark/scripts/test_compare_perf_tests.py b/benchmark/scripts/test_compare_perf_tests.py
index bb0f79d..04af04c 100644
--- a/benchmark/scripts/test_compare_perf_tests.py
+++ b/benchmark/scripts/test_compare_perf_tests.py
@@ -591,7 +591,7 @@
     def test_results_from_merge_verbose(self):
         """Parsing verbose log  merges all PerformanceTestSamples.
         ...this should technically be on TestPerformanceTestResult, but it's
-        easier to write here. ¯\_(ツ)_/¯"""
+        easier to write here. ¯\\_(ツ)_/¯"""
         concatenated_logs = """
     Sample 0,355883
     Sample 1,358817
diff --git a/benchmark/single-source/AnyHashableWithAClass.swift b/benchmark/single-source/AnyHashableWithAClass.swift
index d3e2ef8..eac874e 100644
--- a/benchmark/single-source/AnyHashableWithAClass.swift
+++ b/benchmark/single-source/AnyHashableWithAClass.swift
@@ -25,9 +25,12 @@
 public var AnyHashableWithAClass = BenchmarkInfo(
   name: "AnyHashableWithAClass",
   runFunction: run_AnyHashableWithAClass,
-  tags: [.abstraction, .runtime, .cpubench]
+  tags: [.abstraction, .runtime, .cpubench],
+  legacyFactor: lf
 )
 
+let lf = 500
+
 class TestHashableBase : Hashable {
   var value: Int
   init(_ value: Int) {
@@ -55,8 +58,7 @@
 @inline(never)
 public func run_AnyHashableWithAClass(_ N: Int) {
   let c = TestHashableDerived5(10)
-  for _ in 0...(N*500000) {
+  for _ in 0...(N*500000/lf) {
     _ = AnyHashable(c)
   }
 }
-
diff --git a/benchmark/single-source/ArrayOfGenericRef.swift b/benchmark/single-source/ArrayOfGenericRef.swift
index b4bfac1..a1f3650 100644
--- a/benchmark/single-source/ArrayOfGenericRef.swift
+++ b/benchmark/single-source/ArrayOfGenericRef.swift
@@ -13,14 +13,15 @@
 // This benchmark tests creation and destruction of an array of enum
 // and generic type bound to nontrivial types.
 //
-// For comparison, we always create three arrays of 10,000 words.
+// For comparison, we always create three arrays of 1,000 words.
 
 import TestsUtils
 
 public let ArrayOfGenericRef = BenchmarkInfo(
   name: "ArrayOfGenericRef",
   runFunction: run_ArrayOfGenericRef,
-  tags: [.validation, .api, .Array])
+  tags: [.validation, .api, .Array],
+  legacyFactor: 10)
 
 protocol Constructible {
   associatedtype Element
@@ -31,8 +32,8 @@
 
   init(_ e:T.Element) {
     array = [T]()
-    array.reserveCapacity(10_000)
-    for _ in 0...10_000 {
+    array.reserveCapacity(1_000)
+    for _ in 0...1_000 {
       array.append(T(e:e) as T)
     }
   }
@@ -65,7 +66,7 @@
 class RefArray<T> {
   var array: [T]
 
-  init(_ i:T, count:Int = 10_000) {
+  init(_ i:T, count:Int = 1_000) {
     array = [T](repeating: i, count: count)
   }
 }
diff --git a/benchmark/single-source/ArrayOfRef.swift b/benchmark/single-source/ArrayOfRef.swift
index d333487..85b11ec 100644
--- a/benchmark/single-source/ArrayOfRef.swift
+++ b/benchmark/single-source/ArrayOfRef.swift
@@ -14,14 +14,15 @@
 // references. It is meant to be a baseline for comparison against
 // ArrayOfGenericRef.
 //
-// For comparison, we always create four arrays of 10,000 words.
+// For comparison, we always create four arrays of 1,000 words.
 
 import TestsUtils
 
 public let ArrayOfRef = BenchmarkInfo(
   name: "ArrayOfRef",
   runFunction: run_ArrayOfRef,
-  tags: [.validation, .api, .Array])
+  tags: [.validation, .api, .Array],
+  legacyFactor: 10)
 
 protocol Constructible {
   associatedtype Element
@@ -32,8 +33,8 @@
 
   init(_ e:T.Element) {
     array = [T]()
-    array.reserveCapacity(10_000)
-    for _ in 0...10_000 {
+    array.reserveCapacity(1_000)
+    for _ in 0...1_000 {
       array.append(T(e:e) as T)
     }
   }
@@ -77,7 +78,7 @@
 class RefArray<T> {
   var array : [T]
 
-  init(_ i:T, count:Int = 10_000) {
+  init(_ i:T, count:Int = 1_000) {
     array = [T](repeating: i, count: count)
   }
 }
diff --git a/benchmark/single-source/ArraySetElement.swift b/benchmark/single-source/ArraySetElement.swift
index 292b6a3..9d6d59d 100644
--- a/benchmark/single-source/ArraySetElement.swift
+++ b/benchmark/single-source/ArraySetElement.swift
@@ -18,7 +18,8 @@
 public var ArraySetElement = BenchmarkInfo(
   name: "ArraySetElement",
   runFunction: run_ArraySetElement,
-  tags: [.runtime, .cpubench, .unstable]
+  tags: [.runtime, .cpubench, .unstable],
+  legacyFactor: 10
 )
 
 // This is an effort to defeat isUniquelyReferenced optimization. Ideally
@@ -29,9 +30,8 @@
 }
 
 public func run_ArraySetElement(_ N: Int) {
-  let scale = 10
   var array = [Int](repeating: 0, count: 10000)
-  for _ in 0..<N*scale {
+  for _ in 0..<N {
     for i in 0..<array.count {
       storeArrayElement(&array, i)
     }
diff --git a/benchmark/single-source/DataBenchmarks.swift b/benchmark/single-source/DataBenchmarks.swift
index 02c79fd..52aa244 100644
--- a/benchmark/single-source/DataBenchmarks.swift
+++ b/benchmark/single-source/DataBenchmarks.swift
@@ -14,13 +14,34 @@
 import Foundation
 
 public let DataBenchmarks = [
-    BenchmarkInfo(name: "DataSubscript", runFunction: run_Subscript, tags: [.validation, .api, .Data]),
-    BenchmarkInfo(name: "DataCount", runFunction: run_Count, tags: [.validation, .api, .Data]),
-    BenchmarkInfo(name: "DataSetCount", runFunction: run_SetCount, tags: [.validation, .api, .Data]),
-    BenchmarkInfo(name: "DataAccessBytes", runFunction: run_AccessBytes, tags: [.validation, .api, .Data]),
-    BenchmarkInfo(name: "DataMutateBytes", runFunction: run_MutateBytes, tags: [.validation, .api, .Data]),
-    BenchmarkInfo(name: "DataCopyBytes", runFunction: run_CopyBytes, tags: [.validation, .api, .Data]),
-    BenchmarkInfo(name: "DataAppendBytes", runFunction: run_AppendBytes, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCreateEmpty", runFunction: run_createEmpty, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCreateSmall", runFunction: run_createSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCreateMedium", runFunction: run_createMedium, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCreateLarge", runFunction: run_createLarge, tags: [.validation, .api, .Data, .skip]),
+    BenchmarkInfo(name: "DataCreateEmptyArray", runFunction: run_createEmptyArray, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCreateSmallArray", runFunction: run_createSmallArray, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCreateMediumArray", runFunction: run_createMediumArray, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataSubscriptSmall", runFunction: run_SubscriptSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataSubscriptMedium", runFunction: run_SubscriptMedium, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataSubscriptLarge", runFunction: run_SubscriptLarge, tags: [.validation, .api, .Data, .skip]),
+    BenchmarkInfo(name: "DataCountSmall", runFunction: run_CountSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCountMedium", runFunction: run_CountMedium, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCountLarge", runFunction: run_CountLarge, tags: [.validation, .api, .Data, .skip]),
+    BenchmarkInfo(name: "DataSetCountSmall", runFunction: run_SetCountSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataSetCountMedium", runFunction: run_SetCountMedium, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataSetCountLarge", runFunction: run_SetCountLarge, tags: [.validation, .api, .Data, .skip]),
+    BenchmarkInfo(name: "DataAccessBytesSmall", runFunction: run_AccessBytesSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataAccessBytesMedium", runFunction: run_AccessBytesMedium, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataAccessBytesLarge", runFunction: run_AccessBytesLarge, tags: [.validation, .api, .Data, .skip]),
+    BenchmarkInfo(name: "DataMutateBytesSmall", runFunction: run_MutateBytesSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataMutateBytesMedium", runFunction: run_MutateBytesMedium, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataMutateBytesLarge", runFunction: run_MutateBytesLarge, tags: [.validation, .api, .Data, .skip]),
+    BenchmarkInfo(name: "DataCopyBytesSmall", runFunction: run_CopyBytesSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCopyBytesMedium", runFunction: run_CopyBytesMedium, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataCopyBytesLarge", runFunction: run_CopyBytesLarge, tags: [.validation, .api, .Data, .skip]),
+    BenchmarkInfo(name: "DataAppendBytesSmall", runFunction: run_AppendBytesSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataAppendBytesMedium", runFunction: run_AppendBytesMedium, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataAppendBytesLarge", runFunction: run_AppendBytesLarge, tags: [.validation, .api, .Data, .skip]),
     BenchmarkInfo(name: "DataAppendArray", runFunction: run_AppendArray, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataReset", runFunction: run_Reset, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataReplaceSmall", runFunction: run_ReplaceSmall, tags: [.validation, .api, .Data]),
@@ -28,22 +49,25 @@
     BenchmarkInfo(name: "DataReplaceLarge", runFunction: run_ReplaceLarge, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataReplaceSmallBuffer", runFunction: run_ReplaceSmallBuffer, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataReplaceMediumBuffer", runFunction: run_ReplaceMediumBuffer, tags: [.validation, .api, .Data]),
-    BenchmarkInfo(name: "DataReplaceLargeBuffer", runFunction: run_ReplaceLargeBuffer, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataReplaceLargeBuffer", runFunction: run_ReplaceLargeBuffer, tags: [.validation, .api, .Data, .skip]),
     BenchmarkInfo(name: "DataAppendSequence", runFunction: run_AppendSequence, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataAppendDataSmallToSmall", runFunction: run_AppendDataSmallToSmall, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataAppendDataSmallToMedium", runFunction: run_AppendDataSmallToMedium, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataAppendDataSmallToLarge", runFunction: run_AppendDataSmallToLarge, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataAppendDataMediumToSmall", runFunction: run_AppendDataMediumToSmall, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataAppendDataMediumToMedium", runFunction: run_AppendDataMediumToMedium, tags: [.validation, .api, .Data]),
-    BenchmarkInfo(name: "DataAppendDataMediumToLarge", runFunction: run_AppendDataMediumToLarge, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataAppendDataMediumToLarge", runFunction: run_AppendDataMediumToLarge, tags: [.validation, .api, .Data, .skip]),
     BenchmarkInfo(name: "DataAppendDataLargeToSmall", runFunction: run_AppendDataLargeToSmall, tags: [.validation, .api, .Data]),
     BenchmarkInfo(name: "DataAppendDataLargeToMedium", runFunction: run_AppendDataLargeToMedium, tags: [.validation, .api, .Data]),
-    BenchmarkInfo(name: "DataAppendDataLargeToLarge", runFunction: run_AppendDataLargeToLarge, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataAppendDataLargeToLarge", runFunction: run_AppendDataLargeToLarge, tags: [.validation, .api, .Data, .skip]),
+    BenchmarkInfo(name: "DataToStringEmpty", runFunction: run_DataToStringEmpty, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataToStringSmall", runFunction: run_DataToStringSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "DataToStringMedium", runFunction: run_DataToStringMedium, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "StringToDataEmpty", runFunction: run_StringToDataEmpty, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "StringToDataSmall", runFunction: run_StringToDataSmall, tags: [.validation, .api, .Data]),
+    BenchmarkInfo(name: "StringToDataMedium", runFunction: run_StringToDataMedium, tags: [.validation, .api, .Data]),
 ]
 
-let small = sampleData(.small)
-let medium = sampleData(.medium)
-
 enum SampleKind {
     case small
     case medium
@@ -98,28 +122,28 @@
 
 @inline(__always)
 func getRandomBuf(_ arg: UnsafeMutableBufferPointer<UInt8>) {
-#if os(Linux)
+    #if os(Linux)
     let fd = open("/dev/urandom", O_RDONLY)
     defer { if (fd >= 0) { close(fd) } }
     if fd >= 0 {
-         read(fd, arg.baseAddress, arg.count)
+        read(fd, arg.baseAddress, arg.count)
     }
-#else
+    #else
     arc4random_buf(arg.baseAddress, arg.count)
-#endif
+    #endif
 }
 
 @inline(__always)
 func getRandomBuf(baseAddress: UnsafeMutablePointer<UInt8>, count: Int) {
-#if os(Linux)
+    #if os(Linux)
     let fd = open("/dev/urandom", O_RDONLY)
     defer { if (fd >= 0) { close(fd) } }
     if fd >= 0 {
-         read(fd, baseAddress, count)
+        read(fd, baseAddress, count)
     }
-#else
+    #else
     arc4random_buf(baseAddress, count)
-#endif
+    #endif
 }
 
 func sampleBridgedNSData() -> Data {
@@ -141,10 +165,11 @@
     case .string: return sampleString()
     case .immutableBacking: return sampleBridgedNSData()
     }
+    
 }
 
 func benchmark_AccessBytes(_ N: Int, _ data: Data) {
-    for _ in 1...10000*N {
+    for _ in 0..<10000*N {
         data.withUnsafeBytes { (ptr: UnsafePointer<UInt8>) in
             // Ensure that the compiler does not optimize away this call
             blackHole(ptr.pointee)
@@ -153,7 +178,7 @@
 }
 
 func benchmark_MutateBytes(_ N: Int, _ data_: Data) {
-    for _ in 1...10000*N {
+    for _ in 0..<10000*N {
         var data = data_
         data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) in
             // Mutate a byte
@@ -166,15 +191,15 @@
     let amount = data.count
     var buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: amount)
     defer { buffer.deallocate() }
-    for _ in 1...10000*N {
-        data.copyBytes(to: buffer, count: amount)
+    for _ in 0..<10000*N {
+        data.copyBytes(to: buffer, from: 0..<amount)
     }
 }
 
 func benchmark_AppendBytes(_ N: Int, _ count: Int, _ data_: Data) {
     let bytes = malloc(count).assumingMemoryBound(to: UInt8.self)
     defer { free(bytes) }
-    for _ in 1...10000*N {
+    for _ in 0..<10000*N {
         var data = data_
         data.append(bytes, count: count)
     }
@@ -185,7 +210,7 @@
     bytes.withUnsafeMutableBufferPointer {
         getRandomBuf($0)
     }
-    for _ in 1...10000*N {
+    for _ in 0..<10000*N {
         var data = data_
         data.append(contentsOf: bytes)
     }
@@ -193,28 +218,28 @@
 
 func benchmark_AppendSequence(_ N: Int, _ count: Int, _ data_: Data) {
     let bytes = repeatElement(UInt8(0xA0), count: count)
-    for _ in 1...10000*N {
+    for _ in 0..<10000*N {
         var data = data_
         data.append(contentsOf: bytes)
     }
 }
 
 func benchmark_Reset(_ N: Int, _ range: Range<Data.Index>, _ data_: Data) {
-    for _ in 1...10000*N {
+    for _ in 0..<10000*N {
         var data = data_
         data.resetBytes(in: range)
     }
 }
 
 func benchmark_Replace(_ N: Int, _ range: Range<Data.Index>, _ data_: Data, _ replacement: Data) {
-    for _ in 1...10000*N {
+    for _ in 0..<10000*N {
         var data = data_
         data.replaceSubrange(range, with: replacement)
     }
 }
 
 func benchmark_ReplaceBuffer(_ N: Int, _ range: Range<Data.Index>, _ data_: Data, _ replacement: UnsafeBufferPointer<UInt8>) {
-    for _ in 1...10000*N {
+    for _ in 0..<10000*N {
         var data = data_
         data.replaceSubrange(range, with: replacement)
     }
@@ -222,104 +247,212 @@
 
 func benchmark_AppendData(_ N: Int, _ lhs: Data, _ rhs: Data) {
     var data = lhs
-    for _ in 1...10000*N {
+    for _ in 0..<10000*N {
         data = lhs
         data.append(rhs)
     }
 }
 
 @inline(never)
-public func run_Subscript(_ N: Int) {
-    let data = medium
-    let index = 521
-    for _ in 1...10000*N {
+public func run_SubscriptSmall(_ N: Int) {
+    let data = sampleData(.small)
+    let index = 1
+    for _ in 0..<10000*N {
         // Ensure that the compiler does not optimize away this call
         blackHole(data[index])
     }
 }
 
 @inline(never)
-public func run_Count(_ N: Int) {
-    let data = medium
-    for _ in 1...10000*N {
+public func run_SubscriptMedium(_ N: Int) {
+    let data = sampleData(.medium)
+    let index = 521
+    for _ in 0..<10000*N {
+        // Ensure that the compiler does not optimize away this call
+        blackHole(data[index])
+    }
+}
+
+@inline(never)
+public func run_SubscriptLarge(_ N: Int) {
+    let data = sampleData(.veryLarge)
+    let index = 521
+    for _ in 0..<10000*N {
+        // Ensure that the compiler does not optimize away this call
+        blackHole(data[index])
+    }
+}
+
+@inline(never)
+public func run_CountSmall(_ N: Int) {
+    let data = sampleData(.small)
+    for _ in 0..<10000*N {
         // Ensure that the compiler does not optimize away this call
         blackHole(data.count)
     }
 }
 
 @inline(never)
-public func run_SetCount(_ N: Int) {
-    let data = medium
-    let count = data.count + 100
-    var otherData = data
-    let orig = data.count
-    for _ in 1...10000*N {
-        otherData.count = count
-        otherData.count = orig
+public func run_CountMedium(_ N: Int) {
+    let data = sampleData(.medium)
+    for _ in 0..<10000*N {
+        // Ensure that the compiler does not optimize away this call
+        blackHole(data.count)
     }
 }
 
 @inline(never)
-public func run_AccessBytes(_ N: Int) {
-    let data = medium
+public func run_CountLarge(_ N: Int) {
+    let data = sampleData(.veryLarge)
+    for _ in 0..<10000*N {
+        // Ensure that the compiler does not optimize away this call
+        blackHole(data.count)
+    }
+}
+
+@inline(never)
+public func run_SetCountSmall(_ N: Int) {
+    var data = sampleData(.small)
+    let count = data.count + 3
+    let orig = data.count
+    for _ in 0..<10000*N {
+        data.count = count
+        data.count = orig
+    }
+}
+
+@inline(never)
+public func run_SetCountMedium(_ N: Int) {
+    var data = sampleData(.medium)
+    let count = data.count + 100
+    let orig = data.count
+    for _ in 0..<10000*N {
+        data.count = count
+        data.count = orig
+    }
+}
+
+@inline(never)
+public func run_SetCountLarge(_ N: Int) {
+    var data = sampleData(.large)
+    let count = data.count + 100
+    let orig = data.count
+    for _ in 0..<10000*N {
+        data.count = count
+        data.count = orig
+    }
+}
+
+@inline(never)
+public func run_AccessBytesSmall(_ N: Int) {
+    let data = sampleData(.small)
+    benchmark_AccessBytes(N, data)
+}
+
+
+@inline(never)
+public func run_AccessBytesMedium(_ N: Int) {
+    let data = sampleData(.medium)
     benchmark_AccessBytes(N, data)
 }
 
 @inline(never)
-public func run_MutateBytes(_ N: Int) {
-    let data = medium
+public func run_AccessBytesLarge(_ N: Int) {
+    let data = sampleData(.veryLarge)
+    benchmark_AccessBytes(N, data)
+}
+
+@inline(never)
+public func run_MutateBytesSmall(_ N: Int) {
+    let data = sampleData(.small)
     benchmark_MutateBytes(N, data)
 }
 
 @inline(never)
-public func run_CopyBytes(_ N: Int) {
-    let data = medium
+public func run_MutateBytesMedium(_ N: Int) {
+    let data = sampleData(.medium)
+    benchmark_MutateBytes(N, data)
+}
+
+@inline(never)
+public func run_MutateBytesLarge(_ N: Int) {
+    let data = sampleData(.veryLarge)
+    benchmark_MutateBytes(N, data)
+}
+
+@inline(never)
+public func run_CopyBytesSmall(_ N: Int) {
+    let data = sampleData(.small)
     benchmark_CopyBytes(N, data)
 }
 
 @inline(never)
-public func run_AppendBytes(_ N: Int) {
-    let data = medium
+public func run_CopyBytesMedium(_ N: Int) {
+    let data = sampleData(.medium)
+    benchmark_CopyBytes(N, data)
+}
+
+@inline(never)
+public func run_CopyBytesLarge(_ N: Int) {
+    let data = sampleData(.large)
+    benchmark_CopyBytes(N, data)
+}
+
+@inline(never)
+public func run_AppendBytesSmall(_ N: Int) {
+    let data = sampleData(.small)
+    benchmark_AppendBytes(N, 3, data)
+}
+
+@inline(never)
+public func run_AppendBytesMedium(_ N: Int) {
+    let data = sampleData(.medium)
+    benchmark_AppendBytes(N, 809, data)
+}
+
+@inline(never)
+public func run_AppendBytesLarge(_ N: Int) {
+    let data = sampleData(.veryLarge)
     benchmark_AppendBytes(N, 809, data)
 }
 
 @inline(never)
 public func run_AppendArray(_ N: Int) {
-    let data = medium
+    let data = sampleData(.medium)
     benchmark_AppendArray(N, 809, data)
 }
 
 @inline(never)
 public func run_Reset(_ N: Int) {
-    let data = medium
+    let data = sampleData(.medium)
     benchmark_Reset(N, 431..<809, data)
 }
 
 @inline(never)
 public func run_ReplaceSmall(_ N: Int) {
-    let data = medium
-    let replacement = small
+    let data = sampleData(.medium)
+    let replacement = sampleData(.small)
     benchmark_Replace(N, 431..<809, data, replacement)
 }
 
 @inline(never)
 public func run_ReplaceMedium(_ N: Int) {
-    let data = medium
-    let replacement = medium
+    let data = sampleData(.medium)
+    let replacement = sampleData(.medium)
     benchmark_Replace(N, 431..<809, data, replacement)
 }
 
 @inline(never)
 public func run_ReplaceLarge(_ N: Int) {
-    let data = medium
+    let data = sampleData(.medium)
     let replacement = sampleData(.large)
     benchmark_Replace(N, 431..<809, data, replacement)
 }
 
 @inline(never)
 public func run_ReplaceSmallBuffer(_ N: Int) {
-    let data = medium
-    let replacement = small
+    let data = sampleData(.medium)
+    let replacement = sampleData(.small)
     let sz = replacement.count
     replacement.withUnsafeBytes { (ptr: UnsafePointer<UInt8>) in
         benchmark_ReplaceBuffer(N, 431..<809, data, UnsafeBufferPointer(start: ptr, count: sz))
@@ -328,8 +461,8 @@
 
 @inline(never)
 public func run_ReplaceMediumBuffer(_ N: Int) {
-    let data = medium
-    let replacement = medium
+    let data = sampleData(.medium)
+    let replacement = sampleData(.medium)
     let sz = replacement.count
     replacement.withUnsafeBytes { (ptr: UnsafePointer<UInt8>) in
         benchmark_ReplaceBuffer(N, 431..<809, data, UnsafeBufferPointer(start: ptr, count: sz))
@@ -338,7 +471,7 @@
 
 @inline(never)
 public func run_ReplaceLargeBuffer(_ N: Int) {
-    let data = medium
+    let data = sampleData(.medium)
     let replacement = sampleData(.large)
     let sz = replacement.count
     replacement.withUnsafeBytes { (ptr: UnsafePointer<UInt8>) in
@@ -348,62 +481,62 @@
 
 @inline(never)
 public func run_AppendSequence(_ N: Int) {
-    let data = medium
+    let data = sampleData(.medium)
     benchmark_AppendSequence(N, 809, data)
 }
 
 @inline(never)
 public func run_AppendDataSmallToSmall(_ N: Int) {
-    let data = small
-    let other = small
+    let data = sampleData(.small)
+    let other = sampleData(.small)
     benchmark_AppendData(N, data, other)
 }
 
 @inline(never)
 public func run_AppendDataSmallToMedium(_ N: Int) {
-    let data = medium
-    let other = small
+    let data = sampleData(.medium)
+    let other = sampleData(.small)
     benchmark_AppendData(N, data, other)
 }
 
 @inline(never)
 public func run_AppendDataSmallToLarge(_ N: Int) {
     let data = sampleData(.large)
-    let other = small
+    let other = sampleData(.small)
     benchmark_AppendData(N, data, other)
 }
 
 @inline(never)
 public func run_AppendDataMediumToSmall(_ N: Int) {
-    let data = small
-    let other = medium
+    let data = sampleData(.small)
+    let other = sampleData(.medium)
     benchmark_AppendData(N, data, other)
 }
 
 @inline(never)
 public func run_AppendDataMediumToMedium(_ N: Int) {
-    let data = medium
-    let other = medium
+    let data = sampleData(.medium)
+    let other = sampleData(.medium)
     benchmark_AppendData(N, data, other)
 }
 
 @inline(never)
 public func run_AppendDataMediumToLarge(_ N: Int) {
     let data = sampleData(.large)
-    let other = medium
+    let other = sampleData(.medium)
     benchmark_AppendData(N, data, other)
 }
 
 @inline(never)
 public func run_AppendDataLargeToSmall(_ N: Int) {
-    let data = small
+    let data = sampleData(.small)
     let other = sampleData(.large)
     benchmark_AppendData(N, data, other)
 }
 
 @inline(never)
 public func run_AppendDataLargeToMedium(_ N: Int) {
-    let data = medium
+    let data = sampleData(.medium)
     let other = sampleData(.large)
     benchmark_AppendData(N, data, other)
 }
@@ -414,3 +547,104 @@
     let other = sampleData(.large)
     benchmark_AppendData(N, data, other)
 }
+
+@inline(never)
+public func run_createEmpty(_ N: Int) {
+    for _ in 0..<100000 * N {
+        blackHole(Data())
+    }
+}
+
+@inline(never)
+public func run_createSmall(_ N: Int) {
+    for _ in 0..<100000 * N {
+        blackHole(sampleData(.small))
+    }
+}
+
+@inline(never)
+public func run_createMedium(_ N: Int) {
+    for _ in 0..<10000 * N {
+        blackHole(sampleData(.medium))
+    }
+}
+
+@inline(never)
+public func run_createLarge(_ N: Int) {
+    blackHole(sampleData(.veryLarge))
+}
+
+@inline(never)
+public func run_createEmptyArray(_ N: Int) {
+    for _ in 0..<100000 * N {
+        blackHole(Data([]))
+    }
+}
+
+@inline(never)
+public func run_createSmallArray(_ N: Int) {
+    for _ in 0..<100000 * N {
+        blackHole(Data([0, 1, 2, 3, 4, 5, 6]))
+    }
+}
+
+@inline(never)
+public func run_createMediumArray(_ N: Int) {
+    for _ in 0..<10000 * N {
+        blackHole(Data([0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6]))
+    }
+}
+
+@inline(never)
+public func run_DataToStringEmpty(_ N: Int) {
+    let d = Data()
+    for _ in 0..<10000 * N {
+        let s = String(decoding: d, as: UTF8.self)
+        blackHole(s)
+    }
+}
+
+@inline(never)
+public func run_DataToStringSmall(_ N: Int) {
+    let d = Data([0x0D, 0x0A])
+    for _ in 0..<10000 * N {
+        let s = String(decoding: d, as: UTF8.self)
+        blackHole(s)
+    }
+}
+
+@inline(never)
+public func run_DataToStringMedium(_ N: Int) {
+    let d = Data([0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A, 0x0D, 0x0A])
+    for _ in 0..<10000 * N {
+        let s = String(decoding: d, as: UTF8.self)
+        blackHole(s)
+    }
+}
+
+@inline(never)
+public func run_StringToDataEmpty(_ N: Int) {
+    let s = ""
+    for _ in 0..<10000 * N {
+        let d = Data(s.utf8)
+        blackHole(d)
+    }
+}
+
+@inline(never)
+public func run_StringToDataSmall(_ N: Int) {
+    let s = "\r\n"
+    for _ in 0..<10000 * N {
+        let d = Data(s.utf8)
+        blackHole(d)
+    }
+}
+
+@inline(never)
+public func run_StringToDataMedium(_ N: Int) {
+    let s = "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"
+    for _ in 0..<10000 * N {
+        let d = Data(s.utf8)
+        blackHole(d)
+    }
+}
diff --git a/benchmark/single-source/ObjectiveCBridgingStubs.swift b/benchmark/single-source/ObjectiveCBridgingStubs.swift
index 4be2714..126488e 100644
--- a/benchmark/single-source/ObjectiveCBridgingStubs.swift
+++ b/benchmark/single-source/ObjectiveCBridgingStubs.swift
@@ -27,8 +27,20 @@
   BenchmarkInfo(name: "ObjectiveCBridgeStubToNSDate2", runFunction: run_ObjectiveCBridgeStubToNSDate, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubToNSString", runFunction: run_ObjectiveCBridgeStubToNSString, tags: [.validation, .bridging]),
   BenchmarkInfo(name: "ObjectiveCBridgeStubURLAppendPath2", runFunction: run_ObjectiveCBridgeStubURLAppendPath, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringIsEqual", runFunction: run_ObjectiveCBridgeStringIsEqual, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringIsEqual2", runFunction: run_ObjectiveCBridgeStringIsEqual2, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringIsEqualAllSwift", runFunction: run_ObjectiveCBridgeStringIsEqualAllSwift, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringCompare", runFunction: run_ObjectiveCBridgeStringCompare, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringCompare2", runFunction: run_ObjectiveCBridgeStringCompare2, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringGetASCIIContents", runFunction: run_ObjectiveCBridgeStringGetASCIIContents, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringGetUTF8Contents", runFunction: run_ObjectiveCBridgeStringGetUTF8Contents, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringRangeOfString", runFunction: run_ObjectiveCBridgeStringRangeOfString, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringHash", runFunction: run_ObjectiveCBridgeStringHash, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
+  BenchmarkInfo(name: "ObjectiveCBridgeStringUTF8String", runFunction: run_ObjectiveCBridgeStringUTF8String, tags: [.validation, .String, .bridging], setUpFunction: setup_StringBridgeBenchmark),
 ]
 
+var b:BridgeTester! = nil
+
 #if _runtime(_ObjC)
 @inline(never)
 func testObjectiveCBridgeStubFromNSString() {
@@ -258,3 +270,127 @@
   }
 #endif
 }
+
+@inline(never)
+internal func getStringsToBridge() -> [String] {
+  let strings1 = ["hello", "the quick brown fox jumps over the lazy dog", "the quick brown fox jumps over the lazy dög"]
+  return strings1 + strings1.map { $0 + $0 } //mix of literals and non-literals
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringIsEqual(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testIsEqualToString()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringIsEqual2(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testIsEqualToString2()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringIsEqualAllSwift(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testIsEqualToStringAllSwift()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringCompare(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testCompare()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringCompare2(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testCompare2()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringGetASCIIContents(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testGetASCIIContents()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringGetUTF8Contents(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testGetUTF8Contents()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringRangeOfString(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testRangeOfString()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringHash(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testHash()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func run_ObjectiveCBridgeStringUTF8String(N: Int) {
+  #if _runtime(_ObjC)
+  for _ in 0 ..< N {
+    autoreleasepool {
+      b.testUTF8String()
+    }
+  }
+  #endif
+}
+
+@inline(never)
+public func setup_StringBridgeBenchmark() {
+#if _runtime(_ObjC)
+  b = BridgeTester()
+  b.setUpStringTests(getStringsToBridge())
+#endif
+}
diff --git a/benchmark/utils/DriverUtils.swift b/benchmark/utils/DriverUtils.swift
index fc7b921..3785c89 100644
--- a/benchmark/utils/DriverUtils.swift
+++ b/benchmark/utils/DriverUtils.swift
@@ -524,6 +524,10 @@
     }
 
     test.tearDownFunction?()
+    if let lf = test.legacyFactor {
+      logVerbose("    Applying legacy factor: \(lf)")
+      samples = samples.map { $0 * lf }
+    }
 
     return BenchResults(samples, maxRSS: measureMemoryUsage())
   }
diff --git a/benchmark/utils/ObjectiveCTests/ObjectiveCTests.h b/benchmark/utils/ObjectiveCTests/ObjectiveCTests.h
index 8600c32..bfffa2f 100644
--- a/benchmark/utils/ObjectiveCTests/ObjectiveCTests.h
+++ b/benchmark/utils/ObjectiveCTests/ObjectiveCTests.h
@@ -19,9 +19,12 @@
   NSArray<NSString *> *myArrayOfStrings;
   NSDate *myBeginDate;
   NSDate *myEndDate;
+  NSArray<NSString *> *cornucopiaOfStrings;
+  NSArray<NSString *> *bridgedStrings;
 }
 
 - (id)init;
+- (void)setUpStringTests:(NSArray<NSString *> *)bridgedStrings;
 - (void)testFromString:(NSString *) str;
 - (NSString *)testToString;
 - (void)testFromArrayOfStrings:(NSArray<NSString *> *)arr;
@@ -31,6 +34,17 @@
 - (NSDate *)endDate;
 - (void)useDate:(NSDate *)date;
 
+- (void)testIsEqualToString;
+- (void)testIsEqualToString2;
+- (void)testIsEqualToStringAllSwift;
+- (void)testUTF8String;
+- (void)testGetUTF8Contents;
+- (void)testGetASCIIContents;
+- (void)testRangeOfString;
+- (void)testHash;
+- (void)testCompare;
+- (void)testCompare2;
+
 @end
 
 NS_ASSUME_NONNULL_END
diff --git a/benchmark/utils/ObjectiveCTests/ObjectiveCTests.m b/benchmark/utils/ObjectiveCTests/ObjectiveCTests.m
index 56a3d22..8c151fa 100644
--- a/benchmark/utils/ObjectiveCTests/ObjectiveCTests.m
+++ b/benchmark/utils/ObjectiveCTests/ObjectiveCTests.m
@@ -11,6 +11,94 @@
 //===----------------------------------------------------------------------===//
 
 #import "ObjectiveCTests.h"
+#import <objc/runtime.h>
+
+@interface CustomString : NSString {
+  unichar *_backing;
+  NSUInteger _length;
+}
+
+@end
+
+@implementation CustomString
+
+- (instancetype)initWithCharacters:(const unichar *)characters
+                            length:(NSUInteger)length {
+  self = [super init];
+  _backing = malloc(sizeof(unichar) * length);
+  memcpy(_backing, characters, length * sizeof(unichar));
+  _length = length;
+  return self;
+}
+
+- (void)dealloc {
+  free(_backing);
+}
+
+- (unichar)characterAtIndex:(NSUInteger)index {
+  return _backing[index];
+}
+
+- (NSUInteger)length {
+  return _length;
+}
+
+@end
+
+@interface CustomFastASCIIString : NSString {
+  char *_backing;
+  NSUInteger _length;
+}
+
+@end
+
+@implementation CustomFastASCIIString
+
+- (instancetype)initWithCString:(const char *)bytes
+                       encoding:(NSStringEncoding)encoding {
+  self = [super init];
+  _backing = strdup(bytes);
+  _length = strlen(_backing);
+  return self;
+}
+
+- (void)dealloc {
+  free(_backing);
+}
+
+- (NSStringEncoding)fastestEncoding {
+  return NSASCIIStringEncoding;
+}
+
+- (NSUInteger)length {
+  return _length;
+}
+
+- (unichar)characterAtIndex:(NSUInteger)index {
+  return _backing[index];
+}
+
+- (const char *)_fastCStringContents:(BOOL)nullTerminationRequired {
+  return _backing;
+}
+
+@end
+
+@interface CustomFastUnicodeString : CustomString
+
+@end
+
+@implementation CustomFastUnicodeString
+
+- (NSStringEncoding)fastestEncoding {
+  return NSUnicodeStringEncoding;
+}
+
+- (const unichar *)_fastCharacterContents {
+  return _backing;
+}
+
+@end
 
 @implementation BridgeTester
 
@@ -46,6 +134,177 @@
   return self;
 }
 
+- (void)setUpStringTests:(NSArray<NSString *> *)inBridgedStrings {
+  
+  const char *taggedContents = "hello";
+  const char *tagged2Contents = "hella";
+  const char *notTaggedContents = "the quick brown fox jumps over the lazy dog";
+  const char *notTagged2Contents = "the quick brown fox jumps over the lazy dogabc";
+  const char *nonASCIIContents = "the quick brown fox jümps over the lazy dog";
+  const char *nonASCII2Contents = "the quick brown fox jumps over the lazy dög";
+  const char *longNonASCIIContents = "the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy dïgz";
+  const char *longASCIIContents = "the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy the quick brown fox jumps over the lazy dogz";
+  
+  NSString *tagged = [NSString stringWithUTF8String:taggedContents];
+  NSString *tagged2 = [NSString stringWithUTF8String:tagged2Contents];
+  NSString *notTagged = [NSString stringWithUTF8String:notTaggedContents];
+  NSString *notTagged2 = [NSString stringWithUTF8String:notTaggedContents];
+  NSString *notTaggedLonger = [NSString stringWithUTF8String:notTagged2Contents];
+  NSString *nonASCII = [NSString stringWithUTF8String:nonASCIIContents];
+  NSString *nonASCII2 = [NSString stringWithUTF8String:nonASCIIContents];
+  NSString *nonASCIIOther = [NSString stringWithUTF8String:nonASCII2Contents];
+  NSString *longNonASCII = [NSString stringWithUTF8String:longNonASCIIContents];
+  NSString *noCopyLongNonASCII = [[NSString alloc] initWithBytesNoCopy:(void *)longNonASCIIContents length:strlen(longNonASCIIContents) encoding:NSUTF8StringEncoding freeWhenDone:NO];
+  NSString *noCopyLongASCII = [[NSString alloc] initWithBytesNoCopy:(void *)longASCIIContents length:strlen(longASCIIContents) encoding:NSUTF8StringEncoding freeWhenDone:NO];
+  NSString *constantTaggable = @"hello";
+  NSString *constantASCII = @"the quick brown fox jumps over the lazy dog";
+  NSString *constantNonASCII = @"the quick brown fox jümps over the lazy dog";
+  
+  unichar taggableUnichars[] = {
+    'h', 'e', 'l', 'l', 'o'
+  };
+  unichar nonTaggableUnichars[] = {
+    't', 'h', 'e',  'q', 'u', 'i', 'c', 'k',  'b', 'r', 'o', 'w', 'n',  'f', 'o', 'x',  'j', 'u', 'm', 'p', 's',  'o', 'v', 'e', 'r',  't', 'h', 'e',  'l', 'a', 'z', 'y',  'd', 'o', 'g'
+  };
+  NSString *taggableCustom = [[CustomString alloc] initWithCharacters:&taggableUnichars[0] length:sizeof(taggableUnichars) / sizeof(taggableUnichars[0])];
+  NSString *nonTaggableCustom = [[CustomString alloc] initWithCharacters:&nonTaggableUnichars[0] length:sizeof(nonTaggableUnichars) / sizeof(nonTaggableUnichars[0])];
+  NSString *taggableFastCustom = [[CustomFastASCIIString alloc] initWithCString:taggedContents encoding:NSASCIIStringEncoding];
+  NSString *nonTaggableFastCustom = [[CustomFastASCIIString alloc] initWithCString:notTaggedContents encoding:NSASCIIStringEncoding];
+  NSString *taggableUnicodeCustom = [[CustomFastUnicodeString alloc] initWithCharacters:&taggableUnichars[0] length:sizeof(taggableUnichars) / sizeof(taggableUnichars[0])];
+  NSString *nonTaggableUnicodeCustom = [[CustomFastUnicodeString alloc] initWithCharacters:&nonTaggableUnichars[0] length:sizeof(nonTaggableUnichars) / sizeof(nonTaggableUnichars[0])];
+  
+  cornucopiaOfStrings = [NSArray arrayWithObjects: tagged, tagged2, notTagged, notTagged2, notTaggedLonger, nonASCII, nonASCII2, nonASCIIOther, longNonASCII, noCopyLongASCII, noCopyLongNonASCII, constantASCII, constantNonASCII
+                         , taggableCustom, nonTaggableCustom, taggableFastCustom, nonTaggableFastCustom, taggableUnicodeCustom, nonTaggableUnicodeCustom, nil];
+  bridgedStrings = inBridgedStrings;
+}
+
+- (void)testIsEqualToString {
+  for (NSString *str1 in cornucopiaOfStrings) {
+    for (NSString *str2 in bridgedStrings) {
+      @autoreleasepool {
+        for (int i = 0; i < 10; i++) {
+          [str1 isEqualToString: str2];
+        }
+      }
+    }
+  }
+}
+
+- (void)testIsEqualToString2 {
+  for (NSString *str1 in bridgedStrings) {
+    for (NSString *str2 in cornucopiaOfStrings) {
+      @autoreleasepool {
+        for (int i = 0; i < 20; i++) {
+          [str1 isEqualToString: str2];
+        }
+      }
+    }
+  }
+}
+
+- (void)testIsEqualToStringAllSwift {
+  for (NSString *str1 in bridgedStrings) {
+    for (NSString *str2 in bridgedStrings) {
+      @autoreleasepool {
+        for (int i = 0; i < 50; i++) {
+          [str1 isEqualToString: str2];
+        }
+      }
+    }
+  }
+}
+
+- (void)testCompare {
+  for (NSString *str1 in cornucopiaOfStrings) {
+    for (NSString *str2 in bridgedStrings) {
+      @autoreleasepool {
+        for (int i = 0; i < 20; i++) {
+          (void)[str1 compare: str2];
+        }
+      }
+    }
+  }
+}
+
+- (void)testCompare2 {
+  for (NSString *str1 in bridgedStrings) {
+    for (NSString *str2 in cornucopiaOfStrings) {
+      @autoreleasepool {
+        for (int i = 0; i < 20; i++) {
+          (void)[str1 compare: str2];
+        }
+      }
+    }
+  }
+}
+
+
+- (void)testUTF8String {
+  for (NSString *str1 in bridgedStrings) {
+    @autoreleasepool {
+      for (int i = 0; i < 100; i++) {
+        (void)[str1 UTF8String];
+      }
+    }
+  }
+}
+
+- (void)testGetUTF8Contents {
+  for (NSString *str1 in bridgedStrings) {
+    for (int i = 0; i < 200; i++) {
+      const char *str = CFStringGetCStringPtr((CFStringRef)str1, kCFStringEncodingUTF8);
+      if (!str) {
+        char buffer[1024];
+        [str1 getCString: buffer maxLength: 1024 encoding: NSUTF8StringEncoding];
+      }
+    }
+  }
+}
+
+- (void)testGetASCIIContents {
+  for (NSString *str1 in bridgedStrings) {
+    for (int i = 0; i < 200; i++) {
+      const char *str = CFStringGetCStringPtr((CFStringRef)str1, kCFStringEncodingASCII);
+      if (!str) {
+        char buffer[1024];
+        [str1 getCString: buffer maxLength: 1024 encoding: NSASCIIStringEncoding];
+      }
+    }
+  }
+}
+
+- (void)testRangeOfString {
+  for (NSString *str1 in bridgedStrings) {
+    @autoreleasepool {
+      for (int i = 0; i < 300; i++) {
+        (void)[str1 rangeOfString:@"z"];
+      }
+    }
+  };
+}
+
+- (void) testHash {
+  for (NSString *str1 in bridgedStrings) {
+    @autoreleasepool {
+      for (int i = 0; i < 100; i++) {
+        [str1 hash];
+      }
+    }
+  }
+}
+
+- (void)testGetCharactersRange {
+  unichar *buffer = malloc(10000);
+  for (NSString *str1 in bridgedStrings) {
+    @autoreleasepool {
+      for (int i = 0; i < 100; i++) {
+        (void)[str1 getCharacters:buffer range:NSMakeRange(0, [str1 length])];
+      }
+    }
+  };
+  free(buffer);
+}
+
 - (NSString *)testToString {
   return myString;
 }
diff --git a/benchmark/utils/TestsUtils.swift b/benchmark/utils/TestsUtils.swift
index 8d6f52f..bdd63bb 100644
--- a/benchmark/utils/TestsUtils.swift
+++ b/benchmark/utils/TestsUtils.swift
@@ -26,18 +26,18 @@
   case runtime, refcount, metadata
   // Other general areas of compiled code validation.
   case abstraction, safetychecks, exceptions, bridging, concurrency
-   
+
   // Algorithms are "micro" that test some well-known algorithm in isolation:
   // sorting, searching, hashing, fibonaci, crypto, etc.
   case algorithm
-   
+
   // Miniapplications are contrived to mimic some subset of application behavior
   // in a way that can be easily measured. They are larger than micro-benchmarks,
   // combining multiple APIs, data structures, or algorithms. This includes small
   // standardized benchmarks, pieces of real applications that have been extracted
   // into a benchmark, important functionality like JSON parsing, etc.
   case miniapplication
-   
+
   // Regression benchmarks is a catch-all for less important "micro"
   // benchmarks. This could be a random piece of code that was attached to a bug
   // report. We want to make sure the optimizer as a whole continues to handle
@@ -46,12 +46,12 @@
   // as highly as "validation" benchmarks and likely won't be the subject of
   // future investigation unless they significantly regress.
   case regression
-   
+
   // Most benchmarks are assumed to be "stable" and will be regularly tracked at
   // each commit. A handful may be marked unstable if continually tracking them is
   // counterproductive.
   case unstable
-   
+
   // CPU benchmarks represent instrinsic Swift performance. They are useful for
   // measuring a fully baked Swift implementation across different platforms and
   // hardware. The benchmark should also be reasonably applicable to real Swift
@@ -151,16 +151,20 @@
     return _tearDownFunction
   }
 
+  public var legacyFactor: Int?
+
   public init(name: String, runFunction: @escaping (Int) -> (), tags: [BenchmarkCategory],
               setUpFunction: (() -> ())? = nil,
               tearDownFunction: (() -> ())? = nil,
-              unsupportedPlatforms: BenchmarkPlatformSet = []) {
+              unsupportedPlatforms: BenchmarkPlatformSet = [],
+              legacyFactor: Int? = nil) {
     self.name = name
     self._runFunction = runFunction
     self.tags = Set(tags)
     self._setUpFunction = setUpFunction
     self._tearDownFunction = tearDownFunction
     self.unsupportedPlatforms = unsupportedPlatforms
+    self.legacyFactor = legacyFactor
   }
 
   /// Returns true if this benchmark should be run on the current platform.
@@ -217,7 +221,7 @@
   return lfsrRandomGenerator.randInt()
 }
 
-@inline(__always)
+@inlinable @inline(__always)
 public func CheckResults(
     _ resultsMatch: Bool,
     file: StaticString = #file,
@@ -266,4 +270,3 @@
 // The same for Substring.
 @inline(never)
 public func getSubstring(_ s: Substring) -> Substring { return s }
-
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 86e0eef..f9dadec 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -2078,7 +2078,7 @@
 function(_add_swift_executable_single name)
   # Parse the arguments we were given.
   cmake_parse_arguments(SWIFTEXE_SINGLE
-    "EXCLUDE_FROM_ALL;DONT_STRIP_NON_MAIN_SYMBOLS;DISABLE_ASLR"
+    "EXCLUDE_FROM_ALL"
     "SDK;ARCHITECTURE"
     "DEPENDS;LLVM_COMPONENT_DEPENDS;LINK_LIBRARIES;LINK_FAT_LIBRARIES;COMPILE_FLAGS"
     ${ARGN})
@@ -2121,10 +2121,6 @@
     RESULT_VAR_NAME link_flags
     LIBRARY_SEARCH_DIRECTORIES_VAR_NAME library_search_directories)
 
-  if(SWIFTEXE_SINGLE_DISABLE_ASLR)
-    list(APPEND link_flags "-Wl,-no_pie")
-  endif()
-
   if(${SWIFTEXE_SINGLE_SDK} IN_LIST SWIFT_APPLE_PLATFORMS)
     list(APPEND link_flags
         "-Xlinker" "-rpath"
@@ -2205,7 +2201,7 @@
 function(add_swift_target_executable name)
   # Parse the arguments we were given.
   cmake_parse_arguments(SWIFTEXE_TARGET
-    "EXCLUDE_FROM_ALL;DONT_STRIP_NON_MAIN_SYMBOLS;DISABLE_ASLR;BUILD_WITH_STDLIB"
+    "EXCLUDE_FROM_ALL;;BUILD_WITH_STDLIB"
     ""
     "DEPENDS;LLVM_COMPONENT_DEPENDS;LINK_FAT_LIBRARIES"
     ${ARGN})
@@ -2215,12 +2211,6 @@
   translate_flag(${SWIFTEXE_TARGET_EXCLUDE_FROM_ALL}
       "EXCLUDE_FROM_ALL"
       SWIFTEXE_TARGET_EXCLUDE_FROM_ALL_FLAG)
-  translate_flag(${SWIFTEXE_TARGET_DONT_STRIP_NON_MAIN_SYMBOLS}
-      "DONT_STRIP_NON_MAIN_SYMBOLS"
-      SWIFTEXE_TARGET_DONT_STRIP_NON_MAIN_SYMBOLS_FLAG)
-  translate_flag(${SWIFTEXE_TARGET_DISABLE_ASLR}
-      "DISABLE_ASLR"
-      SWIFTEXE_DISABLE_ASLR_FLAG)
 
   # All Swift executables depend on the standard library.
   list(APPEND SWIFTEXE_TARGET_LINK_FAT_LIBRARIES swiftCore)
@@ -2263,9 +2253,7 @@
           SDK "${sdk}"
           ARCHITECTURE "${arch}"
           LINK_FAT_LIBRARIES ${SWIFTEXE_TARGET_LINK_FAT_LIBRARIES}
-          ${SWIFTEXE_TARGET_EXCLUDE_FROM_ALL_FLAG_CURRENT}
-          ${SWIFTEXE_TARGET_DONT_STRIP_NON_MAIN_SYMBOLS_FLAG}
-          ${SWIFTEXE_DISABLE_ASLR_FLAG})
+          ${SWIFTEXE_TARGET_EXCLUDE_FROM_ALL_FLAG_CURRENT})
 
       if(${sdk} IN_LIST SWIFT_APPLE_PLATFORMS)
         add_custom_command_target(unused_var2
diff --git a/cmake/modules/SwiftConfigureSDK.cmake b/cmake/modules/SwiftConfigureSDK.cmake
index def7d99..21e47a6 100644
--- a/cmake/modules/SwiftConfigureSDK.cmake
+++ b/cmake/modules/SwiftConfigureSDK.cmake
@@ -277,19 +277,21 @@
     set(WinSDK${arch}UMDir "$ENV{UniversalCRTSdkDir}/Lib/$ENV{UCRTVersion}/um/${WinSDKArchitecture}")
     set(OverlayDirectory "${CMAKE_BINARY_DIR}/winsdk_lib_${arch}_symlinks")
 
-    file(MAKE_DIRECTORY ${OverlayDirectory})
+    if(NOT EXISTS "$ENV{UniversalCRTSdkDir}/Include/$ENV{UCRTVersion}/um/WINDOWS.H")
+      file(MAKE_DIRECTORY ${OverlayDirectory})
 
-    file(GLOB libraries RELATIVE "${WinSDK${arch}UMDir}" "${WinSDK${arch}UMDir}/*")
-    foreach(library ${libraries})
-      get_filename_component(name_we "${library}" NAME_WE)
-      get_filename_component(ext "${library}" EXT)
-      string(TOLOWER "${ext}" lowercase_ext)
-      set(lowercase_ext_symlink_name "${name_we}${lowercase_ext}")
-      if(NOT library STREQUAL lowercase_ext_symlink_name)
-        execute_process(COMMAND
-                        "${CMAKE_COMMAND}" -E create_symlink "${WinSDK${arch}UMDir}/${library}" "${OverlayDirectory}/${lowercase_ext_symlink_name}")
-      endif()
-    endforeach()
+      file(GLOB libraries RELATIVE "${WinSDK${arch}UMDir}" "${WinSDK${arch}UMDir}/*")
+      foreach(library ${libraries})
+        get_filename_component(name_we "${library}" NAME_WE)
+        get_filename_component(ext "${library}" EXT)
+        string(TOLOWER "${ext}" lowercase_ext)
+        set(lowercase_ext_symlink_name "${name_we}${lowercase_ext}")
+        if(NOT library STREQUAL lowercase_ext_symlink_name)
+          execute_process(COMMAND
+                          "${CMAKE_COMMAND}" -E create_symlink "${WinSDK${arch}UMDir}/${library}" "${OverlayDirectory}/${lowercase_ext_symlink_name}")
+        endif()
+      endforeach()
+    endif()
   endforeach()
 
   # Add this to the list of known SDKs.
diff --git a/cmake/modules/SwiftSource.cmake b/cmake/modules/SwiftSource.cmake
index 9439d7b..92dfd62 100644
--- a/cmake/modules/SwiftSource.cmake
+++ b/cmake/modules/SwiftSource.cmake
@@ -243,10 +243,11 @@
 
   if(SWIFTFILE_IS_STDLIB)
     list(APPEND swift_flags "-Xfrontend" "-enable-sil-ownership")
+    list(APPEND swift_flags "-Xfrontend" "-enable-mandatory-semantic-arc-opts")
   endif()
 
-  if(SWIFT_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING AND SWIFTFILE_IS_STDLIB)
-    list(APPEND swift_flags "-Xfrontend" "-enforce-exclusivity=checked")
+  if(NOT SWIFT_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING AND SWIFTFILE_IS_STDLIB)
+    list(APPEND swift_flags "-Xfrontend" "-enforce-exclusivity=unchecked")
   endif()
 
   if(SWIFT_EMIT_SORTED_SIL_OUTPUT)
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index a0e91df..3f0d68f 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -90,6 +90,10 @@
    dependent-associated-conformance ::= '\x05' .{4}  // Reference points directly to associated conformance descriptor (NOT IMPLEMENTED)
    dependent-associated-conformance ::= '\x06' .{4}  // Reference points indirectly to associated conformance descriptor (NOT IMPLEMENTED)
 
+   associated-conformance-acceess-function ::= '\x07' .{4}  // Reference points directly to associated conformance access function relative to the protocol
+   associated-conformance-acceess-function ::= '\x08' .{4}  // Reference points directly to associated conformance access function relative to the conforming type
+   keypath-metadata-access-function ::= '\x09' {.4}  // Reference points directly to keypath type metadata access function
+
 Globals
 ~~~~~~~
 
@@ -113,7 +117,7 @@
   global ::= context 'MXE'               // extension descriptor
   global ::= context 'MXX'               // anonymous context descriptor
   global ::= context identifier 'MXY'    // anonymous context descriptor
-  global ::= type assoc-type-list 'MXA'  // generic parameter ref
+  global ::= type assoc-type-list 'MXA'  // generic parameter ref (HISTORICAL)
   global ::= protocol 'Mp'               // protocol descriptor
 
   global ::= nominal-type 'Mo'           // class metadata immediate member base offset
@@ -171,6 +175,8 @@
   global ::= global 'To'                 // swift-as-ObjC thunk
   global ::= global 'TD'                 // dynamic dispatch thunk
   global ::= global 'Td'                 // direct method reference thunk
+  global ::= global 'TI'                 // implementation of a dynamic_replaceable function
+  global ::= global 'TX'                 // function pointer of a dynamic_replaceable function
   global ::= entity entity 'TV'          // vtable override thunk, derived followed by base
   global ::= type label-list? 'D'        // type mangling for the debugger with label list for function types.
   global ::= type 'TC'                   // continuation prototype (not actually used for real symbols)
@@ -287,8 +293,8 @@
   ACCESSOR ::= 'p'                           // pseudo accessor referring to the storage itself
 
   ADDRESSOR-KIND ::= 'u'                     // unsafe addressor (no owner)
-  ADDRESSOR-KIND ::= 'O'                     // owning addressor (non-native owner)
-  ADDRESSOR-KIND ::= 'o'                     // owning addressor (native owner)
+  ADDRESSOR-KIND ::= 'O'                     // owning addressor (non-native owner), not used anymore
+  ADDRESSOR-KIND ::= 'o'                     // owning addressor (native owner), not used anymore
   ADDRESSOR-KIND ::= 'p'                     // pinning addressor (native owner), not used anymore
 
   decl-name ::= identifier
diff --git a/docs/ABIStabilityManifesto.md b/docs/ABIStabilityManifesto.md
index 19d52a6..8b4c57f 100644
--- a/docs/ABIStabilityManifesto.md
+++ b/docs/ABIStabilityManifesto.md
@@ -213,7 +213,7 @@
 
 For all of the areas discussed above, more aggressive layout improvements may be invented in the post-ABI stability future. For example, we may want to explore rearranging and packing nested type data members with outer type data members. Such improvements would have to be done in an ABI-additive fashion through deployment target and/or min-version checking. This may mean that the module file will need to track per-type ABI versioning information.
 
-A potentially out of date description of Swift's current type layout can be found in the [Type Layout docs](https://github.com/apple/swift/blob/master/docs/ABI.rst#type-layout).
+A potentially out of date description of Swift's current type layout can be found in the [Type Layout docs](https://github.com/apple/swift/blob/master/docs/ABI/TypeLayout.rst).
 
 
 ## <a name="metadata"></a>Type Metadata
@@ -230,7 +230,7 @@
 
 Stabilizing the ABI means producing a precise technical specification for the fixed part of the metadata layout of all language constructs so that future compilers and tools can continue to read and write them. A prose description is not necessarily needed, though explanations are useful. We will also want to carve out extra space for areas where it is likely to be needed for future functionality [[SR-3731](https://bugs.swift.org/browse/SR-3731)].
 
-For more, but potentially out of date, details see the [Type Metadata docs](https://github.com/apple/swift/blob/master/docs/ABI.rst#type-metadata).
+For more, but potentially out of date, details see the [Type Metadata docs](https://github.com/apple/swift/blob/master/docs/ABI/TypeMetadata.rst).
 
 ### Generic Parameters
 
@@ -284,7 +284,7 @@
 
 Mangling is used to produce unique symbols. It applies to both external (public) symbols as well as internal or hidden symbols. Only the mangling scheme for external symbols is part of ABI.
 
-ABI stability means a stable mangling scheme, fully specified so that future compilers and tools can honor it. For a potentially out-of-date specification of what the mangling currently looks like, see the [Name Mangling docs](https://github.com/apple/swift/blob/master/docs/ABI.rst#mangling).
+ABI stability means a stable mangling scheme, fully specified so that future compilers and tools can honor it. For a potentially out-of-date specification of what the mangling currently looks like, see the [Name Mangling docs](https://github.com/apple/swift/blob/master/docs/ABI/Mangling.rst).
 
 There are some corner cases currently in the mangling scheme that should be fixed before declaring ABI stability. We need to come up with a canonicalization of generic and protocol requirements to allow for order-agnostic mangling [[SR-3733](https://bugs.swift.org/browse/SR-3733)]. We also may decide to more carefully mangle variadicity of function parameters, etc [[SR-3734](https://bugs.swift.org/browse/SR-3734)]. Most often, though, mangling improvements focus on reducing symbol size.
 
diff --git a/docs/WindowsBuild.md b/docs/WindowsBuild.md
index 33a6e1e..aabcd6a 100644
--- a/docs/WindowsBuild.md
+++ b/docs/WindowsBuild.md
@@ -127,6 +127,7 @@
  -DLLVM_BUILD_EXTERNAL_COMPILER_RT=TRUE^
  -DLLVM_LIT_ARGS=-sv^
  -DLLVM_TARGETS_TO_BUILD=X86^
+ -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-windows-msvc^
  "%swift_source_dir%/llvm"
 popd
 cmake --build "%swift_source_dir%/build/Ninja-DebugAssert/llvm-windows-amd64"
diff --git a/include/swift/ABI/Enum.h b/include/swift/ABI/Enum.h
new file mode 100644
index 0000000..bf3c5ce
--- /dev/null
+++ b/include/swift/ABI/Enum.h
@@ -0,0 +1,53 @@
+//===--- Enum.h - Enum implementation runtime declarations ------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Enum implementation details declarations relevant to the ABI.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_ABI_ENUM_H
+#define SWIFT_ABI_ENUM_H
+
+#include <stdlib.h>
+
+namespace swift {
+
+struct EnumTagCounts {
+  unsigned numTags, numTagBytes;
+};
+
+inline EnumTagCounts
+getEnumTagCounts(size_t size, unsigned emptyCases, unsigned payloadCases) {
+  // We can use the payload area with a tag bit set somewhere outside of the
+  // payload area to represent cases. See how many bytes we need to cover
+  // all the empty cases.
+  unsigned numTags = payloadCases;
+  if (emptyCases > 0) {
+    if (size >= 4)
+      // Assume that one tag bit is enough if the precise calculation overflows
+      // an int32.
+      numTags += 1;
+    else {
+      unsigned bits = size * 8U;
+      unsigned casesPerTagBitValue = 1U << bits;
+      numTags += ((emptyCases + (casesPerTagBitValue-1U)) >> bits);
+    }
+  }
+  unsigned numTagBytes = (numTags <=    1 ? 0 :
+                          numTags <   256 ? 1 :
+                          numTags < 65536 ? 2 : 4);
+  return {numTags, numTagBytes};
+}
+
+} // namespace swift
+
+#endif // SWIFT_ABI_ENUM_H
diff --git a/include/swift/ABI/Metadata.h b/include/swift/ABI/Metadata.h
index 8ca8a9a..aba90ab 100644
--- a/include/swift/ABI/Metadata.h
+++ b/include/swift/ABI/Metadata.h
@@ -167,8 +167,9 @@
 /// The result of requesting type metadata.  Generally the return value of
 /// a function.
 ///
-/// For performance, functions returning this type should use SWIFT_CC so
-/// that the components are returned as separate values.
+/// For performance and ABI matching across Swift/C++, functions returning
+/// this type must use SWIFT_CC so that the components are returned as separate
+/// values.
 struct MetadataResponse {
   /// The requested metadata.
   const Metadata *Value;
@@ -624,11 +625,27 @@
     getValueWitnesses()->_asEVWT()->destructiveInjectEnumTag(value, tag, this);
   }
 
+  size_t vw_size() const {
+    return getValueWitnesses()->getSize();
+  }
+
+  size_t vw_alignment() const {
+    return getValueWitnesses()->getAlignment();
+  }
+
+  size_t vw_stride() const {
+    return getValueWitnesses()->getStride();
+  }
+
   /// Allocate an out-of-line buffer if values of this type don't fit in the
   /// ValueBuffer.
   /// NOTE: This is not a box for copy-on-write existentials.
   OpaqueValue *allocateBufferIn(ValueBuffer *buffer) const;
 
+  /// Get the address of the memory previously allocated in the ValueBuffer.
+  /// NOTE: This is not a box for copy-on-write existentials.
+  OpaqueValue *projectBufferFrom(ValueBuffer *buffer) const;
+
   /// Deallocate an out-of-line buffer stored in 'buffer' if values of this type
   /// are not stored inline in the ValueBuffer.
   void deallocateBufferIn(ValueBuffer *buffer) const;
@@ -2501,137 +2518,13 @@
 using GenericContextDescriptorHeader =
   TargetGenericContextDescriptorHeader<InProcess>;
 
-/// A reference to a generic parameter that is the subject of a requirement.
-/// This can refer either directly to a generic parameter or to a path to an
-/// associated type.
-template<typename Runtime>
-class TargetGenericParamRef {
-  union {
-    /// The word of storage, whose low bit indicates whether there is an
-    /// associated type path stored out-of-line and whose upper bits describe
-    /// the generic parameter at root of the path.
-    uint32_t Word;
-
-    /// This is the associated type path stored out-of-line. The \c bool
-    /// is used for masking purposes and is otherwise unused; instead, check
-    /// the low bit of \c Word.
-    RelativeDirectPointerIntPair<const void, bool> AssociatedTypePath;
-  };
-
-public:
-  /// Index of the parameter being referenced. 0 is the first generic parameter
-  /// of the root of the context hierarchy, and subsequent parameters are
-  /// numbered breadth-first from there.
-  unsigned getRootParamIndex() const {
-    // If there is no path, retrieve the index directly.
-    if ((Word & 0x01) == 0) return Word >> 1;
-
-    // Otherwise, the index is at the start of the associated type path.
-    return *reinterpret_cast<const unsigned *>(AssociatedTypePath.getPointer());
-  }
-  
-  /// A reference to an associated type along the reference path.
-  struct AssociatedTypeRef {
-    /// The protocol the associated type belongs to.
-    RelativeIndirectablePointer<TargetProtocolDescriptor<Runtime>,
-                                /*nullable*/ false> Protocol;
-    /// A reference to the associated type descriptor within the protocol.
-    RelativeIndirectablePointer<TargetProtocolRequirement<Runtime>,
-                                /*nullable*/ false> Requirement;
-  };
-  
-  /// A forward iterator that walks through the associated type path, which is
-  /// a zero-terminated array of AssociatedTypeRefs.
-  class AssociatedTypeIterator {
-    const void *addr;
-    
-    explicit AssociatedTypeIterator(const void *startAddr) : addr(startAddr) {}
-    
-    bool isEnd() const {
-      if (addr == nullptr)
-        return true;
-      unsigned word;
-      memcpy(&word, addr, sizeof(unsigned));
-      if (word == 0)
-        return true;
-      return false;
-    }
-
-    template <class> friend class TargetGenericParamRef;
-
-  public:
-    AssociatedTypeIterator() : addr(nullptr) {}
-
-    using iterator_category = std::forward_iterator_tag;
-    using value_type = AssociatedTypeRef;
-    using difference_type = std::ptrdiff_t;
-    using pointer = const AssociatedTypeRef *;
-    using reference = const AssociatedTypeRef &;
-    
-    bool operator==(AssociatedTypeIterator i) const {
-      // Iterators are same if they both point at the same place, or are both
-      // at the end (either by being initialized as an end iterator with a
-      // null address, or by being advanced to the null terminator of an
-      // associated type list).
-      if (addr == i.addr)
-        return true;
-      
-      if (isEnd() && i.isEnd())
-        return true;
-      
-      return false;
-    }
-    
-    bool operator!=(AssociatedTypeIterator i) const {
-      return !(*this == i);
-    }
-    
-    reference operator*() const {
-      return *reinterpret_cast<pointer>(addr);
-    }
-    pointer operator->() const {
-      return reinterpret_cast<pointer>(addr);
-    }
-    
-    AssociatedTypeIterator &operator++() {
-      addr = reinterpret_cast<const char*>(addr) + sizeof(AssociatedTypeRef);
-      return *this;
-    }
-    
-    AssociatedTypeIterator operator++(int) {
-      auto copy = *this;
-      ++*this;
-      return copy;
-    }
-  };
-  
-  /// Iterators for going through the associated type path from the root param.
-  AssociatedTypeIterator begin() const {
-    if (Word & 0x01) {
-      // The associated types start after the first word, which holds the
-      // root param index.
-      return AssociatedTypeIterator(
-        reinterpret_cast<const char*>(AssociatedTypePath.getPointer()) +
-                                        sizeof(unsigned));
-    } else {
-      // This is a direct param reference, so there are no associated types.
-      return end();
-    }
-  }
-  
-  AssociatedTypeIterator end() const {
-    return AssociatedTypeIterator{};
-  }
-};
-
-using GenericParamRef = TargetGenericParamRef<InProcess>;
-
 template<typename Runtime>
 class TargetGenericRequirementDescriptor {
 public:
   GenericRequirementFlags Flags;
-  /// The generic parameter or associated type that's constrained.
-  TargetGenericParamRef<Runtime> Param;
+
+  /// The type that's constrained, described as a mangled name.
+  RelativeDirectPointer<const char, /*nullable*/ false> Param;
 
 private:
   union {
@@ -2667,9 +2560,10 @@
     return getFlags().getKind();
   }
 
-  /// Retrieve the generic parameter that is the subject of this requirement.
-  const TargetGenericParamRef<Runtime> &getParam() const {
-    return Param;
+  /// Retrieve the generic parameter that is the subject of this requirement,
+  /// as a mangled type name.
+  StringRef getParam() const {
+    return swift::Demangle::makeSymbolicMangledNameStringRef(Param.get());
   }
 
   /// Retrieve the protocol for a Protocol requirement.
@@ -4230,6 +4124,80 @@
   }
 }
 
+/// An entry in the chain of dynamic replacement functions.
+struct DynamicReplacementChainEntry {
+  void *implementationFunction;
+  DynamicReplacementChainEntry *next;
+};
+
+/// A record describing the root of dynamic replacements for a function.
+struct DynamicReplacementKey {
+  RelativeDirectPointer<DynamicReplacementChainEntry, false> root;
+  uint32_t flags;
+};
+
+/// A record describing a dynamic function replacement.
+class DynamicReplacementDescriptor {
+  RelativeIndirectablePointer<DynamicReplacementKey, false> replacedFunctionKey;
+  RelativeDirectPointer<void, false> replacementFunction;
+  RelativeDirectPointer<DynamicReplacementChainEntry, false> chainEntry;
+  uint32_t flags;
+
+  enum : uint32_t { EnableChainingMask = 0x1 };
+
+public:
+  /// Enable this replacement by changing the function's replacement chain's
+  /// root entry.
+  /// This replacement must be done while holding a global lock that guards this
+  /// function's chain. Currently this is done by holding the
+  /// \p DynamicReplacementLock.
+  void enableReplacement() const;
+
+  /// Disable this replacement by changing the function's replacement chain's
+  /// root entry.
+  /// This replacement must be done while holding a global lock that guards this
+  /// function's chain. Currently this is done by holding the
+  /// \p DynamicReplacementLock.
+  void disableReplacement() const;
+
+  uint32_t getFlags() const { return flags; }
+
+  bool shouldChain() const { return (flags & EnableChainingMask); }
+};
+
+/// A collection of dynamic replacement records.
+class DynamicReplacementScope
+    : private swift::ABI::TrailingObjects<DynamicReplacementScope,
+                                          DynamicReplacementDescriptor> {
+
+  uint32_t flags;
+  uint32_t numReplacements;
+
+  using TrailingObjects =
+      swift::ABI::TrailingObjects<DynamicReplacementScope,
+                                  DynamicReplacementDescriptor>;
+  friend TrailingObjects;
+
+  ArrayRef<DynamicReplacementDescriptor> getReplacementDescriptors() const {
+    return {this->template getTrailingObjects<DynamicReplacementDescriptor>(),
+            numReplacements};
+  }
+
+public:
+  void enable() const {
+    for (auto &descriptor : getReplacementDescriptors()) {
+      descriptor.enableReplacement();
+    }
+  }
+
+  void disable() const {
+    for (auto &descriptor : getReplacementDescriptors()) {
+      descriptor.disableReplacement();
+    }
+  }
+  uint32_t getFlags() { return flags; }
+};
+
 } // end namespace swift
 
 #pragma clang diagnostic pop
diff --git a/include/swift/AST/ASTMangler.h b/include/swift/AST/ASTMangler.h
index 392b2b7..f3221f9 100644
--- a/include/swift/AST/ASTMangler.h
+++ b/include/swift/AST/ASTMangler.h
@@ -33,13 +33,12 @@
 protected:
   CanGenericSignature CurGenericSignature;
   ModuleDecl *Mod = nullptr;
-  const DeclContext *DeclCtx = nullptr;
-  GenericEnvironment *GenericEnv = nullptr;
 
   /// Optimize out protocol names if a type only conforms to one protocol.
   bool OptimizeProtocolNames = true;
 
-  /// If enabled, Arche- and Alias types are mangled with context.
+  /// If enabled, non-canonical types are allowed and type alias types get a
+  /// special mangling.
   bool DWARFMangling;
 
   /// If enabled, entities that ought to have names but don't get a placeholder.
@@ -93,7 +92,6 @@
                                           bool isDestroyer, SymbolKind SKind);
 
   std::string mangleAccessorEntity(AccessorKind kind,
-                                   AddressorKind addressorKind,
                                    const AbstractStorageDecl *decl,
                                    bool isStatic,
                                    SymbolKind SKind);
@@ -148,8 +146,7 @@
   std::string mangleKeyPathHashHelper(ArrayRef<CanType> indices,
                                       GenericSignature *signature);
 
-  std::string mangleTypeForDebugger(Type decl, const DeclContext *DC,
-                                    GenericEnvironment *GE);
+  std::string mangleTypeForDebugger(Type decl, const DeclContext *DC);
 
   std::string mangleDeclType(const ValueDecl *decl);
   
@@ -164,7 +161,6 @@
   std::string mangleDeclAsUSR(const ValueDecl *Decl, StringRef USRPrefix);
 
   std::string mangleAccessorEntityAsUSR(AccessorKind kind,
-                                        AddressorKind addressorKind,
                                         const AbstractStorageDecl *decl,
                                         StringRef USRPrefix);
 
@@ -233,7 +229,7 @@
   void appendAnyGenericType(const GenericTypeDecl *decl);
 
   void appendFunction(AnyFunctionType *fn, bool isFunctionMangling = false);
-  void appendFunctionType(AnyFunctionType *fn);
+  void appendFunctionType(AnyFunctionType *fn, bool isAutoClosure = false);
 
   void appendFunctionSignature(AnyFunctionType *fn);
 
@@ -269,8 +265,7 @@
   void appendClosureEntity(const AbstractClosureExpr *closure);
 
   void appendClosureComponents(Type Ty, unsigned discriminator, bool isImplicit,
-                               const DeclContext *parentContext,
-                               const DeclContext *localContext);
+                               const DeclContext *parentContext);
 
   void appendDefaultArgumentEntity(const DeclContext *ctx, unsigned index);
 
diff --git a/include/swift/AST/AccessorKinds.def b/include/swift/AST/AccessorKinds.def
index eedc586..ad5f4db 100644
--- a/include/swift/AST/AccessorKinds.def
+++ b/include/swift/AST/AccessorKinds.def
@@ -73,36 +73,31 @@
 #define COROUTINE_ACCESSOR(ID, KEYWORD) OPAQUE_ACCESSOR(ID, KEYWORD)
 #endif
 
-/// ANY_ADDRESSOR(ACCESSOR_ID, ADDRESSOR_ID, KEYWORD)
+/// ANY_ADDRESSOR(ID, KEYWORD)
 ///   The given keyword corresponds to an addressor of the given kind.
 ///
-///   Defaults to ACCESSOR_KEYWORD(KEYWORD) if that is defined; otherwise
-///   defaults to nothing.
+///   Defaults to SINGLETON_ACCESSOR(ID, KEYWORD).
 #ifndef ANY_ADDRESSOR
-#if defined(ACCESSOR_KEYWORD)
-#define ANY_ADDRESSOR(ACCESSOR_ID, ADDRESSOR_ID, KEYWORD) \
-  ACCESSOR_KEYWORD(KEYWORD)
-#else
-#define ANY_ADDRESSOR(ACCESSOR_ID, ADDRESSOR_ID, KEYWORD)
-#endif
+#define ANY_ADDRESSOR(ID, KEYWORD) \
+  SINGLETON_ACCESSOR(ID, KEYWORD)
 #endif
 
-/// IMMUTABLE_ADDRESSOR(ADDRESSOR_ID, KEYWORD)
+/// IMMUTABLE_ADDRESSOR(ID, KEYWORD)
 ///   The given keyword corresponds to an immutable addressor of the given kind.
 ///
-///   DEfaults to ANY_ADDRESSOR(Address, ADDRESSOR_ID, KEYWORD).
+///   DEfaults to ANY_ADDRESSOR(ID, KEYWORD).
 #ifndef IMMUTABLE_ADDRESSOR
-#define IMMUTABLE_ADDRESSOR(ADDRESSOR_ID, KEYWORD) \
-  ANY_ADDRESSOR(Address, ADDRESSOR_ID, KEYWORD)
+#define IMMUTABLE_ADDRESSOR(ID, KEYWORD) \
+  ANY_ADDRESSOR(ID, KEYWORD)
 #endif
 
-/// MUTABLE_ADDRESSOR(ADDRESSOR_ID, KEYWORD)
+/// MUTABLE_ADDRESSOR(ID, KEYWORD)
 ///   The given keyword corresponds to a mutable addressor of the given kind.
 ///
-///   DEfaults to ANY_ADDRESSOR(MutableAddress, ADDRESSOR_ID, KEYWORD).
+///   DEfaults to ANY_ADDRESSOR(ID, KEYWORD).
 #ifndef MUTABLE_ADDRESSOR
-#define MUTABLE_ADDRESSOR(ADDRESSOR_ID, KEYWORD) \
-  ANY_ADDRESSOR(MutableAddress, ADDRESSOR_ID, KEYWORD)
+#define MUTABLE_ADDRESSOR(ID, KEYWORD) \
+  ANY_ADDRESSOR(ID, KEYWORD)
 #endif
 
 // Suppress entries for accessors which can't be written in source code.
@@ -167,11 +162,7 @@
 /// Addressors are a way of proving more efficient access to storage
 /// when it is already stored in memory (but not as a stored member
 /// of the type).
-ACCESSOR(Address)
-
-IMMUTABLE_ADDRESSOR(Unsafe, unsafeAddress)
-IMMUTABLE_ADDRESSOR(Owning, addressWithOwner)
-IMMUTABLE_ADDRESSOR(NativeOwning, addressWithNativeOwner)
+IMMUTABLE_ADDRESSOR(Address, unsafeAddress)
 
 /// This is a mutableAddress-family accessor: a function that is
 /// called when the storage is modified and which works by returning
@@ -181,11 +172,7 @@
 /// Addressors are a way of proving more efficient access to storage
 /// when it is already stored in memory (but not as a stored member
 /// of the type).
-ACCESSOR(MutableAddress)
-
-MUTABLE_ADDRESSOR(Unsafe, unsafeMutableAddress)
-MUTABLE_ADDRESSOR(Owning, mutableAddressWithOwner)
-MUTABLE_ADDRESSOR(NativeOwning, mutableAddressWithNativeOwner)
+MUTABLE_ADDRESSOR(MutableAddress, unsafeMutableAddress)
 
 #ifdef LAST_ACCESSOR
 LAST_ACCESSOR(MutableAddress)
diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def
index 533aabd..8693e9b 100644
--- a/include/swift/AST/Attr.def
+++ b/include/swift/AST/Attr.def
@@ -133,7 +133,9 @@
   OnConstructor | OnFunc | OnAccessor | OnVar | OnSubscript |
   DeclModifier,
   5)
-// NOTE: 6 is unused
+SIMPLE_DECL_ATTR(dynamicCallable, DynamicCallable,
+  OnNominalType,
+  6)
 SIMPLE_DECL_ATTR(noreturn, NoReturn,
   OnFunc | OnAccessor,
   7)
@@ -177,7 +179,7 @@
   UserInaccessible,
   19)
 DECL_ATTR(inline, Inline,
-  OnFunc | OnAccessor | OnConstructor,
+  OnVar | OnSubscript | OnAbstractFunction,
   20)
 DECL_ATTR(_semantics, Semantics,
   OnAbstractFunction | OnSubscript |
@@ -243,9 +245,9 @@
   OnFunc | OnAccessor | OnVar | OnSubscript | OnConstructor | OnAssociatedType |
   DeclModifier |
   NotSerialized, 44)
-SIMPLE_DECL_ATTR(sil_stored, SILStored,
+SIMPLE_DECL_ATTR(_hasStorage, HasStorage,
   OnVar |
-  SILOnly |
+  UserInaccessible |
   NotSerialized, 45)
 DECL_ATTR(private, AccessControl,
   OnFunc | OnAccessor | OnExtension | OnGenericType | OnVar | OnSubscript |
@@ -378,6 +380,16 @@
   OnFunc | OnAccessor | OnVar | OnSubscript | OnConstructor | OnAssociatedType |
   UserInaccessible | NotSerialized,
   79)
+DECL_ATTR(_dynamicReplacement, DynamicReplacement,
+  OnAbstractFunction | OnVar | OnSubscript | UserInaccessible,
+  80)
+SIMPLE_DECL_ATTR(_borrowed, Borrowed,
+  OnVar | OnSubscript | UserInaccessible |
+  NotSerialized, 81)
+DECL_ATTR(_private, PrivateImport,
+  OnImport |
+  UserInaccessible |
+  NotSerialized, 82)
 
 #undef TYPE_ATTR
 #undef DECL_ATTR_ALIAS
diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h
index 417f924..367a198 100644
--- a/include/swift/AST/Attr.h
+++ b/include/swift/AST/Attr.h
@@ -44,6 +44,8 @@
 class ASTContext;
 struct PrintOptions;
 class Decl;
+class AbstractFunctionDecl;
+class FuncDecl;
 class ClassDecl;
 class GenericFunctionType;
 class LazyConformanceLoader;
@@ -205,6 +207,12 @@
       Swift3Inferred : 1
     );
 
+    SWIFT_INLINE_BITFIELD(DynamicReplacementAttr, DeclAttribute, 1,
+      /// Whether this attribute has location information that trails the main
+      /// record, which contains the locations of the parentheses and any names.
+      HasTrailingLocationInfo : 1
+    );
+
     SWIFT_INLINE_BITFIELD(AbstractAccessControlAttr, DeclAttribute, 3,
       AccessLevel : 3
     );
@@ -893,6 +901,96 @@
   }
 };
 
+class PrivateImportAttr final
+: public DeclAttribute {
+  StringRef SourceFile;
+
+  PrivateImportAttr(SourceLoc atLoc, SourceRange baseRange,
+                    StringRef sourceFile, SourceRange parentRange);
+
+public:
+  static PrivateImportAttr *create(ASTContext &Ctxt, SourceLoc AtLoc,
+                                   SourceLoc PrivateLoc, SourceLoc LParenLoc,
+                                   StringRef sourceFile, SourceLoc RParenLoc);
+
+  StringRef getSourceFile() const {
+    return SourceFile;
+  }
+  static bool classof(const DeclAttribute *DA) {
+    return DA->getKind() == DAK_PrivateImport;
+  }
+};
+
+/// The @_dynamicReplacement(for:) attribute.
+class DynamicReplacementAttr final
+    : public DeclAttribute,
+      private llvm::TrailingObjects<DynamicReplacementAttr, SourceLoc> {
+  friend TrailingObjects;
+
+  DeclName ReplacedFunctionName;
+  AbstractFunctionDecl *ReplacedFunction;
+
+  /// Create an @_dynamicReplacement(for:) attribute written in the source.
+  DynamicReplacementAttr(SourceLoc atLoc, SourceRange baseRange,
+                         DeclName replacedFunctionName, SourceRange parenRange);
+
+  explicit DynamicReplacementAttr(DeclName name)
+      : DeclAttribute(DAK_DynamicReplacement, SourceLoc(), SourceRange(),
+                      /*Implicit=*/false),
+        ReplacedFunctionName(name), ReplacedFunction(nullptr) {
+    Bits.DynamicReplacementAttr.HasTrailingLocationInfo = false;
+  }
+
+  /// Retrieve the trailing location information.
+  MutableArrayRef<SourceLoc> getTrailingLocations() {
+    assert(Bits.DynamicReplacementAttr.HasTrailingLocationInfo);
+    unsigned length = 2;
+    return {getTrailingObjects<SourceLoc>(), length};
+  }
+
+  /// Retrieve the trailing location information.
+  ArrayRef<SourceLoc> getTrailingLocations() const {
+    assert(Bits.DynamicReplacementAttr.HasTrailingLocationInfo);
+    unsigned length = 2; // lParens, rParens
+    return {getTrailingObjects<SourceLoc>(), length};
+  }
+
+public:
+  static DynamicReplacementAttr *
+  create(ASTContext &Context, SourceLoc AtLoc, SourceLoc DynReplLoc,
+         SourceLoc LParenLoc, DeclName replacedFunction, SourceLoc RParenLoc);
+
+  static DynamicReplacementAttr *create(ASTContext &ctx,
+                                        DeclName replacedFunction);
+
+  static DynamicReplacementAttr *create(ASTContext &ctx,
+                                        DeclName replacedFunction,
+                                        AbstractFunctionDecl *replacedFuncDecl);
+
+  DeclName getReplacedFunctionName() const {
+    return ReplacedFunctionName;
+  }
+
+  AbstractFunctionDecl *getReplacedFunction() const {
+    return ReplacedFunction;
+  }
+
+  void setReplacedFunction(AbstractFunctionDecl *f) {
+    assert(ReplacedFunction == nullptr);
+    ReplacedFunction = f;
+  }
+
+  /// Retrieve the location of the opening parentheses, if there is one.
+  SourceLoc getLParenLoc() const;
+
+  /// Retrieve the location of the closing parentheses, if there is one.
+  SourceLoc getRParenLoc() const;
+
+  static bool classof(const DeclAttribute *DA) {
+    return DA->getKind() == DAK_DynamicReplacement;
+  }
+};
+
 /// Represents any sort of access control modifier.
 class AbstractAccessControlAttr : public DeclAttribute {
 protected:
diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def
index 8e7dbc6..432f60e 100644
--- a/include/swift/AST/Builtins.def
+++ b/include/swift/AST/Builtins.def
@@ -536,6 +536,9 @@
 /// willThrow: Error -> ()
 BUILTIN_MISC_OPERATION(WillThrow, "willThrow", "", Special)
 
+/// poundAssert has type (Builtin.Int1, Builtin.RawPointer) -> ().
+BUILTIN_MISC_OPERATION(PoundAssert, "poundAssert", "", Special)
+
 #undef BUILTIN_MISC_OPERATION
 
 /// Builtins for instrumentation added by sanitizers during SILGen.
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 8dc885f..ca9e039 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -431,12 +431,9 @@
     SelfAccess : 2
   );
 
-  SWIFT_INLINE_BITFIELD(AccessorDecl, FuncDecl, 4+3,
+  SWIFT_INLINE_BITFIELD(AccessorDecl, FuncDecl, 4,
     /// The kind of accessor this is.
-    AccessorKind : 4,
-
-    /// The kind of addressor this is.
-    AddressorKind : 3
+    AccessorKind : 4
   );
 
   SWIFT_INLINE_BITFIELD(ConstructorDecl, AbstractFunctionDecl, 3+2+2+1,
@@ -573,7 +570,7 @@
     HasAnyUnavailableValues : 1
   );
 
-  SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1,
+  SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1,
     /// If the module was or is being compiled with `-enable-testing`.
     TestingEnabled : 1,
 
@@ -586,7 +583,10 @@
     RawResilienceStrategy : 1,
 
     /// Whether all imports have been resolved. Used to detect circular imports.
-    HasResolvedImports : 1
+    HasResolvedImports : 1,
+
+    // If the module was or is being compiled with `-enable-private-imports`.
+    PrivateImportsEnabled : 1
   );
 
   SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2,
@@ -2590,6 +2590,10 @@
   /// Is this declaration marked with 'dynamic'?
   bool isDynamic() const;
 
+  bool isObjCDynamic() const {
+    return isObjC() && isDynamic();
+  }
+
   /// Set whether this type is 'dynamic' or not.
   void setIsDynamic(bool value);
 
@@ -3015,6 +3019,14 @@
   llvm_unreachable("Unhandled PointerTypeKind in switch.");
 }
 
+enum KeyPathTypeKind : unsigned char {
+  KPTK_AnyKeyPath,
+  KPTK_PartialKeyPath,
+  KPTK_KeyPath,
+  KPTK_WritableKeyPath,
+  KPTK_ReferenceWritableKeyPath
+};
+
 /// NominalTypeDecl - a declaration of a nominal type, like a struct.
 class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
   SourceRange Braces;
@@ -3236,6 +3248,9 @@
   /// Is this the decl for Optional<T>?
   bool isOptionalDecl() const;
 
+  /// Is this a key path type?
+  Optional<KeyPathTypeKind> getKeyPathTypeKind() const;
+
 private:
   /// Predicate used to filter StoredPropertyRange.
   struct ToStoredProperty {
@@ -4834,7 +4849,10 @@
 
   /// The default value, if any, along with whether this is varargs.
   llvm::PointerIntPair<StoredDefaultArgument *, 1> DefaultValueAndIsVariadic;
-  
+
+  /// `@autoclosure` flag associated with this parameter.
+  bool IsAutoClosure = false;
+
 public:
   ParamDecl(VarDecl::Specifier specifier,
             SourceLoc specifierLoc, SourceLoc argumentNameLoc,
@@ -4918,7 +4936,11 @@
   /// Whether or not this parameter is varargs.
   bool isVariadic() const { return DefaultValueAndIsVariadic.getInt(); }
   void setVariadic(bool value = true) {DefaultValueAndIsVariadic.setInt(value);}
-  
+
+  /// Whether or not this parameter is marked with `@autoclosure`.
+  bool isAutoClosure() const { return IsAutoClosure; }
+  void setAutoClosure(bool value = true) { IsAutoClosure = value; }
+
   /// Remove the type of this varargs element designator, without the array
   /// type wrapping it.  A parameter like "Int..." will have formal parameter
   /// type of "[Int]" and this returns "Int".
@@ -5676,8 +5698,7 @@
   AbstractStorageDecl *Storage;
 
   AccessorDecl(SourceLoc declLoc, SourceLoc accessorKeywordLoc,
-               AccessorKind accessorKind, AddressorKind addressorKind,
-               AbstractStorageDecl *storage,
+               AccessorKind accessorKind, AbstractStorageDecl *storage,
                SourceLoc staticLoc, StaticSpellingKind staticSpelling,
                bool throws, SourceLoc throwsLoc,
                unsigned numParameterLists, GenericParamList *genericParams,
@@ -5689,14 +5710,12 @@
       AccessorKeywordLoc(accessorKeywordLoc),
       Storage(storage) {
     Bits.AccessorDecl.AccessorKind = unsigned(accessorKind);
-    Bits.AccessorDecl.AddressorKind = unsigned(addressorKind);
   }
 
   static AccessorDecl *createImpl(ASTContext &ctx,
                                   SourceLoc declLoc,
                                   SourceLoc accessorKeywordLoc,
                                   AccessorKind accessorKind,
-                                  AddressorKind addressorKind,
                                   AbstractStorageDecl *storage,
                                   SourceLoc staticLoc,
                                   StaticSpellingKind staticSpelling,
@@ -5710,7 +5729,6 @@
                               SourceLoc declLoc,
                               SourceLoc accessorKeywordLoc,
                               AccessorKind accessorKind,
-                              AddressorKind addressorKind,
                               AbstractStorageDecl *storage,
                               SourceLoc staticLoc,
                               StaticSpellingKind staticSpelling,
@@ -5721,7 +5739,6 @@
   static AccessorDecl *create(ASTContext &ctx, SourceLoc declLoc,
                               SourceLoc accessorKeywordLoc,
                               AccessorKind accessorKind,
-                              AddressorKind addressorKind,
                               AbstractStorageDecl *storage,
                               SourceLoc staticLoc,
                               StaticSpellingKind staticSpelling,
@@ -5741,10 +5758,6 @@
     return AccessorKind(Bits.AccessorDecl.AccessorKind);
   }
 
-  AddressorKind getAddressorKind() const {
-    return AddressorKind(Bits.AccessorDecl.AddressorKind);
-  }
-
   bool isGetter() const { return getAccessorKind() == AccessorKind::Get; }
   bool isSetter() const { return getAccessorKind() == AccessorKind::Set; }
   bool isAnyAddressor() const {
@@ -6791,12 +6804,6 @@
   }
 }
 
-inline bool DeclContext::isExtensionContext() const {
-  if (auto D = getAsDecl())
-    return ExtensionDecl::classof(D);
-  return false;
-}
-
 inline bool DeclContext::classof(const Decl *D) {
   switch (D->getKind()) { //
   default: return false;
@@ -6835,16 +6842,8 @@
   return result;
 }
 
-/// Determine the default argument kind and type for the given argument index
-/// in this declaration, which must be a function or constructor.
-///
-/// \param Index The index of the argument for which we are querying the
-/// default argument.
-///
-/// \returns the default argument kind and, if there is a default argument,
-/// the type of the corresponding parameter.
-std::pair<DefaultArgumentKind, Type>
-getDefaultArgumentInfo(ValueDecl *source, unsigned Index);
+/// Retrieve parameter declaration from the given source at given index.
+const ParamDecl *getParameterAt(ValueDecl *source, unsigned index);
 
 /// Display Decl subclasses.
 void simple_display(llvm::raw_ostream &out, const Decl *decl);
diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h
index ca665e4..9437de7 100644
--- a/include/swift/AST/DeclContext.h
+++ b/include/swift/AST/DeclContext.h
@@ -277,10 +277,6 @@
   LLVM_READONLY
   bool isTypeContext() const;
 
-  /// \brief Determine whether this is an extension context.
-  LLVM_READONLY
-  bool isExtensionContext() const; // see swift/AST/Decl.h
-
   /// If this DeclContext is a NominalType declaration or an
   /// extension thereof, return the NominalTypeDecl.
   LLVM_READONLY
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 2e7c09d..96ee05e 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -99,6 +99,11 @@
         "keyword '%0' does not need to be escaped in argument list",
         (StringRef))
 
+ERROR(forbidden_interpolated_string,none,
+      "%0 cannot be an interpolated string literal", (StringRef))
+ERROR(forbidden_extended_escaping_string,none,
+      "%0 cannot be an extended escaping string literal", (StringRef))
+
 //------------------------------------------------------------------------------
 // MARK: Lexer diagnostics
 //------------------------------------------------------------------------------
@@ -625,6 +630,8 @@
       "expected '}' at the end of a sil body", ())
 ERROR(expected_sil_function_type, none,
       "sil function expected to have SIL function type", ())
+ERROR(sil_dynamically_replaced_func_not_found,none,
+      "dynamically replaced function not found %0", (Identifier))
 
 // SIL Stage
 ERROR(expected_sil_stage_name, none,
@@ -1261,6 +1268,17 @@
 ERROR(expr_dynamictype_deprecated,PointsToFirstBadToken,
       "'.dynamicType' is deprecated. Use 'type(of: ...)' instead", ())
 
+ERROR(pound_assert_disabled,PointsToFirstBadToken,
+      "#assert is an experimental feature that is currently disabled", ())
+ERROR(pound_assert_expected_lparen,PointsToFirstBadToken,
+      "expected '(' in #assert directive", ())
+ERROR(pound_assert_expected_rparen,PointsToFirstBadToken,
+      "expected ')' in #assert directive", ())
+ERROR(pound_assert_expected_expression,PointsToFirstBadToken,
+      "expected a condition expression", ())
+ERROR(pound_assert_expected_string_literal,PointsToFirstBadToken,
+      "expected a string literal", ())
+
 //------------------------------------------------------------------------------
 // MARK: Attribute-parsing diagnostics
 //------------------------------------------------------------------------------
@@ -1309,11 +1327,6 @@
 ERROR(swift_native_objc_runtime_base_must_be_identifier,none,
       "@_swift_native_objc_runtime_base class name must be an identifier", ())
 
-ERROR(attr_interpolated_string,none,
-"'%0' cannot be an interpolated string literal", (StringRef))
-ERROR(attr_extended_escaping_string,none,
-"'%0' cannot be an extended escaping string literal", (StringRef))
-
 ERROR(attr_only_at_non_local_scope, none,
       "attribute '%0' can only be used in a non-local scope", (StringRef))
 
@@ -1406,6 +1419,24 @@
       "@NSKeyedArchiverEncodeNonGenericSubclassesOnly is no longer necessary",
       ())
 
+ERROR(attr_dynamic_replacement_expected_rparen,none,
+      "expected ')' after function name for @_dynamicReplacement", ())
+ERROR(attr_dynamic_replacement_expected_function,none,
+      "expected a function name in @_dynamicReplacement(for:)", ())
+ERROR(attr_dynamic_replacement_expected_for,none,
+      "expected 'for' in '_dynamicReplacement' attribute", ())
+ERROR(attr_dynamic_replacement_expected_colon,none,
+      "expected ':' after @_dynamicReplacement(for", ())
+
+ERROR(attr_private_import_expected_rparen,none,
+      "expected ')' after function name for @_private", ())
+ERROR(attr_private_import_expected_sourcefile, none,
+      "expected 'sourceFile' in '_private' attribute", ())
+ERROR(attr_private_import_expected_sourcefile_name,none,
+      "expected a source file name in @_private(sourceFile:)", ())
+ERROR(attr_private_import_expected_colon,none,
+      "expected ':' after @_private(sourceFile", ())
+
 // opened
 ERROR(opened_attribute_expected_lparen,none,
       "expected '(' after 'opened' attribute", ())
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 3ab04ca..639cee3 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -510,6 +510,8 @@
       "string interpolation can only appear inside a string literal", ())
 ERROR(unsupported_keypath_tuple_element_reference,none,
       "key path cannot reference tuple elements", ())
+ERROR(expr_keypath_unimplemented_tuple,none,
+      "key path support for tuples is not implemented", ())
 ERROR(expr_keypath_subscript_index_not_hashable, none,
       "subscript index of type %0 in a key path must be Hashable", (Type))
 ERROR(expr_smart_keypath_application_type_mismatch,none,
@@ -759,6 +761,10 @@
 ERROR(module_not_testable,none,
       "module %0 was not compiled for testing", (Identifier))
 
+ERROR(module_not_compiled_for_private_import,none,
+      "module %0 was not compiled for private import", (Identifier))
+
+
 // Operator decls
 ERROR(ambiguous_operator_decls,none,
       "ambiguous operator declarations found for operator", ())
@@ -966,6 +972,10 @@
 ERROR(extra_address_of_unsafepointer,none,
       "'&' is not allowed passing array value as %0 argument",
       (Type))
+ERROR(cannot_pass_inout_arg_to_subscript,none,
+      "cannot pass an inout argument to a subscript; use "
+      "'withUnsafeMutablePointer' to explicitly convert argument "
+      "to a pointer", ())
 
 ERROR(missing_init_on_metatype_initialization,none,
       "initializing from a metatype value must reference 'init' explicitly",
@@ -1038,9 +1048,18 @@
 NOTE(unbound_generic_parameter_explicit_fix,none,
      "explicitly specify the generic arguments to fix this issue", ())
 
-ERROR(type_invalid_dml,none,
+ERROR(invalid_dynamic_callable_type,none,
+      "@dynamicCallable attribute requires %0 to have either a valid "
+      "'dynamicallyCall(withArguments:)' method or "
+      "'dynamicallyCall(withKeywordArguments:)' method", (Type))
+ERROR(missing_dynamic_callable_kwargs_method,none,
+      "@dynamicCallable type %0 cannot be applied with keyword arguments; "
+      "missing 'dynamicCall(withKeywordArguments:)' method", (Type))
+
+ERROR(invalid_dynamic_member_lookup_type,none,
       "@dynamicMemberLookup attribute requires %0 to have a "
-      "'subscript(dynamicMember:)' member with a string index", (Type))
+      "'subscript(dynamicMember:)' method with an "
+      "'ExpressibleByStringLiteral' parameter", (Type))
 
 ERROR(string_index_not_integer,none,
       "String must not be indexed with %0, it has variable size elements",
@@ -1367,15 +1386,6 @@
       "variables",
       (unsigned))
 
-ERROR(pattern_no_uninhabited_type,none,
-      "%select{%select{variable|constant}0|stored property}1 %2 cannot have "
-      "enum type %3 with no cases",
-      (bool, bool, Identifier, Type))
-ERROR(pattern_no_uninhabited_tuple_type,none,
-      "%select{%select{variable|constant}0|stored property}1 %2 cannot have "
-      "tuple type %3 containing enum with no cases",
-      (bool, bool, Identifier, Type))
-
 ERROR(nscoding_unstable_mangled_name,none,
       "%select{private|fileprivate|nested|local}0 class %1 has an "
       "unstable name when archiving via 'NSCoding'",
@@ -1687,6 +1697,14 @@
       "%0 %1 must be as accessible as its enclosing type because it "
       "matches a requirement in protocol %3",
       (DescriptiveDeclKind, DeclName, AccessLevel, DeclName))
+ERROR(witness_not_usable_from_inline,none,
+      "%0 %1 must be declared '@usableFromInline' because "
+      "because it matches a requirement in protocol %2",
+      (DescriptiveDeclKind, DeclName, DeclName))
+WARNING(witness_not_usable_from_inline_warn,none,
+        "%0 %1 should be declared '@usableFromInline' because "
+        "because it matches a requirement in protocol %2",
+        (DescriptiveDeclKind, DeclName, DeclName))
 ERROR(type_witness_objc_generic_parameter,none,
       "type %0 involving Objective-C type parameter%select{| %1}2 cannot be "
       "used for associated type %3 of protocol %4",
@@ -3300,6 +3318,12 @@
 WARNING(type_inferred_to_undesirable_type,none,
         "%select{variable|constant}2 %0 inferred to have type %1, "
         "which may be unexpected", (Identifier, Type, bool))
+WARNING(type_inferred_to_uninhabited_type,none,
+        "%select{variable|constant}2 %0 inferred to have type %1, "
+        "which is an enum with no cases", (Identifier, Type, bool))
+WARNING(type_inferred_to_uninhabited_tuple_type,none,
+        "%select{variable|constant}2 %0 inferred to have type %1, "
+        "which contains an enum with no cases", (Identifier, Type, bool))
 NOTE(add_explicit_type_annotation_to_silence,none,
      "add an explicit type annotation to silence this warning", ())
 
@@ -3863,6 +3887,16 @@
 #undef OBJC_ATTR_SELECT
 
 //------------------------------------------------------------------------------
+// MARK: @_borrowed
+//------------------------------------------------------------------------------
+ERROR(borrowed_with_objc_dynamic,none,
+      "%0 cannot be '@_borrowed' if it is '@objc dynamic'",
+      (DescriptiveDeclKind))
+ERROR(borrowed_on_objc_protocol_requirement,none,
+      "%0 cannot be '@_borrowed' if it is an @objc protocol requirement",
+      (DescriptiveDeclKind))
+
+//------------------------------------------------------------------------------
 // MARK: dynamic
 //------------------------------------------------------------------------------
 
@@ -3874,11 +3908,40 @@
 ERROR(dynamic_with_nonobjc,none,
       "a declaration cannot be both '@nonobjc' and 'dynamic'",
       ())
+ERROR(dynamic_with_transparent,none,
+      "a declaration cannot be both '@_tranparent' and 'dynamic'",
+      ())
 ERROR(dynamic_requires_objc,none,
       "'dynamic' %0 %1 must also be '@objc'",
       (DescriptiveDeclKind, DeclName))
 
 //------------------------------------------------------------------------------
+// MARK: @_dynamicReplacement(for:)
+//------------------------------------------------------------------------------
+
+ERROR(dynamic_replacement_accessor_type_mismatch, none,
+      "replaced accessor %0's type does not match", (DeclName))
+ERROR(dynamic_replacement_accessor_not_dynamic, none,
+      "replaced accessor for %0 is not marked dynamic", (DeclName))
+ERROR(dynamic_replacement_accessor_not_explicit, none,
+      "replaced accessor %select{get|set|_read|_modify|willSet|didSet|unsafeAddress|addressWithOwner|addressWithNativeOwner|unsafeMutableAddress|mutableAddressWithOwner|}0 for %1 is not explicitly defined",
+      (unsigned, DeclName))
+ERROR(dynamic_replacement_function_not_dynamic, none,
+      "replaced function %0 is not marked dynamic", (DeclName))
+ERROR(dynamic_replacement_function_not_found, none,
+     "replaced function %0 could not be found", (DeclName))
+ERROR(dynamic_replacement_accessor_not_found, none,
+      "replaced accessor for %0 could not be found", (DeclName))
+ERROR(dynamic_replacement_function_of_type_not_found, none,
+      "replaced function %0 of type %1 could not be found", (DeclName, Type))
+NOTE(dynamic_replacement_found_function_of_type, none,
+      "found function %0 of type %1", (DeclName, Type))
+ERROR(dynamic_replacement_not_in_extension, none,
+      "dynamicReplacement(for:) of %0 is not defined in an extension or at the file level", (DeclName))
+ERROR(dynamic_replacement_must_not_be_dynamic, none,
+      "dynamicReplacement(for:) of %0 must not be dynamic itself", (DeclName))
+
+//------------------------------------------------------------------------------
 // MARK: @available
 //------------------------------------------------------------------------------
 
@@ -4034,7 +4097,6 @@
 
 #define FRAGILE_FUNC_KIND \
   "%select{a '@_transparent' function|" \
-  "an '@inline(__always)' function|" \
   "an '@inlinable' function|" \
   "a default argument value|" \
   "a property initializer in a '@_fixed_layout' type}"
@@ -4063,7 +4125,7 @@
 
 ERROR(class_designated_init_inlinable_resilient,none,
       "initializer for class %0 is "
-      "'%select{@_transparent|@inline(__always)|@inlinable|%error}1' and must "
+      "'%select{@_transparent|@inlinable|%error}1' and must "
       "delegate to another initializer", (Type, unsigned))
 
 ERROR(attribute_invalid_on_stored_property,
diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h
index f9a9c47..cfe0243 100644
--- a/include/swift/AST/IRGenOptions.h
+++ b/include/swift/AST/IRGenOptions.h
@@ -187,6 +187,9 @@
   /// Instrument code to generate profiling information.
   unsigned GenerateProfile : 1;
 
+  /// Enable chaining of dynamic replacements.
+  unsigned EnableDynamicReplacementChaining : 1;
+
   /// Path to the profdata file to be used for PGO, or the empty string.
   std::string UseProfile = "";
 
@@ -219,7 +222,8 @@
         ValueNames(false), EnableReflectionMetadata(true),
         EnableReflectionNames(true), EnableClassResilience(false),
         EnableResilienceBypass(false), UseIncrementalLLVMCodeGen(true),
-        UseSwiftCall(false), GenerateProfile(false), CmdArgs(),
+        UseSwiftCall(false), GenerateProfile(false),
+        EnableDynamicReplacementChaining(false), CmdArgs(),
         SanitizeCoverage(llvm::SanitizerCoverageOptions()),
         TypeInfoFilter(TypeInfoDumpFilter::All) {}
 
diff --git a/include/swift/AST/KnownDecls.def b/include/swift/AST/KnownDecls.def
index 764b0c3..0bc8f4a 100644
--- a/include/swift/AST/KnownDecls.def
+++ b/include/swift/AST/KnownDecls.def
@@ -71,11 +71,15 @@
 
 FUNC_DECL(UnsafeBitCast, "unsafeBitCast")
 
-FUNC_DECL(ProjectKeyPathAny, "_projectKeyPathAny")
-FUNC_DECL(ProjectKeyPathPartial, "_projectKeyPathPartial")
-FUNC_DECL(ProjectKeyPathReadOnly, "_projectKeyPathReadOnly")
-FUNC_DECL(ProjectKeyPathWritable, "_projectKeyPathWritable")
-FUNC_DECL(ProjectKeyPathReferenceWritable, "_projectKeyPathReferenceWritable")
+FUNC_DECL(GetAtKeyPath, "_getAtKeyPath")
+FUNC_DECL(GetAtAnyKeyPath, "_getAtAnyKeyPath")
+FUNC_DECL(GetAtPartialKeyPath, "_getAtPartialKeyPath")
+FUNC_DECL(SetAtWritableKeyPath, "_setAtWritableKeyPath")
+FUNC_DECL(SetAtReferenceWritableKeyPath, "_setAtReferenceWritableKeyPath")
+// These don't actually have AST nodes associated with them right now.
+FUNC_DECL(ReadAtKeyPath, "_readAtKeyPath")
+FUNC_DECL(ModifyAtWritableKeyPath, "_modifyAtWritableKeyPath")
+FUNC_DECL(ModifyAtReferenceWritableKeyPath, "_modifyAtReferenceWritableKeyPath")
 
 FUNC_DECL(Swap, "swap")
 
diff --git a/include/swift/AST/KnownIdentifiers.def b/include/swift/AST/KnownIdentifiers.def
index 9119283..0808f93 100644
--- a/include/swift/AST/KnownIdentifiers.def
+++ b/include/swift/AST/KnownIdentifiers.def
@@ -47,6 +47,7 @@
 IDENTIFIER(decodeIfPresent)
 IDENTIFIER(Decoder)
 IDENTIFIER(decoder)
+IDENTIFIER(dynamicallyCall)
 IDENTIFIER(dynamicMember)
 IDENTIFIER(Element)
 IDENTIFIER(Encodable)
@@ -114,6 +115,8 @@
 IDENTIFIER(value)
 IDENTIFIER_WITH_NAME(value_, "_value")
 IDENTIFIER(with)
+IDENTIFIER(withArguments)
+IDENTIFIER(withKeywordArguments)
 
 // Kinds of layout constraints
 IDENTIFIER_WITH_NAME(UnknownLayout, "_UnknownLayout")
diff --git a/include/swift/AST/LazyResolver.h b/include/swift/AST/LazyResolver.h
index b2911aa..80b64cc 100644
--- a/include/swift/AST/LazyResolver.h
+++ b/include/swift/AST/LazyResolver.h
@@ -78,6 +78,10 @@
   /// Mark the given conformance as "used" from the given declaration context.
   virtual void markConformanceUsed(ProtocolConformanceRef conformance,
                                    DeclContext *dc) = 0;
+
+  /// Fill in the signature conformances of the given protocol conformance.
+  virtual void checkConformanceRequirements(
+                                    NormalProtocolConformance *conformance) = 0;
 };
 
 class LazyMemberLoader;
diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h
index 47af3f7..0dd6e12 100644
--- a/include/swift/AST/Module.h
+++ b/include/swift/AST/Module.h
@@ -283,6 +283,15 @@
     Bits.ModuleDecl.TestingEnabled = enabled;
   }
 
+  /// Returns true if this module was or is begin compile with
+  /// `-enable-private-imports`.
+  bool arePrivateImportsEnabled() const {
+    return Bits.ModuleDecl.PrivateImportsEnabled;
+  }
+  void setPrivateImportsEnabled(bool enabled = true) {
+    Bits.ModuleDecl.PrivateImportsEnabled = true;
+  }
+
   /// Returns true if there was an error trying to load this module.
   bool failedToLoad() const {
     return Bits.ModuleDecl.FailedToLoad;
@@ -844,12 +853,30 @@
 
     /// This source file has access to testable declarations in the imported
     /// module.
-    Testable = 0x2
+    Testable = 0x2,
+
+    /// This source file has access to private declarations in the imported
+    /// module.
+    PrivateImport = 0x4,
   };
 
   /// \see ImportFlags
   using ImportOptions = OptionSet<ImportFlags>;
 
+  typedef std::pair<ImportOptions, StringRef> ImportOptionsAndFilename;
+
+  struct ImportedModuleDesc {
+    ModuleDecl::ImportedModule module;
+    ImportOptions importOptions;
+    StringRef filename;
+
+    ImportedModuleDesc(ModuleDecl::ImportedModule module, ImportOptions options)
+        : module(module), importOptions(options) {}
+    ImportedModuleDesc(ModuleDecl::ImportedModule module, ImportOptions options,
+                       StringRef filename)
+        : module(module), importOptions(options), filename(filename) {}
+  };
+
 private:
   std::unique_ptr<LookupCache> Cache;
   LookupCache &getCache() const;
@@ -857,7 +884,7 @@
   /// This is the list of modules that are imported by this module.
   ///
   /// This is filled in by the Name Binding phase.
-  ArrayRef<std::pair<ModuleDecl::ImportedModule, ImportOptions>> Imports;
+  ArrayRef<ImportedModuleDesc> Imports;
 
   /// A unique identifier representing this file; used to mark private decls
   /// within the file to keep them from conflicting with other files in the
@@ -961,10 +988,9 @@
              ImplicitModuleImportKind ModImpKind, bool KeepParsedTokens = false,
              bool KeepSyntaxTree = false);
 
-  void
-  addImports(ArrayRef<std::pair<ModuleDecl::ImportedModule, ImportOptions>> IM);
+  void addImports(ArrayRef<ImportedModuleDesc> IM);
 
-  bool hasTestableImport(const ModuleDecl *module) const;
+  bool hasTestableOrPrivateImport(AccessLevel accessLevel, const ValueDecl *ofDecl) const;
 
   void clearLookupCache();
 
@@ -1224,12 +1250,29 @@
     assert(classof(this) && "invalid kind");
   }
 
+  /// A map from private/fileprivate decls to the file they were defined in.
+  llvm::DenseMap<const ValueDecl *, Identifier> FilenameForPrivateDecls;
+
 public:
+
   /// Returns an arbitrary string representing the storage backing this file.
   ///
   /// This is usually a filesystem path.
   virtual StringRef getFilename() const;
 
+  void addFilenameForPrivateDecl(const ValueDecl *decl, Identifier id) {
+    assert(!FilenameForPrivateDecls.count(decl) ||
+           FilenameForPrivateDecls[decl] == id);
+    FilenameForPrivateDecls[decl] = id;
+  }
+
+  StringRef getFilenameForPrivateDecl(const ValueDecl *decl) {
+    auto it = FilenameForPrivateDecls.find(decl);
+    if (it == FilenameForPrivateDecls.end())
+      return StringRef();
+    return it->second.str();
+  }
+
   /// Look up an operator declaration.
   ///
   /// \param name The operator name ("+", ">>", etc.)
diff --git a/include/swift/AST/ProtocolConformance.h b/include/swift/AST/ProtocolConformance.h
index 7c641c6..d89495b 100644
--- a/include/swift/AST/ProtocolConformance.h
+++ b/include/swift/AST/ProtocolConformance.h
@@ -549,6 +549,10 @@
   /// modules, but in a manner that ensures that all copies are equivalent.
   bool isSynthesizedNonUnique() const;
 
+  /// Whether clients from outside the module can rely on the value witnesses
+  /// being consistent across versions of the framework.
+  bool isResilient() const;
+
   /// Retrieve the type witness and type decl (if one exists)
   /// for the given associated type.
   std::pair<Type, TypeDecl *>
diff --git a/include/swift/AST/Stmt.h b/include/swift/AST/Stmt.h
index 8399259..fbf68ed 100644
--- a/include/swift/AST/Stmt.h
+++ b/include/swift/AST/Stmt.h
@@ -1225,6 +1225,31 @@
   }
 };
 
+/// PoundAssertStmt - Asserts that a condition is true, at compile time.
+class PoundAssertStmt : public Stmt {
+  SourceRange Range;
+  Expr *Condition;
+  StringRef Message;
+
+ public:
+  PoundAssertStmt(SourceRange Range, Expr *condition, StringRef message)
+      : Stmt(StmtKind::PoundAssert, /*Implicit=*/false),
+        Range(Range),
+        Condition(condition),
+        Message(message) {}
+
+  SourceRange getSourceRange() const { return Range; }
+
+  Expr *getCondition() const { return Condition; }
+  StringRef getMessage() const { return Message; }
+
+  void setCondition(Expr *condition) { Condition = condition; }
+
+  static bool classof(const Stmt *S) {
+    return S->getKind() == StmtKind::PoundAssert;
+  }
+};
+
 } // end namespace swift
 
 #endif // SWIFT_AST_STMT_H
diff --git a/include/swift/AST/StmtNodes.def b/include/swift/AST/StmtNodes.def
index b7cf7f8..9f53ea9 100644
--- a/include/swift/AST/StmtNodes.def
+++ b/include/swift/AST/StmtNodes.def
@@ -67,7 +67,8 @@
 STMT(Fallthrough, Stmt)
 STMT(Fail, Stmt)
 STMT(Throw, Stmt)
-LAST_STMT(Throw)
+STMT(PoundAssert, Stmt)
+LAST_STMT(PoundAssert)
 
 #undef STMT_RANGE
 #undef LABELED_STMT
diff --git a/include/swift/AST/StorageImpl.h b/include/swift/AST/StorageImpl.h
index 5dbb783..dc0e453 100644
--- a/include/swift/AST/StorageImpl.h
+++ b/include/swift/AST/StorageImpl.h
@@ -54,20 +54,6 @@
                                 AccessorKind(NumAccessorKinds));
 }
 
-/// The safety semantics of this addressor.
-enum class AddressorKind : uint8_t {
-  /// \brief This is not an addressor.
-  NotAddressor,
-  /// \brief This is an unsafe addressor; it simply returns an address.
-  Unsafe,
-  /// \brief This is an owning addressor; it returns an AnyObject
-  /// which should be released when the caller is done with the object.
-  Owning,
-  /// \brief This is an owning addressor; it returns a Builtin.NativeObject
-  /// which should be released when the caller is done with the object.
-  NativeOwning,
-};
-
 /// Whether an access to storage is for reading, writing, or both.
 enum class AccessKind : uint8_t {
   /// The access is just to read the current value.
@@ -160,8 +146,12 @@
 
   Kind getKind() const { return TheKind; }
 
+  bool hasAccessor() const {
+    return TheKind == DirectToAccessor || TheKind == DispatchToAccessor;
+  }
+
   AccessorKind getAccessor() const {
-    assert(TheKind == DirectToAccessor || TheKind == DispatchToAccessor);
+    assert(hasAccessor());
     return FirstAccessor;
   }
 
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index a030883..d3f0857 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -276,7 +276,7 @@
   }
 
 protected:
-  enum { NumAFTExtInfoBits = 7 };
+  enum { NumAFTExtInfoBits = 6 };
   enum { NumSILExtInfoBits = 6 };
   union { uint64_t OpaqueBits;
 
@@ -1743,7 +1743,8 @@
 
   /// Create one from what's present in the parameter type
   inline static ParameterTypeFlags
-  fromParameterType(Type paramTy, bool isVariadic, ValueOwnership ownership);
+  fromParameterType(Type paramTy, bool isVariadic, bool isAutoClosure,
+                    ValueOwnership ownership);
 
   bool isNone() const { return !value; }
   bool isVariadic() const { return value.contains(Variadic); }
@@ -2835,15 +2836,14 @@
     // If bits are added or removed, then TypeBase::AnyFunctionTypeBits
     // and NumMaskBits must be updated, and they must match.
     //
-    //   |representation|isAutoClosure|noEscape|throws|
-    //   |    0 .. 3    |      4      |    5   |   6  |
+    //   |representation|noEscape|throws|
+    //   |    0 .. 3    |    4   |   5  |
     //
     enum : unsigned {
       RepresentationMask     = 0xF << 0,
-      AutoClosureMask        = 1 << 4,
-      NoEscapeMask           = 1 << 5,
-      ThrowsMask             = 1 << 6,
-      NumMaskBits            = 7
+      NoEscapeMask           = 1 << 4,
+      ThrowsMask             = 1 << 5,
+      NumMaskBits            = 6
     };
 
     unsigned Bits; // Naturally sized for speed.
@@ -2865,14 +2865,12 @@
 
     // Constructor with no defaults.
     ExtInfo(Representation Rep,
-            bool IsAutoClosure, bool IsNoEscape,
+            bool IsNoEscape,
             bool Throws)
       : ExtInfo(Rep, Throws) {
-      Bits |= (IsAutoClosure ? AutoClosureMask : 0);
       Bits |= (IsNoEscape ? NoEscapeMask : 0);
     }
 
-    bool isAutoClosure() const { return Bits & AutoClosureMask; }
     bool isNoEscape() const { return Bits & NoEscapeMask; }
     bool throws() const { return Bits & ThrowsMask; }
     Representation getRepresentation() const {
@@ -2925,13 +2923,6 @@
                      | (unsigned)Rep);
     }
     LLVM_NODISCARD
-    ExtInfo withIsAutoClosure(bool IsAutoClosure = true) const {
-      if (IsAutoClosure)
-        return ExtInfo(Bits | AutoClosureMask);
-      else
-        return ExtInfo(Bits & ~AutoClosureMask);
-    }
-    LLVM_NODISCARD
     ExtInfo withNoEscape(bool NoEscape = true) const {
       if (NoEscape)
         return ExtInfo(Bits | NoEscapeMask);
@@ -3028,12 +3019,6 @@
   Representation getRepresentation() const {
     return getExtInfo().getRepresentation();
   }
-  
-  /// \brief True if this type allows an implicit conversion from a function
-  /// argument expression of type T to a function of type () -> T.
-  bool isAutoClosure() const {
-    return getExtInfo().isAutoClosure();
-  }
 
   /// \brief True if the parameter declaration it is attached to is guaranteed
   /// to not persist the closure for longer than the duration of the call.
@@ -5325,9 +5310,8 @@
 /// Create one from what's present in the parameter decl and type
 inline ParameterTypeFlags
 ParameterTypeFlags::fromParameterType(Type paramTy, bool isVariadic,
+                                      bool isAutoClosure,
                                       ValueOwnership ownership) {
-  bool autoclosure = paramTy->is<AnyFunctionType>() &&
-                     paramTy->castTo<AnyFunctionType>()->isAutoClosure();
   bool escaping = paramTy->is<AnyFunctionType>() &&
                   !paramTy->castTo<AnyFunctionType>()->isNoEscape();
   // FIXME(Remove InOut): The last caller that needs this is argument
@@ -5339,7 +5323,7 @@
            ownership == ValueOwnership::InOut);
     ownership = ValueOwnership::InOut;
   }
-  return {isVariadic, autoclosure, escaping, ownership};
+  return {isVariadic, isAutoClosure, escaping, ownership};
 }
 
 inline const Type *BoundGenericType::getTrailingObjectsPointer() const {
diff --git a/include/swift/Basic/FileTypes.def b/include/swift/Basic/FileTypes.def
index f388f8a..94c946f 100644
--- a/include/swift/Basic/FileTypes.def
+++ b/include/swift/Basic/FileTypes.def
@@ -50,8 +50,6 @@
 TYPE("swiftdoc",            SwiftModuleDocFile,        "swiftdoc",        "")
 TYPE("swiftinterface",      SwiftParseableInterfaceFile, \
                                                        "swiftinterface",  "")
-TYPE("swiftinterfacedeps",  SwiftParseableInterfaceDeps, \
-                                                       "sid",             "")
 TYPE("assembly",            Assembly,                  "s",               "")
 TYPE("raw-sil",             RawSIL,                    "sil",             "")
 TYPE("raw-sib",             RawSIB,                    "sib",             "")
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index db2cbc5..fbd54a1 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -144,6 +144,10 @@
     /// was not compiled with -enable-testing.
     bool EnableTestableAttrRequiresTestableModule = true;
 
+    /// If true, the 'dynamic' attribute is added to all applicable
+    /// declarations.
+    bool EnableImplicitDynamic = false;
+
     ///
     /// Flags for developers
     ///
@@ -207,6 +211,9 @@
     /// optimized custom allocator, so that memory debugging tools can be used.
     bool UseMalloc = false;
 
+    /// \brief Enable experimental #assert feature.
+    bool EnableExperimentalStaticAssert = false;
+
     /// \brief Enable experimental property behavior feature.
     bool EnableExperimentalPropertyBehaviors = false;
 
diff --git a/include/swift/Basic/Sanitizers.h b/include/swift/Basic/Sanitizers.h
index af7a706..b86718e 100644
--- a/include/swift/Basic/Sanitizers.h
+++ b/include/swift/Basic/Sanitizers.h
@@ -19,7 +19,8 @@
 enum class SanitizerKind : unsigned {
   Address = 1 << 1,
   Thread = 1 << 2,
-  Fuzzer = 1 << 3
+  Fuzzer = 1 << 3,
+  Undefined = 1 << 4
 };
 
 } // end namespace swift
diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def
index 10ac2d9..ca4dda0 100644
--- a/include/swift/Demangling/DemangleNodes.def
+++ b/include/swift/Demangling/DemangleNodes.def
@@ -71,6 +71,9 @@
 NODE(DynamicAttribute)
 NODE(DirectMethodReferenceAttribute)
 NODE(DynamicSelf)
+NODE(DynamicallyReplaceableFunctionImpl)
+NODE(DynamicallyReplaceableFunctionKey)
+NODE(DynamicallyReplaceableFunctionVar)
 CONTEXT_NODE(Enum)
 NODE(EnumCase)
 NODE(ErrorType)
diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h
index c254ba9..0547850 100644
--- a/include/swift/Driver/Driver.h
+++ b/include/swift/Driver/Driver.h
@@ -270,14 +270,12 @@
   /// \param[out] TopLevelActions The main Actions to build Jobs for.
   /// \param TC the default host tool chain.
   /// \param OI The OutputInfo for which Actions should be generated.
-  /// \param OFM The OutputFileMap for the compilation; used to find any
-  /// cross-build information.
   /// \param OutOfDateMap If present, information used to decide which files
   /// need to be rebuilt.
   /// \param C The Compilation to which Actions should be added.
   void buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
                     const ToolChain &TC, const OutputInfo &OI,
-                    const OutputFileMap *OFM, const InputInfoMap *OutOfDateMap,
+                    const InputInfoMap *OutOfDateMap,
                     Compilation &C) const;
 
   /// Construct the OutputFileMap for the driver from the given arguments.
@@ -331,7 +329,6 @@
                          CommandOutput *Output) const;
 
   void chooseSwiftModuleOutputPath(Compilation &C,
-                                   const OutputFileMap *OFM,
                                    const TypeToPathMap *OutputMap,
                                    StringRef workingDirectory,
                                    CommandOutput *Output) const;
diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h
index eb1093f..bb3d070 100644
--- a/include/swift/Frontend/FrontendOptions.h
+++ b/include/swift/Frontend/FrontendOptions.h
@@ -192,6 +192,11 @@
   /// \see ModuleDecl::isTestingEnabled
   bool EnableTesting = false;
 
+  /// Indicates whether we are compiling for private imports.
+  ///
+  /// \see ModuleDecl::arePrivateImportsEnabled
+  bool EnablePrivateImports = false;
+
   /// Enables the "fully resilient" resilience strategy.
   ///
   /// \see ResilienceStrategy::Resilient
diff --git a/include/swift/Frontend/ParseableInterfaceSupport.h b/include/swift/Frontend/ParseableInterfaceSupport.h
index 087d6c9..58b5c24 100644
--- a/include/swift/Frontend/ParseableInterfaceSupport.h
+++ b/include/swift/Frontend/ParseableInterfaceSupport.h
@@ -49,6 +49,11 @@
                             ParseableInterfaceOptions const &Opts,
                             ModuleDecl *M);
 
+/// Extract the specified-or-defaulted -module-cache-path that winds up in
+/// the clang importer, for reuse as the .swiftmodule cache path when
+/// building a ParseableInterfaceModuleLoader.
+std::string
+getModuleCachePathFromClang(const clang::CompilerInstance &Instance);
 
 /// A ModuleLoader that runs a subordinate \c CompilerInvocation and \c
 /// CompilerInstance to convert .swiftinterface files to .swiftmodule
@@ -66,8 +71,7 @@
   void
   configureSubInvocationAndOutputPaths(CompilerInvocation &SubInvocation,
                                        StringRef InPath,
-                                       llvm::SmallString<128> &OutPath,
-                                       llvm::SmallString<128> &DepPath);
+                                       llvm::SmallString<128> &OutPath);
 
   std::error_code
   openModuleFiles(StringRef DirName, StringRef ModuleFilename,
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index 3bbe48f..318e3d2 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -24,6 +24,8 @@
 #include "swift/SIL/SILModule.h"
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/GlobalObject.h"
+#include "llvm/IR/Module.h"
 
 namespace llvm {
 class Triple;
@@ -101,6 +103,10 @@
     // This field appears in associated conformance access functions.
     AssociatedConformanceIndexShift = 8,
     AssociatedConformanceIndexMask = ~KindMask,
+
+    // This field appears in SILFunction.
+    IsDynamicallyReplaceableImplShift = 8,
+    IsDynamicallyReplaceableImplMask = ~KindMask,
   };
 #define LINKENTITY_SET_FIELD(field, value) (value << field##Shift)
 #define LINKENTITY_GET_FIELD(value, field) ((value & field##Mask) >> field##Shift)
@@ -224,6 +230,20 @@
     /// is stored in the data.
     DefaultAssociatedConformanceAccessor,
 
+    /// A global function pointer for dynamically replaceable functions.
+    /// The pointer is a AbstractStorageDecl*.
+    DynamicallyReplaceableFunctionVariableAST,
+
+    /// The pointer is a AbstractStorageDecl*.
+    DynamicallyReplaceableFunctionKeyAST,
+
+    /// The original implementation of a dynamically replaceable function.
+    /// The pointer is a AbstractStorageDecl*.
+    DynamicallyReplaceableFunctionImpl,
+
+    /// The pointer is a SILFunction*.
+    DynamicallyReplaceableFunctionKey,
+
     /// A SIL function. The pointer is a SILFunction*.
     SILFunction,
 
@@ -313,6 +333,9 @@
 
     /// A coroutine continuation prototype function.
     CoroutineContinuationPrototype,
+
+    /// A global function pointer for dynamically replaceable functions.
+    DynamicallyReplaceableFunctionVariable,
   };
   friend struct llvm::DenseMapInfo<LinkEntity>;
 
@@ -321,7 +344,7 @@
   }
 
   static bool isDeclKind(Kind k) {
-    return k <= Kind::DefaultAssociatedConformanceAccessor;
+    return k <= Kind::DynamicallyReplaceableFunctionImpl;
   }
   static bool isTypeKind(Kind k) {
     return k >= Kind::ProtocolWitnessTableLazyAccessFunction;
@@ -703,12 +726,15 @@
     return entity;
   }
 
-  static LinkEntity forSILFunction(SILFunction *F)
-  {
+  static LinkEntity
+  forSILFunction(SILFunction *F, bool IsDynamicallyReplaceableImplementation) {
     LinkEntity entity;
     entity.Pointer = F;
     entity.SecondaryPointer = nullptr;
-    entity.Data = LINKENTITY_SET_FIELD(Kind, unsigned(Kind::SILFunction));
+    entity.Data =
+        LINKENTITY_SET_FIELD(Kind, unsigned(Kind::SILFunction)) |
+        LINKENTITY_SET_FIELD(IsDynamicallyReplaceableImpl,
+                             (unsigned)IsDynamicallyReplaceableImplementation);
     return entity;
   }
 
@@ -835,6 +861,45 @@
     return entity;
   }
 
+  static LinkEntity forDynamicallyReplaceableFunctionVariable(SILFunction *F) {
+    LinkEntity entity;
+    entity.Pointer = F;
+    entity.SecondaryPointer = nullptr;
+    entity.Data = LINKENTITY_SET_FIELD(
+        Kind, unsigned(Kind::DynamicallyReplaceableFunctionVariable));
+    return entity;
+  }
+
+  static LinkEntity
+  forDynamicallyReplaceableFunctionVariable(AbstractFunctionDecl *decl) {
+    LinkEntity entity;
+    entity.setForDecl(Kind::DynamicallyReplaceableFunctionVariableAST, decl);
+    return entity;
+  }
+
+  static LinkEntity forDynamicallyReplaceableFunctionKey(SILFunction *F) {
+    LinkEntity entity;
+    entity.Pointer = F;
+    entity.SecondaryPointer = nullptr;
+    entity.Data = LINKENTITY_SET_FIELD(
+        Kind, unsigned(Kind::DynamicallyReplaceableFunctionKey));
+    return entity;
+  }
+
+  static LinkEntity
+  forDynamicallyReplaceableFunctionKey(AbstractFunctionDecl *decl) {
+    LinkEntity entity;
+    entity.setForDecl(Kind::DynamicallyReplaceableFunctionKeyAST, decl);
+    return entity;
+  }
+
+  static LinkEntity
+  forDynamicallyReplaceableFunctionImpl(AbstractFunctionDecl *decl) {
+    LinkEntity entity;
+    entity.setForDecl(Kind::DynamicallyReplaceableFunctionImpl, decl);
+    return entity;
+  }
+
   void mangle(llvm::raw_ostream &out) const;
   void mangle(SmallVectorImpl<char> &buffer) const;
   std::string mangleAsString() const;
@@ -861,7 +926,9 @@
   }
 
   SILFunction *getSILFunction() const {
-    assert(getKind() == Kind::SILFunction);
+    assert(getKind() == Kind::SILFunction ||
+           getKind() == Kind::DynamicallyReplaceableFunctionVariable ||
+           getKind() == Kind::DynamicallyReplaceableFunctionKey);
     return reinterpret_cast<SILFunction*>(Pointer);
   }
 
@@ -897,7 +964,10 @@
     assert(getKind() == Kind::AssociatedTypeWitnessTableAccessFunction);
     return reinterpret_cast<ProtocolDecl*>(Pointer);
   }
-
+  bool isDynamicallyReplaceable() const {
+    assert(getKind() == Kind::SILFunction);
+    return LINKENTITY_GET_FIELD(Data, IsDynamicallyReplaceableImpl);
+  }
   bool isValueWitness() const { return getKind() == Kind::ValueWitness; }
   CanType getType() const {
     assert(isTypeKind(getKind()));
@@ -917,6 +987,9 @@
   bool isObjCClassRef() const {
     return getKind() == Kind::ObjCClassRef;
   }
+  bool isSILFunction() const {
+    return getKind() == Kind::SILFunction;
+  }
 
   /// Determine whether this entity will be weak-imported.
   bool isWeakImported(ModuleDecl *module) const;
@@ -935,14 +1008,46 @@
 #undef LINKENTITY_SET_FIELD
 };
 
+struct IRLinkage {
+  llvm::GlobalValue::LinkageTypes Linkage;
+  llvm::GlobalValue::VisibilityTypes Visibility;
+  llvm::GlobalValue::DLLStorageClassTypes DLLStorage;
+
+  static const IRLinkage InternalLinkOnceODR;
+  static const IRLinkage Internal;
+};
+
+class ApplyIRLinkage {
+  IRLinkage IRL;
+public:
+  ApplyIRLinkage(IRLinkage IRL) : IRL(IRL) {}
+  void to(llvm::GlobalValue *GV) const {
+    GV->setLinkage(IRL.Linkage);
+    GV->setVisibility(IRL.Visibility);
+    GV->setDLLStorageClass(IRL.DLLStorage);
+
+    if (IRL.Linkage == llvm::GlobalValue::LinkOnceODRLinkage ||
+        IRL.Linkage == llvm::GlobalValue::WeakODRLinkage) {
+      llvm::Module *M = GV->getParent();
+      const llvm::Triple Triple(M->getTargetTriple());
+
+      // TODO: BFD and gold do not handle COMDATs properly
+      if (Triple.isOSBinFormatELF())
+        return;
+
+      if (Triple.supportsCOMDAT())
+        if (llvm::GlobalObject *GO = dyn_cast<llvm::GlobalObject>(GV))
+          GO->setComdat(M->getOrInsertComdat(GV->getName()));
+    }
+  }
+};
+
 /// Encapsulated information about the linkage of an entity.
 class LinkInfo {
   LinkInfo() = default;
 
   llvm::SmallString<32> Name;
-  llvm::GlobalValue::LinkageTypes Linkage;
-  llvm::GlobalValue::VisibilityTypes Visibility;
-  llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass;
+  IRLinkage IRL;
   ForDefinition_t ForDefinition;
 
 public:
@@ -962,25 +1067,19 @@
     return Name.str();
   }
   llvm::GlobalValue::LinkageTypes getLinkage() const {
-    return Linkage;
+    return IRL.Linkage;
   }
   llvm::GlobalValue::VisibilityTypes getVisibility() const {
-    return Visibility;
+    return IRL.Visibility;
   }
   llvm::GlobalValue::DLLStorageClassTypes getDLLStorage() const {
-    return DLLStorageClass;
+    return IRL.DLLStorage;
   }
 
-  bool isForDefinition() const {
-    return ForDefinition;
-  }
-  bool isUsed() const {
-    return ForDefinition && isUsed(Linkage, Visibility, DLLStorageClass);
-  }
+  bool isForDefinition() const { return ForDefinition; }
+  bool isUsed() const { return ForDefinition && isUsed(IRL); }
 
-  static bool isUsed(llvm::GlobalValue::LinkageTypes Linkage,
-                     llvm::GlobalValue::VisibilityTypes Visibility,
-                     llvm::GlobalValue::DLLStorageClassTypes DLLStorage);
+  static bool isUsed(IRLinkage IRL);
 };
 
 StringRef encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index ea4dc3a..e03c32b 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -304,8 +304,8 @@
 def disable_guaranteed_normal_arguments : Flag<["-"], "disable-guaranteed-normal-arguments">,
   HelpText<"If set to true, all normal parameters (except to inits/setters) will be passed at +1">;
 
-def disable_mandatory_semantic_arc_opts : Flag<["-"], "disable-mandatory-semantic-arc-opts">,
-  HelpText<"Disable the mandatory semantic arc optimizer">;
+def enable_mandatory_semantic_arc_opts : Flag<["-"], "enable-mandatory-semantic-arc-opts">,
+  HelpText<"Enable the mandatory semantic arc optimizer">;
 
 def assume_parsing_unqualified_ownership_sil : Flag<["-"], "assume-parsing-unqualified-ownership-sil">,
   HelpText<"Assume unqualified SIL ownership when parsing SIL">;
@@ -319,6 +319,10 @@
 def enable_large_loadable_types : Flag<["-"], "enable-large-loadable-types">,
   HelpText<"Enable Large Loadable types IRGen pass">;
 
+def enable_experimental_static_assert :
+  Flag<["-"], "enable-experimental-static-assert">,
+  HelpText<"Enable experimental #assert">;
+
 def enable_experimental_property_behaviors :
   Flag<["-"], "enable-experimental-property-behaviors">,
   HelpText<"Enable experimental property behaviors">;
@@ -354,6 +358,15 @@
   Flags<[FrontendOption, HelpHidden]>,
   HelpText<"Disable Swift 3's @objc inference rules for NSObject-derived classes and 'dynamic' members (emulates Swift 4 behavior)">;
 
+def enable_implicit_dynamic : Flag<["-"], "enable-implicit-dynamic">,
+  Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
+  HelpText<"Add 'dynamic' to all declarations">;
+
+def enable_dynamic_replacement_chaining :
+  Flag<["-"], "enable-dynamic-replacement-chaining">,
+  Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
+  HelpText<"Enable chaining of dynamic replacements">;
+
 def enable_nskeyedarchiver_diagnostics :
   Flag<["-"], "enable-nskeyedarchiver-diagnostics">,
   HelpText<"Diagnose classes with unstable mangled names adopting NSCoding">;
diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td
index 17f9fb6..c38cd0f 100644
--- a/include/swift/Option/Options.td
+++ b/include/swift/Option/Options.td
@@ -791,6 +791,10 @@
   Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
   HelpText<"Allows this module's internal API to be accessed for testing">;
 
+def enable_private_imports : Flag<["-"], "enable-private-imports">,
+  Flags<[FrontendOption, NoInteractiveOption, HelpHidden]>,
+  HelpText<"Allows this module's internal and private API to be accessed">;
+
 def sanitize_EQ : CommaJoined<["-"], "sanitize=">,
   Flags<[FrontendOption, NoInteractiveOption]>, MetaVarName<"<check>">,
   HelpText<"Turn on runtime checks for erroneous behavior.">;
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index fce560c..6463192 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -555,7 +555,16 @@
 
   /// Parse an #endif.
   bool parseEndIfDirective(SourceLoc &Loc);
-  
+
+  /// Given that the current token is a string literal,
+  /// - if it is not interpolated, returns the contents;
+  /// - otherwise, diagnoses and returns None.
+  ///
+  /// \param Loc where to diagnose.
+  /// \param DiagText name for the string literal in the diagnostic.
+  Optional<StringRef>
+  getStringLiteralIfNotInterpolated(SourceLoc Loc, StringRef DiagText);
+
 public:
   InFlightDiagnostic diagnose(SourceLoc Loc, Diagnostic Diag) {
     if (Diags.isDiagnosticPointsToFirstBadToken(Diag.getID()) &&
@@ -1247,7 +1256,8 @@
   DeclName parseUnqualifiedDeclName(bool afterDot, DeclNameLoc &loc,
                                     const Diagnostic &diag,
                                     bool allowOperators=false,
-                                    bool allowZeroArgCompoundNames=false);
+                                    bool allowZeroArgCompoundNames=false,
+                                    bool allowDeinitAndSubscript=false);
 
   Expr *parseExprIdentifier();
   Expr *parseExprEditorPlaceholder(Token PlaceholderTok,
@@ -1325,6 +1335,7 @@
   ParserResult<Expr> parseExprCollection();
   ParserResult<Expr> parseExprArray(SourceLoc LSquareLoc);
   ParserResult<Expr> parseExprDictionary(SourceLoc LSquareLoc);
+  ParserResult<Expr> parseExprPoundAssert();
   ParserResult<Expr> parseExprPoundUnknown(SourceLoc LSquareLoc);
   ParserResult<Expr>
   parseExprPoundCodeCompletion(Optional<StmtKind> ParentKind);
@@ -1363,6 +1374,7 @@
   ParserResult<Stmt> parseStmtSwitch(LabeledStmtInfo LabelInfo);
   ParserStatus parseStmtCases(SmallVectorImpl<ASTNode> &cases, bool IsActive);
   ParserResult<CaseStmt> parseStmtCase(bool IsActive);
+  ParserResult<Stmt> parseStmtPoundAssert();
 
   //===--------------------------------------------------------------------===//
   // Generics Parsing
diff --git a/include/swift/Parse/SyntaxParsingCache.h b/include/swift/Parse/SyntaxParsingCache.h
index b82b73a..ffdbdce 100644
--- a/include/swift/Parse/SyntaxParsingCache.h
+++ b/include/swift/Parse/SyntaxParsingCache.h
@@ -34,8 +34,11 @@
   /// The length of the string that replaced the range described above.
   size_t ReplacementLength;
 
+  SourceEdit(size_t Start, size_t End, size_t ReplacementLength)
+      : Start(Start), End(End), ReplacementLength(ReplacementLength){};
+
   /// The length of the range that has been replaced
-  size_t originalLength() { return End - Start; }
+  size_t originalLength() const { return End - Start; }
 
   /// Check if the characters replaced by this edit fall into the given range
   /// or are directly adjacent to it
@@ -65,12 +68,16 @@
       : OldSyntaxTree(OldSyntaxTree) {}
 
   /// Add an edit that transformed the source file which created this cache into
-  /// the source file that is now being parsed incrementally. The order in which
-  /// the edits are added using this method needs to be the same order in which
-  /// the edits were applied to the source file.
-  void addEdit(size_t Start, size_t End, size_t ReplacementLength) {
-    Edits.push_back({Start, End, ReplacementLength});
-  }
+  /// the source file that is now being parsed incrementally. \c Start must be a
+  /// position from the *original* source file, and it must not overlap any
+  /// other edits previously added. For instance, given:
+  ///   (aaa, bbb)
+  ///   0123456789
+  /// When you want to turn this into:
+  ///   (c, dddd)
+  ///   0123456789
+  /// edits should be: { 1, 4, 1 } and { 6, 9, 4 }.
+  void addEdit(size_t Start, size_t End, size_t ReplacementLength);
 
   /// Check if a syntax node of the given kind at the given position can be
   /// reused for a new syntax tree.
@@ -86,11 +93,13 @@
   getReusedRegions(const SourceFileSyntax &SyntaxTree) const;
 
   /// Translates a post-edit position to a pre-edit position by undoing the
-  /// specified edits.
+  /// specified edits. Returns \c None if no pre-edit position exists because
+  /// the post-edit position has been inserted by an edit.
+  /// 
   /// Should not be invoked externally. Only public for testing purposes.
-  static size_t
+  static Optional<size_t>
   translateToPreEditPosition(size_t PostEditPosition,
-                             llvm::SmallVector<SourceEdit, 4> Edits);
+                             ArrayRef<SourceEdit> Edits);
 
 private:
   llvm::Optional<Syntax> lookUpFrom(const Syntax &Node, size_t NodeStart,
diff --git a/include/swift/Reflection/Records.h b/include/swift/Reflection/Records.h
index 350b0d1..6c95f9f 100644
--- a/include/swift/Reflection/Records.h
+++ b/include/swift/Reflection/Records.h
@@ -402,10 +402,23 @@
 
 public:
   uint32_t Size;
-  uint32_t Alignment;
+
+  // - Least significant 16 bits are the alignment.
+  // - Bit 16 is 'bitwise takable'.
+  // - Remaining bits are reserved.
+  uint32_t AlignmentAndFlags;
+
   uint32_t Stride;
   uint32_t NumExtraInhabitants;
 
+  bool isBitwiseTakable() const {
+    return (AlignmentAndFlags >> 16) & 1;
+  }
+
+  uint32_t getAlignment() const {
+    return AlignmentAndFlags & 0xffff;
+  }
+
   bool hasMangledTypeName() const {
     return TypeName;
   }
diff --git a/include/swift/Reflection/ReflectionContext.h b/include/swift/Reflection/ReflectionContext.h
index e77a6d1..935faad 100644
--- a/include/swift/Reflection/ReflectionContext.h
+++ b/include/swift/Reflection/ReflectionContext.h
@@ -541,13 +541,17 @@
       return nullptr;
 
     // Initialize the builder.
-    Builder.addField(*OffsetToFirstCapture, sizeof(StoredPointer),
-                     /*numExtraInhabitants=*/0);
+    Builder.addField(*OffsetToFirstCapture,
+                     /*alignment=*/sizeof(StoredPointer),
+                     /*numExtraInhabitants=*/0,
+                     /*bitwiseTakable=*/true);
 
     // Skip the closure's necessary bindings struct, if it's present.
     auto SizeOfNecessaryBindings = Info.NumBindings * sizeof(StoredPointer);
-    Builder.addField(SizeOfNecessaryBindings, sizeof(StoredPointer),
-                     /*numExtraInhabitants=*/0);
+    Builder.addField(/*size=*/SizeOfNecessaryBindings,
+                     /*alignment=*/sizeof(StoredPointer),
+                     /*numExtraInhabitants=*/0,
+                     /*bitwiseTakable=*/true);
 
     // FIXME: should be unordered_set but I'm too lazy to write a hash
     // functor
diff --git a/include/swift/Reflection/TypeLowering.h b/include/swift/Reflection/TypeLowering.h
index 13be1a7..55ffc6f 100644
--- a/include/swift/Reflection/TypeLowering.h
+++ b/include/swift/Reflection/TypeLowering.h
@@ -110,13 +110,16 @@
 class TypeInfo {
   TypeInfoKind Kind;
   unsigned Size, Alignment, Stride, NumExtraInhabitants;
+  bool BitwiseTakable;
 
 public:
   TypeInfo(TypeInfoKind Kind,
            unsigned Size, unsigned Alignment,
-           unsigned Stride, unsigned NumExtraInhabitants)
+           unsigned Stride, unsigned NumExtraInhabitants,
+           bool BitwiseTakable)
     : Kind(Kind), Size(Size), Alignment(Alignment), Stride(Stride),
-      NumExtraInhabitants(NumExtraInhabitants) {
+      NumExtraInhabitants(NumExtraInhabitants),
+      BitwiseTakable(BitwiseTakable) {
     assert(Alignment > 0);
   }
 
@@ -126,6 +129,7 @@
   unsigned getAlignment() const { return Alignment; }
   unsigned getStride() const { return Stride; }
   unsigned getNumExtraInhabitants() const { return NumExtraInhabitants; }
+  bool isBitwiseTakable() const { return BitwiseTakable; }
 
   void dump() const;
   void dump(std::ostream &OS, unsigned Indent = 0) const;
@@ -162,9 +166,10 @@
 public:
   RecordTypeInfo(unsigned Size, unsigned Alignment,
                  unsigned Stride, unsigned NumExtraInhabitants,
+                 bool BitwiseTakable,
                  RecordKind SubKind, const std::vector<FieldInfo> &Fields)
     : TypeInfo(TypeInfoKind::Record, Size, Alignment, Stride,
-               NumExtraInhabitants),
+               NumExtraInhabitants, BitwiseTakable),
       SubKind(SubKind), Fields(Fields) {}
 
   RecordKind getRecordKind() const { return SubKind; }
@@ -185,9 +190,10 @@
 public:
   ReferenceTypeInfo(unsigned Size, unsigned Alignment,
                     unsigned Stride, unsigned NumExtraInhabitants,
-                    ReferenceKind SubKind, ReferenceCounting Refcounting)
+                    bool BitwiseTakable, ReferenceKind SubKind,
+                    ReferenceCounting Refcounting)
     : TypeInfo(TypeInfoKind::Reference, Size, Alignment, Stride,
-               NumExtraInhabitants),
+               NumExtraInhabitants, BitwiseTakable),
       SubKind(SubKind), Refcounting(Refcounting) {}
 
   ReferenceKind getReferenceKind() const {
@@ -286,6 +292,7 @@
 class RecordTypeInfoBuilder {
   TypeConverter &TC;
   unsigned Size, Alignment, NumExtraInhabitants;
+  bool BitwiseTakable;
   RecordKind Kind;
   std::vector<FieldInfo> Fields;
   bool Empty;
@@ -294,14 +301,15 @@
 public:
   RecordTypeInfoBuilder(TypeConverter &TC, RecordKind Kind)
     : TC(TC), Size(0), Alignment(1), NumExtraInhabitants(0),
-      Kind(Kind), Empty(true), Invalid(false) {}
+      BitwiseTakable(true), Kind(Kind), Empty(true), Invalid(false) {}
 
   bool isInvalid() const {
     return Invalid;
   }
 
   unsigned addField(unsigned fieldSize, unsigned fieldAlignment,
-                    unsigned numExtraInhabitants);
+                    unsigned numExtraInhabitants,
+                    bool bitwiseTakable);
 
   // Add a field of a record type, such as a struct.
   void addField(const std::string &Name, const TypeRef *TR);
diff --git a/include/swift/Runtime/Debug.h b/include/swift/Runtime/Debug.h
index 92d7f09..d877e92 100644
--- a/include/swift/Runtime/Debug.h
+++ b/include/swift/Runtime/Debug.h
@@ -130,6 +130,14 @@
 SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
 void swift_abortWeakRetainOverflow();
 
+// Halt due to enabling an already enabled dynamic replacement().
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
+void swift_abortDynamicReplacementEnabling();
+
+// Halt due to disabling an already disabled dynamic replacement().
+SWIFT_RUNTIME_ATTRIBUTE_NORETURN SWIFT_RUNTIME_ATTRIBUTE_NOINLINE
+void swift_abortDynamicReplacementDisabling();
+
 /// This function dumps one line of a stack trace. It is assumed that \p framePC
 /// is the address of the stack frame at index \p index. If \p shortOutput is
 /// true, this functions prints only the name of the symbol and offset, ignores
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index d8643ba..fffea61 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -22,6 +22,37 @@
 
 namespace swift {
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
+
+/// The buffer used by a yield-once coroutine (such as the generalized
+/// accessors `read` and `modify`).
+struct YieldOnceBuffer {
+  void *Data[NumWords_YieldOnceBuffer];
+};
+using YieldOnceContinuation =
+  SWIFT_CC(swift) void (YieldOnceBuffer *buffer, bool forUnwind);
+
+/// The return type of a call to a yield-once coroutine.  The function
+/// must be declared with the swiftcall calling convention.
+template <class ResultTy>
+struct YieldOnceResult {
+  YieldOnceContinuation *Continuation;
+  ResultTy YieldValue;
+};
+
+template <class FnTy>
+struct YieldOnceCoroutine;
+
+/// A template which generates the type of the ramp function of a
+/// yield-once coroutine.
+template <class ResultTy, class... ArgTys>
+struct YieldOnceCoroutine<ResultTy(ArgTys...)> {
+  using type =
+    SWIFT_CC(swift) YieldOnceResult<ResultTy> (YieldOnceBuffer *buffer,
+                                               ArgTys...);
+};
+
 #if SWIFT_OBJC_INTEROP
 
   // Const cast shorthands for ObjC types.
@@ -385,7 +416,7 @@
 /// \param assocType Associated type descriptor.
 ///
 /// \returns metadata for the associated type witness.
-SWIFT_RUNTIME_EXPORT
+SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
 MetadataResponse swift_getAssociatedTypeWitness(
                                           MetadataRequest request,
                                           WitnessTable *wtable,
@@ -393,6 +424,24 @@
                                           const ProtocolRequirement *reqBase,
                                           const ProtocolRequirement *assocType);
 
+/// Retrieve an associated conformance witness table from the given witness
+/// table.
+///
+/// \param wtable The witness table.
+/// \param conformingType Metadata for the conforming type.
+/// \param assocType Metadata for the associated type.
+/// \param reqBase "Base" requirement used to compute the witness index
+/// \param assocConformance Associated conformance descriptor.
+///
+/// \returns corresponding witness table.
+SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
+const WitnessTable *swift_getAssociatedConformanceWitness(
+                                  WitnessTable *wtable,
+                                  const Metadata *conformingType,
+                                  const Metadata *assocType,
+                                  const ProtocolRequirement *reqBase,
+                                  const ProtocolRequirement *assocConformance);
+
 /// \brief Fetch a uniqued metadata for a function type.
 SWIFT_RUNTIME_EXPORT
 const FunctionTypeMetadata *
@@ -788,6 +837,36 @@
 SWIFT_RUNTIME_EXPORT
 const HeapObject *swift_getKeyPath(const void *pattern, const void *arguments);
 
+/// Given a pointer to a borrowed value of type `Root` and a
+/// `KeyPath<Root, Value>`, project a pointer to a borrowed value of type
+/// `Value`.
+SWIFT_RUNTIME_EXPORT
+YieldOnceCoroutine<const OpaqueValue* (const OpaqueValue *root,
+                                       void *keyPath)>::type
+swift_readAtKeyPath;
+
+/// Given a pointer to a mutable value of type `Root` and a
+/// `WritableKeyPath<Root, Value>`, project a pointer to a mutable value
+/// of type `Value`.
+SWIFT_RUNTIME_EXPORT
+YieldOnceCoroutine<OpaqueValue* (OpaqueValue *root, void *keyPath)>::type
+swift_modifyAtWritableKeyPath;
+
+/// Given a pointer to a borrowed value of type `Root` and a
+/// `ReferenceWritableKeyPath<Root, Value>`, project a pointer to a
+/// mutable value of type `Value`.
+SWIFT_RUNTIME_EXPORT
+YieldOnceCoroutine<OpaqueValue* (const OpaqueValue *root, void *keyPath)>::type
+swift_modifyAtReferenceWritableKeyPath;
+
+SWIFT_RUNTIME_EXPORT
+void swift_enableDynamicReplacementScope(const DynamicReplacementScope *scope);
+
+SWIFT_RUNTIME_EXPORT
+void swift_disableDynamicReplacementScope(const DynamicReplacementScope *scope);
+
+#pragma clang diagnostic pop
+
 } // end namespace swift
 
 #endif // SWIFT_RUNTIME_METADATA_H
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index f19e885..06cf69a 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -641,7 +641,7 @@
 //                                            const Metadata *conformingType,
 //                                            ProtocolRequirement *reqBase,
 //                                            ProtocolRequirement *assocType);
-FUNCTION(GetAssociatedTypeWitness, swift_getAssociatedTypeWitness, C_CC,
+FUNCTION(GetAssociatedTypeWitness, swift_getAssociatedTypeWitness, SwiftCC,
          RETURNS(TypeMetadataResponseTy),
          ARGS(SizeTy,
               WitnessTablePtrTy,
@@ -650,6 +650,23 @@
               ProtocolRequirementStructTy->getPointerTo()),
          ATTRS(NoUnwind, ReadNone))
 
+// SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
+// const WitnessTable *swift_getAssociatedConformanceWitness(
+//                                 WitnessTable *wtable,
+//                                 const Metadata *conformingType,
+//                                 const Metadata *assocType,
+//                                 const ProtocolRequirement *reqBase,
+//                                 const ProtocolRequirement *assocConformance);
+FUNCTION(GetAssociatedConformanceWitness,
+         swift_getAssociatedConformanceWitness, SwiftCC,
+         RETURNS(WitnessTablePtrTy),
+         ARGS(WitnessTablePtrTy,
+              TypeMetadataPtrTy,
+              TypeMetadataPtrTy,
+              ProtocolRequirementStructTy->getPointerTo(),
+              ProtocolRequirementStructTy->getPointerTo()),
+         ATTRS(NoUnwind, ReadNone))
+
 // Metadata *swift_getMetatypeMetadata(Metadata *instanceTy);
 FUNCTION(GetMetatypeMetadata, swift_getMetatypeMetadata, C_CC,
          RETURNS(TypeMetadataPtrTy),
diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h
index 46dc7aa..d1686d7 100644
--- a/include/swift/SIL/ApplySite.h
+++ b/include/swift/SIL/ApplySite.h
@@ -147,6 +147,14 @@
     FOREACH_IMPL_RETURN(getReferencedFunction());
   }
 
+  /// Should we optimize this call.
+  /// Calls to (previous_)dynamic_function_ref have a dynamic target function so
+  /// we should not optimize them.
+  bool canOptimize() const {
+    return !DynamicFunctionRefInst::classof(getCallee()) &&
+      !PreviousDynamicFunctionRefInst::classof(getCallee());
+  }
+
   /// Return the type.
   SILType getType() const { return getSubstCalleeConv().getSILResultType(); }
 
diff --git a/include/swift/SIL/InstructionUtils.h b/include/swift/SIL/InstructionUtils.h
index b2d53a7..e9e8f05 100644
--- a/include/swift/SIL/InstructionUtils.h
+++ b/include/swift/SIL/InstructionUtils.h
@@ -17,6 +17,10 @@
 
 namespace swift {
 
+//===----------------------------------------------------------------------===//
+//                         SSA Use-Def Helpers
+//===----------------------------------------------------------------------===//
+
 /// Strip off casts/indexing insts/address projections from V until there is
 /// nothing left to strip.
 SILValue getUnderlyingObject(SILValue V);
@@ -78,6 +82,10 @@
 /// ust return V.
 SILValue stripBorrow(SILValue V);
 
+//===----------------------------------------------------------------------===//
+//                         Instruction Properties
+//===----------------------------------------------------------------------===//
+
 /// Return a non-null SingleValueInstruction if the given instruction merely
 /// copies the value of its first operand, possibly changing its type or
 /// ownership state, but otherwise having no effect.
@@ -110,6 +118,10 @@
 /// only used in recognizable patterns without otherwise "escaping".
 bool onlyAffectsRefCount(SILInstruction *user);
 
+/// Returns true if the given user instruction checks the ref count of a
+/// pointer.
+bool mayCheckRefCount(SILInstruction *User);
+
 /// Return true when the instruction represents added instrumentation for
 /// run-time sanitizers.
 bool isSanitizerInstrumentation(SILInstruction *Instruction);
diff --git a/include/swift/SIL/OwnershipUtils.h b/include/swift/SIL/OwnershipUtils.h
index 7c474a5..7a60169 100644
--- a/include/swift/SIL/OwnershipUtils.h
+++ b/include/swift/SIL/OwnershipUtils.h
@@ -114,9 +114,12 @@
 
 bool isGuaranteedForwardingValue(SILValue value);
 
+bool isOwnershipForwardingInst(SILInstruction *i);
+
 bool isGuaranteedForwardingInst(SILInstruction *i);
 
-bool isOwnershipForwardingInst(SILInstruction *i);
+bool getUnderlyingBorrowIntroducers(SILValue inputValue,
+                                    SmallVectorImpl<SILValue> &out);
 
 } // namespace swift
 
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index 3e97c08..bb13196 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -121,8 +121,19 @@
   /// Reference to the provided SILBuilderContext.
   SILBuilderContext &C;
 
+  /// The SILFunction that we are currently inserting into if we have one.
+  ///
+  /// If we are building into a block associated with a SILGlobalVariable this
+  /// will be a nullptr.
+  ///
+  /// TODO: This can be made cleaner by using a PointerUnion or the like so we
+  /// can store the SILGlobalVariable here as well.
   SILFunction *F;
 
+  /// If the current block that we are inserting into must assume that
+  /// the current context we are in has ownership.
+  bool hasOwnership;
+
   /// If this is non-null, the instruction is inserted in the specified
   /// basic block, at the specified InsertPt.  If null, created instructions
   /// are not auto-inserted.
@@ -133,18 +144,20 @@
 
 public:
   explicit SILBuilder(SILFunction &F, bool isParsing = false)
-      : TempContext(F.getModule()), C(TempContext), F(&F), BB(0) {
+      : TempContext(F.getModule()), C(TempContext), F(&F),
+        hasOwnership(F.hasQualifiedOwnership()), BB(0) {
     C.isParsing = isParsing;
   }
 
   SILBuilder(SILFunction &F, SmallVectorImpl<SILInstruction *> *InsertedInstrs)
       : TempContext(F.getModule(), InsertedInstrs), C(TempContext), F(&F),
-        BB(0) {}
+        hasOwnership(F.hasQualifiedOwnership()), BB(0) {}
 
   explicit SILBuilder(SILInstruction *I,
                       SmallVectorImpl<SILInstruction *> *InsertedInstrs = 0)
       : TempContext(I->getFunction()->getModule(), InsertedInstrs),
-        C(TempContext), F(I->getFunction()) {
+        C(TempContext), F(I->getFunction()),
+        hasOwnership(F->hasQualifiedOwnership()) {
     setInsertionPoint(I);
   }
 
@@ -155,7 +168,8 @@
   explicit SILBuilder(SILBasicBlock *BB,
                       SmallVectorImpl<SILInstruction *> *InsertedInstrs = 0)
       : TempContext(BB->getParent()->getModule(), InsertedInstrs),
-        C(TempContext), F(BB->getParent()) {
+        C(TempContext), F(BB->getParent()),
+        hasOwnership(F->hasQualifiedOwnership()) {
     setInsertionPoint(BB);
   }
 
@@ -165,7 +179,8 @@
   SILBuilder(SILBasicBlock *BB, SILBasicBlock::iterator InsertPt,
              SmallVectorImpl<SILInstruction *> *InsertedInstrs = 0)
       : TempContext(BB->getParent()->getModule(), InsertedInstrs),
-        C(TempContext), F(BB->getParent()) {
+        C(TempContext), F(BB->getParent()),
+        hasOwnership(F->hasQualifiedOwnership()) {
     setInsertionPoint(BB, InsertPt);
   }
 
@@ -174,7 +189,8 @@
   ///
   /// SILBuilderContext must outlive this SILBuilder instance.
   SILBuilder(SILInstruction *I, const SILDebugScope *DS, SILBuilderContext &C)
-      : TempContext(C.getModule()), C(C), F(I->getFunction()) {
+      : TempContext(C.getModule()), C(C), F(I->getFunction()),
+        hasOwnership(F->hasQualifiedOwnership()) {
     assert(DS && "instruction has no debug scope");
     setCurrentDebugScope(DS);
     setInsertionPoint(I);
@@ -185,7 +201,8 @@
   ///
   /// SILBuilderContext must outlive this SILBuilder instance.
   SILBuilder(SILBasicBlock *BB, const SILDebugScope *DS, SILBuilderContext &C)
-      : TempContext(C.getModule()), C(C), F(BB->getParent()) {
+      : TempContext(C.getModule()), C(C), F(BB->getParent()),
+        hasOwnership(F->hasQualifiedOwnership()) {
     assert(DS && "block has no debug scope");
     setCurrentDebugScope(DS);
     setInsertionPoint(BB);
@@ -243,6 +260,16 @@
     return SILDebugLocation(overriddenLoc, Scope);
   }
 
+  /// Allow for users to override has ownership if necessary.
+  ///
+  /// This is only used in the SILParser since it sets whether or not ownership
+  /// is qualified after the SILBuilder is constructed due to the usage of
+  /// AssumeUnqualifiedOwnershipWhenParsing.
+  ///
+  /// TODO: Once we start printing [ossa] on SILFunctions to indicate ownership
+  /// and get rid of this global option, this can go away.
+  void setHasOwnership(bool newHasOwnership) { hasOwnership = newHasOwnership; }
+
   //===--------------------------------------------------------------------===//
   // Insertion Point Management
   //===--------------------------------------------------------------------===//
@@ -556,10 +583,43 @@
     return createBuiltinBinaryFunction(Loc, Name, OpdTy, SILResultTy, Args);
   }
 
+  // Creates a dynamic_function_ref or function_ref depending on whether f is
+  // dynamically_replaceable.
+  FunctionRefBaseInst *createFunctionRefFor(SILLocation Loc, SILFunction *f) {
+    if (f->isDynamicallyReplaceable())
+      return createDynamicFunctionRef(Loc, f);
+    else return createFunctionRef(Loc, f);
+  }
+
+  FunctionRefBaseInst *createFunctionRef(SILLocation Loc, SILFunction *f,
+                                         SILInstructionKind kind) {
+    if (kind == SILInstructionKind::FunctionRefInst)
+      return createFunctionRef(Loc, f);
+    else if (kind == SILInstructionKind::DynamicFunctionRefInst)
+      return createDynamicFunctionRef(Loc, f);
+    else if (kind == SILInstructionKind::PreviousDynamicFunctionRefInst)
+      return createPreviousDynamicFunctionRef(Loc, f);
+    assert(false && "Should not get here");
+    return nullptr;
+  }
+
   FunctionRefInst *createFunctionRef(SILLocation Loc, SILFunction *f) {
     return insert(new (getModule())
                       FunctionRefInst(getSILDebugLocation(Loc), f));
   }
+
+  DynamicFunctionRefInst *
+  createDynamicFunctionRef(SILLocation Loc, SILFunction *f) {
+    return insert(new (getModule()) DynamicFunctionRefInst(
+        getSILDebugLocation(Loc), f));
+  }
+
+  PreviousDynamicFunctionRefInst *
+  createPreviousDynamicFunctionRef(SILLocation Loc, SILFunction *f) {
+    return insert(new (getModule()) PreviousDynamicFunctionRefInst(
+        getSILDebugLocation(Loc), f));
+  }
+
   AllocGlobalInst *createAllocGlobal(SILLocation Loc, SILGlobalVariable *g) {
     return insert(new (getModule())
                       AllocGlobalInst(getSILDebugLocation(Loc), g));
@@ -1154,25 +1214,23 @@
   ObjectInst *createObject(SILLocation Loc, SILType Ty,
                            ArrayRef<SILValue> Elements,
                            unsigned NumBaseElements) {
-    return insert(
-        ObjectInst::create(getSILDebugLocation(Loc), Ty, Elements,
-                           NumBaseElements, getModule()));
+    return insert(ObjectInst::create(getSILDebugLocation(Loc), Ty, Elements,
+                                     NumBaseElements, getModule(),
+                                     hasOwnership));
   }
 
   StructInst *createStruct(SILLocation Loc, SILType Ty,
                            ArrayRef<SILValue> Elements) {
     assert(Ty.isLoadableOrOpaque(getModule()));
-    return insert(
-        StructInst::create(getSILDebugLocation(Loc), Ty, Elements,
-                           getModule()));
+    return insert(StructInst::create(getSILDebugLocation(Loc), Ty, Elements,
+                                     getModule(), hasOwnership));
   }
 
   TupleInst *createTuple(SILLocation Loc, SILType Ty,
                          ArrayRef<SILValue> Elements) {
     assert(Ty.isLoadableOrOpaque(getModule()));
-    return insert(
-        TupleInst::create(getSILDebugLocation(Loc), Ty, Elements,
-                          getModule()));
+    return insert(TupleInst::create(getSILDebugLocation(Loc), Ty, Elements,
+                                    getModule(), hasOwnership));
   }
 
   TupleInst *createTuple(SILLocation loc, ArrayRef<SILValue> elts);
@@ -1253,7 +1311,7 @@
     assert(Ty.isLoadableOrOpaque(getModule()));
     return insert(SelectEnumInst::create(
         getSILDebugLocation(Loc), Operand, Ty, DefaultValue, CaseValues,
-        getFunction(), CaseCounts, DefaultCount));
+        getModule(), CaseCounts, DefaultCount, hasOwnership));
   }
 
   SelectEnumAddrInst *createSelectEnumAddr(
@@ -1263,7 +1321,7 @@
       ProfileCounter DefaultCount = ProfileCounter()) {
     return insert(SelectEnumAddrInst::create(
         getSILDebugLocation(Loc), Operand, Ty, DefaultValue, CaseValues,
-        getFunction(), CaseCounts, DefaultCount));
+        getModule(), CaseCounts, DefaultCount));
   }
 
   SelectValueInst *createSelectValue(
@@ -1271,7 +1329,7 @@
       ArrayRef<std::pair<SILValue, SILValue>> CaseValuesAndResults) {
     return insert(SelectValueInst::create(getSILDebugLocation(Loc), Operand, Ty,
                                           DefaultResult, CaseValuesAndResults,
-                                          getFunction()));
+                                          getModule(), hasOwnership));
   }
 
   TupleExtractInst *createTupleExtract(SILLocation Loc, SILValue Operand,
@@ -1458,7 +1516,7 @@
   OpenExistentialRefInst *
   createOpenExistentialRef(SILLocation Loc, SILValue Operand, SILType Ty) {
     auto *I = insert(new (getModule()) OpenExistentialRefInst(
-        getSILDebugLocation(Loc), Operand, Ty));
+        getSILDebugLocation(Loc), Operand, Ty, hasOwnership));
     if (C.OpenedArchetypesTracker)
       C.OpenedArchetypesTracker->registerOpenedArchetypes(I);
     return I;
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 7918bfa..78cc044 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -915,6 +915,24 @@
 
 template<typename ImplClass>
 void
+SILCloner<ImplClass>::visitDynamicFunctionRefInst(DynamicFunctionRefInst *Inst) {
+  SILFunction *OpFunction = getOpFunction(Inst->getReferencedFunction());
+  getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
+  recordClonedInstruction(Inst, getBuilder().createDynamicFunctionRef(
+                                    getOpLocation(Inst->getLoc()), OpFunction));
+}
+
+template <typename ImplClass>
+void SILCloner<ImplClass>::visitPreviousDynamicFunctionRefInst(
+    PreviousDynamicFunctionRefInst *Inst) {
+  SILFunction *OpFunction = getOpFunction(Inst->getReferencedFunction());
+  getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
+  recordClonedInstruction(Inst, getBuilder().createPreviousDynamicFunctionRef(
+                                    getOpLocation(Inst->getLoc()), OpFunction));
+}
+
+template<typename ImplClass>
+void
 SILCloner<ImplClass>::visitAllocGlobalInst(AllocGlobalInst *Inst) {
   getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
   recordClonedInstruction(
diff --git a/include/swift/SIL/SILDeclRef.h b/include/swift/SIL/SILDeclRef.h
index e249e3f..b513fac 100644
--- a/include/swift/SIL/SILDeclRef.h
+++ b/include/swift/SIL/SILDeclRef.h
@@ -252,6 +252,12 @@
     return kind == Kind::IVarInitializer || kind == Kind::IVarDestroyer;
   }
 
+  /// True if the SILDeclRef references an allocating or deallocating entry
+  /// point.
+  bool isInitializerOrDestroyer() const {
+    return kind == Kind::Initializer || kind == Kind::Destroyer;
+  }
+
   /// \brief True if the function should be treated as transparent.
   bool isTransparent() const;
   /// \brief True if the function should have its body serialized.
@@ -384,6 +390,8 @@
   /// subclassed.
   SubclassScope getSubclassScope() const;
 
+  bool isDynamicallyReplaceable() const;
+
 private:
   friend struct llvm::DenseMapInfo<swift::SILDeclRef>;
   /// Produces a SILDeclRef from an opaque value.
diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h
index 981e49a..9157fb4 100644
--- a/include/swift/SIL/SILFunction.h
+++ b/include/swift/SIL/SILFunction.h
@@ -47,6 +47,10 @@
   IsReabstractionThunk,
   IsSignatureOptimizedThunk
 };
+enum IsDynamicallyReplaceable_t {
+  IsNotDynamic,
+  IsDynamic
+};
 
 class SILSpecializeAttr final {
   friend SILFunction;
@@ -145,6 +149,12 @@
   /// disabled.
   SILProfiler *Profiler = nullptr;
 
+  /// The function this function is meant to replace. Null if this is not a
+  /// @_dynamicReplacement(for:) function.
+  SILFunction *ReplacedFunction = nullptr;
+
+  Identifier ObjCReplacementFor;
+
   /// The function's bare attribute. Bare means that the function is SIL-only
   /// and does not require debug info.
   unsigned Bare : 1;
@@ -182,6 +192,9 @@
   /// Whether cross-module references to this function should use weak linking.
   unsigned IsWeakLinked : 1;
 
+  // Whether the implementation can be dynamically replaced.
+  unsigned IsDynamicReplaceable : 1;
+
   /// If != OptimizationMode::NotSet, the optimization mode specified with an
   /// function attribute.
   OptimizationMode OptMode;
@@ -273,14 +286,16 @@
               ProfileCounter entryCount, IsThunk_t isThunk,
               SubclassScope classSubclassScope, Inline_t inlineStrategy,
               EffectsKind E, SILFunction *insertBefore,
-              const SILDebugScope *debugScope);
+              const SILDebugScope *debugScope,
+              IsDynamicallyReplaceable_t isDynamic);
 
   static SILFunction *
   create(SILModule &M, SILLinkage linkage, StringRef name,
          CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
          Optional<SILLocation> loc, IsBare_t isBareSILFunction,
          IsTransparent_t isTrans, IsSerialized_t isSerialized,
-         ProfileCounter entryCount, IsThunk_t isThunk = IsNotThunk,
+         ProfileCounter entryCount, IsDynamicallyReplaceable_t isDynamic,
+         IsThunk_t isThunk = IsNotThunk,
          SubclassScope classSubclassScope = SubclassScope::NotApplicable,
          Inline_t inlineStrategy = InlineDefault,
          EffectsKind EffectsKindAttr = EffectsKind::Unspecified,
@@ -304,6 +319,38 @@
 
   SILProfiler *getProfiler() const { return Profiler; }
 
+  SILFunction *getDynamicallyReplacedFunction() const {
+    return ReplacedFunction;
+  }
+  void setDynamicallyReplacedFunction(SILFunction *f) {
+    assert(ReplacedFunction == nullptr && "already set");
+    assert(!hasObjCReplacement());
+
+    if (f == nullptr)
+      return;
+    ReplacedFunction = f;
+    ReplacedFunction->incrementRefCount();
+  }
+
+  /// This function should only be called when SILFunctions are bulk deleted.
+  void dropDynamicallyReplacedFunction() {
+    if (!ReplacedFunction)
+      return;
+    ReplacedFunction->decrementRefCount();
+    ReplacedFunction = nullptr;
+  }
+
+  bool hasObjCReplacement() const {
+    return !ObjCReplacementFor.empty();
+  }
+
+  Identifier getObjCReplacement() const {
+    return ObjCReplacementFor;
+  }
+
+  void setObjCReplacement(AbstractFunctionDecl *replacedDecl);
+  void setObjCReplacement(Identifier replacedDecl);
+
   void setProfiler(SILProfiler *InheritedProfiler) {
     assert(!Profiler && "Function already has a profiler");
     Profiler = InheritedProfiler;
@@ -517,6 +564,16 @@
     IsWeakLinked = value;
   }
 
+  /// Returs whether this function implementation can be dynamically replaced.
+  IsDynamicallyReplaceable_t isDynamicallyReplaceable() const {
+    return IsDynamicallyReplaceable_t(IsDynamicReplaceable);
+  }
+  void setIsDynamic(IsDynamicallyReplaceable_t value = IsDynamic) {
+    assert(IsDynamicReplaceable == IsNotDynamic && "already set");
+    IsDynamicReplaceable = value;
+    assert(!Transparent || !IsDynamicReplaceable);
+  }
+
   /// Get the DeclContext of this function. (Debug info only).
   DeclContext *getDeclContext() const {
     return getLocation().getAsDeclContext();
@@ -619,7 +676,10 @@
 
   /// Get this function's transparent attribute.
   IsTransparent_t isTransparent() const { return IsTransparent_t(Transparent); }
-  void setTransparent(IsTransparent_t isT) { Transparent = isT; }
+  void setTransparent(IsTransparent_t isT) {
+    Transparent = isT;
+    assert(!Transparent || !IsDynamicReplaceable);
+  }
 
   /// Get this function's serialized attribute.
   IsSerialized_t isSerialized() const { return IsSerialized_t(Serialized); }
diff --git a/include/swift/SIL/SILFunctionBuilder.h b/include/swift/SIL/SILFunctionBuilder.h
index 40a8cf7..1a587ca 100644
--- a/include/swift/SIL/SILFunctionBuilder.h
+++ b/include/swift/SIL/SILFunctionBuilder.h
@@ -58,13 +58,15 @@
                                          IsTransparent_t isTransparent,
                                          IsSerialized_t isSerialized,
                                          ProfileCounter entryCount,
-                                         IsThunk_t isThunk);
+                                         IsThunk_t isThunk,
+                                         IsDynamicallyReplaceable_t isDynamic);
 
   /// Return the declaration of a function, or create it if it doesn't exist.
   SILFunction *getOrCreateFunction(
       SILLocation loc, StringRef name, SILLinkage linkage,
       CanSILFunctionType type, IsBare_t isBareSILFunction,
       IsTransparent_t isTransparent, IsSerialized_t isSerialized,
+      IsDynamicallyReplaceable_t isDynamic,
       ProfileCounter entryCount = ProfileCounter(),
       IsThunk_t isThunk = IsNotThunk,
       SubclassScope subclassScope = SubclassScope::NotApplicable);
@@ -85,6 +87,7 @@
                  CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
                  Optional<SILLocation> loc, IsBare_t isBareSILFunction,
                  IsTransparent_t isTrans, IsSerialized_t isSerialized,
+                 IsDynamicallyReplaceable_t isDynamic,
                  ProfileCounter entryCount = ProfileCounter(),
                  IsThunk_t isThunk = IsNotThunk,
                  SubclassScope subclassScope = SubclassScope::NotApplicable,
@@ -92,6 +95,9 @@
                  EffectsKind EK = EffectsKind::Unspecified,
                  SILFunction *InsertBefore = nullptr,
                  const SILDebugScope *DebugScope = nullptr);
+
+  void addFunctionAttributes(SILFunction *F, DeclAttributes &Attrs,
+                             SILModule &M, SILDeclRef constant = SILDeclRef());
 };
 } // namespace swift
 
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 393f991..b7b1a98 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -35,6 +35,7 @@
 #include "swift/SIL/SILLocation.h"
 #include "swift/SIL/SILSuccessor.h"
 #include "swift/SIL/SILValue.h"
+#include "swift/SIL/ValueUtils.h"
 #include "swift/Strings.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
@@ -70,7 +71,7 @@
 class StringLiteralExpr;
 class ValueDecl;
 class VarDecl;
-class FunctionRefInst;
+class FunctionRefBaseInst;
 
 template <typename ImplClass> class SILClonerWithScopes;
 
@@ -781,6 +782,25 @@
            inst->getKind() <= SILInstructionKind::Last_##ID;    \
   }
 
+/// A single value inst that also forwards either owned or guaranteed ownership.
+///
+/// The specific forwarded ownership is static since it is set upon
+/// construction. After that point the instruction can not have a different form
+/// of ownership.
+class OwnershipForwardingSingleValueInst : public SingleValueInstruction {
+  ValueOwnershipKind ownershipKind;
+
+protected:
+  OwnershipForwardingSingleValueInst(SILInstructionKind kind,
+                                     SILDebugLocation debugLoc, SILType ty,
+                                     ValueOwnershipKind ownershipKind)
+      : SingleValueInstruction(kind, debugLoc, ty),
+        ownershipKind(ownershipKind) {}
+
+public:
+  ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
+};
+
 /// A value base result of a multiple value instruction.
 ///
 /// *NOTE* We want this to be a pure abstract class that does not add /any/ size
@@ -1786,7 +1806,7 @@
 
   /// Gets the referenced function if the callee is a function_ref instruction.
   SILFunction *getReferencedFunction() const {
-    if (auto *FRI = dyn_cast<FunctionRefInst>(getCallee()))
+    if (auto *FRI = dyn_cast<FunctionRefBaseInst>(getCallee()))
       return FRI->getReferencedFunction();
     return nullptr;
   }
@@ -2214,24 +2234,18 @@
   DEFINE_ABSTRACT_SINGLE_VALUE_INST_BOILERPLATE(LiteralInst)
 };
 
-/// FunctionRefInst - Represents a reference to a SIL function.
-class FunctionRefInst
-    : public InstructionBase<SILInstructionKind::FunctionRefInst,
-                             LiteralInst> {
-  friend SILBuilder;
+class FunctionRefBaseInst : public LiteralInst {
+  SILFunction *f;
 
-  SILFunction *Function;
-  /// Construct a FunctionRefInst.
-  ///
-  /// \param DebugLoc  The location of the reference.
-  /// \param F         The function being referenced.
-  FunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F);
+protected:
+  FunctionRefBaseInst(SILInstructionKind Kind, SILDebugLocation DebugLoc,
+                      SILFunction *F);
 
 public:
-  ~FunctionRefInst();
+  ~FunctionRefBaseInst();
 
   /// Return the referenced function.
-  SILFunction *getReferencedFunction() const { return Function; }
+  SILFunction *getReferencedFunction() const { return f; }
 
   void dropReferencedFunction();
 
@@ -2244,6 +2258,73 @@
 
   ArrayRef<Operand> getAllOperands() const { return {}; }
   MutableArrayRef<Operand> getAllOperands() { return {}; }
+
+  static bool classof(const SILNode *node) {
+    return (node->getKind() == SILNodeKind::FunctionRefInst ||
+        node->getKind() == SILNodeKind::DynamicFunctionRefInst ||
+        node->getKind() == SILNodeKind::PreviousDynamicFunctionRefInst);
+  }
+  static bool classof(const SingleValueInstruction *node) {
+    return (node->getKind() == SILInstructionKind::FunctionRefInst ||
+        node->getKind() == SILInstructionKind::DynamicFunctionRefInst ||
+        node->getKind() == SILInstructionKind::PreviousDynamicFunctionRefInst);
+  }
+};
+
+/// FunctionRefInst - Represents a reference to a SIL function.
+class FunctionRefInst : public FunctionRefBaseInst {
+  friend SILBuilder;
+
+  /// Construct a FunctionRefInst.
+  ///
+  /// \param DebugLoc  The location of the reference.
+  /// \param F         The function being referenced.
+  FunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F);
+
+public:
+  static bool classof(const SILNode *node) {
+    return node->getKind() == SILNodeKind::FunctionRefInst;
+  }
+  static bool classof(const SingleValueInstruction *node) {
+    return node->getKind() == SILInstructionKind::FunctionRefInst;
+  }
+};
+
+class DynamicFunctionRefInst : public FunctionRefBaseInst {
+  friend SILBuilder;
+
+  /// Construct a DynamicFunctionRefInst.
+  ///
+  /// \param DebugLoc  The location of the reference.
+  /// \param F         The function being referenced.
+  DynamicFunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F);
+
+public:
+  static bool classof(const SILNode *node) {
+    return node->getKind() == SILNodeKind::DynamicFunctionRefInst;
+  }
+  static bool classof(const SingleValueInstruction *node) {
+    return node->getKind() == SILInstructionKind::DynamicFunctionRefInst;
+  }
+};
+
+class PreviousDynamicFunctionRefInst : public FunctionRefBaseInst {
+  friend SILBuilder;
+
+  /// Construct a PreviousDynamicFunctionRefInst.
+  ///
+  /// \param DebugLoc  The location of the reference.
+  /// \param F         The function being referenced.
+  PreviousDynamicFunctionRefInst(SILDebugLocation DebugLoc, SILFunction *F);
+
+public:
+  static bool classof(const SILNode *node) {
+    return node->getKind() == SILNodeKind::PreviousDynamicFunctionRefInst;
+  }
+  static bool classof(const SingleValueInstruction *node) {
+    return node->getKind() ==
+           SILInstructionKind::PreviousDynamicFunctionRefInst;
+  }
 };
 
 /// Component of a KeyPathInst.
@@ -3538,14 +3619,12 @@
   MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }
 };
 
-/// Abstract base class for instructions that mark storage as uninitialized.
-
-/// Indicates that a memory location is uninitialized at
-/// this point and needs to be initialized by the end of the function and before
-/// any escape point for this instruction.  This is only valid in Raw SIL.
+/// Indicates that a memory location is uninitialized at this point and needs to
+/// be initialized by the end of the function and before any escape point for
+/// this instruction. This is only valid in Raw SIL.
 class MarkUninitializedInst
     : public UnaryInstructionBase<SILInstructionKind::MarkUninitializedInst,
-                                  SingleValueInstruction> {
+                                  OwnershipForwardingSingleValueInst> {
   friend SILBuilder;
 
 public:
@@ -3579,8 +3658,9 @@
 private:
   Kind ThisKind;
 
-  MarkUninitializedInst(SILDebugLocation DebugLoc, SILValue Address, Kind K)
-      : UnaryInstructionBase(DebugLoc, Address, Address->getType()),
+  MarkUninitializedInst(SILDebugLocation DebugLoc, SILValue Value, Kind K)
+      : UnaryInstructionBase(DebugLoc, Value, Value->getType(),
+                             Value.getOwnershipKind()),
         ThisKind(K) {}
 
 public:
@@ -3962,19 +4042,35 @@
   DEFINE_ABSTRACT_SINGLE_VALUE_INST_BOILERPLATE(ConversionInst)
 };
 
+/// A conversion inst that produces a static OwnershipKind set upon the
+/// instruction's construction.
+class OwnershipForwardingConversionInst : public ConversionInst {
+  ValueOwnershipKind ownershipKind;
+
+protected:
+  OwnershipForwardingConversionInst(SILInstructionKind kind,
+                                    SILDebugLocation debugLoc, SILType ty,
+                                    ValueOwnershipKind ownershipKind)
+      : ConversionInst(kind, debugLoc, ty), ownershipKind(ownershipKind) {}
+
+public:
+  ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
+};
+
 /// ConvertFunctionInst - Change the type of a function value without
 /// affecting how it will codegen.
 class ConvertFunctionInst final
     : public UnaryInstructionWithTypeDependentOperandsBase<
-          SILInstructionKind::ConvertFunctionInst,
-          ConvertFunctionInst, ConversionInst> {
+          SILInstructionKind::ConvertFunctionInst, ConvertFunctionInst,
+          OwnershipForwardingConversionInst> {
   friend SILBuilder;
 
   ConvertFunctionInst(SILDebugLocation DebugLoc, SILValue Operand,
                       ArrayRef<SILValue> TypeDependentOperands, SILType Ty,
                       bool WithoutActuallyEscaping)
       : UnaryInstructionWithTypeDependentOperandsBase(
-            DebugLoc, Operand, TypeDependentOperands, Ty) {
+            DebugLoc, Operand, TypeDependentOperands, Ty,
+            Operand.getOwnershipKind()) {
     SILInstruction::Bits.ConvertFunctionInst.WithoutActuallyEscaping =
         WithoutActuallyEscaping;
     assert((Operand->getType().castTo<SILFunctionType>()->isNoEscape() ==
@@ -4079,18 +4175,16 @@
 };
 
 /// UpcastInst - Perform a conversion of a class instance to a supertype.
-class UpcastInst final
-    : public UnaryInstructionWithTypeDependentOperandsBase<
-                             SILInstructionKind::UpcastInst,
-                             UpcastInst, ConversionInst>
-
-{
+class UpcastInst final : public UnaryInstructionWithTypeDependentOperandsBase<
+                             SILInstructionKind::UpcastInst, UpcastInst,
+                             OwnershipForwardingConversionInst> {
   friend SILBuilder;
 
   UpcastInst(SILDebugLocation DebugLoc, SILValue Operand,
              ArrayRef<SILValue> TypeDependentOperands, SILType Ty)
       : UnaryInstructionWithTypeDependentOperandsBase(
-            DebugLoc, Operand, TypeDependentOperands, Ty) {}
+            DebugLoc, Operand, TypeDependentOperands, Ty,
+            Operand.getOwnershipKind()) {}
 
   static UpcastInst *
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty,
@@ -4140,17 +4234,16 @@
 /// Convert a heap object reference to a different type without any runtime
 /// checks.
 class UncheckedRefCastInst final
-  : public UnaryInstructionWithTypeDependentOperandsBase<
-                                SILInstructionKind::UncheckedRefCastInst,
-                                UncheckedRefCastInst,
-                                ConversionInst>
-{
+    : public UnaryInstructionWithTypeDependentOperandsBase<
+          SILInstructionKind::UncheckedRefCastInst, UncheckedRefCastInst,
+          OwnershipForwardingConversionInst> {
   friend SILBuilder;
 
   UncheckedRefCastInst(SILDebugLocation DebugLoc, SILValue Operand,
                        ArrayRef<SILValue> TypeDependentOperands, SILType Ty)
-      : UnaryInstructionWithTypeDependentOperandsBase(DebugLoc, Operand,
-                                               TypeDependentOperands, Ty) {}
+      : UnaryInstructionWithTypeDependentOperandsBase(
+            DebugLoc, Operand, TypeDependentOperands, Ty,
+            Operand.getOwnershipKind()) {}
   static UncheckedRefCastInst *
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty,
          SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes);
@@ -4252,13 +4345,14 @@
 /// in bits from a word.
 class RefToBridgeObjectInst
     : public InstructionBase<SILInstructionKind::RefToBridgeObjectInst,
-                             ConversionInst> {
+                             OwnershipForwardingConversionInst> {
   friend SILBuilder;
 
   FixedOperandList<2> Operands;
   RefToBridgeObjectInst(SILDebugLocation DebugLoc, SILValue ConvertedValue,
                         SILValue MaskValue, SILType BridgeObjectTy)
-      : InstructionBase(DebugLoc, BridgeObjectTy),
+      : InstructionBase(DebugLoc, BridgeObjectTy,
+                        ConvertedValue.getOwnershipKind()),
         Operands(this, ConvertedValue, MaskValue) {}
 
 public:
@@ -4282,14 +4376,13 @@
 
 /// Extract the heap object reference from a BridgeObject.
 class BridgeObjectToRefInst
-  : public UnaryInstructionBase<SILInstructionKind::BridgeObjectToRefInst,
-                                ConversionInst>
-{
+    : public UnaryInstructionBase<SILInstructionKind::BridgeObjectToRefInst,
+                                  OwnershipForwardingConversionInst> {
   friend SILBuilder;
 
-  BridgeObjectToRefInst(SILDebugLocation DebugLoc, SILValue Operand,
-                        SILType Ty)
-      : UnaryInstructionBase(DebugLoc, Operand, Ty) {}
+  BridgeObjectToRefInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty)
+      : UnaryInstructionBase(DebugLoc, Operand, Ty,
+                             Operand.getOwnershipKind()) {}
 };
 
 /// Sets the BridgeObject to a tagged pointer representation holding its
@@ -4455,19 +4548,17 @@
 
 /// Perform an unconditional checked cast that aborts if the cast fails.
 class UnconditionalCheckedCastInst final
-  : public UnaryInstructionWithTypeDependentOperandsBase<
-                                SILInstructionKind::UnconditionalCheckedCastInst,
-                                UnconditionalCheckedCastInst,
-                                ConversionInst>
-{
+    : public UnaryInstructionWithTypeDependentOperandsBase<
+          SILInstructionKind::UnconditionalCheckedCastInst,
+          UnconditionalCheckedCastInst, OwnershipForwardingConversionInst> {
   friend SILBuilder;
 
   UnconditionalCheckedCastInst(SILDebugLocation DebugLoc, SILValue Operand,
                                ArrayRef<SILValue> TypeDependentOperands,
                                SILType DestTy)
-      : UnaryInstructionWithTypeDependentOperandsBase(DebugLoc, Operand,
-                                               TypeDependentOperands,
-                                               DestTy) {}
+      : UnaryInstructionWithTypeDependentOperandsBase(
+            DebugLoc, Operand, TypeDependentOperands, DestTy,
+            Operand.getOwnershipKind()) {}
 
   static UnconditionalCheckedCastInst *
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType DestTy,
@@ -4542,19 +4633,20 @@
 };
 
 /// StructInst - Represents a constructed loadable struct.
-class StructInst final
-    : public InstructionBaseWithTrailingOperands<SILInstructionKind::StructInst,
-                                           StructInst, SingleValueInstruction> {
+class StructInst final : public InstructionBaseWithTrailingOperands<
+                             SILInstructionKind::StructInst, StructInst,
+                             OwnershipForwardingSingleValueInst> {
   friend SILBuilder;
 
   /// Because of the storage requirements of StructInst, object
   /// creation goes through 'create()'.
-  StructInst(SILDebugLocation DebugLoc, SILType Ty,
-             ArrayRef<SILValue> Elements);
+  StructInst(SILDebugLocation DebugLoc, SILType Ty, ArrayRef<SILValue> Elements,
+             bool HasOwnership);
 
   /// Construct a StructInst.
   static StructInst *create(SILDebugLocation DebugLoc, SILType Ty,
-                            ArrayRef<SILValue> Elements, SILModule &M);
+                            ArrayRef<SILValue> Elements, SILModule &M,
+                            bool HasOwnership);
 
 public:
   /// The elements referenced by this StructInst.
@@ -4795,24 +4887,27 @@
 ///
 /// This instruction can only appear at the end of a gobal variable's
 /// static initializer list.
-class ObjectInst final
-    : public InstructionBaseWithTrailingOperands<SILInstructionKind::ObjectInst,
-                                                 ObjectInst,
-                                                 SingleValueInstruction> {
+class ObjectInst final : public InstructionBaseWithTrailingOperands<
+                             SILInstructionKind::ObjectInst, ObjectInst,
+                             OwnershipForwardingSingleValueInst> {
   friend SILBuilder;
 
   /// Because of the storage requirements of ObjectInst, object
   /// creation goes through 'create()'.
-  ObjectInst(SILDebugLocation DebugLoc, SILType Ty,
-            ArrayRef<SILValue> Elements, unsigned NumBaseElements)
-    : InstructionBaseWithTrailingOperands(Elements, DebugLoc, Ty) {
-      SILInstruction::Bits.ObjectInst.NumBaseElements = NumBaseElements;
+  ObjectInst(SILDebugLocation DebugLoc, SILType Ty, ArrayRef<SILValue> Elements,
+             unsigned NumBaseElements, bool HasOwnership)
+      : InstructionBaseWithTrailingOperands(
+            Elements, DebugLoc, Ty,
+            HasOwnership ? *mergeSILValueOwnership(Elements)
+                         : ValueOwnershipKind(ValueOwnershipKind::Any)) {
+    SILInstruction::Bits.ObjectInst.NumBaseElements = NumBaseElements;
   }
 
   /// Construct an ObjectInst.
   static ObjectInst *create(SILDebugLocation DebugLoc, SILType Ty,
                             ArrayRef<SILValue> Elements,
-                            unsigned NumBaseElements, SILModule &M);
+                            unsigned NumBaseElements, SILModule &M,
+                            bool HasOwnership);
 
 public:
   /// All elements referenced by this ObjectInst.
@@ -4839,20 +4934,24 @@
 };
 
 /// TupleInst - Represents a constructed loadable tuple.
-class TupleInst final
-    : public InstructionBaseWithTrailingOperands<SILInstructionKind::TupleInst,
-                                                  TupleInst,
-                                                  SingleValueInstruction> {
+class TupleInst final : public InstructionBaseWithTrailingOperands<
+                            SILInstructionKind::TupleInst, TupleInst,
+                            OwnershipForwardingSingleValueInst> {
   friend SILBuilder;
 
   /// Because of the storage requirements of TupleInst, object
   /// creation goes through 'create()'.
-  TupleInst(SILDebugLocation DebugLoc, SILType Ty, ArrayRef<SILValue> Elems)
-    : InstructionBaseWithTrailingOperands(Elems, DebugLoc, Ty) {}
+  TupleInst(SILDebugLocation DebugLoc, SILType Ty, ArrayRef<SILValue> Elems,
+            bool HasOwnership)
+      : InstructionBaseWithTrailingOperands(
+            Elems, DebugLoc, Ty,
+            HasOwnership ? *mergeSILValueOwnership(Elems)
+                         : ValueOwnershipKind(ValueOwnershipKind::Any)) {}
 
   /// Construct a TupleInst.
   static TupleInst *create(SILDebugLocation DebugLoc, SILType Ty,
-                           ArrayRef<SILValue> Elements, SILModule &M);
+                           ArrayRef<SILValue> Elements, SILModule &M,
+                           bool HasOwnership);
 
 public:
   /// The elements referenced by this TupleInst.
@@ -4912,9 +5011,8 @@
 
 /// Represents a loadable enum constructed from one of its
 /// elements.
-class EnumInst
-    : public InstructionBase<SILInstructionKind::EnumInst,
-                             SingleValueInstruction> {
+class EnumInst : public InstructionBase<SILInstructionKind::EnumInst,
+                                        OwnershipForwardingSingleValueInst> {
   friend SILBuilder;
 
   Optional<FixedOperandList<1>> OptionalOperand;
@@ -4922,7 +5020,10 @@
 
   EnumInst(SILDebugLocation DebugLoc, SILValue Operand,
            EnumElementDecl *Element, SILType ResultTy)
-      : InstructionBase(DebugLoc, ResultTy),
+      : InstructionBase(DebugLoc, ResultTy,
+                        Operand
+                            ? Operand.getOwnershipKind()
+                            : ValueOwnershipKind(ValueOwnershipKind::Trivial)),
         Element(Element) {
     if (Operand) {
       OptionalOperand.emplace(this, Operand);
@@ -4950,16 +5051,17 @@
 /// Unsafely project the data for an enum case out of an enum without checking
 /// the tag.
 class UncheckedEnumDataInst
-  : public UnaryInstructionBase<SILInstructionKind::UncheckedEnumDataInst,
-                                SingleValueInstruction>
-{
+    : public UnaryInstructionBase<SILInstructionKind::UncheckedEnumDataInst,
+                                  OwnershipForwardingSingleValueInst> {
   friend SILBuilder;
 
   EnumElementDecl *Element;
 
   UncheckedEnumDataInst(SILDebugLocation DebugLoc, SILValue Operand,
                         EnumElementDecl *Element, SILType ResultTy)
-      : UnaryInstructionBase(DebugLoc, Operand, ResultTy), Element(Element) {}
+      : UnaryInstructionBase(DebugLoc, Operand, ResultTy,
+                             Operand.getOwnershipKind()),
+        Element(Element) {}
 
 public:
   EnumElementDecl *getElement() const { return Element; }
@@ -5062,11 +5164,13 @@
 // Subclasses must provide tail allocated storage.
 // The first operand is the operand of select_xxx instruction. The rest of
 // the operands are the case values and results of a select instruction.
-template <class Derived, class T>
-class SelectInstBase : public SingleValueInstruction {
+template <class Derived, class T, class Base = SingleValueInstruction>
+class SelectInstBase : public Base {
 public:
-  SelectInstBase(SILInstructionKind kind, SILDebugLocation Loc, SILType type)
-      : SingleValueInstruction(kind, Loc, type) {}
+  template <typename... Args>
+  SelectInstBase(SILInstructionKind kind, SILDebugLocation Loc, SILType type,
+                 Args &&... otherArgs)
+      : Base(kind, Loc, type, std::forward<Args>(otherArgs)...) {}
 
   SILValue getOperand() const { return getAllOperands()[0].get(); }
 
@@ -5120,9 +5224,8 @@
   createSelectEnum(SILDebugLocation DebugLoc, SILValue Enum, SILType Type,
                    SILValue DefaultValue,
                    ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues,
-                   SILFunction &F,
-                   Optional<ArrayRef<ProfileCounter>> CaseCounts,
-                   ProfileCounter DefaultCount);
+                   SILModule &M, Optional<ArrayRef<ProfileCounter>> CaseCounts,
+                   ProfileCounter DefaultCount, bool HasOwnership);
 
 public:
   ArrayRef<Operand> getAllOperands() const;
@@ -5173,27 +5276,45 @@
   /// not to need this.
   NullablePtr<EnumElementDecl> getSingleTrueElement() const;
 };
-  
+
+/// A select enum inst that produces a static OwnershipKind set upon the
+/// instruction's construction.
+class OwnershipForwardingSelectEnumInstBase : public SelectEnumInstBase {
+  ValueOwnershipKind ownershipKind;
+
+protected:
+  OwnershipForwardingSelectEnumInstBase(
+      SILInstructionKind kind, SILDebugLocation debugLoc, SILType type,
+      bool defaultValue, Optional<ArrayRef<ProfileCounter>> caseCounts,
+      ProfileCounter defaultCount, ValueOwnershipKind ownershipKind)
+      : SelectEnumInstBase(kind, debugLoc, type, defaultValue, caseCounts,
+                           defaultCount),
+        ownershipKind(ownershipKind) {}
+
+public:
+  ValueOwnershipKind getOwnershipKind() const { return ownershipKind; }
+};
+
 /// Select one of a set of values based on the case of an enum.
 class SelectEnumInst final
     : public InstructionBaseWithTrailingOperands<
-                                        SILInstructionKind::SelectEnumInst,
-                                        SelectEnumInst,
-                                        SelectEnumInstBase, EnumElementDecl *> {
+          SILInstructionKind::SelectEnumInst, SelectEnumInst,
+          OwnershipForwardingSelectEnumInstBase, EnumElementDecl *> {
   friend SILBuilder;
 
 private:
   friend SelectEnumInstBase;
 
   SelectEnumInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
-                 bool DefaultValue,
-                 ArrayRef<SILValue> CaseValues,
+                 bool DefaultValue, ArrayRef<SILValue> CaseValues,
                  ArrayRef<EnumElementDecl *> CaseDecls,
                  Optional<ArrayRef<ProfileCounter>> CaseCounts,
-                 ProfileCounter DefaultCount)
-      : InstructionBaseWithTrailingOperands(Operand, CaseValues, DebugLoc, Type,
-                                            bool(DefaultValue), CaseCounts,
-                                            DefaultCount) {
+                 ProfileCounter DefaultCount, bool HasOwnership)
+      : InstructionBaseWithTrailingOperands(
+            Operand, CaseValues, DebugLoc, Type, bool(DefaultValue), CaseCounts,
+            DefaultCount,
+            HasOwnership ? *mergeSILValueOwnership(CaseValues)
+                         : ValueOwnershipKind(ValueOwnershipKind::Any)) {
     assert(CaseValues.size() - DefaultValue == CaseDecls.size());
     std::uninitialized_copy(CaseDecls.begin(), CaseDecls.end(),
                             getTrailingObjects<EnumElementDecl *>());
@@ -5202,8 +5323,8 @@
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
          SILValue DefaultValue,
          ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues,
-         SILFunction &F, Optional<ArrayRef<ProfileCounter>> CaseCounts,
-         ProfileCounter DefaultCount);
+         SILModule &M, Optional<ArrayRef<ProfileCounter>> CaseCounts,
+         ProfileCounter DefaultCount, bool HasOwnership);
 };
 
 /// Select one of a set of values based on the case of an enum.
@@ -5215,16 +5336,15 @@
   friend SILBuilder;
   friend SelectEnumInstBase;
 
-  SelectEnumAddrInst(
-      SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
-      bool DefaultValue,
-      ArrayRef<SILValue> CaseValues,
-      ArrayRef<EnumElementDecl *> CaseDecls,
-      Optional<ArrayRef<ProfileCounter>> CaseCounts,
-      ProfileCounter DefaultCount)
+  SelectEnumAddrInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
+                     bool DefaultValue, ArrayRef<SILValue> CaseValues,
+                     ArrayRef<EnumElementDecl *> CaseDecls,
+                     Optional<ArrayRef<ProfileCounter>> CaseCounts,
+                     ProfileCounter DefaultCount, bool HasOwnership)
       : InstructionBaseWithTrailingOperands(Operand, CaseValues, DebugLoc, Type,
                                             bool(DefaultValue), CaseCounts,
                                             DefaultCount) {
+    (void)HasOwnership;
     assert(CaseValues.size() - DefaultValue == CaseDecls.size());
     std::uninitialized_copy(CaseDecls.begin(), CaseDecls.end(),
                             getTrailingObjects<EnumElementDecl *>());
@@ -5233,7 +5353,7 @@
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
          SILValue DefaultValue,
          ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues,
-         SILFunction &F, Optional<ArrayRef<ProfileCounter>> CaseCounts,
+         SILModule &M, Optional<ArrayRef<ProfileCounter>> CaseCounts,
          ProfileCounter DefaultCount);
 };
 
@@ -5243,21 +5363,20 @@
 /// followed by an optional default operand.
 class SelectValueInst final
     : public InstructionBaseWithTrailingOperands<
-                                    SILInstructionKind::SelectValueInst,
-                                    SelectValueInst,
-                                    SelectInstBase<SelectValueInst, SILValue>> {
+          SILInstructionKind::SelectValueInst, SelectValueInst,
+          SelectInstBase<SelectValueInst, SILValue,
+                         OwnershipForwardingSingleValueInst>> {
   friend SILBuilder;
 
   SelectValueInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
                   SILValue DefaultResult,
-                  ArrayRef<SILValue> CaseValuesAndResults)
-      : InstructionBaseWithTrailingOperands(Operand, CaseValuesAndResults,
-                                            DebugLoc, Type) {}
+                  ArrayRef<SILValue> CaseValuesAndResults, bool HasOwnership);
 
   static SelectValueInst *
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Type,
          SILValue DefaultValue,
-         ArrayRef<std::pair<SILValue, SILValue>> CaseValues, SILFunction &F);
+         ArrayRef<std::pair<SILValue, SILValue>> CaseValues, SILModule &M,
+         bool HasOwnership);
 
 public:
   std::pair<SILValue, SILValue>
@@ -5696,13 +5815,12 @@
 /// existential by returning a pointer to a fresh archetype T, which also
 /// captures the (dynamic) conformances.
 class OpenExistentialRefInst
-  : public UnaryInstructionBase<SILInstructionKind::OpenExistentialRefInst,
-                                SingleValueInstruction>
-{
+    : public UnaryInstructionBase<SILInstructionKind::OpenExistentialRefInst,
+                                  OwnershipForwardingSingleValueInst> {
   friend SILBuilder;
 
   OpenExistentialRefInst(SILDebugLocation DebugLoc, SILValue Operand,
-                         SILType Ty);
+                         SILType Ty, bool HasOwnership);
 };
 
 /// Given an existential metatype,
@@ -5827,11 +5945,9 @@
 /// conformances, creates a class existential value referencing the
 /// class instance.
 class InitExistentialRefInst final
-  : public UnaryInstructionWithTypeDependentOperandsBase<
-                                SILInstructionKind::InitExistentialRefInst,
-                                InitExistentialRefInst,
-                                SingleValueInstruction>
-{
+    : public UnaryInstructionWithTypeDependentOperandsBase<
+          SILInstructionKind::InitExistentialRefInst, InitExistentialRefInst,
+          OwnershipForwardingSingleValueInst> {
   friend SILBuilder;
 
   CanType ConcreteType;
@@ -5841,9 +5957,9 @@
                          CanType FormalConcreteType, SILValue Instance,
                          ArrayRef<SILValue> TypeDependentOperands,
                          ArrayRef<ProtocolConformanceRef> Conformances)
-      : UnaryInstructionWithTypeDependentOperandsBase(DebugLoc, Instance,
-                                               TypeDependentOperands,
-                                               ExistentialType),
+      : UnaryInstructionWithTypeDependentOperandsBase(
+            DebugLoc, Instance, TypeDependentOperands, ExistentialType,
+            Instance.getOwnershipKind()),
         ConcreteType(FormalConcreteType), Conformances(Conformances) {}
 
   static InitExistentialRefInst *
@@ -7530,6 +7646,9 @@
   SILValue Callee = getCalleeOrigin();
 
   while (true) {
+    // Intentionally don't lookup throught dynamic_function_ref and
+    // previous_dynamic_function_ref as the target of those functions is not
+    // statically known.
     if (auto *FRI = dyn_cast<FunctionRefInst>(Callee))
       return FRI->getReferencedFunction();
 
diff --git a/include/swift/SIL/SILNodes.def b/include/swift/SIL/SILNodes.def
index 977ab8d..db2ddaf 100644
--- a/include/swift/SIL/SILNodes.def
+++ b/include/swift/SIL/SILNodes.def
@@ -402,6 +402,10 @@
   ABSTRACT_SINGLE_VALUE_INST(LiteralInst, SingleValueInstruction)
     SINGLE_VALUE_INST(FunctionRefInst, function_ref,
                       LiteralInst, None, DoesNotRelease)
+    SINGLE_VALUE_INST(DynamicFunctionRefInst, dynamic_function_ref,
+                      LiteralInst, None, DoesNotRelease)
+    SINGLE_VALUE_INST(PreviousDynamicFunctionRefInst, prev_dynamic_function_ref,
+                      LiteralInst, None, DoesNotRelease)
     SINGLE_VALUE_INST(GlobalAddrInst, global_addr,
                       LiteralInst, None, DoesNotRelease)
     SINGLE_VALUE_INST(GlobalValueInst, global_value,
diff --git a/include/swift/SIL/SILWitnessTable.h b/include/swift/SIL/SILWitnessTable.h
index c7ae3b9..a9bda2d 100644
--- a/include/swift/SIL/SILWitnessTable.h
+++ b/include/swift/SIL/SILWitnessTable.h
@@ -285,7 +285,8 @@
                       IsSerialized_t isSerialized);
 
   // Whether a conformance should be serialized.
-  static bool conformanceIsSerialized(ProtocolConformance *conformance);
+  static bool
+  conformanceIsSerialized(const NormalProtocolConformance *conformance);
 
   /// Call \c fn on each (split apart) conditional requirement of \c conformance
   /// that should appear in a witness table, i.e., conformance requirements that
diff --git a/include/swift/SIL/TypeSubstCloner.h b/include/swift/SIL/TypeSubstCloner.h
index 014e5d0..22adf0c 100644
--- a/include/swift/SIL/TypeSubstCloner.h
+++ b/include/swift/SIL/TypeSubstCloner.h
@@ -353,8 +353,9 @@
       ParentFunction = FuncBuilder.getOrCreateFunction(
           ParentFunction->getLocation(), MangledName, SILLinkage::Shared,
           ParentFunction->getLoweredFunctionType(), ParentFunction->isBare(),
-          ParentFunction->isTransparent(), ParentFunction->isSerialized(), 0,
-          ParentFunction->isThunk(), ParentFunction->getClassSubclassScope());
+          ParentFunction->isTransparent(), ParentFunction->isSerialized(),
+          IsNotDynamic, 0, ParentFunction->isThunk(),
+          ParentFunction->getClassSubclassScope());
       // Increment the ref count for the inlined function, so it doesn't
       // get deleted before we can emit abstract debug info for it.
       if (!ParentFunction->isZombie()) {
diff --git a/include/swift/SIL/ValueUtils.h b/include/swift/SIL/ValueUtils.h
new file mode 100644
index 0000000..646f77b
--- /dev/null
+++ b/include/swift/SIL/ValueUtils.h
@@ -0,0 +1,29 @@
+//===--- ValueUtils.h -----------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 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_SIL_VALUEUTILS_H
+#define SWIFT_SIL_VALUEUTILS_H
+
+#include "swift/SIL/SILValue.h"
+
+namespace swift {
+
+/// Attempt to merge the ValueOwnershipKind of the passed in range's
+/// SILValues. Returns Optional<None> if we found an incompatibility.
+///
+/// NOTE: This assumes that the passed in SILValues are not values used as type
+/// dependent operands.
+Optional<ValueOwnershipKind> mergeSILValueOwnership(ArrayRef<SILValue> values);
+
+} // namespace swift
+
+#endif
diff --git a/include/swift/SILOptimizer/Analysis/ARCAnalysis.h b/include/swift/SILOptimizer/Analysis/ARCAnalysis.h
index 3473fcc..c2e99fe 100644
--- a/include/swift/SILOptimizer/Analysis/ARCAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/ARCAnalysis.h
@@ -51,9 +51,6 @@
 bool mayDecrementRefCount(SILInstruction *User, SILValue Ptr,
                           AliasAnalysis *AA);
 
-/// \returns True if the user \p User checks the ref count of a pointer.
-bool mayCheckRefCount(SILInstruction *User);
-
 /// \returns True if the \p User might use the pointer \p Ptr in a manner that
 /// requires \p Ptr to be alive before Inst or the release of Ptr may use memory
 /// accessed by \p User.
diff --git a/include/swift/SILOptimizer/Utils/Local.h b/include/swift/SILOptimizer/Utils/Local.h
index 2ead781..f5cb3dc 100644
--- a/include/swift/SILOptimizer/Utils/Local.h
+++ b/include/swift/SILOptimizer/Utils/Local.h
@@ -640,7 +640,8 @@
 ///
 /// 1. We discovered that the function_ref never escapes.
 /// 2. We were able to find either a partial apply or a full apply site.
-Optional<FindLocalApplySitesResult> findLocalApplySites(FunctionRefInst *FRI);
+Optional<FindLocalApplySitesResult>
+findLocalApplySites(FunctionRefBaseInst *FRI);
 
 } // end namespace swift
 
diff --git a/include/swift/SILOptimizer/Utils/StackNesting.h b/include/swift/SILOptimizer/Utils/StackNesting.h
index 0719355..988b3a5 100644
--- a/include/swift/SILOptimizer/Utils/StackNesting.h
+++ b/include/swift/SILOptimizer/Utils/StackNesting.h
@@ -20,6 +20,25 @@
 
 namespace swift {
 
+struct InstructionMatchResult {
+  /// The instruction matches.
+  bool matches;
+
+  /// The search should be halted.
+  bool halt;
+};
+
+using InstructionMatcher =
+  llvm::function_ref<InstructionMatchResult(SILInstruction *i)>;
+
+/// Given a predicate defining interesting instructions, check whether
+/// the stack is different at any of them from how it stood at the start
+/// of the search.
+///
+/// The matcher function must halt the search before any edges which would
+/// lead back to before the start point.
+bool hasStackDifferencesAt(SILInstruction *start, InstructionMatcher matcher);
+
 /// A utility to correct the nesting of stack allocating/deallocating
 /// instructions.
 ///
diff --git a/include/swift/Serialization/DeclTypeRecordNodes.def b/include/swift/Serialization/DeclTypeRecordNodes.def
index 3c18af0..2e47a5f 100644
--- a/include/swift/Serialization/DeclTypeRecordNodes.def
+++ b/include/swift/Serialization/DeclTypeRecordNodes.def
@@ -159,15 +159,16 @@
 OTHER(TOP_LEVEL_CODE_DECL_CONTEXT, 223)
 
 OTHER(GENERIC_PARAM_LIST, 230)
-TRAILING_INFO(GENERIC_PARAM)
+OTHER(GENERIC_SIGNATURE, 231)
 TRAILING_INFO(GENERIC_REQUIREMENT)
 TRAILING_INFO(LAYOUT_REQUIREMENT)
-OTHER(GENERIC_SIGNATURE, 234)
+// 234 is unused
 OTHER(SIL_GENERIC_ENVIRONMENT, 235)
 OTHER(SUBSTITUTION_MAP, 236)
 
 OTHER(LOCAL_DISCRIMINATOR, 237)
 OTHER(PRIVATE_DISCRIMINATOR, 238)
+OTHER(FILENAME_FOR_PRIVATE, 239)
 
 OTHER(ABSTRACT_PROTOCOL_CONFORMANCE, 240)
 OTHER(NORMAL_PROTOCOL_CONFORMANCE, 241)
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index 38618da..c4e4b01 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -52,7 +52,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 = 456; // Last change: encode depth in generic param XREFs
+const uint16_t SWIFTMODULE_VERSION_MINOR = 466; // Last change: add isAutoClosure flag to param
 
 using DeclIDField = BCFixed<31>;
 
@@ -289,13 +289,6 @@
 
 // These IDs must \em not be renumbered or reordered without incrementing
 // the module version.
-enum class AddressorKind : uint8_t {
-  NotAddressor, Unsafe, Owning, NativeOwning
-};
-using AddressorKindField = BCFixed<3>;
- 
-// These IDs must \em not be renumbered or reordered without incrementing
-// the module version.
 enum class SelfAccessKind : uint8_t {
   NonMutating = 0,
   Mutating,
@@ -592,7 +585,8 @@
     XCC,
     IS_SIB,
     IS_TESTABLE,
-    RESILIENCE_STRATEGY
+    RESILIENCE_STRATEGY,
+    ARE_PRIVATE_IMPORTS_ENABLED
   };
 
   using SDKPathLayout = BCRecordLayout<
@@ -614,6 +608,10 @@
     IS_TESTABLE
   >;
 
+  using ArePrivateImportsEnabledLayout = BCRecordLayout<
+    ARE_PRIVATE_IMPORTS_ENABLED
+  >;
+
   using ResilienceStrategyLayout = BCRecordLayout<
     RESILIENCE_STRATEGY,
     BCFixed<2>
@@ -630,7 +628,8 @@
     IMPORTED_HEADER,
     IMPORTED_HEADER_CONTENTS,
     MODULE_FLAGS, // [unused]
-    SEARCH_PATH
+    SEARCH_PATH,
+    FILE_DEPENDENCY
   };
 
   using ImportedModuleLayout = BCRecordLayout<
@@ -668,6 +667,13 @@
     BCFixed<1>, // system?
     BCBlob      // path
   >;
+
+  using FileDependencyLayout = BCRecordLayout<
+    FILE_DEPENDENCY,
+    FileSizeField,    // file size (for validation)
+    FileModTimeField, // file mtime (for validation)
+    BCBlob            // path
+  >;
 }
 
 /// The record types within the "decls-and-types" block.
@@ -731,7 +737,6 @@
     FUNCTION_TYPE,
     TypeIDField, // output
     FunctionTypeRepresentationField, // representation
-    BCFixed<1>,  // auto-closure?
     BCFixed<1>,  // noescape?
     BCFixed<1>   // throws?
 
@@ -1018,6 +1023,7 @@
     VarDeclSpecifierField, // specifier
     TypeIDField,           // interface type
     BCFixed<1>,            // isVariadic?
+    BCFixed<1>,            // isAutoClosure?
     DefaultArgumentField,  // default argument kind
     BCBlob                 // default argument text
   >;
@@ -1069,7 +1075,6 @@
     DeclIDField,  // overridden function
     DeclIDField,  // AccessorStorageDecl
     AccessorKindField, // accessor kind
-    AddressorKindField, // addressor kind
     AccessLevelField, // access level
     BCFixed<1>,   // requires a new vtable slot
     BCFixed<1>,   // default argument resilience expansion
@@ -1246,13 +1251,8 @@
   >;
 
   using GenericParamListLayout = BCRecordLayout<
-    GENERIC_PARAM_LIST
-    // The actual parameters and requirements trail the record.
-  >;
-
-  using GenericParamLayout = BCRecordLayout<
-    GENERIC_PARAM,
-    DeclIDField // Typealias
+    GENERIC_PARAM_LIST,
+    BCArray<DeclIDField>        // the GenericTypeParamDecls
   >;
 
   using GenericSignatureLayout = BCRecordLayout<
@@ -1301,6 +1301,11 @@
     BCVBR<2> // context-scoped discriminator counter
   >;
 
+  using FilenameForPrivateLayout = BCRecordLayout<
+    FILENAME_FOR_PRIVATE,
+    IdentifierIDField  // the file name, as an identifier
+  >;
+
   /// A placeholder for lack of concrete conformance information.
   using AbstractProtocolConformanceLayout = BCRecordLayout<
     ABSTRACT_PROTOCOL_CONFORMANCE,
@@ -1505,6 +1510,7 @@
     = BCRecordLayout<RestatedObjCConformance_DECL_ATTR>;
   using ClangImporterSynthesizedTypeDeclAttrLayout
     = BCRecordLayout<ClangImporterSynthesizedType_DECL_ATTR>;
+  using PrivateImportDeclAttrLayout = BCRecordLayout<PrivateImport_DECL_ATTR>;
 
   using InlineDeclAttrLayout = BCRecordLayout<
     Inline_DECL_ATTR,
@@ -1568,6 +1574,14 @@
   >;
 #include "swift/AST/Attr.def"
 
+  using DynamicReplacementDeclAttrLayout = BCRecordLayout<
+    DynamicReplacement_DECL_ATTR,
+    BCFixed<1>, // implicit flag
+    DeclIDField, // replaced function
+    BCVBR<4>,   // # of arguments (+1) or zero if no name
+    BCArray<IdentifierIDField>
+  >;
+
 }
 
 /// Returns the encoding kind for the given decl.
diff --git a/include/swift/Serialization/SerializationOptions.h b/include/swift/Serialization/SerializationOptions.h
index e53dd14..1c31f6b 100644
--- a/include/swift/Serialization/SerializationOptions.h
+++ b/include/swift/Serialization/SerializationOptions.h
@@ -35,6 +35,13 @@
     StringRef ModuleLinkName;
     ArrayRef<std::string> ExtraClangOptions;
 
+    struct FileDependency {
+      uint64_t Size;
+      llvm::sys::TimePoint<> LastModTime;
+      StringRef Path;
+    };
+    ArrayRef<FileDependency> Dependencies;
+
     bool AutolinkForceLoad = false;
     bool EnableNestedTypeLookupTable = false;
     bool SerializeAllSIL = false;
diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h
index 723bbb9..a0c2ba5 100644
--- a/include/swift/Serialization/Validation.h
+++ b/include/swift/Serialization/Validation.h
@@ -14,6 +14,7 @@
 #define SWIFT_SERIALIZATION_VALIDATION_H
 
 #include "swift/Basic/LLVM.h"
+#include "swift/Serialization/SerializationOptions.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -92,6 +93,7 @@
   SmallVector<StringRef, 4> ExtraClangImporterOpts;
   StringRef SDKPath;
   struct {
+    unsigned ArePrivateImportsEnabled : 1;
     unsigned IsSIB : 1;
     unsigned IsTestable : 1;
     unsigned ResilienceStrategy : 2;
@@ -116,6 +118,10 @@
   void setIsSIB(bool val) {
       Bits.IsSIB = val;
   }
+  bool arePrivateImportsEnabled() { return Bits.ArePrivateImportsEnabled; }
+  void setPrivateImportsEnabled(bool enabled) {
+    Bits.ArePrivateImportsEnabled = enabled;
+  }
   bool isTestable() const { return Bits.IsTestable; }
   void setIsTestable(bool val) {
     Bits.IsTestable = val;
@@ -144,9 +150,12 @@
 /// \param[out] extendedInfo If present, will be populated with additional
 /// compilation options serialized into the AST at build time that may be
 /// necessary to load it properly.
-ValidationInfo
-validateSerializedAST(StringRef data,
-                      ExtendedValidationInfo *extendedInfo = nullptr);
+/// \param[out] dependencies If present, will be populated with list of
+/// input files the module depends on, if present in INPUT_BLOCK.
+ValidationInfo validateSerializedAST(
+    StringRef data, ExtendedValidationInfo *extendedInfo = nullptr,
+    SmallVectorImpl<SerializationOptions::FileDependency> *dependencies =
+        nullptr);
 
 /// Emit diagnostics explaining a failure to load a serialized AST.
 ///
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 735d0d7..945c683 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3722,7 +3722,7 @@
   default:
     result.emplace_back(type->getInOutObjectType(), Identifier(),
                         ParameterTypeFlags::fromParameterType(
-                          type, false, ValueOwnership::Default));
+                          type, false, false, ValueOwnership::Default));
     return;
   }
 }
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 288b36c..4d9c337 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -316,8 +316,6 @@
 #define SINGLETON_ACCESSOR(ID, KEYWORD) \
   case AccessorKind::ID: return #KEYWORD;
 #include "swift/AST/AccessorKinds.def"
-  case AccessorKind::Address: return "address";
-  case AccessorKind::MutableAddress: return "mutableAddress";
   }
 
   llvm_unreachable("Unhandled AccessorKind in switch.");
@@ -770,6 +768,12 @@
         OS << " @objc";
       if (VD->isDynamic())
         OS << " dynamic";
+      if (auto *attr =
+              VD->getAttrs().getAttribute<DynamicReplacementAttr>()) {
+        OS << " @_dynamicReplacement(for: \"";
+        OS << attr->getReplacedFunctionName();
+        OS << "\")";
+      }
     }
 
     void printCommon(NominalTypeDecl *NTD, const char *Name,
@@ -978,6 +982,9 @@
       if (P->isVariadic())
         OS << " variadic";
 
+      if (P->isAutoClosure())
+        OS << " autoclosure";
+
       if (P->getDefaultArgumentKind() != DefaultArgumentKind::None)
         printField("default_arg",
                    getDefaultArgumentKindString(P->getDefaultArgumentKind()));
@@ -1649,6 +1656,13 @@
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
 
+  void visitPoundAssertStmt(PoundAssertStmt *S) {
+    printCommon(S, "pound_assert");
+    OS << " message=" << QuotedString(S->getMessage()) << "\n";
+    printRec(S->getCondition());
+    OS << ")";
+  }
+
   void visitDoCatchStmt(DoCatchStmt *S) {
     printCommon(S, "do_catch_stmt") << '\n';
     printRec(S->getBody());
@@ -3425,7 +3439,6 @@
         printField("representation",
                    getSILFunctionTypeRepresentationString(representation));
 
-      printFlag(T->isAutoClosure(), "autoclosure");
       printFlag(!T->isNoEscape(), "escaping");
       printFlag(T->throws(), "throws");
 
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 19effcc..d368c06 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -18,7 +18,7 @@
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ASTVisitor.h"
 #include "swift/AST/ExistentialLayout.h"
-#include "swift/AST/GenericEnvironment.h"
+#include "swift/AST/GenericSignature.h"
 #include "swift/AST/Initializer.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/Ownership.h"
@@ -45,8 +45,7 @@
 using namespace swift;
 using namespace swift::Mangle;
 
-static StringRef getCodeForAccessorKind(AccessorKind kind,
-                                        AddressorKind addressorKind) {
+static StringRef getCodeForAccessorKind(AccessorKind kind) {
   switch (kind) {
   case AccessorKind::Get:
     return "g";
@@ -62,29 +61,9 @@
     return "M";
   case AccessorKind::Address:
     // 'l' is for location. 'A' was taken.
-    switch (addressorKind) {
-    case AddressorKind::NotAddressor:
-      llvm_unreachable("bad combo");
-    case AddressorKind::Unsafe:
-      return "lu";
-    case AddressorKind::Owning:
-      return "lO";
-    case AddressorKind::NativeOwning:
-      return "lo";
-    }
-    llvm_unreachable("bad addressor kind");
+    return "lu";
   case AccessorKind::MutableAddress:
-    switch (addressorKind) {
-    case AddressorKind::NotAddressor:
-      llvm_unreachable("bad combo");
-    case AddressorKind::Unsafe:
-      return "au";
-    case AddressorKind::Owning:
-      return "aO";
-    case AddressorKind::NativeOwning:
-      return "ao";
-    }
-    llvm_unreachable("bad addressor kind");
+    return "au";
   }
   llvm_unreachable("bad accessor kind");
 }
@@ -139,13 +118,11 @@
 }
 
 std::string ASTMangler::mangleAccessorEntity(AccessorKind kind,
-                                             AddressorKind addressorKind,
                                              const AbstractStorageDecl *decl,
                                              bool isStatic,
                                              SymbolKind SKind) {
   beginMangling();
-  appendAccessorEntity(getCodeForAccessorKind(kind, addressorKind), decl,
-                       isStatic);
+  appendAccessorEntity(getCodeForAccessorKind(kind), decl, isStatic);
   appendSymbolKind(SKind);
   return finalize();
 }
@@ -378,18 +355,15 @@
   return finalize();
 }
 
-std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC,
-                                              GenericEnvironment *GE) {
+std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) {
   PrettyStackTraceType prettyStackTrace(Ty->getASTContext(),
                                         "mangling type for debugger", Ty);
 
-  GenericEnv = GE;
   DWARFMangling = true;
   beginMangling();
   
   if (DC)
     bindGenericParameters(DC);
-  DeclCtx = DC;
 
   if (auto *fnType = Ty->getAs<AnyFunctionType>()) {
     appendFunction(fnType, false);
@@ -516,14 +490,12 @@
 }
 
 std::string ASTMangler::mangleAccessorEntityAsUSR(AccessorKind kind,
-                                                  AddressorKind addressorKind,
                                                   const AbstractStorageDecl *decl,
                                                   StringRef USRPrefix) {
   beginManglingWithoutPrefix();
   llvm::SaveAndRestore<bool> allowUnnamedRAII(AllowNamelessEntities, true);
   Buffer << USRPrefix;
-  appendAccessorEntity(getCodeForAccessorKind(kind, addressorKind), decl,
-                       /*isStatic*/ false);
+  appendAccessorEntity(getCodeForAccessorKind(kind), decl, /*isStatic*/ false);
   // We have a custom prefix, so finalize() won't verify for us. Do it manually.
   verify(Storage.str().drop_front(USRPrefix.size()));
   return finalize();
@@ -677,6 +649,17 @@
   return dc->isModuleScopeContext() && dc->getParentModule()->isStdlibModule();
 }
 
+/// Whether to mangle the given type as generic.
+static bool shouldMangleAsGeneric(Type type) {
+  if (!type)
+    return false;
+
+  if (auto typeAlias = dyn_cast<NameAliasType>(type.getPointer()))
+    return !typeAlias->getSubstitutionMap().empty();
+
+  return type->isSpecialized();
+}
+
 /// Mangle a type into the buffer.
 ///
 void ASTMangler::appendType(Type type) {
@@ -845,11 +828,12 @@
     case TypeKind::BoundGenericClass:
     case TypeKind::BoundGenericEnum:
     case TypeKind::BoundGenericStruct: {
-      // We can't use getAnyNominal here because this can be TypeAliasDecl only
-      // in case of UnboundGenericType. Such mangling happens in, for instance,
-      // SourceKit 'cursorinfo' request.
-      auto *Decl = type->getAnyGeneric();
-      if (type->isSpecialized()) {
+      GenericTypeDecl *Decl;
+      if (auto typeAlias = dyn_cast<NameAliasType>(type.getPointer()))
+        Decl = typeAlias->getDecl();
+      else
+        Decl = type->getAnyGeneric();
+      if (shouldMangleAsGeneric(type)) {
         // Try to mangle the entire name as a substitution.
         if (tryMangleSubstitution(tybase))
           return;
@@ -869,7 +853,7 @@
         addSubstitution(type.getPointer());
         return;
       }
-      appendAnyGenericType(Decl);
+      appendAnyGenericType(type->getAnyGeneric());
       return;
     }
 
@@ -1091,15 +1075,15 @@
 
   if (auto *unboundType = dyn_cast<UnboundGenericType>(typePtr)) {
     if (Type parent = unboundType->getParent())
-      appendBoundGenericArgs(parent, isFirstArgList);
+      appendBoundGenericArgs(parent->getDesugaredType(), isFirstArgList);
   } else if (auto *nominalType = dyn_cast<NominalType>(typePtr)) {
     if (Type parent = nominalType->getParent())
-      appendBoundGenericArgs(parent, isFirstArgList);
+      appendBoundGenericArgs(parent->getDesugaredType(), isFirstArgList);
   } else {
     auto boundType = cast<BoundGenericType>(typePtr);
     genericArgs = boundType->getGenericArgs();
     if (Type parent = boundType->getParent())
-      appendBoundGenericArgs(parent, isFirstArgList);
+      appendBoundGenericArgs(parent->getDesugaredType(), isFirstArgList);
   }
   if (isFirstArgList) {
     appendOperator("y");
@@ -1155,14 +1139,23 @@
 }
 
 void ASTMangler::appendRetroactiveConformances(Type type) {
-  auto nominal = type->getAnyNominal();
-  if (!nominal) return;
+  // Dig out the substitution map to use.
+  SubstitutionMap subMap;
+  ModuleDecl *module;
+  if (auto typeAlias = dyn_cast<NameAliasType>(type.getPointer())) {
+    module = Mod ? Mod : typeAlias->getDecl()->getModuleContext();
+    subMap = typeAlias->getSubstitutionMap();
+  } else {
+    if (type->hasUnboundGenericType())
+      return;
 
-  auto genericSig = nominal->getGenericSignatureOfContext();
-  if (!genericSig) return;
+    auto nominal = type->getAnyNominal();
+    if (!nominal) return;
 
-  auto module = Mod ? Mod : nominal->getModuleContext();
-  auto subMap = type->getContextSubstitutionMap(module, nominal);
+    module = Mod ? Mod : nominal->getModuleContext();
+    subMap = type->getContextSubstitutionMap(module, nominal);
+  }
+
   if (subMap.empty()) return;
 
   unsigned numProtocolRequirements = 0;
@@ -1700,7 +1693,7 @@
   }
 }
 
-void ASTMangler::appendFunctionType(AnyFunctionType *fn) {
+void ASTMangler::appendFunctionType(AnyFunctionType *fn, bool isAutoClosure) {
   assert((DWARFMangling || fn->isCanonical()) &&
          "expecting canonical types when not mangling for the debugger");
 
@@ -1722,7 +1715,7 @@
   case AnyFunctionType::Representation::Thin:
     return appendOperator("Xf");
   case AnyFunctionType::Representation::Swift:
-    if (fn->isAutoClosure()) {
+    if (isAutoClosure) {
       if (fn->isNoEscape())
         return appendOperator("XK");
       else
@@ -1806,7 +1799,11 @@
 
 void ASTMangler::appendTypeListElement(Identifier name, Type elementType,
                                        ParameterTypeFlags flags) {
-  appendType(elementType);
+  if (auto *fnType = elementType->getAs<FunctionType>())
+    appendFunctionType(fnType, flags.isAutoClosure());
+  else
+    appendType(elementType);
+
   switch (flags.getValueOwnership()) {
   case ValueOwnership::Default:
     /* nothing */
@@ -2029,29 +2026,24 @@
 void ASTMangler::appendClosureEntity(
                               const SerializedAbstractClosureExpr *closure) {
   appendClosureComponents(closure->getType(), closure->getDiscriminator(),
-                          closure->isImplicit(), closure->getParent(),
-                          closure->getLocalContext());
+                          closure->isImplicit(), closure->getParent());
 }
 
 void ASTMangler::appendClosureEntity(const AbstractClosureExpr *closure) {
   appendClosureComponents(closure->getType(), closure->getDiscriminator(),
-                          isa<AutoClosureExpr>(closure), closure->getParent(),
-                          closure->getLocalContext());
+                          isa<AutoClosureExpr>(closure), closure->getParent());
 }
 
 void ASTMangler::appendClosureComponents(Type Ty, unsigned discriminator,
-                                      bool isImplicit,
-                                      const DeclContext *parentContext,
-                                      const DeclContext *localContext) {
-  if (!DeclCtx) DeclCtx = localContext;
-
+                                         bool isImplicit,
+                                         const DeclContext *parentContext) {
   assert(discriminator != AbstractClosureExpr::InvalidDiscriminator
          && "closure must be marked correctly with discriminator");
 
   appendContext(parentContext);
 
   if (!Ty)
-    Ty = ErrorType::get(localContext->getASTContext());
+    Ty = ErrorType::get(parentContext->getASTContext());
 
   Ty = Ty->mapTypeOutOfContext();
   appendType(Ty->getCanonicalType());
@@ -2195,7 +2187,6 @@
 
 void ASTMangler::appendEntity(const ValueDecl *decl, StringRef EntityOp,
                               bool isStatic) {
-  if (!DeclCtx) DeclCtx = decl->getInnermostDeclContext();
   appendContextOf(decl);
   appendDeclName(decl);
   appendDeclType(decl);
@@ -2205,7 +2196,6 @@
 }
 
 void ASTMangler::appendEntity(const ValueDecl *decl) {
-  if (!DeclCtx) DeclCtx = decl->getInnermostDeclContext();
   assert(!isa<ConstructorDecl>(decl));
   assert(!isa<DestructorDecl>(decl));
   
@@ -2213,8 +2203,7 @@
   // declaration.
   if (auto accessor = dyn_cast<AccessorDecl>(decl)) {
     return appendAccessorEntity(
-        getCodeForAccessorKind(accessor->getAccessorKind(),
-                               accessor->getAddressorKind()),
+        getCodeForAccessorKind(accessor->getAccessorKind()),
         accessor->getStorage(), accessor->isStatic());
   }
 
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index d839e69..0a1ae31 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -71,6 +71,20 @@
   return scope.isPublic();
 }
 
+static bool isPublicOrUsableFromInline(Type ty) {
+  // Note the double negative here: we're looking for any referenced decls that
+  // are *not* public-or-usableFromInline.
+  return !ty.findIf([](Type typePart) -> bool {
+    // FIXME: If we have an internal typealias for a non-internal type, we ought
+    // to be able to print it by desugaring.
+    if (auto *aliasTy = dyn_cast<NameAliasType>(typePart.getPointer()))
+      return !isPublicOrUsableFromInline(aliasTy->getDecl());
+    if (auto *nominal = typePart->getAnyNominal())
+      return !isPublicOrUsableFromInline(nominal);
+    return false;
+  });
+}
+
 static bool contributesToParentTypeStorage(const AbstractStorageDecl *ASD) {
   auto *DC = ASD->getDeclContext()->getAsDecl();
   if (!DC) return false;
@@ -118,8 +132,21 @@
       if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
         if (!shouldPrint(ED->getExtendedNominal(), options))
           return false;
-        // FIXME: We also need to check the generic signature for constraints
-        // that we can't reference.
+        for (const Requirement &req : ED->getGenericRequirements()) {
+          if (!isPublicOrUsableFromInline(req.getFirstType()))
+            return false;
+
+          switch (req.getKind()) {
+          case RequirementKind::Conformance:
+          case RequirementKind::Superclass:
+          case RequirementKind::SameType:
+            if (!isPublicOrUsableFromInline(req.getSecondType()))
+              return false;
+            break;
+          case RequirementKind::Layout:
+            break;
+          }
+        }
       }
 
       // Skip typealiases that just redeclare generic parameters.
@@ -1568,26 +1595,6 @@
   case AccessorKind::ID: return #KEYWORD;
 #define ACCESSOR(ID)
 #include "swift/AST/AccessorKinds.def"
-
-  case AccessorKind::Address:
-    switch (accessor->getAddressorKind()) {
-    case AddressorKind::NotAddressor: llvm_unreachable("bad combination");
-#define IMMUTABLE_ADDRESSOR(ID, KEYWORD) \
-    case AddressorKind::ID: return #KEYWORD;
-#define ACCESSOR(ID)
-#include "swift/AST/AccessorKinds.def"
-    }
-    llvm_unreachable("bad addressor kind");
-
-  case AccessorKind::MutableAddress:
-    switch (accessor->getAddressorKind()) {
-    case AddressorKind::NotAddressor: llvm_unreachable("bad combination");
-#define MUTABLE_ADDRESSOR(ID, KEYWORD) \
-    case AddressorKind::ID: return #KEYWORD;
-#define ACCESSOR(ID)
-#include "swift/AST/AccessorKinds.def"
-    }
-    llvm_unreachable("bad addressor kind");
   }
   llvm_unreachable("bad accessor kind");
 }
@@ -2348,12 +2355,12 @@
 
 void PrintAST::visitVarDecl(VarDecl *decl) {
   printDocumentationComment(decl);
-  // Print @sil_stored when the attribute is not already
+  // Print @_hasStorage when the attribute is not already
   // on, decl has storage and it is on a class.
   if (Options.PrintForSIL && decl->hasStorage() &&
       isStructOrClassContext(decl->getDeclContext()) &&
-      !decl->getAttrs().hasAttribute<SILStoredAttr>())
-    Printer << "@sil_stored ";
+      !decl->getAttrs().hasAttribute<HasStorageAttr>())
+    Printer << "@_hasStorage ";
   printAttributes(decl);
   printAccess(decl);
   if (!Options.SkipIntroducerKeywords) {
@@ -3030,6 +3037,11 @@
   // FIXME: print expression.
 }
 
+void PrintAST::visitPoundAssertStmt(PoundAssertStmt *stmt) {
+  Printer << tok::pound_assert << " ";
+  // FIXME: print expression.
+}
+
 void PrintAST::visitDeferStmt(DeferStmt *stmt) {
   Printer << tok::kw_defer << " ";
   visit(stmt->getBodyAsWritten());
@@ -4418,12 +4430,18 @@
     inherited = ed->getInherited();
   }
 
-  // Collect explicit inheritted types.
+  // Collect explicit inherited types.
   for (auto TL: inherited) {
-    if (auto Ty = TL.getType()) {
-      if (auto NTD = Ty->getAnyNominal())
-        if (!shouldPrint(NTD))
-          continue;
+    if (auto ty = TL.getType()) {
+      bool foundUnprintable = ty.findIf([shouldPrint](Type subTy) {
+        if (auto aliasTy = dyn_cast<NameAliasType>(subTy.getPointer()))
+          return !shouldPrint(aliasTy->getDecl());
+        if (auto NTD = subTy->getAnyNominal())
+          return !shouldPrint(NTD);
+        return false;
+      });
+      if (foundUnprintable)
+        continue;
     }
     Results.push_back(TL);
   }
diff --git a/lib/AST/ASTScope.cpp b/lib/AST/ASTScope.cpp
index 50b890d..677d140 100644
--- a/lib/AST/ASTScope.cpp
+++ b/lib/AST/ASTScope.cpp
@@ -1089,6 +1089,7 @@
   case StmtKind::Fallthrough:
   case StmtKind::Fail:
   case StmtKind::Throw:
+  case StmtKind::PoundAssert:
     // Nothing to do for these statements.
     return nullptr;
   }
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index e289c94..81a8814 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -86,15 +86,23 @@
               std::is_same<Ty, ConstructorRefCallExpr>::value> {};
 
 template <typename Ty>
+struct is_subscript_expr
+    : public std::integral_constant<
+          bool, std::is_same<Ty, SubscriptExpr>::value ||
+                    std::is_same<Ty, DynamicSubscriptExpr>::value> {};
+
+template <typename Ty>
 struct is_autoclosure_expr
     : public std::integral_constant<bool,
                                     std::is_same<Ty, AutoClosureExpr>::value> {
 };
 
 template <typename Ty>
-struct is_apply_or_autoclosure_expr
-    : public std::integral_constant<
-          bool, is_apply_expr<Ty>::value || is_autoclosure_expr<Ty>::value> {};
+struct is_apply_subscript_or_autoclosure_expr
+    : public std::integral_constant<bool, is_apply_expr<Ty>::value ||
+                                              is_subscript_expr<Ty>::value ||
+                                              is_autoclosure_expr<Ty>::value> {
+};
 
 template <typename Verifier, typename Kind>
 std::pair<bool, Expr *> dispatchVisitPreExprHelper(
@@ -116,6 +124,22 @@
 std::pair<bool, Expr *> dispatchVisitPreExprHelper(
     Verifier &V,
     typename std::enable_if<
+        is_subscript_expr<typename std::remove_pointer<Kind>::type>::value,
+        Kind>::type node) {
+  if (V.shouldVerify(node)) {
+    // Record any inout_to_pointer or array_to_pointer that we see in
+    // the proper position.
+    V.maybeRecordValidPointerConversion(node, node->getIndex());
+    return {true, node};
+  }
+  V.cleanup(node);
+  return {false, node};
+}
+
+template <typename Verifier, typename Kind>
+std::pair<bool, Expr *> dispatchVisitPreExprHelper(
+    Verifier &V,
+    typename std::enable_if<
         is_autoclosure_expr<typename std::remove_pointer<Kind>::type>::value,
         Kind>::type node) {
   if (V.shouldVerify(node)) {
@@ -131,7 +155,7 @@
 template <typename Verifier, typename Kind>
 std::pair<bool, Expr *> dispatchVisitPreExprHelper(
     Verifier &V, typename std::enable_if<
-                     !is_apply_or_autoclosure_expr<
+                     !is_apply_subscript_or_autoclosure_expr<
                          typename std::remove_pointer<Kind>::type>::value,
                      Kind>::type node) {
   if (V.shouldVerify(node)) {
@@ -2714,6 +2738,48 @@
       verifyCheckedBase(nominal);
     }
 
+    void verifyCheckedAlways(GenericTypeParamDecl *GTPD) {
+      PrettyStackTraceDecl debugStack("verifying GenericTypeParamDecl", GTPD);
+
+      const DeclContext *DC = GTPD->getDeclContext();
+      if (!GTPD->getDeclContext()->isInnermostContextGeneric()) {
+        Out << "DeclContext of GenericTypeParamDecl does not have "
+               "generic params\n";
+        abort();
+      }
+
+      GenericParamList *paramList =
+          static_cast<const GenericContext *>(DC)->getGenericParams();
+      if (!paramList) {
+        Out << "DeclContext of GenericTypeParamDecl does not have "
+               "generic params\n";
+        abort();
+      }
+
+      unsigned currentDepth = paramList->getDepth();
+      if (currentDepth < GTPD->getDepth()) {
+        Out << "GenericTypeParamDecl has incorrect depth\n";
+        abort();
+      }
+      while (currentDepth > GTPD->getDepth()) {
+        paramList = paramList->getOuterParameters();
+        --currentDepth;
+      }
+      assert(paramList && "this is guaranteed by the parameter list's depth");
+
+      if (paramList->size() <= GTPD->getIndex() ||
+          paramList->getParams()[GTPD->getIndex()] != GTPD) {
+        if (llvm::is_contained(paramList->getParams(), GTPD))
+          Out << "GenericTypeParamDecl has incorrect index\n";
+        else
+          Out << "GenericTypeParamDecl not found in GenericParamList; "
+                 "incorrect depth or wrong DeclContext\n";
+        abort();
+      }
+
+      verifyCheckedBase(GTPD);
+    }
+
     void verifyChecked(ExtensionDecl *ext) {
       // Make sure that the protocol conformances are complete.
       for (auto conformance : ext->getLocalConformances()) {
@@ -3009,10 +3075,9 @@
           abort();
         }
 
-        if (AD->getAccessorKind() != AccessorKind::Read &&
-            AD->getAccessorKind() != AccessorKind::Modify) {
-          Out << "hasForcedStaticDispatch() set on accessor other than "
-                 "read or modify\n";
+        if (AD->getStorage()->requiresOpaqueAccessor(AD->getAccessorKind())) {
+          Out << "hasForcedStaticDispatch() set on accessor that's opaque "
+                 "for its storage\n";
           abort();
         }
       }
@@ -3076,10 +3141,29 @@
           Out << "Property and accessor do not match for 'final'\n";
           abort();
         }
-        if (FD->isDynamic() != storageDecl->isDynamic()) {
+        if (FD->isDynamic() != storageDecl->isDynamic() &&
+            // We allow a non dynamic setter if there is a dynamic modify,
+            // observer, or mutable addressor.
+            !(FD->isSetter() &&
+              (storageDecl->getWriteImpl() == WriteImplKind::Modify ||
+               storageDecl->getWriteImpl() ==
+                   WriteImplKind::StoredWithObservers ||
+               storageDecl->getWriteImpl() == WriteImplKind::MutableAddress) &&
+              storageDecl->isDynamic() && !storageDecl->isObjC()) &&
+            // We allow a non dynamic getter if there is a dynamic read.
+            !(FD->isGetter() &&
+              (storageDecl->getReadImpl() == ReadImplKind::Read ||
+               storageDecl->getReadImpl() == ReadImplKind::Address) &&
+              storageDecl->isDynamic() && !storageDecl->isObjC())) {
           Out << "Property and accessor do not match for 'dynamic'\n";
           abort();
         }
+        if (FD->isDynamic()) {
+          if (FD->isObjC() != storageDecl->isObjC()) {
+            Out << "Property and accessor do not match for '@objc'\n";
+            abort();
+          }
+        }
       }
 
       auto storedAccessor = storageDecl->getAccessor(FD->getAccessorKind());
@@ -3088,28 +3172,6 @@
         abort();
       }
 
-      switch (FD->getAccessorKind()) {
-      case AccessorKind::Get:
-      case AccessorKind::Set:
-      case AccessorKind::WillSet:
-      case AccessorKind::DidSet:
-      case AccessorKind::Read:
-      case AccessorKind::Modify:
-        if (FD->getAddressorKind() != AddressorKind::NotAddressor) {
-          Out << "non-addressor accessor has an addressor kind\n";
-          abort();
-        }
-        break;
-
-      case AccessorKind::Address:
-      case AccessorKind::MutableAddress:
-        if (FD->getAddressorKind() == AddressorKind::NotAddressor) {
-          Out << "addressor does not have an addressor kind\n";
-          abort();
-        }
-        break;
-      }
-
       verifyCheckedBase(FD);
     }
 
diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp
index aecae9e..c9b0610 100644
--- a/lib/AST/ASTWalker.cpp
+++ b/lib/AST/ASTWalker.cpp
@@ -1299,6 +1299,14 @@
   return nullptr;
 }
 
+Stmt *Traversal::visitPoundAssertStmt(PoundAssertStmt *S) {
+  if (auto *condition = doIt(S->getCondition())) {
+    S->setCondition(condition);
+  } else {
+    return nullptr;
+  }
+  return S;
+}
 
 Stmt *Traversal::visitBraceStmt(BraceStmt *BS) {
   for (auto &Elem : BS->getElements()) {
@@ -1614,6 +1622,10 @@
 }
 
 Pattern *Traversal::visitEnumElementPattern(EnumElementPattern *P) {
+  if (!P->isParentTypeImplicit())
+    if (doIt(P->getParentType()))
+      return nullptr;
+
   if (!P->hasSubPattern())
     return P;
 
diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp
index 23a231a..d865881 100644
--- a/lib/AST/Attr.cpp
+++ b/lib/AST/Attr.cpp
@@ -468,6 +468,12 @@
     }
     break;
   }
+
+  case DAK_PrivateImport: {
+    Printer.printAttrName("@_private(sourceFile: \"");
+    Printer << cast<PrivateImportAttr>(this)->getSourceFile() << "\")";
+    break;
+  }
     
   case DAK_SwiftNativeObjCRuntimeBase: {
     auto *attr = cast<SwiftNativeObjCRuntimeBaseAttr>(this);
@@ -546,6 +552,14 @@
     break;
   }
 
+  case DAK_DynamicReplacement: {
+    Printer.printAttrName("@_dynamicReplacement");
+    Printer << "(for: \"";
+    auto *attr = cast<DynamicReplacementAttr>(this);
+    Printer << attr->getReplacedFunctionName() << "\")";
+    break;
+  }
+
   case DAK_Count:
     llvm_unreachable("exceed declaration attribute kinds");
 
@@ -612,6 +626,10 @@
   case DAK_ObjC:
   case DAK_ObjCRuntimeName:
     return "objc";
+  case DAK_DynamicReplacement:
+    return "_dynamicReplacement";
+  case DAK_PrivateImport:
+    return "_private";
   case DAK_RestatedObjCConformance:
     return "_restatedObjCConformance";
   case DAK_Inline: {
@@ -776,6 +794,66 @@
   return attr;
 }
 
+PrivateImportAttr::PrivateImportAttr(SourceLoc atLoc, SourceRange baseRange,
+                                     StringRef sourceFile,
+                                     SourceRange parenRange)
+    : DeclAttribute(DAK_PrivateImport, atLoc, baseRange, /*Implicit=*/false),
+      SourceFile(sourceFile) {}
+
+PrivateImportAttr *PrivateImportAttr::create(ASTContext &Ctxt, SourceLoc AtLoc,
+                                             SourceLoc PrivateLoc,
+                                             SourceLoc LParenLoc,
+                                             StringRef sourceFile,
+                                             SourceLoc RParenLoc) {
+  return new (Ctxt)
+      PrivateImportAttr(AtLoc, SourceRange(PrivateLoc, RParenLoc), sourceFile,
+                        SourceRange(LParenLoc, RParenLoc));
+}
+
+DynamicReplacementAttr::DynamicReplacementAttr(SourceLoc atLoc,
+                                               SourceRange baseRange,
+                                               DeclName name,
+                                               SourceRange parenRange)
+    : DeclAttribute(DAK_DynamicReplacement, atLoc, baseRange,
+                    /*Implicit=*/false),
+      ReplacedFunctionName(name), ReplacedFunction(nullptr) {
+  Bits.DynamicReplacementAttr.HasTrailingLocationInfo = true;
+  getTrailingLocations()[0] = parenRange.Start;
+  getTrailingLocations()[1] = parenRange.End;
+}
+
+DynamicReplacementAttr *
+DynamicReplacementAttr::create(ASTContext &Ctx, SourceLoc AtLoc,
+                               SourceLoc DynReplLoc, SourceLoc LParenLoc,
+                               DeclName ReplacedFunction, SourceLoc RParenLoc) {
+  void *mem = Ctx.Allocate(totalSizeToAlloc<SourceLoc>(2),
+                           alignof(DynamicReplacementAttr));
+  return new (mem) DynamicReplacementAttr(
+      AtLoc, SourceRange(DynReplLoc, RParenLoc), ReplacedFunction,
+      SourceRange(LParenLoc, RParenLoc));
+}
+
+DynamicReplacementAttr *DynamicReplacementAttr::create(ASTContext &Ctx,
+                                                       DeclName name) {
+  return new (Ctx) DynamicReplacementAttr(name);
+}
+
+DynamicReplacementAttr *
+DynamicReplacementAttr::create(ASTContext &Ctx, DeclName name,
+                               AbstractFunctionDecl *f) {
+  auto res = new (Ctx) DynamicReplacementAttr(name);
+  res->setReplacedFunction(f);
+  return res;
+}
+
+SourceLoc DynamicReplacementAttr::getLParenLoc() const {
+  return getTrailingLocations()[0];
+}
+
+SourceLoc DynamicReplacementAttr::getRParenLoc() const {
+  return getTrailingLocations()[1];
+}
+
 AvailableAttr *
 AvailableAttr::createPlatformAgnostic(ASTContext &C,
                                    StringRef Message,
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index bf040f0..931af61 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -949,6 +949,14 @@
   return builder.build(Id);
 }
 
+static ValueDecl *getPoundAssert(ASTContext &Context, Identifier Id) {
+  auto int1Type = BuiltinIntegerType::get(1, Context);
+  auto optionalRawPointerType = BoundGenericEnumType::get(
+      Context.getOptionalDecl(), Type(), {Context.TheRawPointerType});
+  return getBuiltinFunction(Id, {int1Type, optionalRawPointerType},
+                            Context.TheEmptyTupleType);
+}
+
 static ValueDecl *getTSanInoutAccess(ASTContext &Context, Identifier Id) {
   // <T> T -> ()
   BuiltinGenericSignatureBuilder builder(Context);
@@ -1873,6 +1881,9 @@
   case BuiltinValueKind::GetObjCTypeEncoding:
     return getGetObjCTypeEncodingOperation(Context, Id);
 
+  case BuiltinValueKind::PoundAssert:
+    return getPoundAssert(Context, Id);
+
   case BuiltinValueKind::TSanInoutAccess:
     return getTSanInoutAccess(Context, Id);
 
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 87e05ff..024e9d5 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1416,9 +1416,10 @@
 }
 
 static bool isPolymorphic(const AbstractStorageDecl *storage) {
-  if (storage->isDynamic())
+  if (storage->isObjCDynamic())
     return true;
 
+
   // Imported declarations behave like they are dynamic, even if they're
   // not marked as such explicitly.
   if (storage->isObjC() && storage->hasClangNode())
@@ -1535,14 +1536,25 @@
 }
 
 static AccessStrategy
+getOpaqueReadAccessStrategy(const AbstractStorageDecl *storage, bool dispatch);
+static AccessStrategy
+getOpaqueWriteAccessStrategy(const AbstractStorageDecl *storage, bool dispatch);
+
+static AccessStrategy
 getDirectReadWriteAccessStrategy(const AbstractStorageDecl *storage) {
   switch (storage->getReadWriteImpl()) {
   case ReadWriteImplKind::Immutable:
     assert(isa<VarDecl>(storage) && cast<VarDecl>(storage)->isLet() &&
            "mutation of a immutable variable that isn't a let");
     return AccessStrategy::getStorage();
-  case ReadWriteImplKind::Stored:
+  case ReadWriteImplKind::Stored: {
+    // If the storage isDynamic (and not @objc) use the accessors.
+    if (storage->isDynamic() && !storage->isObjC())
+      return AccessStrategy::getMaterializeToTemporary(
+          getOpaqueReadAccessStrategy(storage, false),
+          getOpaqueWriteAccessStrategy(storage, false));
     return AccessStrategy::getStorage();
+  }
   case ReadWriteImplKind::MutableAddress:
     return AccessStrategy::getAccessor(AccessorKind::MutableAddress,
                                        /*dispatch*/ false);
@@ -1559,6 +1571,8 @@
 
 static AccessStrategy
 getOpaqueReadAccessStrategy(const AbstractStorageDecl *storage, bool dispatch) {
+  if (storage->requiresOpaqueReadCoroutine())
+    return AccessStrategy::getAccessor(AccessorKind::Read, dispatch);
   return AccessStrategy::getAccessor(AccessorKind::Get, dispatch);
 }
 
@@ -1609,6 +1623,9 @@
       if (isPolymorphic(this))
         return getOpaqueAccessStrategy(this, accessKind, /*dispatch*/ true);
 
+      if (isDynamic())
+        return getOpaqueAccessStrategy(this, accessKind, /*dispatch*/ false);
+
       // If the storage is resilient to the given use DC (perhaps because
       // it's @_transparent and we have to be careful about it being inlined
       // across module lines), we cannot use direct access.
@@ -1696,7 +1713,7 @@
   // Dynamic storage suppresses the modify coroutine.
   // If we add a Swift-native concept of `dynamic`, this should be restricted
   // to the ObjC-supported concept.
-  if (isDynamic())
+  if (isObjCDynamic())
     return false;
 
   // Requirements of ObjC protocols don't support the modify coroutine.
@@ -1767,18 +1784,18 @@
   if (getAttrs().hasAttribute<FixedLayoutAttr>())
     return false;
 
-  // Private and (unversioned) internal variables always have a
-  // fixed layout.
-  if (!getFormalAccessScope(/*useDC=*/nullptr,
-                            /*treatUsableFromInlineAsPublic=*/true).isPublic())
-    return false;
-
   // If we're an instance property of a nominal type, query the type.
   auto *dc = getDeclContext();
   if (!isStatic())
     if (auto *nominalDecl = dc->getSelfNominalTypeDecl())
       return nominalDecl->isResilient();
 
+  // Non-public global and static variables always have a
+  // fixed layout.
+  if (!getFormalAccessScope(/*useDC=*/nullptr,
+                            /*treatUsableFromInlineAsPublic=*/true).isPublic())
+    return false;
+
   return true;
 }
 
@@ -2026,7 +2043,6 @@
     return AnyFunctionType::ExtInfo();
   return AnyFunctionType::ExtInfo()
       .withRepresentation(info.getRepresentation())
-      .withIsAutoClosure(info.isAutoClosure())
       .withThrows(info.throws());
 }
 
@@ -2404,7 +2420,7 @@
 
 /// Return the access level of an internal or public declaration
 /// that's been testably imported.
-static AccessLevel getTestableAccess(const ValueDecl *decl) {
+static AccessLevel getTestableOrPrivateImportsAccess(const ValueDecl *decl) {
   // Non-final classes are considered open to @testable importers.
   if (auto cls = dyn_cast<ClassDecl>(decl)) {
     if (!cls->isFinal())
@@ -2436,11 +2452,13 @@
     return AccessLevel::Public;
   }
 
-  if (useDC && (access == AccessLevel::Internal ||
-                access == AccessLevel::Public)) {
-    if (auto *useSF = dyn_cast<SourceFile>(useDC->getModuleScopeContext()))
-      if (useSF->hasTestableImport(VD->getModuleContext()))
-        return getTestableAccess(VD);
+  if (useDC) {
+    // Check whether we need to modify the access level based on
+    // @testable/@_private import attributes.
+    auto *useSF = dyn_cast<SourceFile>(useDC->getModuleScopeContext());
+    if (!useSF) return access;
+    if (useSF->hasTestableOrPrivateImport(access, VD))
+      return getTestableOrPrivateImportsAccess(VD);
   }
 
   return access;
@@ -2460,19 +2478,24 @@
     getAdjustedFormalAccess(this, /*useDC=*/nullptr,
                             /*treatUsableFromInlineAsPublic=*/true);
 
-  // Handle @testable.
+  // Handle @testable/@_private(sourceFile:)
   switch (effectiveAccess) {
   case AccessLevel::Open:
     break;
   case AccessLevel::Public:
   case AccessLevel::Internal:
-    if (getModuleContext()->isTestingEnabled())
-      effectiveAccess = getTestableAccess(this);
+    if (getModuleContext()->isTestingEnabled() ||
+        getModuleContext()->arePrivateImportsEnabled())
+      effectiveAccess = getTestableOrPrivateImportsAccess(this);
     break;
   case AccessLevel::FilePrivate:
+    if (getModuleContext()->arePrivateImportsEnabled())
+      effectiveAccess = getTestableOrPrivateImportsAccess(this);
     break;
   case AccessLevel::Private:
     effectiveAccess = AccessLevel::FilePrivate;
+    if (getModuleContext()->arePrivateImportsEnabled())
+      effectiveAccess = getTestableOrPrivateImportsAccess(this);
     break;
   }
 
@@ -2650,18 +2673,30 @@
 
   switch (access) {
   case AccessLevel::Private:
+    if (useDC != sourceDC) {
+      auto *useSF = dyn_cast<SourceFile>(useDC->getModuleScopeContext());
+      if (useSF && useSF->hasTestableOrPrivateImport(access, VD))
+        return true;
+    }
     return (useDC == sourceDC ||
       AccessScope::allowsPrivateAccess(useDC, sourceDC));
   case AccessLevel::FilePrivate:
-    return useDC->getModuleScopeContext() == sourceDC->getModuleScopeContext();
+    if (useDC->getModuleScopeContext() != sourceDC->getModuleScopeContext()) {
+      auto *useSF = dyn_cast<SourceFile>(useDC->getModuleScopeContext());
+      if (useSF && useSF->hasTestableOrPrivateImport(access, VD))
+        return true;
+      return false;
+    }
+    return true;
   case AccessLevel::Internal: {
     const ModuleDecl *sourceModule = sourceDC->getParentModule();
     const DeclContext *useFile = useDC->getModuleScopeContext();
     if (useFile->getParentModule() == sourceModule)
       return true;
-    if (auto *useSF = dyn_cast<SourceFile>(useFile))
-      if (useSF->hasTestableImport(sourceModule))
-        return true;
+    auto *useSF = dyn_cast<SourceFile>(useFile);
+    if (!useSF) return false;
+    if (useSF->hasTestableOrPrivateImport(access, sourceModule))
+      return true;
     return false;
   }
   case AccessLevel::Public:
@@ -3014,6 +3049,18 @@
   return this == getASTContext().getOptionalDecl();
 }
 
+Optional<KeyPathTypeKind> NominalTypeDecl::getKeyPathTypeKind() const {
+  auto &ctx = getASTContext();
+#define CASE(NAME) if (this == ctx.get##NAME##Decl()) return KPTK_##NAME;
+  CASE(KeyPath)
+  CASE(WritableKeyPath)
+  CASE(ReferenceWritableKeyPath)
+  CASE(AnyKeyPath)
+  CASE(PartialKeyPath)
+#undef CASE
+  return None;
+}
+
 GenericTypeDecl::GenericTypeDecl(DeclKind K, DeclContext *DC,
                                  Identifier name, SourceLoc nameLoc,
                                  MutableArrayRef<TypeLoc> inherited,
@@ -3208,6 +3255,7 @@
   // Find the best anchor among the anchors of the overridden decls.
   AssociatedTypeDecl *bestAnchor = nullptr;
   for (auto assocType : overridden) {
+    assert(this != assocType && "AssociatedTypeDecl cannot override itself");
     auto anchor = assocType->getAssociatedTypeAnchor();
     if (!bestAnchor || compare(anchor, bestAnchor) < 0)
       bestAnchor = anchor;
@@ -3598,7 +3646,8 @@
   // Testably imported enums are exhaustive, on the grounds that only the author
   // of the original library can import it testably.
   if (auto *useSF = dyn_cast<SourceFile>(useDC->getModuleScopeContext()))
-    if (useSF->hasTestableImport(containingModule))
+    if (useSF->hasTestableOrPrivateImport(AccessLevel::Internal,
+                                          containingModule))
       return true;
 
   // Otherwise, the enum is non-exhaustive.
@@ -4292,7 +4341,8 @@
 
 void
 AbstractStorageDecl::setSynthesizedSetter(AccessorDecl *accessor) {
-  assert(getGetter() && "declaration doesn't already have getter!");
+  assert((getGetter() || getReadCoroutine()) &&
+         "declaration doesn't already have getter!");
   assert(supportsMutation() && "adding setter to immutable storage");
   assert(isAccessor(accessor, AccessorKind::Set, this));
 
@@ -4301,7 +4351,8 @@
 
 void
 AbstractStorageDecl::setSynthesizedModifyCoroutine(AccessorDecl *accessor) {
-  assert(getGetter() && "declaration doesn't already have getter!");
+  assert((getGetter() || getReadCoroutine()) &&
+         "declaration doesn't already have getter!");
   assert(getSetter() && "declaration doesn't already have setter!");
   assert(supportsMutation() && "adding modify to immutable storage");
   assert(!getModifyCoroutine() && "already has a modify accessor");
@@ -4753,7 +4804,8 @@
     ArgumentName(PD->getArgumentName()),
     ArgumentNameLoc(PD->getArgumentNameLoc()),
     SpecifierLoc(PD->getSpecifierLoc()),
-    DefaultValueAndIsVariadic(nullptr, PD->DefaultValueAndIsVariadic.getInt()) {
+    DefaultValueAndIsVariadic(nullptr, PD->DefaultValueAndIsVariadic.getInt()),
+    IsAutoClosure(PD->isAutoClosure()) {
   Bits.ParamDecl.IsTypeLocImplicit = PD->Bits.ParamDecl.IsTypeLocImplicit;
   Bits.ParamDecl.defaultArgumentKind = PD->Bits.ParamDecl.defaultArgumentKind;
   typeLoc = PD->getTypeLoc().clone(PD->getASTContext());
@@ -5058,8 +5110,7 @@
   return DeclName();
 }
 
-std::pair<DefaultArgumentKind, Type>
-swift::getDefaultArgumentInfo(ValueDecl *source, unsigned Index) {
+const ParamDecl *swift::getParameterAt(ValueDecl *source, unsigned index) {
   const ParameterList *paramList;
   if (auto *AFD = dyn_cast<AbstractFunctionDecl>(source)) {
     paramList = AFD->getParameters();
@@ -5067,8 +5118,7 @@
     paramList = cast<EnumElementDecl>(source)->getParameterList();
   }
 
-  auto param = paramList->get(Index);
-  return { param->getDefaultArgumentKind(), param->getInterfaceType() };
+  return paramList->get(index);
 }
 
 Type AbstractFunctionDecl::getMethodInterfaceType() const {
@@ -5289,7 +5339,7 @@
 
   // Final members are always be called directly.
   // Dynamic methods are always accessed by objc_msgSend().
-  if (decl->isFinal() || decl->isDynamic() || decl->hasClangNode())
+  if (decl->isFinal() || decl->isObjCDynamic() || decl->hasClangNode())
     return false;
   
   // Initializers are not normally inherited, but required initializers can
@@ -5312,7 +5362,8 @@
   }
 
   auto base = decl->getOverriddenDecl();
-  if (!base || base->hasClangNode() || base->isDynamic())
+
+  if (!base || base->hasClangNode() || base->isObjCDynamic())
     return true;
   
   // As above, convenience initializers are not formally overridable in Swift
@@ -5570,7 +5621,6 @@
                                        SourceLoc declLoc,
                                        SourceLoc accessorKeywordLoc,
                                        AccessorKind accessorKind,
-                                       AddressorKind addressorKind,
                                        AbstractStorageDecl *storage,
                                        SourceLoc staticLoc,
                                        StaticSpellingKind staticSpelling,
@@ -5585,7 +5635,7 @@
   void *buffer = allocateMemoryForDecl<AccessorDecl>(ctx, size,
                                                      !clangNode.isNull());
   auto D = ::new (buffer)
-      AccessorDecl(declLoc, accessorKeywordLoc, accessorKind, addressorKind,
+      AccessorDecl(declLoc, accessorKeywordLoc, accessorKind,
                    storage, staticLoc, staticSpelling, throws, throwsLoc,
                    hasImplicitSelfDecl, genericParams, parent);
   if (clangNode)
@@ -5600,7 +5650,6 @@
                                                SourceLoc declLoc,
                                                SourceLoc accessorKeywordLoc,
                                                AccessorKind accessorKind,
-                                               AddressorKind addressorKind,
                                                AbstractStorageDecl *storage,
                                                SourceLoc staticLoc,
                                               StaticSpellingKind staticSpelling,
@@ -5608,7 +5657,7 @@
                                                GenericParamList *genericParams,
                                                DeclContext *parent) {
   return createImpl(ctx, declLoc, accessorKeywordLoc, accessorKind,
-                    addressorKind, storage, staticLoc, staticSpelling,
+                    storage, staticLoc, staticSpelling,
                     throws, throwsLoc, genericParams, parent,
                     ClangNode());
 }
@@ -5617,7 +5666,6 @@
                                    SourceLoc declLoc,
                                    SourceLoc accessorKeywordLoc,
                                    AccessorKind accessorKind,
-                                   AddressorKind addressorKind,
                                    AbstractStorageDecl *storage,
                                    SourceLoc staticLoc,
                                    StaticSpellingKind staticSpelling,
@@ -5628,7 +5676,7 @@
                                    DeclContext *parent,
                                    ClangNode clangNode) {
   auto *D = AccessorDecl::createImpl(
-      ctx, declLoc, accessorKeywordLoc, accessorKind, addressorKind, storage,
+      ctx, declLoc, accessorKeywordLoc, accessorKind, storage,
       staticLoc, staticSpelling, throws, throwsLoc,
       genericParams, parent, clangNode);
   D->setParameters(bodyParams);
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index 36c80e1..07d3223 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -323,18 +323,13 @@
       if (!funcAccess.isPublic())
         break;
 
-      // Bodies of public transparent and always-inline functions are
-      // serialized, so use conservative access patterns.
+      // If the function is public, @_transparent implies @inlinable.
       if (AFD->isTransparent())
         return ResilienceExpansion::Minimal;
 
       if (AFD->getAttrs().hasAttribute<InlinableAttr>())
         return ResilienceExpansion::Minimal;
 
-      if (auto attr = AFD->getAttrs().getAttribute<InlineAttr>())
-        if (attr->getKind() == InlineKind::Always)
-          return ResilienceExpansion::Minimal;
-
       // If a property or subscript is @inlinable, the accessors are
       // @inlinable also.
       if (auto accessor = dyn_cast<AccessorDecl>(AFD))
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index 252fdc9..d1b589b 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -778,7 +778,7 @@
 class SourceFile::Impl {
 public:
   /// Only intended for use by lookupOperatorDeclForName.
-  static ArrayRef<std::pair<ModuleDecl::ImportedModule, SourceFile::ImportOptions>>
+  static ArrayRef<SourceFile::ImportedModuleDesc>
   getImportsForSourceFile(const SourceFile &SF) {
     return SF.Imports;
   }
@@ -888,16 +888,16 @@
   ImportedOperatorsMap<OP_DECL> importedOperators;
   for (auto &imported : SourceFile::Impl::getImportsForSourceFile(SF)) {
     // Protect against source files that contrive to import their own modules.
-    if (imported.first.second == ownModule)
+    if (imported.module.second == ownModule)
       continue;
 
     bool isExported =
-        imported.second.contains(SourceFile::ImportFlags::Exported);
+        imported.importOptions.contains(SourceFile::ImportFlags::Exported);
     if (!includePrivate && !isExported)
       continue;
 
-    Optional<OP_DECL *> maybeOp
-      = lookupOperatorDeclForName(imported.first.second, Loc, Name, OP_MAP);
+    Optional<OP_DECL *> maybeOp =
+        lookupOperatorDeclForName(imported.module.second, Loc, Name, OP_MAP);
     if (!maybeOp)
       return None;
     
@@ -989,21 +989,21 @@
 SourceFile::getImportedModules(SmallVectorImpl<ModuleDecl::ImportedModule> &modules,
                                ModuleDecl::ImportFilter filter) const {
   assert(ASTStage >= Parsed || Kind == SourceFileKind::SIL);
-  for (auto importPair : Imports) {
+  for (auto desc : Imports) {
     switch (filter) {
     case ModuleDecl::ImportFilter::All:
       break;
     case ModuleDecl::ImportFilter::Public:
-      if (!importPair.second.contains(ImportFlags::Exported))
+      if (!desc.importOptions.contains(ImportFlags::Exported))
         continue;
       break;
     case ModuleDecl::ImportFilter::Private:
-      if (importPair.second.contains(ImportFlags::Exported))
+      if (desc.importOptions.contains(ImportFlags::Exported))
         continue;
       break;
     }
 
-    modules.push_back(importPair.first);
+    modules.push_back(desc.module);
   }
 }
 
@@ -1373,14 +1373,12 @@
   }
 }
 
-void SourceFile::addImports(
-    ArrayRef<std::pair<ModuleDecl::ImportedModule, ImportOptions>> IM) {
-  using ImportPair = std::pair<ModuleDecl::ImportedModule, ImportOptions>;
+void SourceFile::addImports(ArrayRef<ImportedModuleDesc> IM) {
   if (IM.empty())
     return;
   ASTContext &ctx = getASTContext();
   auto newBuf =
-     ctx.AllocateUninitialized<ImportPair>(Imports.size() + IM.size());
+      ctx.AllocateUninitialized<ImportedModuleDesc>(Imports.size() + IM.size());
 
   auto iter = newBuf.begin();
   iter = std::uninitialized_copy(Imports.begin(), Imports.end(), iter);
@@ -1390,13 +1388,53 @@
   Imports = newBuf;
 }
 
-bool SourceFile::hasTestableImport(const swift::ModuleDecl *module) const {
-  using ImportPair = std::pair<ModuleDecl::ImportedModule, ImportOptions>;
+bool SourceFile::hasTestableOrPrivateImport(
+    AccessLevel accessLevel, const swift::ValueDecl *ofDecl) const {
+  auto *module = ofDecl->getModuleContext();
+  switch (accessLevel) {
+  case AccessLevel::Internal:
+  case AccessLevel::Public:
+    // internal/public access only needs an import marked as @_private. The
+    // filename does not need to match (and we don't serialize it for such
+    // decls).
+    return std::any_of(
+        Imports.begin(), Imports.end(),
+        [module](ImportedModuleDesc desc) -> bool {
+          return desc.module.second == module &&
+                 (desc.importOptions.contains(ImportFlags::PrivateImport) ||
+                  desc.importOptions.contains(ImportFlags::Testable));
+        });
+  case AccessLevel::Open:
+    return true;
+  case AccessLevel::FilePrivate:
+  case AccessLevel::Private:
+    // Fallthrough.
+    break;
+  }
+
+  auto *DC = ofDecl->getDeclContext();
+  if (!DC)
+    return false;
+  auto *scope = DC->getModuleScopeContext();
+  if (!scope)
+    return false;
+
+  StringRef filename;
+  if (auto *file = dyn_cast<LoadedFile>(scope)) {
+    filename = file->getFilenameForPrivateDecl(ofDecl);
+  } else
+    return false;
+
+  if (filename.empty())
+    return false;
+
   return std::any_of(Imports.begin(), Imports.end(),
-                     [module](ImportPair importPair) -> bool {
-    return importPair.first.second == module &&
-        importPair.second.contains(ImportFlags::Testable);
-  });
+                     [module, filename](ImportedModuleDesc desc) -> bool {
+                       return desc.module.second == module &&
+                              desc.importOptions.contains(
+                                  ImportFlags::PrivateImport) &&
+                              desc.filename == filename;
+                     });
 }
 
 void SourceFile::clearLookupCache() {
@@ -1444,8 +1482,8 @@
 
   // FIXME: These will be the same for most source files, but we copy them
   // over and over again.
-  auto Imports =
-    std::make_pair(ModuleDecl::ImportedModule({}, M), SourceFile::ImportOptions());
+  auto Imports = SourceFile::ImportedModuleDesc(
+      ModuleDecl::ImportedModule({}, M), SourceFile::ImportOptions());
   SF.addImports(Imports);
 }
 
diff --git a/lib/AST/NameLookupImpl.h b/lib/AST/NameLookupImpl.h
index a0f062b..9433963 100644
--- a/lib/AST/NameLookupImpl.h
+++ b/lib/AST/NameLookupImpl.h
@@ -117,6 +117,7 @@
   void visitReturnStmt(ReturnStmt *) {}
   void visitYieldStmt(YieldStmt *) {}
   void visitThrowStmt(ThrowStmt *) {}
+  void visitPoundAssertStmt(PoundAssertStmt *) {}
   void visitDeferStmt(DeferStmt *DS) {
     // Nothing in the defer is visible.
   }
diff --git a/lib/AST/Parameter.cpp b/lib/AST/Parameter.cpp
index 09c327b..9138bb1 100644
--- a/lib/AST/Parameter.cpp
+++ b/lib/AST/Parameter.cpp
@@ -106,7 +106,9 @@
       type = ParamDecl::getVarargBaseTy(type);
 
     auto label = P->getArgumentName();
-    auto flags = ParameterTypeFlags::fromParameterType(type, P->isVariadic(),
+    auto flags = ParameterTypeFlags::fromParameterType(type,
+                                                       P->isVariadic(),
+                                                       P->isAutoClosure(),
                                                        P->getValueOwnership());
     params.emplace_back(type, label, flags);
   }
diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp
index e6421e2..e2985f3 100644
--- a/lib/AST/ProtocolConformance.cpp
+++ b/lib/AST/ProtocolConformance.cpp
@@ -387,6 +387,23 @@
   return isa<ClangModuleUnit>(getDeclContext()->getModuleScopeContext());
 }
 
+bool NormalProtocolConformance::isResilient() const {
+  // If the type is non-resilient or the module we're in is non-resilient, the
+  // conformance is non-resilient.
+  // FIXME: Looking at the type is not the right long-term solution. We need an
+  // explicit mechanism for declaring conformances as 'fragile', or even
+  // individual witnesses.
+  if (!getType()->getAnyNominal()->isResilient())
+    return false;
+
+  switch (getDeclContext()->getParentModule()->getResilienceStrategy()) {
+  case ResilienceStrategy::Resilient:
+    return true;
+  case ResilienceStrategy::Default:
+    return false;
+  }
+}
+
 Optional<ArrayRef<Requirement>>
 ProtocolConformance::getConditionalRequirementsIfAvailable() const {
   CONFORMANCE_SUBCLASS_DISPATCH(getConditionalRequirementsIfAvailable, ());
@@ -833,6 +850,14 @@
                                                 LazyResolver *resolver) const {
   assert(assocType->isTypeParameter() &&
          "associated type must be a type parameter");
+
+  // Fill in the signature conformances, if we haven't done so yet.
+  if (getSignatureConformances().empty()) {
+    assocType->getASTContext().getLazyResolver()
+      ->checkConformanceRequirements(
+        const_cast<NormalProtocolConformance *>(this));
+  }
+
   assert(!getSignatureConformances().empty() &&
          "signature conformances not yet computed");
 
diff --git a/lib/AST/USRGeneration.cpp b/lib/AST/USRGeneration.cpp
index 2fd3d14..c1342ba 100644
--- a/lib/AST/USRGeneration.cpp
+++ b/lib/AST/USRGeneration.cpp
@@ -35,7 +35,7 @@
 bool ide::printTypeUSR(Type Ty, raw_ostream &OS) {
   assert(!Ty->hasArchetype() && "cannot have contextless archetypes mangled.");
   Mangle::ASTMangler Mangler;
-  OS << Mangler.mangleTypeForDebugger(Ty->getRValueType(), nullptr, nullptr);
+  OS << Mangler.mangleTypeForDebugger(Ty->getRValueType(), nullptr);
   return false;
 }
 
@@ -291,7 +291,7 @@
 
   Mangle::ASTMangler NewMangler;
   std::string Mangled = NewMangler.mangleAccessorEntityAsUSR(AccKind,
-                          AddressorKind::NotAddressor, SD, getUSRSpacePrefix());
+                          SD, getUSRSpacePrefix());
 
   OS << Mangled;
 
diff --git a/lib/Basic/FileTypes.cpp b/lib/Basic/FileTypes.cpp
index 76fd3d1..88cf557 100644
--- a/lib/Basic/FileTypes.cpp
+++ b/lib/Basic/FileTypes.cpp
@@ -79,7 +79,6 @@
   case file_types::TY_ModuleTrace:
   case file_types::TY_OptRecord:
   case file_types::TY_SwiftParseableInterfaceFile:
-  case file_types::TY_SwiftParseableInterfaceDeps:
     return true;
   case file_types::TY_Image:
   case file_types::TY_Object:
@@ -136,7 +135,6 @@
   case file_types::TY_ModuleTrace:
   case file_types::TY_OptRecord:
   case file_types::TY_SwiftParseableInterfaceFile:
-  case file_types::TY_SwiftParseableInterfaceDeps:
     return false;
   case file_types::TY_INVALID:
     llvm_unreachable("Invalid type ID.");
@@ -169,7 +167,6 @@
   case file_types::TY_SwiftModuleFile:
   case file_types::TY_SwiftModuleDocFile:
   case file_types::TY_SwiftParseableInterfaceFile:
-  case file_types::TY_SwiftParseableInterfaceDeps:
   case file_types::TY_SerializedDiagnostics:
   case file_types::TY_ClangModuleFile:
   case file_types::TY_SwiftDeps:
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index 1707011..73c86d7 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -1023,6 +1023,7 @@
   if (importerOpts.Mode == ClangImporterOptions::Modes::EmbedBitcode)
     return importer;
 
+  instance.getLangOpts().NeededByPCHOrCompilationUsesPCH = true;
   bool canBegin = action->BeginSourceFile(instance,
                                           instance.getFrontendOpts().Inputs[0]);
   if (!canBegin)
@@ -1403,6 +1404,7 @@
   invocation->getFrontendOpts().OutputFile = outputPCHPath;
   invocation->getFrontendOpts().ProgramAction = clang::frontend::GeneratePCH;
   invocation->getPreprocessorOpts().resetNonModularOptions();
+  invocation->getLangOpts()->NeededByPCHOrCompilationUsesPCH = true;
 
   clang::CompilerInstance emitInstance(
     Impl.Instance->getPCHContainerOperations());
@@ -2021,7 +2023,7 @@
 }
 
 static bool isVisibleFromModule(const ClangModuleUnit *ModuleFilter,
-                                const ValueDecl *VD) {
+                                ValueDecl *VD) {
   assert(ModuleFilter);
 
   auto ContainingUnit = VD->getDeclContext()->getModuleScopeContext();
@@ -2036,24 +2038,34 @@
 
   auto ClangNode = VD->getClangNode();
   if (!ClangNode) {
-    // If we synthesized a ValueDecl, it won't have a Clang node. But so far
-    // all the situations where we synthesize top-level declarations are
-    // situations where we don't have to worry about C redeclarations.
-    // We should only consider the declaration visible from its owning module.
+    // If we synthesized a ValueDecl, it won't have a Clang node. Find the
+    // associated declaration that /does/ have a Clang node, and use that.
     auto *SynthesizedTypeAttr =
         VD->getAttrs().getAttribute<ClangImporterSynthesizedTypeAttr>();
     assert(SynthesizedTypeAttr);
 
-    // When adding new ClangImporterSynthesizedTypeAttr::Kinds, make sure that
-    // the above statement still holds: "we don't want to allow these
-    // declarations to be treated as present in multiple modules".
     switch (SynthesizedTypeAttr->getKind()) {
     case ClangImporterSynthesizedTypeAttr::Kind::NSErrorWrapper:
-    case ClangImporterSynthesizedTypeAttr::Kind::NSErrorWrapperAnon:
+    case ClangImporterSynthesizedTypeAttr::Kind::NSErrorWrapperAnon: {
+      ASTContext &Ctx = ContainingUnit->getASTContext();
+      auto LookupFlags =
+          NominalTypeDecl::LookupDirectFlags::IgnoreNewExtensions;
+      auto WrapperStruct = cast<StructDecl>(VD);
+      TinyPtrVector<ValueDecl *> LookupResults =
+          WrapperStruct->lookupDirect(Ctx.Id_Code, LookupFlags);
+      assert(!LookupResults.empty() && "imported error enum without Code");
+
+      auto CodeEnumIter = llvm::find_if(LookupResults,
+                                        [&](ValueDecl *Member) -> bool {
+        return Member->getDeclContext() == WrapperStruct;
+      });
+      assert(CodeEnumIter != LookupResults.end() &&
+             "could not find Code enum in wrapper struct");
+      assert((*CodeEnumIter)->hasClangNode());
+      ClangNode = (*CodeEnumIter)->getClangNode();
       break;
     }
-
-    return false;
+    }
   }
 
   // Macros can be "redeclared" by putting an equivalent definition in two
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 0f199d3..5782247 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -165,7 +165,6 @@
     return AccessorDecl::create(ctx, funcLoc,
                                 /*accessorKeywordLoc*/ SourceLoc(),
                                 accessorInfo->Kind,
-                                AddressorKind::NotAddressor,
                                 accessorInfo->Storage,
                                 /*StaticLoc*/SourceLoc(),
                                 StaticSpellingKind::None,
@@ -505,7 +504,6 @@
                      /*FuncLoc=*/SourceLoc(),
                      /*AccessorKeywordLoc=*/SourceLoc(),
                      AccessorKind::Get,
-                     AddressorKind::NotAddressor,
                      rawValueDecl,
                      /*StaticLoc=*/SourceLoc(),
                      StaticSpellingKind::None,
@@ -586,7 +584,6 @@
                      /*FuncLoc=*/SourceLoc(),
                      /*AccessorKeywordLoc=*/SourceLoc(),
                      AccessorKind::Get,
-                     AddressorKind::NotAddressor,
                      computedVar,
                      /*StaticLoc=*/SourceLoc(),
                      StaticSpellingKind::None,
@@ -652,7 +649,6 @@
                      /*FuncLoc=*/importedFieldDecl->getLoc(),
                      /*AccessorKeywordLoc=*/SourceLoc(),
                      AccessorKind::Get,
-                     AddressorKind::NotAddressor,
                      importedFieldDecl,
                      /*StaticLoc=*/SourceLoc(),
                      StaticSpellingKind::None,
@@ -689,7 +685,6 @@
                      /*FuncLoc=*/SourceLoc(),
                      /*AccessorKeywordLoc=*/SourceLoc(),
                      AccessorKind::Set,
-                     AddressorKind::NotAddressor,
                      importedFieldDecl,
                      /*StaticLoc=*/SourceLoc(),
                      StaticSpellingKind::None,
@@ -1555,7 +1550,6 @@
                      /*FuncLoc=*/loc,
                      /*AccessorKeywordLoc=*/SourceLoc(),
                      AccessorKind::Get,
-                     AddressorKind::NotAddressor,
                      subscript,
                      /*StaticLoc=*/SourceLoc(),
                      StaticSpellingKind::None,
@@ -1612,7 +1606,6 @@
                      /*FuncLoc=*/setter->getLoc(),
                      /*AccessorKeywordLoc=*/SourceLoc(),
                      AccessorKind::Set,
-                     AddressorKind::NotAddressor,
                      subscript,
                      /*StaticLoc=*/SourceLoc(),
                      StaticSpellingKind::None,
@@ -1784,7 +1777,6 @@
                      /*FuncLoc=*/SourceLoc(),
                      /*AccessorKeywordLoc=*/SourceLoc(),
                      AccessorKind::Get,
-                     AddressorKind::NotAddressor,
                      errorDomainPropertyDecl,
                      /*StaticLoc=*/SourceLoc(),
                      StaticSpellingKind::None,
@@ -8185,7 +8177,6 @@
                      /*FuncLoc=*/SourceLoc(),
                      /*AccessorKeywordLoc=*/SourceLoc(),
                      AccessorKind::Get,
-                     AddressorKind::NotAddressor,
                      var,
                      /*StaticLoc=*/SourceLoc(),
                      StaticSpellingKind::None,
diff --git a/lib/ClangImporter/ImportName.h b/lib/ClangImporter/ImportName.h
index abce4ac..ddb4b0a 100644
--- a/lib/ClangImporter/ImportName.h
+++ b/lib/ClangImporter/ImportName.h
@@ -61,7 +61,9 @@
     // importing of names.  We treat that with a rawValue of 5, and treat
     // all major values of 5 or higher as being rawValue = majorversion + 1.
     const auto &version = langOpts.EffectiveLanguageVersion;
-    if (version.size() > 1 && version[0] == 4 && version[1] == 2) {
+    // If the effective version is 4.x, where x >= 2, the import version
+    // is 4.2.
+    if (version.size() > 1 && version[0] == 4 && version[1] >= 2) {
       return ImportNameVersion::swift4_2();
     }
     unsigned major = version[0];
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index 7aff1bf..74422f8 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -111,6 +111,9 @@
     case Node::Kind::OutlinedVariable:
     case Node::Kind::OutlinedBridgedMethod:
     case Node::Kind::MergedFunction:
+    case Node::Kind::DynamicallyReplaceableFunctionImpl:
+    case Node::Kind::DynamicallyReplaceableFunctionKey:
+    case Node::Kind::DynamicallyReplaceableFunctionVar:
       return true;
     default:
       return false;
@@ -1933,6 +1936,9 @@
     case 'a': return createNode(Node::Kind::PartialApplyObjCForwarder);
     case 'A': return createNode(Node::Kind::PartialApplyForwarder);
     case 'm': return createNode(Node::Kind::MergedFunction);
+    case 'X': return createNode(Node::Kind::DynamicallyReplaceableFunctionVar);
+    case 'x': return createNode(Node::Kind::DynamicallyReplaceableFunctionKey);
+    case 'I': return createNode(Node::Kind::DynamicallyReplaceableFunctionImpl);
     case 'C': {
       NodePointer type = popNode(Node::Kind::Type);
       return createWithChild(Node::Kind::CoroutineContinuationPrototype, type);
diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp
index add5341..311524c 100644
--- a/lib/Demangling/NodePrinter.cpp
+++ b/lib/Demangling/NodePrinter.cpp
@@ -493,6 +493,9 @@
     case Node::Kind::DependentProtocolConformanceInherited:
     case Node::Kind::DependentProtocolConformanceRoot:
     case Node::Kind::ProtocolConformanceRef:
+    case Node::Kind::DynamicallyReplaceableFunctionKey:
+    case Node::Kind::DynamicallyReplaceableFunctionImpl:
+    case Node::Kind::DynamicallyReplaceableFunctionVar:
       return false;
     }
     printer_unreachable("bad node kind");
@@ -1521,6 +1524,21 @@
     Printer << "type symbolic reference 0x";
     Printer.writeHex(Node->getIndex());
     return nullptr;
+  case Node::Kind::DynamicallyReplaceableFunctionKey:
+    if (!Options.ShortenThunk) {
+      Printer << "dynamically replaceable key for ";
+    }
+    return nullptr;
+  case Node::Kind::DynamicallyReplaceableFunctionImpl:
+    if (!Options.ShortenThunk) {
+      Printer << "dynamically replaceable thunk for ";
+    }
+    return nullptr;
+  case Node::Kind::DynamicallyReplaceableFunctionVar:
+    if (!Options.ShortenThunk) {
+      Printer << "dynamically replaceable variable for ";
+    }
+    return nullptr;
   case Node::Kind::ProtocolSymbolicReference:
     Printer << "protocol symbolic reference 0x";
     Printer.writeHex(Node->getIndex());
diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp
index b16c443..958f120 100644
--- a/lib/Demangling/OldRemangler.cpp
+++ b/lib/Demangling/OldRemangler.cpp
@@ -832,6 +832,18 @@
   Out << "Tm";
 }
 
+void Remangler::mangleDynamicallyReplaceableFunctionImpl(Node *node) {
+  Out << "TI";
+}
+
+void Remangler::mangleDynamicallyReplaceableFunctionKey(Node *node) {
+  Out << "Tx";
+}
+
+void Remangler::mangleDynamicallyReplaceableFunctionVar(Node *node) {
+  Out << "TX";
+}
+
 void Remangler::mangleDirectness(Node *node) {
   auto getChar = [](Directness d) -> char {
     switch (d) {
diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp
index 486117f..dab4bc9 100644
--- a/lib/Demangling/Remangler.cpp
+++ b/lib/Demangling/Remangler.cpp
@@ -1255,6 +1255,9 @@
       case Node::Kind::VTableAttribute:
       case Node::Kind::DirectMethodReferenceAttribute:
       case Node::Kind::MergedFunction:
+      case Node::Kind::DynamicallyReplaceableFunctionKey:
+      case Node::Kind::DynamicallyReplaceableFunctionImpl:
+      case Node::Kind::DynamicallyReplaceableFunctionVar:
         mangleInReverseOrder = true;
         break;
       default:
@@ -1587,6 +1590,18 @@
   Buffer << "Tm";
 }
 
+void Remangler::mangleDynamicallyReplaceableFunctionImpl(Node *node) {
+  Buffer << "TI";
+}
+
+void Remangler::mangleDynamicallyReplaceableFunctionKey(Node *node) {
+  Buffer << "Tx";
+}
+
+void Remangler::mangleDynamicallyReplaceableFunctionVar(Node *node) {
+  Buffer << "TX";
+}
+
 void Remangler::manglePostfixOperator(Node *node) {
   mangleIdentifierImpl(node, /*isOperator*/ true);
   Buffer << "oP";
diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp
index 470a368..0ece134 100644
--- a/lib/Driver/DarwinToolChains.cpp
+++ b/lib/Driver/DarwinToolChains.cpp
@@ -360,6 +360,9 @@
   if (context.OI.SelectedSanitizers & SanitizerKind::Thread)
     addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "tsan", *this);
 
+  if (context.OI.SelectedSanitizers & SanitizerKind::Undefined)
+    addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "ubsan", *this);
+
   // Only link in libFuzzer for executables.
   if (job.getKind() == LinkKind::Executable &&
       (context.OI.SelectedSanitizers & SanitizerKind::Fuzzer))
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 7c2d3d4..b2e953b 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -947,7 +947,7 @@
 
   // Construct the graph of Actions.
   SmallVector<const Action *, 8> TopLevelActions;
-  buildActions(TopLevelActions, TC, OI, OFM ? OFM.getPointer() : nullptr,
+  buildActions(TopLevelActions, TC, OI,
                rebuildEverything ? nullptr : &outOfDateMap, *C);
 
   if (Diags.hadAnyError())
@@ -1662,7 +1662,6 @@
 
 void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
                           const ToolChain &TC, const OutputInfo &OI,
-                          const OutputFileMap *OFM,
                           const InputInfoMap *OutOfDateMap,
                           Compilation &C) const {
   const DerivedArgList &Args = C.getArgs();
@@ -1783,7 +1782,6 @@
       case file_types::TY_ModuleTrace:
       case file_types::TY_OptRecord:
       case file_types::TY_SwiftParseableInterfaceFile:
-      case file_types::TY_SwiftParseableInterfaceDeps:
         // We could in theory handle assembly or LLVM input, but let's not.
         // FIXME: What about LTO?
         Diags.diagnose(SourceLoc(), diag::error_unexpected_input_file,
@@ -2473,8 +2471,7 @@
                     Output.get());
 
   if (OI.ShouldGenerateModule && isa<CompileJobAction>(JA))
-    chooseSwiftModuleOutputPath(C, OFM, OutputMap, workingDirectory,
-                                Output.get());
+    chooseSwiftModuleOutputPath(C, OutputMap, workingDirectory, Output.get());
 
   if (OI.ShouldGenerateModule &&
       (isa<CompileJobAction>(JA) || isa<MergeModuleJobAction>(JA)))
@@ -2660,7 +2657,6 @@
 }
 
 void Driver::chooseSwiftModuleOutputPath(Compilation &C,
-                                         const OutputFileMap *OFM,
                                          const TypeToPathMap *OutputMap,
                                          StringRef workingDirectory,
                                          CommandOutput *Output) const {
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 79b6b1a..dec3786 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -186,6 +186,7 @@
   inputArgs.AddLastArg(arguments, options::OPT_typo_correction_limit);
   inputArgs.AddLastArg(arguments, options::OPT_enable_app_extension);
   inputArgs.AddLastArg(arguments, options::OPT_enable_testing);
+  inputArgs.AddLastArg(arguments, options::OPT_enable_private_imports);
   inputArgs.AddLastArg(arguments, options::OPT_g_Group);
   inputArgs.AddLastArg(arguments, options::OPT_debug_info_format);
   inputArgs.AddLastArg(arguments, options::OPT_import_underlying_module);
@@ -440,7 +441,6 @@
   case file_types::TY_TBD:
   case file_types::TY_OptRecord:
   case file_types::TY_SwiftParseableInterfaceFile:
-  case file_types::TY_SwiftParseableInterfaceDeps:
     llvm_unreachable("Output type can never be primary output.");
   case file_types::TY_INVALID:
     llvm_unreachable("Invalid type ID");
@@ -673,7 +673,6 @@
     case file_types::TY_ModuleTrace:
     case file_types::TY_OptRecord:
     case file_types::TY_SwiftParseableInterfaceFile:
-    case file_types::TY_SwiftParseableInterfaceDeps:
       llvm_unreachable("Output type can never be primary output.");
     case file_types::TY_INVALID:
       llvm_unreachable("Invalid type ID");
diff --git a/lib/Driver/UnixToolChains.cpp b/lib/Driver/UnixToolChains.cpp
index bcb75fa7..77aa043 100644
--- a/lib/Driver/UnixToolChains.cpp
+++ b/lib/Driver/UnixToolChains.cpp
@@ -301,9 +301,13 @@
       if (context.OI.SelectedSanitizers & SanitizerKind::Thread)
         addLinkSanitizerLibArgsForLinux(context.Args, Arguments, "tsan", *this);
 
+      if (context.OI.SelectedSanitizers & SanitizerKind::Undefined)
+        addLinkSanitizerLibArgsForLinux(context.Args, Arguments, "ubsan", *this);
+
       if (context.OI.SelectedSanitizers & SanitizerKind::Fuzzer)
         addLinkRuntimeLib(context.Args, Arguments,
                           sanitizerRuntimeLibName("fuzzer"));
+
     }
   }
 
diff --git a/lib/Driver/WindowsToolChains.cpp b/lib/Driver/WindowsToolChains.cpp
index ea3cbbc..7dfa371 100644
--- a/lib/Driver/WindowsToolChains.cpp
+++ b/lib/Driver/WindowsToolChains.cpp
@@ -147,6 +147,10 @@
     if (context.OI.SelectedSanitizers & SanitizerKind::Address)
       addLinkRuntimeLib(context.Args, Arguments,
                         sanitizerRuntimeLibName("asan"));
+
+    if (context.OI.SelectedSanitizers & SanitizerKind::Undefined)
+      addLinkRuntimeLib(context.Args, Arguments,
+                        sanitizerRuntimeLibName("ubsan"));
   }
 
   if (context.Args.hasArg(options::OPT_profile_generate)) {
diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp
index 1ca10db..943cc1b 100644
--- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp
+++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp
@@ -67,6 +67,7 @@
   Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
 
   Opts.EnableTesting |= Args.hasArg(OPT_enable_testing);
+  Opts.EnablePrivateImports |= Args.hasArg(OPT_enable_private_imports);
   Opts.EnableResilience |= Args.hasArg(OPT_enable_resilience);
 
   Opts.TrackSystemDeps |= Args.hasArg(OPT_track_system_dependencies);
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index e011746..f65370e 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -206,12 +206,18 @@
   Opts.DiagnosticsEditorMode |= Args.hasArg(OPT_diagnostics_editor_mode,
                                             OPT_serialize_diagnostics_path);
 
+  Opts.EnableExperimentalStaticAssert |=
+    Args.hasArg(OPT_enable_experimental_static_assert);
+
   Opts.EnableExperimentalPropertyBehaviors |=
     Args.hasArg(OPT_enable_experimental_property_behaviors);
 
   Opts.EnableOperatorDesignatedTypes |=
       Args.hasArg(OPT_enable_operator_designated_types);
 
+  // Always enable operator designated types for the standard library.
+  Opts.EnableOperatorDesignatedTypes |= FrontendOpts.ParseStdlib;
+
   Opts.SolverEnableOperatorDesignatedTypes |=
       Args.hasArg(OPT_solver_enable_operator_designated_types);
 
@@ -268,6 +274,7 @@
   Opts.DebugConstraintSolver |= Args.hasArg(OPT_debug_constraints);
   Opts.NamedLazyMemberLoading &= !Args.hasArg(OPT_disable_named_lazy_member_loading);
   Opts.DebugGenericSignatures |= Args.hasArg(OPT_debug_generic_signatures);
+  Opts.EnableImplicitDynamic |= Args.hasArg(OPT_enable_implicit_dynamic);
 
   if (Args.hasArg(OPT_verify_syntax_tree)) {
     Opts.BuildSyntaxTree = true;
@@ -736,7 +743,7 @@
   Opts.AssumeUnqualifiedOwnershipWhenParsing
     |= Args.hasArg(OPT_assume_parsing_unqualified_ownership_sil);
   Opts.EnableMandatorySemanticARCOpts |=
-      !Args.hasArg(OPT_disable_mandatory_semantic_arc_opts);
+      Args.hasArg(OPT_enable_mandatory_semantic_arc_opts);
   Opts.EnableLargeLoadableTypes |= Args.hasArg(OPT_enable_large_loadable_types);
 
   if (const Arg *A = Args.getLastArg(OPT_save_optimization_record_path))
@@ -770,8 +777,11 @@
     Opts.VerifyExclusivity
       = A->getOption().matches(OPT_enable_verify_exclusivity);
   }
-  if (Opts.shouldOptimize() && !Opts.VerifyExclusivity)
+  // If runtime asserts are disabled in general, also disable runtime
+  // exclusivity checks unless explicitly requested.
+  if (Opts.RemoveRuntimeAsserts)
     Opts.EnforceExclusivityDynamic = false;
+
   if (const Arg *A = Args.getLastArg(options::OPT_enforce_exclusivity_EQ)) {
     parseExclusivityEnforcementOptions(A, Opts, Diags);
   }
@@ -982,6 +992,9 @@
 
   Opts.PrintInlineTree |= Args.hasArg(OPT_print_llvm_inline_tree);
 
+  Opts.EnableDynamicReplacementChaining |=
+      Args.hasArg(OPT_enable_dynamic_replacement_chaining);
+
   Opts.UseSwiftCall = Args.hasArg(OPT_enable_swiftcall);
 
   // This is set to true by default.
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index c8bdf41..bd6c177 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -36,9 +36,6 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/HeaderSearch.h"
 
 using namespace swift;
 
@@ -308,20 +305,8 @@
       Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
       return true;
     }
-    // Capture the specified-or-defaulted -module-cache-path that winds up in
-    // the clang importer, for reuse as the .swiftmodule cache path when
-    // building the ParseableInterfaceModuleLoader below.
-    //
-    // The returned-from-clang module cache path includes a suffix directory
-    // that is specific to the clang version and invocation; we want the
-    // directory above that.
     auto const &Clang = clangImporter->getClangInstance();
-    if (Clang.hasPreprocessor()) {
-      std::string SpecificModuleCachePath = Clang.getPreprocessor()
-                                                .getHeaderSearchInfo()
-                                                .getModuleCachePath();
-      ModuleCachePath = llvm::sys::path::parent_path(SpecificModuleCachePath);
-    }
+    ModuleCachePath = getModuleCachePathFromClang(Clang);
     Context->addModuleLoader(std::move(clangImporter), /*isClang*/ true);
   }
   if (Invocation.getFrontendOptions().EnableParseableModuleInterface) {
@@ -501,6 +486,8 @@
     MainModule = ModuleDecl::create(ID, *Context);
     if (Invocation.getFrontendOptions().EnableTesting)
       MainModule->setTestingEnabled();
+    if (Invocation.getFrontendOptions().EnablePrivateImports)
+      MainModule->setPrivateImportsEnabled();
 
     if (Invocation.getFrontendOptions().EnableResilience)
       MainModule->setResilienceStrategy(ResilienceStrategy::Resilient);
@@ -510,22 +497,24 @@
 
 static void addAdditionalInitialImportsTo(
     SourceFile *SF, const CompilerInstance::ImplicitImports &implicitImports) {
-  using ImportPair =
-      std::pair<ModuleDecl::ImportedModule, SourceFile::ImportOptions>;
-  SmallVector<ImportPair, 4> additionalImports;
+  SmallVector<SourceFile::ImportedModuleDesc, 4> additionalImports;
 
   if (implicitImports.objCModuleUnderlyingMixedFramework)
-    additionalImports.push_back(
-        {{/*accessPath=*/{},
-          implicitImports.objCModuleUnderlyingMixedFramework},
-         SourceFile::ImportFlags::Exported});
+    additionalImports.push_back(SourceFile::ImportedModuleDesc(
+        ModuleDecl::ImportedModule(
+            /*accessPath=*/{},
+            implicitImports.objCModuleUnderlyingMixedFramework),
+        SourceFile::ImportFlags::Exported));
   if (implicitImports.headerModule)
-    additionalImports.push_back(
-        {{/*accessPath=*/{}, implicitImports.headerModule},
-         SourceFile::ImportFlags::Exported});
+    additionalImports.push_back(SourceFile::ImportedModuleDesc(
+        ModuleDecl::ImportedModule(/*accessPath=*/{},
+                                   implicitImports.headerModule),
+        SourceFile::ImportFlags::Exported));
   if (!implicitImports.modules.empty()) {
     for (auto &importModule : implicitImports.modules) {
-      additionalImports.push_back({{/*accessPath=*/{}, importModule}, {}});
+      additionalImports.push_back(SourceFile::ImportedModuleDesc(
+          ModuleDecl::ImportedModule(/*accessPath=*/{}, importModule),
+          SourceFile::ImportOptions()));
     }
   }
 
diff --git a/lib/Frontend/ParseableInterfaceSupport.cpp b/lib/Frontend/ParseableInterfaceSupport.cpp
index 5f489fa..90a5369 100644
--- a/lib/Frontend/ParseableInterfaceSupport.cpp
+++ b/lib/Frontend/ParseableInterfaceSupport.cpp
@@ -14,13 +14,18 @@
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/Decl.h"
 #include "swift/AST/DiagnosticsFrontend.h"
+#include "swift/AST/ExistentialLayout.h"
 #include "swift/AST/FileSystem.h"
 #include "swift/AST/Module.h"
 #include "swift/Frontend/Frontend.h"
 #include "swift/Frontend/ParseableInterfaceSupport.h"
+#include "swift/Frontend/PrintingDiagnosticConsumer.h"
 #include "swift/SILOptimizer/PassManager/Passes.h"
 #include "swift/Serialization/SerializationOptions.h"
 #include "clang/Basic/Module.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/HeaderSearch.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/CommandLine.h"
@@ -33,7 +38,6 @@
 
 #define SWIFT_TOOLS_VERSION_KEY "swift-tools-version"
 #define SWIFT_MODULE_FLAGS_KEY "swift-module-flags"
-#define SWIFT_INTERFACE_DEPS_VERSION "swift-interface-deps-version-1"
 
 static bool
 extractSwiftInterfaceVersionAndArgs(DiagnosticEngine &Diags,
@@ -105,8 +109,7 @@
 ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths(
     CompilerInvocation &SubInvocation,
     StringRef InPath,
-    llvm::SmallString<128> &OutPath,
-    llvm::SmallString<128> &DepPath) {
+    llvm::SmallString<128> &OutPath) {
 
   auto &SearchPathOpts = Ctx.SearchPathOpts;
   auto &LangOpts = Ctx.LangOpts;
@@ -119,6 +122,7 @@
   SubInvocation.setInputKind(InputFileKind::SwiftModuleInterface);
   SubInvocation.setRuntimeResourcePath(SearchPathOpts.RuntimeResourcePath);
   SubInvocation.setTargetTriple(LangOpts.Target);
+  SubInvocation.setClangModuleCachePath(CacheDir);
 
   // Calculate an output filename that includes a hash of relevant key data, and
   // wire up the SubInvocation's InputsAndOutputs to contain both input and
@@ -128,14 +132,12 @@
   OutPath.append("-");
   OutPath.append(getCacheHash(Ctx, SubInvocation, InPath));
   OutPath.append(".");
-  DepPath = OutPath;
   auto OutExt = file_types::getExtension(file_types::TY_SwiftModuleFile);
   OutPath.append(OutExt);
-  auto DepExt = file_types::getExtension(file_types::TY_SwiftParseableInterfaceDeps);
-  DepPath.append(DepExt);
 
   auto &FEOpts = SubInvocation.getFrontendOptions();
   FEOpts.RequestedAction = FrontendOptions::ActionType::EmitModuleOnly;
+  FEOpts.EnableParseableModuleInterface = true;
   FEOpts.InputsAndOutputs.addPrimaryInputFile(InPath);
   SupplementaryOutputPaths SOPs;
   SOPs.ModuleOutputPath = OutPath.str();
@@ -143,67 +145,60 @@
   FEOpts.InputsAndOutputs.setMainAndSupplementaryOutputs({MainOut}, {SOPs});
 }
 
-// Write the world's simplest dependencies file: a version identifier on
-// a line followed by a list of files, one per line.
-static bool writeSwiftInterfaceDeps(DiagnosticEngine &Diags,
-                                    ArrayRef<std::string> Deps,
-                                    StringRef DepPath) {
-  return withOutputFile(Diags, DepPath, [&](llvm::raw_pwrite_stream &out) {
-      out << SWIFT_INTERFACE_DEPS_VERSION << '\n';
-      for (auto const &D : Deps) {
-        out << D << '\n';
-      }
-      return false;
-    });
-}
-
 // Check that the output .swiftmodule file is at least as new as all the
 // dependencies it read when it was built last time.
 static bool
 swiftModuleIsUpToDate(clang::vfs::FileSystem &FS,
-                      StringRef InPath, StringRef OutPath, StringRef DepPath) {
+                      StringRef ModuleCachePath,
+                      StringRef OutPath) {
 
-  if (!FS.exists(OutPath) || !FS.exists(DepPath))
+  if (!FS.exists(OutPath))
     return false;
 
   auto OutStatus = FS.status(OutPath);
   if (!OutStatus)
     return false;
 
-  auto DepBuf = FS.getBufferForFile(DepPath);
-  if (!DepBuf)
+  auto OutBuf = FS.getBufferForFile(OutPath);
+  if (!OutBuf)
     return false;
 
-  // Split the deps file into a vector of lines.
-  StringRef Deps =  DepBuf.get()->getBuffer();
-  SmallVector<StringRef, 16> AllDeps;
-  Deps.split(AllDeps, '\n', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+  LLVM_DEBUG(llvm::dbgs() << "Validating deps of " << OutPath << "\n");
+  SmallVector<SerializationOptions::FileDependency, 16> AllDeps;
+  auto VI = serialization::validateSerializedAST(
+      OutBuf.get()->getBuffer(),
+      /*ExtendedValidationInfo=*/nullptr, &AllDeps);
 
-  // First line in vector is a version-string; check it is the expected value.
-  if (AllDeps.size() < 1 ||
-      AllDeps[0] != SWIFT_INTERFACE_DEPS_VERSION) {
+  if (VI.status != serialization::Status::Valid)
     return false;
-  }
 
-  // Overwrite the version-string entry in the vector with the .swiftinterface
-  // input file we're reading, then stat() every entry in the vector and check
-  // none are newer than the .swiftmodule (OutStatus).
-  AllDeps[0] = InPath;
   for (auto In : AllDeps) {
-    auto InStatus = FS.status(In);
+    auto InStatus = FS.status(In.Path);
     if (!InStatus ||
-        (InStatus.get().getLastModificationTime() >
-         OutStatus.get().getLastModificationTime())) {
+        (InStatus.get().getSize() != In.Size) ||
+        (InStatus.get().getLastModificationTime() != In.LastModTime)) {
+      LLVM_DEBUG(llvm::dbgs() << "Dep " << In.Path
+                 << " is directly out of date\n");
       return false;
     }
+    // Recursively check freshness of any .swiftmodules in the module cache.
+    auto Ext = llvm::sys::path::extension(In.Path);
+    auto Ty = file_types::lookupTypeForExtension(Ext);
+    if (Ty == file_types::TY_SwiftModuleFile &&
+        In.Path.startswith(ModuleCachePath) &&
+        !swiftModuleIsUpToDate(FS, ModuleCachePath, In.Path)) {
+      LLVM_DEBUG(llvm::dbgs() << "Dep " << In.Path
+                 << " is indirectly out of date\n");
+      return false;
+    }
+    LLVM_DEBUG(llvm::dbgs() << "Dep " << In.Path << " is up to date\n");
   }
   return true;
 }
 
 static bool buildSwiftModuleFromSwiftInterface(
     clang::vfs::FileSystem &FS, DiagnosticEngine &Diags,
-    CompilerInvocation &SubInvocation, StringRef InPath, StringRef OutPath,
-    StringRef DepPath) {
+    CompilerInvocation &SubInvocation, StringRef InPath, StringRef OutPath) {
   bool SubError = false;
   bool RunSuccess = llvm::CrashRecoveryContext().RunSafelyOnThread([&] {
 
@@ -225,8 +220,14 @@
     // Build the .swiftmodule; this is a _very_ abridged version of the logic in
     // performCompile in libFrontendTool, specialized, to just the one
     // module-serialization task we're trying to do here.
-    LLVM_DEBUG(llvm::dbgs() << "Setting up instance\n");
+    LLVM_DEBUG(llvm::dbgs() << "Setting up instance to compile "
+               << InPath << " to " << OutPath << "\n");
     CompilerInstance SubInstance;
+
+    // FIXME: Temporary: this should forward to the outer Diags somehow.
+    PrintingDiagnosticConsumer PDC;
+    SubInstance.addDiagnosticConsumer(&PDC);
+
     SubInstance.createDependencyTracker(/*TrackSystemDeps=*/false);
     if (SubInstance.setup(SubInvocation)) {
       SubError = true;
@@ -236,6 +237,7 @@
     LLVM_DEBUG(llvm::dbgs() << "Performing sema\n");
     SubInstance.performSema();
     if (SubInstance.getASTContext().hadError()) {
+      LLVM_DEBUG(llvm::dbgs() << "encountered errors\n");
       SubError = true;
       return;
     }
@@ -246,6 +248,7 @@
     if (SILMod) {
       LLVM_DEBUG(llvm::dbgs() << "Running SIL diagnostic passes\n");
       if (runSILDiagnosticPasses(*SILMod)) {
+        LLVM_DEBUG(llvm::dbgs() << "encountered errors\n");
         SubError = true;
         return;
       }
@@ -257,17 +260,26 @@
     std::string OutPathStr = OutPath;
     serializationOpts.OutputPath = OutPathStr.c_str();
     serializationOpts.SerializeAllSIL = true;
+    auto DTDeps = SubInstance.getDependencyTracker()->getDependencies();
+    SmallVector<std::string, 16> DepNames(DTDeps.begin(), DTDeps.end());
+    DepNames.push_back(InPath);
+    SmallVector<SerializationOptions::FileDependency, 16> Deps;
+    for (auto const &Dep : DepNames) {
+      auto DepStatus = FS.status(Dep);
+      if (!DepStatus) {
+        SubError = true;
+        return;
+      }
+      Deps.push_back(SerializationOptions::FileDependency{
+          DepStatus.get().getSize(), DepStatus.get().getLastModificationTime(),
+          Dep});
+    }
+    serializationOpts.Dependencies = Deps;
     SILMod->setSerializeSILAction([&]() {
         serialize(Mod, serializationOpts, SILMod.get());
       });
     SILMod->serialize();
     SubError = Diags.hadAnyError();
-
-    if (!SubError) {
-      SubError |= writeSwiftInterfaceDeps(
-          Diags, SubInstance.getDependencyTracker()->getDependencies(),
-          DepPath);
-    }
   });
   return !RunSuccess || SubError;
 }
@@ -283,7 +295,7 @@
 
   auto &FS = *Ctx.SourceMgr.getFileSystem();
   auto &Diags = Ctx.Diags;
-  llvm::SmallString<128> InPath, OutPath, DepPath;
+  llvm::SmallString<128> InPath, OutPath;
 
   // First check to see if the .swiftinterface exists at all. Bail if not.
   InPath = DirName;
@@ -296,12 +308,12 @@
   // Set up a _potential_ sub-invocation to consume the .swiftinterface and emit
   // the .swiftmodule.
   CompilerInvocation SubInvocation;
-  configureSubInvocationAndOutputPaths(SubInvocation, InPath, OutPath, DepPath);
+  configureSubInvocationAndOutputPaths(SubInvocation, InPath, OutPath);
 
   // Evaluate if we need to run this sub-invocation, and if so run it.
-  if (!swiftModuleIsUpToDate(FS, InPath, OutPath, DepPath)) {
+  if (!swiftModuleIsUpToDate(FS, CacheDir, OutPath)) {
     if (buildSwiftModuleFromSwiftInterface(FS, Diags, SubInvocation, InPath,
-                                           OutPath, DepPath))
+                                           OutPath))
       return std::make_error_code(std::errc::invalid_argument);
   }
 
@@ -313,8 +325,11 @@
       CacheDir, llvm::sys::path::filename(OutPath), ModuleDocFilename,
       ModuleBuffer, ModuleDocBuffer, Scratch);
   LLVM_DEBUG(llvm::dbgs() << "Loaded " << OutPath
-             << " via normal module loader with error: "
-             << ErrorCode.message() << "\n");
+             << " via normal module loader");
+  if (ErrorCode) {
+    LLVM_DEBUG(llvm::dbgs() << " with error: " << ErrorCode.message());
+  }
+  LLVM_DEBUG(llvm::dbgs() << "\n");
   return ErrorCode;
 }
 
@@ -357,6 +372,23 @@
                      llvm::Regex::Newline);
 }
 
+/// Extract the specified-or-defaulted -module-cache-path that winds up in
+/// the clang importer, for reuse as the .swiftmodule cache path when
+/// building a ParseableInterfaceModuleLoader.
+std::string
+swift::getModuleCachePathFromClang(const clang::CompilerInstance &Clang) {
+  if (!Clang.hasPreprocessor())
+    return "";
+  std::string SpecificModuleCachePath = Clang.getPreprocessor()
+    .getHeaderSearchInfo()
+    .getModuleCachePath();
+
+  // The returned-from-clang module cache path includes a suffix directory
+  // that is specific to the clang version and invocation; we want the
+  // directory above that.
+  return llvm::sys::path::parent_path(SpecificModuleCachePath);
+}
+
 /// Prints the imported modules in \p M to \p out in the form of \c import
 /// source declarations.
 static void printImports(raw_ostream &out, ModuleDecl *M) {
@@ -400,6 +432,227 @@
   }
 }
 
+// FIXME: Copied from ASTPrinter.cpp...
+static bool isPublicOrUsableFromInline(const ValueDecl *VD) {
+  AccessScope scope =
+      VD->getFormalAccessScope(/*useDC*/nullptr,
+                               /*treatUsableFromInlineAsPublic*/true);
+  return scope.isPublic();
+}
+
+static bool isPublicOrUsableFromInline(Type ty) {
+  // Note the double negative here: we're looking for any referenced decls that
+  // are *not* public-or-usableFromInline.
+  return !ty.findIf([](Type typePart) -> bool {
+    // FIXME: If we have an internal typealias for a non-internal type, we ought
+    // to be able to print it by desugaring.
+    if (auto *aliasTy = dyn_cast<NameAliasType>(typePart.getPointer()))
+      return !isPublicOrUsableFromInline(aliasTy->getDecl());
+    if (auto *nominal = typePart->getAnyNominal())
+      return !isPublicOrUsableFromInline(nominal);
+    return false;
+  });
+}
+
+namespace {
+/// Collects protocols that are conformed to by a particular nominal. Since
+/// ASTPrinter will only print the public ones, the non-public ones get left by
+/// the wayside. This is a problem when a non-public protocol inherits from a
+/// public protocol; the generated parseable interface still needs to make that
+/// dependency public.
+///
+/// The solution implemented here is to generate synthetic extensions that
+/// declare the extra conformances. This isn't perfect (it loses the sugared
+/// spelling of the protocol type, as well as the locality in the file), but it
+/// does work.
+class InheritedProtocolCollector {
+  static const StringLiteral DummyProtocolName;
+
+  /// Protocols that will be included by the ASTPrinter without any extra work.
+  SmallVector<ProtocolDecl *, 8> IncludedProtocols;
+  /// Protocols that will not be printed by the ASTPrinter.
+  SmallVector<ProtocolDecl *, 8> ExtraProtocols;
+  /// Protocols that can be printed, but whose conformances are constrained with
+  /// something that \e can't be printed.
+  SmallVector<const ProtocolType *, 8> ConditionalConformanceProtocols;
+
+  /// For each type in \p directlyInherited, classify the protocols it refers to
+  /// as included for printing or not, and record them in the appropriate
+  /// vectors.
+  void recordProtocols(ArrayRef<TypeLoc> directlyInherited) {
+    for (TypeLoc inherited : directlyInherited) {
+      Type inheritedTy = inherited.getType();
+      if (!inheritedTy || !inheritedTy->isExistentialType())
+        continue;
+
+      bool canPrintNormally = isPublicOrUsableFromInline(inheritedTy);
+      SmallVectorImpl<ProtocolDecl *> &whichProtocols =
+          canPrintNormally ? IncludedProtocols : ExtraProtocols;
+
+      ExistentialLayout layout = inheritedTy->getExistentialLayout();
+      for (ProtocolType *protoTy : layout.getProtocols())
+        whichProtocols.push_back(protoTy->getDecl());
+      // FIXME: This ignores layout constraints, but currently we don't support
+      // any of those besides 'AnyObject'.
+    }
+  }
+
+  /// For each type in \p directlyInherited, record any protocols that we would
+  /// have printed in ConditionalConformanceProtocols.
+  void recordConditionalConformances(ArrayRef<TypeLoc> directlyInherited) {
+    for (TypeLoc inherited : directlyInherited) {
+      Type inheritedTy = inherited.getType();
+      if (!inheritedTy || !inheritedTy->isExistentialType())
+        continue;
+
+      ExistentialLayout layout = inheritedTy->getExistentialLayout();
+      for (ProtocolType *protoTy : layout.getProtocols())
+        if (isPublicOrUsableFromInline(protoTy))
+          ConditionalConformanceProtocols.push_back(protoTy);
+      // FIXME: This ignores layout constraints, but currently we don't support
+      // any of those besides 'AnyObject'.
+    }
+  }
+
+public:
+  using PerTypeMap = llvm::MapVector<const NominalTypeDecl *,
+                                     InheritedProtocolCollector>;
+
+  /// Given that we're about to print \p D, record its protocols in \p map.
+  ///
+  /// \sa recordProtocols
+  static void collectProtocols(PerTypeMap &map, const Decl *D) {
+    ArrayRef<TypeLoc> directlyInherited;
+    const NominalTypeDecl *nominal;
+    const IterableDeclContext *memberContext;
+
+    if ((nominal = dyn_cast<NominalTypeDecl>(D))) {
+      directlyInherited = nominal->getInherited();
+      memberContext = nominal;
+
+    } else if (auto *extension = dyn_cast<ExtensionDecl>(D)) {
+      if (extension->isConstrainedExtension()) {
+        // Conditional conformances never apply to inherited protocols, nor
+        // can they provide unconditional conformances that might be used in
+        // other extensions.
+        return;
+      }
+      nominal = extension->getExtendedNominal();
+      directlyInherited = extension->getInherited();
+      memberContext = extension;
+
+    } else {
+      return;
+    }
+
+    map[nominal].recordProtocols(directlyInherited);
+
+    // Recurse to find any nested types.
+    for (const Decl *member : memberContext->getMembers())
+      collectProtocols(map, member);
+  }
+
+  /// If \p D is an extension providing conditional conformances, record those
+  /// in \p map.
+  ///
+  /// \sa recordConditionalConformances
+  static void collectSkippedConditionalConformances(PerTypeMap &map,
+                                                    const Decl *D) {
+    auto *extension = dyn_cast<ExtensionDecl>(D);
+    if (!extension || !extension->isConstrainedExtension())
+      return;
+
+    const NominalTypeDecl *nominal = extension->getExtendedNominal();
+    map[nominal].recordConditionalConformances(extension->getInherited());
+    // No recursion here because extensions are never nested.
+  }
+
+  /// If there were any public protocols that need to be printed (i.e. they
+  /// weren't conformed to explicitly or inherited by another printed protocol),
+  /// do so now by printing a dummy extension on \p nominal to \p out.
+  void
+  printSynthesizedExtensionIfNeeded(raw_ostream &out,
+                                    const PrintOptions &printOptions,
+                                    const NominalTypeDecl *nominal) const {
+    if (ExtraProtocols.empty())
+      return;
+
+    SmallPtrSet<ProtocolDecl *, 16> handledProtocols;
+
+    // First record all protocols that have already been handled.
+    for (ProtocolDecl *proto : IncludedProtocols) {
+      proto->walkInheritedProtocols(
+          [&handledProtocols](ProtocolDecl *inherited) -> TypeWalker::Action {
+        handledProtocols.insert(inherited);
+        return TypeWalker::Action::Continue;
+      });
+    }
+
+    // Then walk the remaining ones, and see what we need to print.
+    // Note: We could do this in one pass, but the logic is easier to
+    // understand if we build up the list and then print it, even if it takes
+    // a bit more memory.
+    SmallVector<ProtocolDecl *, 16> protocolsToPrint;
+    for (ProtocolDecl *proto : ExtraProtocols) {
+      proto->walkInheritedProtocols(
+          [&](ProtocolDecl *inherited) -> TypeWalker::Action {
+        if (!handledProtocols.insert(inherited).second)
+          return TypeWalker::Action::SkipChildren;
+        if (isPublicOrUsableFromInline(inherited)) {
+          protocolsToPrint.push_back(inherited);
+          return TypeWalker::Action::SkipChildren;
+        }
+        return TypeWalker::Action::Continue;
+      });
+    }
+    if (protocolsToPrint.empty())
+      return;
+
+    out << "extension ";
+    nominal->getDeclaredType().print(out, printOptions);
+    out << " : ";
+    swift::interleave(protocolsToPrint,
+                      [&out, &printOptions](ProtocolDecl *proto) {
+                        proto->getDeclaredType()->print(out, printOptions);
+                      }, [&out] { out << ", "; });
+    out << " {}\n";
+  }
+
+  /// If there were any conditional conformances that couldn't be printed,
+  /// make a dummy extension that conforms to all of them, constrained by a
+  /// fake protocol.
+  bool printInaccessibleConformanceExtensionIfNeeded(
+      raw_ostream &out, const PrintOptions &printOptions,
+      const NominalTypeDecl *nominal) const {
+    if (ConditionalConformanceProtocols.empty())
+      return false;
+    assert(nominal->isGenericContext());
+
+    out << "extension ";
+    nominal->getDeclaredType().print(out, printOptions);
+    out << " : ";
+    swift::interleave(ConditionalConformanceProtocols,
+                      [&out, &printOptions](const ProtocolType *protoTy) {
+                        protoTy->print(out, printOptions);
+                      }, [&out] { out << ", "; });
+    out << " where "
+        << nominal->getGenericParamsOfContext()->getParams().front()->getName()
+        << " : " << DummyProtocolName << " {}\n";
+    return true;
+  }
+
+  /// Print a fake protocol declaration for use by
+  /// #printInaccessibleConformanceExtensionIfNeeded.
+  static void printDummyProtocolDeclaration(raw_ostream &out) {
+    out << "\n@usableFromInline\ninternal protocol " << DummyProtocolName
+        << " {}\n";
+  }
+};
+
+const StringLiteral InheritedProtocolCollector::DummyProtocolName =
+    "_ConstraintThatIsNotPartOfTheAPIOfThisLibrary";
+} // end anonymous namespace
+
 bool swift::emitParseableInterface(raw_ostream &out,
                                    ParseableInterfaceOptions const &Opts,
                                    ModuleDecl *M) {
@@ -409,13 +662,37 @@
   printImports(out, M);
 
   const PrintOptions printOptions = PrintOptions::printParseableInterfaceFile();
+  InheritedProtocolCollector::PerTypeMap inheritedProtocolMap;
+
   SmallVector<Decl *, 16> topLevelDecls;
   M->getTopLevelDecls(topLevelDecls);
   for (const Decl *D : topLevelDecls) {
-    if (!D->shouldPrintInContext(printOptions))
+    if (!D->shouldPrintInContext(printOptions) ||
+        !printOptions.CurrentPrintabilityChecker->shouldPrint(D, printOptions)){
+      InheritedProtocolCollector::collectSkippedConditionalConformances(
+          inheritedProtocolMap, D);
       continue;
+    }
+
     D->print(out, printOptions);
     out << "\n";
+
+    InheritedProtocolCollector::collectProtocols(inheritedProtocolMap, D);
   }
+
+  // Print dummy extensions for any protocols that were indirectly conformed to.
+  bool needDummyProtocolDeclaration = false;
+  for (const auto &nominalAndCollector : inheritedProtocolMap) {
+    const NominalTypeDecl *nominal = nominalAndCollector.first;
+    const InheritedProtocolCollector &collector = nominalAndCollector.second;
+    collector.printSynthesizedExtensionIfNeeded(out, printOptions, nominal);
+    needDummyProtocolDeclaration |=
+        collector.printInaccessibleConformanceExtensionIfNeeded(out,
+                                                                printOptions,
+                                                                nominal);
+  }
+  if (needDummyProtocolDeclaration)
+    InheritedProtocolCollector::printDummyProtocolDeclaration(out);
+
   return false;
 }
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index 1b68822..303d2ff 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -2172,7 +2172,7 @@
 
       Builder.addCallParameter(param->getArgumentName(), type,
                                param->isVariadic(), /*Outermost*/ true,
-                               param->isInOut(), isIUO);
+                               param->isInOut(), isIUO, param->isAutoClosure());
     }
   }
 
@@ -2270,12 +2270,12 @@
         auto isIUO =
             PD->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
         Builder.addCallParameter(argName, bodyName, ParamType,
-                                 Param.isVariadic(), /*TopLevel*/true,
-                                 Param.isInOut(), isIUO);
-      } else {
-        Builder.addCallParameter(Param.getLabel(), ParamType,
                                  Param.isVariadic(), /*TopLevel*/ true,
-                                 Param.isInOut(), /*isIUO*/ false);
+                                 Param.isInOut(), isIUO, Param.isAutoClosure());
+      } else {
+        Builder.addCallParameter(
+            Param.getLabel(), ParamType, Param.isVariadic(), /*TopLevel*/ true,
+            Param.isInOut(), /*isIUO*/ false, Param.isAutoClosure());
       }
       modifiedBuilder = true;
       NeedComma = true;
@@ -2490,7 +2490,7 @@
         Builder.addCallParameter(Ctx.Id_self, SelfParam.getPlainType(),
                                  /*IsVarArg*/ false, /*TopLevel*/ true,
                                  SelfParam.isInOut(),
-                                 /*isIUO*/ false);
+                                 /*isIUO*/ false, /*isAutoClosure*/ false);
         Builder.addRightParen();
       } else if (trivialTrailingClosure) {
         Builder.addBraceStmtWithCursor(" { code }");
@@ -3336,7 +3336,8 @@
     assert(RHSType && resultType);
     builder.addCallParameter(Identifier(), Identifier(), RHSType,
                              /*IsVarArg*/ false, /*TopLevel*/ true,
-                             /*IsInOut*/ false, /*isIUO*/ false);
+                             /*IsInOut*/ false, /*isIUO*/ false,
+                             /*isAutoClosure*/ false);
     addTypeAnnotation(builder, resultType);
   }
 
@@ -3359,7 +3360,8 @@
     builder.addWhitespace(" ");
     if (RHSType)
       builder.addCallParameter(Identifier(), Identifier(), RHSType, false, true,
-                               /*IsInOut*/ false, /*isIUO*/ false);
+                               /*IsInOut*/ false, /*isIUO*/ false,
+                               /*isAutoClosure*/ false);
     if (resultType)
       addTypeAnnotation(builder, resultType);
   }
@@ -3648,19 +3650,19 @@
       builder.addLeftParen();
       builder.addCallParameter(context.getIdentifier("red"), floatType, false,
                                true, /*IsInOut*/ false,
-                               /*isIUO*/ false);
+                               /*isIUO*/ false, /*isAutoClosure*/ false);
       builder.addComma();
       builder.addCallParameter(context.getIdentifier("green"), floatType, false,
-                               true, /*IsInOut*/ false,
-                               /*isIUO*/ false);
+                               true, /*IsInOut*/ false, /*isIUO*/ false,
+                               /*isAutoClosure*/ false);
       builder.addComma();
       builder.addCallParameter(context.getIdentifier("blue"), floatType, false,
-                               true, /*IsInOut*/ false,
-                               /*isIUO*/ false);
+                               true, /*IsInOut*/ false, /*isIUO*/ false,
+                               /*isAutoClosure*/ false);
       builder.addComma();
       builder.addCallParameter(context.getIdentifier("alpha"), floatType, false,
-                               true, /*IsInOut*/ false,
-                               /*isIUO*/ false);
+                               true, /*IsInOut*/ false, /*isIUO*/ false,
+                               /*isAutoClosure*/ false);
       builder.addRightParen();
     });
 
@@ -3670,7 +3672,7 @@
       builder.addLeftParen();
       builder.addCallParameter(context.getIdentifier("resourceName"),
                                stringType, false, true, /*IsInOut*/ false,
-                               /*isIUO*/ false);
+                               /*isIUO*/ false, /*isAutoClosure*/ false);
       builder.addRightParen();
     });
 
@@ -5241,7 +5243,6 @@
     friend class CodeCompletionTypeContextAnalyzer;
     Expr *ChildExpr;
     llvm::function_ref<bool(ParentTy, ParentTy)> Predicate;
-    bool AncestorsWithinBrace;
 
     bool arePositionsSame(Expr *E1, Expr *E2) {
       return E1->getSourceRange().Start == E2->getSourceRange().Start &&
@@ -5250,15 +5251,9 @@
 
   public:
     llvm::SmallVector<ParentTy, 5> Ancestors;
-    llvm::SmallVector<size_t, 1> FarthestAncestorIndex;
-    ParentTy ParentClosest;
-    ParentTy ParentFarthest;
     ExprParentFinder(Expr* ChildExpr,
-                     llvm::function_ref<bool(ParentTy, ParentTy)> Predicate,
-                     bool AncestorsWithinBrace = false) :
-                     ChildExpr(ChildExpr), Predicate(Predicate),
-                     AncestorsWithinBrace(AncestorsWithinBrace),
-                     FarthestAncestorIndex({0}) {}
+                     llvm::function_ref<bool(ParentTy, ParentTy)> Predicate) :
+                     ChildExpr(ChildExpr), Predicate(Predicate) {}
 
     std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
       // Finish if we found the target. 'ChildExpr' might have been replaced
@@ -5270,13 +5265,6 @@
         Ancestors.push_back(E);
         return { true, E };
       }
-      if (E == ChildExpr || arePositionsSame(E, ChildExpr)) {
-        if (!Ancestors.empty()) {
-          ParentClosest = Ancestors.back();
-          ParentFarthest = Ancestors[FarthestAncestorIndex.back()];
-        }
-        return {false, nullptr};
-      }
       return { true, E };
     }
 
@@ -5289,14 +5277,10 @@
     std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
       if (Predicate(S, Parent))
         Ancestors.push_back(S);
-      if (AncestorsWithinBrace && isa<BraceStmt>(S))
-        FarthestAncestorIndex.push_back(Ancestors.size());
       return { true, S };
     }
 
     Stmt *walkToStmtPost(Stmt *S) override {
-      if (AncestorsWithinBrace && isa<BraceStmt>(S))
-        FarthestAncestorIndex.pop_back();
       if (Predicate(S, Parent))
         Ancestors.pop_back();
       return S;
@@ -5338,8 +5322,7 @@
   ExprParentFinder Finder;
 
 public:
-  CodeCompletionTypeContextAnalyzer(DeclContext *DC, Expr *ParsedExpr,
-                                    bool AncestorsWithinBrace = false) : DC(DC),
+  CodeCompletionTypeContextAnalyzer(DeclContext *DC, Expr *ParsedExpr) : DC(DC),
     ParsedExpr(ParsedExpr), SM(DC->getASTContext().SourceMgr),
     Context(DC->getASTContext()),
     Finder(ParsedExpr,  [](ASTWalker::ParentTy Node, ASTWalker::ParentTy Parent) {
@@ -5389,7 +5372,7 @@
         }
       } else
         return false;
-    }, /*AncestorsWithinBrace=*/AncestorsWithinBrace) {}
+    }) {}
 
   void analyzeExpr(Expr *Parent, llvm::function_ref<void(Type)> Callback,
                    SmallVectorImpl<StringRef> &PossibleNames) {
@@ -5647,7 +5630,8 @@
     if (isa<BindOptionalExpr>(ParsedExpr) || isa<ForceValueExpr>(ParsedExpr))
       Lookup.setIsUnwrappedOptional(true);
 
-    ::CodeCompletionTypeContextAnalyzer TypeAnalyzer(CurDeclContext, ParsedExpr);
+    ::CodeCompletionTypeContextAnalyzer TypeAnalyzer(CurDeclContext,
+                                                     ParsedExpr);
     llvm::SmallVector<Type, 2> PossibleTypes;
     if (TypeAnalyzer.Analyze(PossibleTypes)) {
       Lookup.setExpectedTypes(PossibleTypes);
@@ -5692,7 +5676,7 @@
   case CompletionKind::ForEachSequence:
   case CompletionKind::PostfixExprBeginning: {
     ::CodeCompletionTypeContextAnalyzer Analyzer(CurDeclContext,
-                                               CodeCompleteTokenExpr);
+                                                 CodeCompleteTokenExpr);
     llvm::SmallVector<Type, 1> Types;
     if (Analyzer.Analyze(Types)) {
       Lookup.setExpectedTypes(Types);
@@ -5720,7 +5704,7 @@
     Lookup.setHaveLParen(true);
 
     ::CodeCompletionTypeContextAnalyzer TypeAnalyzer(CurDeclContext,
-                                                   CodeCompleteTokenExpr);
+                                                     CodeCompleteTokenExpr);
     SmallVector<Type, 2> PossibleTypes;
     SmallVector<StringRef, 2> PossibleNames;
     if (TypeAnalyzer.Analyze(PossibleTypes, PossibleNames)) {
@@ -5844,9 +5828,8 @@
   case CompletionKind::UnresolvedMember: {
     Lookup.setHaveDot(DotLoc);
     SmallVector<Type, 2> PossibleTypes;
-    ::CodeCompletionTypeContextAnalyzer
-        TypeAnalyzer(CurDeclContext, CodeCompleteTokenExpr,
-                     /*AncestorsWithinBrace=*/true);
+    ::CodeCompletionTypeContextAnalyzer TypeAnalyzer(CurDeclContext,
+                                                     CodeCompleteTokenExpr);
     if (TypeAnalyzer.Analyze(PossibleTypes))
       Lookup.setExpectedTypes(PossibleTypes);
     Lookup.getUnresolvedMemberCompletions(PossibleTypes);
@@ -5962,10 +5945,13 @@
       // module loading, for example, the module file is corrupted.
       if (!ModuleFilename.empty()) {
         auto &Ctx = TheModule->getASTContext();
-        CodeCompletionCache::Key K{ModuleFilename, TheModule->getName().str(),
-                                   AccessPath, Request.NeedLeadingDot,
-                                   SF.hasTestableImport(TheModule),
-                                   Ctx.LangOpts.CodeCompleteInitsInPostfixExpr};
+        CodeCompletionCache::Key K{
+            ModuleFilename,
+            TheModule->getName().str(),
+            AccessPath,
+            Request.NeedLeadingDot,
+            SF.hasTestableOrPrivateImport(AccessLevel::Internal, TheModule),
+            Ctx.LangOpts.CodeCompleteInitsInPostfixExpr};
 
         using PairType = llvm::DenseSet<swift::ide::CodeCompletionCache::Key,
             llvm::DenseMapInfo<CodeCompletionCache::Key>>::iterator;
diff --git a/lib/IDE/CodeCompletionResultBuilder.h b/lib/IDE/CodeCompletionResultBuilder.h
index 33d6bcb..be14dfa 100644
--- a/lib/IDE/CodeCompletionResultBuilder.h
+++ b/lib/IDE/CodeCompletionResultBuilder.h
@@ -315,8 +315,8 @@
   }
 
   void addCallParameter(Identifier Name, Identifier LocalName, Type Ty,
-                        bool IsVarArg, bool Outermost, bool IsInOut,
-                        bool IsIUO) {
+                        bool IsVarArg, bool Outermost, bool IsInOut, bool IsIUO,
+                        bool isAutoClosure) {
     CurrentNestingLevel++;
 
     addSimpleChunk(CodeCompletionString::Chunk::ChunkKind::CallParameterBegin);
@@ -364,11 +364,8 @@
     // If the parameter is of the type @autoclosure ()->output, then the
     // code completion should show the parameter of the output type
     // instead of the function type ()->output.
-    if (auto FuncType = Ty->getAs<AnyFunctionType>()) {
-      if (FuncType->isAutoClosure()) {
-        Ty = FuncType->getResult();
-      }
-    }
+    if (isAutoClosure)
+      Ty = Ty->castTo<FunctionType>()->getResult();
 
     PrintOptions PO;
     PO.SkipAttributes = true;
@@ -378,18 +375,16 @@
                      TypeName);
 
     // Look through optional types and type aliases to find out if we have
-    // function/closure parameter type that is not an autoclosure.
+    // function type.
     Ty = Ty->lookThroughAllOptionalTypes();
     if (auto AFT = Ty->getAs<AnyFunctionType>()) {
-      if (!AFT->isAutoClosure()) {
-        // If this is a closure type, add ChunkKind::CallParameterClosureType.
-        PrintOptions PO;
-        PO.PrintFunctionRepresentationAttrs = false;
-        PO.SkipAttributes = true;
-        addChunkWithText(
-            CodeCompletionString::Chunk::ChunkKind::CallParameterClosureType,
-            AFT->getString(PO));
-      }
+      // If this is a closure type, add ChunkKind::CallParameterClosureType.
+      PrintOptions PO;
+      PO.PrintFunctionRepresentationAttrs = false;
+      PO.SkipAttributes = true;
+      addChunkWithText(
+          CodeCompletionString::Chunk::ChunkKind::CallParameterClosureType,
+          AFT->getString(PO));
     }
 
     if (IsVarArg)
@@ -398,9 +393,9 @@
   }
 
   void addCallParameter(Identifier Name, Type Ty, bool IsVarArg, bool Outermost,
-                        bool IsInOut, bool IsIUO) {
+                        bool IsInOut, bool IsIUO, bool isAutoClosure) {
     addCallParameter(Name, Identifier(), Ty, IsVarArg, Outermost, IsInOut,
-                     IsIUO);
+                     IsIUO, isAutoClosure);
   }
 
   void addGenericParameter(StringRef Name) {
diff --git a/lib/IDE/IDETypeChecking.cpp b/lib/IDE/IDETypeChecking.cpp
index 19ec053..db301cf 100644
--- a/lib/IDE/IDETypeChecking.cpp
+++ b/lib/IDE/IDETypeChecking.cpp
@@ -28,7 +28,7 @@
 
 static bool shouldPrintAsFavorable(const Decl *D, const PrintOptions &Options) {
   if (!Options.TransformContext ||
-      !D->getDeclContext()->isExtensionContext() ||
+      !isa<ExtensionDecl>(D->getDeclContext()) ||
       !Options.TransformContext->isPrintingSynthesizedExtension())
     return true;
   auto DC = Options.TransformContext->getDeclContext();
diff --git a/lib/IRGen/ConstantBuilder.h b/lib/IRGen/ConstantBuilder.h
index 44e1715..3bb9e7d 100644
--- a/lib/IRGen/ConstantBuilder.h
+++ b/lib/IRGen/ConstantBuilder.h
@@ -81,6 +81,7 @@
   }
 
   void addRelativeAddress(llvm::Constant *target) {
+    assert(!isa<llvm::ConstantPointerNull>(target));
     addRelativeOffset(IGM().RelativeAddressTy, target);
   }
 
diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp
index 1a1e469..f208f3e 100644
--- a/lib/IRGen/GenCall.cpp
+++ b/lib/IRGen/GenCall.cpp
@@ -1738,9 +1738,11 @@
     }
 
     // Otherwise, it's direct.  Remap.
-    auto temp = schema.getDirectSchema().mapFromNative(IGF.IGM, IGF,
-                                                       rawYieldComponents,
-                                                       schema.getSILType());
+    const auto &directSchema = schema.getDirectSchema();
+    Explosion eltValues;
+    rawYieldComponents.transferInto(eltValues, directSchema.size());
+    auto temp = directSchema.mapFromNative(IGF.IGM, IGF, eltValues,
+                                           schema.getSILType());
 
     auto &yieldTI = cast<LoadableTypeInfo>(schema.getTypeInfo());
     emitCastToSubstSchema(IGF, temp, yieldTI.getSchema(), out);
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 005a0b6..dba6707 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Support/SaveAndRestore.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
 
+#include "Callee.h"
 #include "ConstantBuilder.h"
 #include "Explosion.h"
 #include "FixedTypeInfo.h"
@@ -870,59 +871,6 @@
                                      LinkEntity::forProtocolDescriptor(proto));
 }
 
-llvm::Constant *IRGenModule::getAddrOfAssociatedTypeGenericParamRef(
-                                                   GenericSignature *sig,
-                                                   CanDependentMemberType dmt) {
-  llvm::SmallVector<AssociatedTypeDecl *, 4> assocTypePath;
-
-  // Get the base ordinal.
-  auto baseDMT = dmt;
-  CanType base;
-  do {
-    base = baseDMT.getBase();
-    assocTypePath.push_back(baseDMT->getAssocType());
-    baseDMT = dyn_cast<DependentMemberType>(base);
-  } while (baseDMT);
-  auto ordinal = sig->getGenericParamOrdinal(cast<GenericTypeParamType>(base));
-  
-  // Generate a symbol name for the descriptor. This is a private symbol, so
-  // isn't ABI, but is useful for ODR coalescing within the same binary.
-  IRGenMangler Mangler;
-  auto symbolName = Mangler
-    .mangleAssociatedTypeGenericParamRef(ordinal, dmt);
-  
-  // Use an existing definition if we have one.
-  if (auto existingVar = Module.getGlobalVariable(symbolName))
-    return existingVar;
-  
-  // Otherwise, build the reference path.
-  ConstantInitBuilder builder(*this);
-  auto B = builder.beginStruct();
-  B.addInt32(ordinal);
-
-  for (auto *assocType : reversed(assocTypePath)) {
-    auto proto = getConstantReferenceForProtocolDescriptor(
-                                                      assocType->getProtocol());
-    B.addRelativeAddress(proto);
-
-    // Add a reference to the associated type descriptor.
-    auto assocTypeDescriptor =
-      getAddrOfLLVMVariableOrGOTEquivalent(
-        LinkEntity::forAssociatedTypeDescriptor(assocType));
-    B.addRelativeAddress(assocTypeDescriptor);
-  }
-  
-  // Null terminator.
-  B.addInt32(0);
-  
-  auto var = B.finishAndCreateGlobal(symbolName, Alignment(4),
-                                     /*constant*/ true);
-  var->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
-  var->setVisibility(llvm::GlobalValue::HiddenVisibility);
-  setTrueConstGlobal(var);
-  return var;
-}
-
 void IRGenModule::addLazyConformances(DeclContext *dc) {
   for (const ProtocolConformance *conf :
          dc->getLocalConformances(ConformanceLookupKind::All,
@@ -1057,8 +1005,10 @@
   // Emit SIL functions.
   for (SILFunction &f : PrimaryIGM->getSILModule()) {
     // Eagerly emit functions that are externally visible. Functions with code
-    // coverage instrumentation must also be eagerly emitted.
+    // coverage instrumentation must also be eagerly emitted. So must functions
+    // that are a dynamic replacement for another.
     if (!f.isPossiblyUsedExternally() &&
+        !f.getDynamicallyReplacedFunction() &&
         !hasCodeCoverageInstrumentation(f, PrimaryIGM->getSILModule()))
       continue;
 
@@ -1269,6 +1219,135 @@
     LazyTypeContextDescriptors.push_back(type);
   }
 }
+static std::string getDynamicReplacementSection(IRGenModule &IGM) {
+  std::string sectionName;
+  switch (IGM.TargetInfo.OutputObjectFormat) {
+  case llvm::Triple::MachO:
+    sectionName = "__TEXT, __swift5_replace, regular, no_dead_strip";
+    break;
+  case llvm::Triple::ELF:
+    sectionName = "swift5_replace";
+    break;
+  case llvm::Triple::COFF:
+    sectionName = ".sw5repl";
+    break;
+  default:
+    llvm_unreachable("Don't know how to emit field records table for "
+                     "the selected object format.");
+  }
+  return sectionName;
+}
+
+llvm::GlobalVariable *IRGenModule::getGlobalForDynamicallyReplaceableThunk(
+    LinkEntity &entity, llvm::Type *type, ForDefinition_t forDefinition) {
+  return cast<llvm::GlobalVariable>(
+      getAddrOfLLVMVariable(entity, forDefinition, DebugTypeInfo()));
+}
+
+/// Creates a dynamic replacement chain entry for \p SILFn that contains either
+/// the implementation function pointer \p or a nullptr, the next pointer of the
+/// chain entry is set to nullptr.
+///   struct ChainEntry {
+///      void *funPtr;
+///      struct ChainEntry *next;
+///   }
+static llvm::GlobalVariable *getChainEntryForDynamicReplacement(
+    IRGenModule &IGM, SILFunction *SILFn,
+    llvm::Function *implFunction = nullptr,
+    ForDefinition_t forDefinition = ForDefinition) {
+
+  LinkEntity entity =
+      LinkEntity::forDynamicallyReplaceableFunctionVariable(SILFn);
+  auto linkEntry = IGM.getGlobalForDynamicallyReplaceableThunk(
+      entity, IGM.DynamicReplacementLinkEntryTy, forDefinition);
+  if (!forDefinition)
+    return linkEntry;
+
+  auto *funPtr =
+      implFunction ? llvm::ConstantExpr::getBitCast(implFunction, IGM.Int8PtrTy)
+                   : llvm::ConstantExpr::getNullValue(IGM.Int8PtrTy);
+  auto *nextEntry =
+      llvm::ConstantExpr::getNullValue(IGM.DynamicReplacementLinkEntryPtrTy);
+  llvm::Constant *fields[] = {funPtr, nextEntry};
+  auto *entry =
+      llvm::ConstantStruct::get(IGM.DynamicReplacementLinkEntryTy, fields);
+  linkEntry->setInitializer(entry);
+  return linkEntry;
+}
+
+void IRGenerator::emitDynamicReplacements() {
+  if (DynamicReplacements.empty())
+    return;
+
+  auto &IGM = *getPrimaryIGM();
+
+  // struct ReplacementScope {
+  //   uint32t flags; // unused
+  //   uint32t numReplacements;
+  //   struct Entry {
+  //     RelativeIndirectablePointer<KeyEntry, false> replacedFunctionKey;
+  //     RelativeDirectPointer<void> newFunction;
+  //     RelativeDirectPointer<LinkEntry> replacement;
+  //     uint32_t flags; // shouldChain.
+  //   }[0]
+  // };
+  ConstantInitBuilder builder(IGM);
+  auto replacementScope = builder.beginStruct();
+  replacementScope.addInt32(0); // unused flags.
+  replacementScope.addInt32(DynamicReplacements.size());
+
+  auto replacementsArray =
+      replacementScope.beginArray();
+  for (auto *newFunc : DynamicReplacements) {
+    auto replacementLinkEntry =
+        getChainEntryForDynamicReplacement(IGM, newFunc);
+    // TODO: replacementLinkEntry->setZeroSection()
+    auto *origFunc = newFunc->getDynamicallyReplacedFunction();
+    assert(origFunc);
+    auto keyRef = IGM.getAddrOfLLVMVariableOrGOTEquivalent(
+        LinkEntity::forDynamicallyReplaceableFunctionKey(origFunc));
+
+    llvm::Constant *newFnPtr = llvm::ConstantExpr::getBitCast(
+        IGM.getAddrOfSILFunction(newFunc, NotForDefinition), IGM.Int8PtrTy);
+
+    auto replacement = replacementsArray.beginStruct();
+    replacement.addRelativeAddress(keyRef); // tagged relative reference.
+    replacement.addRelativeAddress(newFnPtr); // direct relative reference.
+    replacement.addRelativeAddress(
+        replacementLinkEntry); // direct relative reference.
+    replacement.addInt32(
+        Opts.EnableDynamicReplacementChaining ? 1 : 0);
+    replacement.finishAndAddTo(replacementsArray);
+  }
+  replacementsArray.finishAndAddTo(replacementScope);
+
+  auto var = replacementScope.finishAndCreateGlobal(
+      "\x01l_unnamed_dynamic_replacements", IGM.getPointerAlignment(),
+      /*isConstant*/ true, llvm::GlobalValue::PrivateLinkage);
+  IGM.setTrueConstGlobal(var);
+  IGM.addUsedGlobal(var);
+
+  // Emit the data for automatic replacement to happen on load.
+  // struct AutomaticReplacements {
+  //   uint32t flags; // unused
+  //   uint32t numReplacements;
+  //   struct Entry {
+  //     RelativeDirectPointer<ReplacementScope> replacements;
+  //     uint32_t flags; // unused.
+  //   }[0]
+  // };
+  auto autoReplacements = builder.beginStruct();
+  autoReplacements.addInt32(0); // unused flags.
+  autoReplacements.addInt32(1); // number of replacement entries.
+  auto autoReplacementsArray = autoReplacements.beginArray();
+  autoReplacementsArray.addRelativeAddress(var);
+  autoReplacementsArray.finishAndAddTo(autoReplacements);
+  auto autoReplVar = autoReplacements.finishAndCreateGlobal(
+      "\x01l_auto_dynamic_replacements", IGM.getPointerAlignment(),
+      /*isConstant*/ true, llvm::GlobalValue::PrivateLinkage);
+  autoReplVar->setSection(getDynamicReplacementSection(IGM));
+  IGM.addUsedGlobal(autoReplVar);
+}
 
 void IRGenerator::emitEagerClassInitialization() {
   if (ClassesForEagerInitialization.empty())
@@ -1348,16 +1427,14 @@
   }
 }
 
-static std::tuple<llvm::GlobalValue::LinkageTypes,
-                  llvm::GlobalValue::VisibilityTypes,
-                  llvm::GlobalValue::DLLStorageClassTypes>
+static IRLinkage
 getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
              ForDefinition_t isDefinition,
              bool isWeakImported) {
 #define RESULT(LINKAGE, VISIBILITY, DLL_STORAGE)                               \
-  std::make_tuple(llvm::GlobalValue::LINKAGE##Linkage,                         \
-                  llvm::GlobalValue::VISIBILITY##Visibility,                   \
-                  llvm::GlobalValue::DLL_STORAGE##StorageClass)
+  IRLinkage{llvm::GlobalValue::LINKAGE##Linkage,                               \
+            llvm::GlobalValue::VISIBILITY##Visibility,                         \
+            llvm::GlobalValue::DLL_STORAGE##StorageClass}
 
   // Use protected visibility for public symbols we define on ELF.  ld.so
   // doesn't support relative relocations at load time, which interferes with
@@ -1375,8 +1452,8 @@
 
   switch (linkage) {
   case SILLinkage::Public:
-    return std::make_tuple(llvm::GlobalValue::ExternalLinkage,
-                           PublicDefinitionVisibility, ExportedStorage);
+    return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility,
+            ExportedStorage};
 
   case SILLinkage::Shared:
   case SILLinkage::SharedExternal:
@@ -1394,34 +1471,25 @@
     auto visibility = info.shouldAllPrivateDeclsBeVisibleFromOtherFiles()
                           ? llvm::GlobalValue::HiddenVisibility
                           : llvm::GlobalValue::DefaultVisibility;
-    return std::make_tuple(linkage, visibility,
-                           llvm::GlobalValue::DefaultStorageClass);
+    return {linkage, visibility, llvm::GlobalValue::DefaultStorageClass};
   }
 
   case SILLinkage::PublicExternal: {
-    if (isDefinition) {
-      return std::make_tuple(llvm::GlobalValue::AvailableExternallyLinkage,
-                             llvm::GlobalValue::DefaultVisibility,
-                             llvm::GlobalValue::DefaultStorageClass);
-    }
+    if (isDefinition)
+      return RESULT(AvailableExternally, Default, Default);
 
     auto linkage = isWeakImported ? llvm::GlobalValue::ExternalWeakLinkage
                                   : llvm::GlobalValue::ExternalLinkage;
-    return std::make_tuple(linkage, llvm::GlobalValue::DefaultVisibility,
-                           ImportedStorage);
+    return {linkage, llvm::GlobalValue::DefaultVisibility, ImportedStorage};
   }
 
   case SILLinkage::HiddenExternal:
   case SILLinkage::PrivateExternal:
-    if (isDefinition) {
-      return std::make_tuple(llvm::GlobalValue::AvailableExternallyLinkage,
-                             llvm::GlobalValue::HiddenVisibility,
-                             llvm::GlobalValue::DefaultStorageClass);
-    }
+    if (isDefinition)
+      return RESULT(AvailableExternally, Hidden, Default);
 
-    return std::make_tuple(llvm::GlobalValue::ExternalLinkage,
-                           llvm::GlobalValue::DefaultVisibility,
-                           ImportedStorage);
+    return {llvm::GlobalValue::ExternalLinkage,
+            llvm::GlobalValue::DefaultVisibility, ImportedStorage};
 
   }
 
@@ -1436,12 +1504,10 @@
   // TODO: there are probably cases where we can avoid redoing the
   // entire linkage computation.
   UniversalLinkageInfo linkInfo(IGM);
-  auto linkage =
+  auto IRL =
       getIRLinkage(linkInfo, entity.getLinkage(ForDefinition),
                    ForDefinition, entity.isWeakImported(IGM.getSwiftModule()));
-  global->setLinkage(std::get<0>(linkage));
-  global->setVisibility(std::get<1>(linkage));
-  global->setDLLStorageClass(std::get<2>(linkage));
+  ApplyIRLinkage(IRL).to(global);
 
   // Everything externally visible is considered used in Swift.
   // That mostly means we need to be good at not marking things external.
@@ -1449,9 +1515,7 @@
   // Exclude "main", because it should naturally be used, and because adding it
   // to llvm.used leaves a dangling use when the REPL attempts to discard
   // intermediate mains.
-  if (LinkInfo::isUsed(std::get<0>(linkage), std::get<1>(linkage),
-                       std::get<2>(linkage)) &&
-      global->getName() != SWIFT_ENTRY_POINT_FUNCTION)
+  if (LinkInfo::isUsed(IRL) && global->getName() != SWIFT_ENTRY_POINT_FUNCTION)
     IGM.addUsedGlobal(global);
 }
 
@@ -1477,9 +1541,8 @@
       ForDefinition_t(swiftModule->isStdlibModule() || isDefinition);
 
   entity.mangle(result.Name);
-  std::tie(result.Linkage, result.Visibility, result.DLLStorageClass) =
-      getIRLinkage(linkInfo, entity.getLinkage(isStdlibOrDefinition),
-                   isDefinition, entity.isWeakImported(swiftModule));
+  result.IRL = getIRLinkage(linkInfo, entity.getLinkage(isStdlibOrDefinition),
+                            isDefinition, entity.isWeakImported(swiftModule));
   result.ForDefinition = isDefinition;
   return result;
 }
@@ -1490,8 +1553,7 @@
   LinkInfo result;
 
   result.Name += name;
-  std::tie(result.Linkage, result.Visibility, result.DLLStorageClass) =
-      getIRLinkage(linkInfo, linkage, isDefinition, isWeakImported);
+  result.IRL = getIRLinkage(linkInfo, linkage, isDefinition, isWeakImported);
   result.ForDefinition = isDefinition;
   return result;
 }
@@ -1523,6 +1585,7 @@
 
   llvm::Function *fn =
     llvm::Function::Create(signature.getType(), linkInfo.getLinkage(), name);
+  // TODO(compnerd) apply COMDAT to definitions
   fn->setVisibility(linkInfo.getVisibility());
   fn->setDLLStorageClass(linkInfo.getDLLStorage());
   fn->setCallingConv(signature.getCallingConv());
@@ -1531,7 +1594,7 @@
     IGM.Module.getFunctionList().insert(insertBefore->getIterator(), fn);
   } else {
     IGM.Module.getFunctionList().push_back(fn);
- }
+  }
 
   llvm::AttrBuilder initialAttrs;
   IGM.constructInitialFnAttributes(initialAttrs, FuncOptMode);
@@ -1556,16 +1619,14 @@
   return fn;
 }
 
-bool LinkInfo::isUsed(llvm::GlobalValue::LinkageTypes Linkage,
-                      llvm::GlobalValue::VisibilityTypes Visibility,
-                      llvm::GlobalValue::DLLStorageClassTypes DLLStorage) {
+bool LinkInfo::isUsed(IRLinkage IRL) {
   // Everything externally visible is considered used in Swift.
   // That mostly means we need to be good at not marking things external.
-  return Linkage == llvm::GlobalValue::ExternalLinkage &&
-         (Visibility == llvm::GlobalValue::DefaultVisibility ||
-          Visibility == llvm::GlobalValue::ProtectedVisibility) &&
-         (DLLStorage == llvm::GlobalValue::DefaultStorageClass ||
-          DLLStorage == llvm::GlobalValue::DLLExportStorageClass);
+  return IRL.Linkage == llvm::GlobalValue::ExternalLinkage &&
+         (IRL.Visibility == llvm::GlobalValue::DefaultVisibility ||
+          IRL.Visibility == llvm::GlobalValue::ProtectedVisibility) &&
+         (IRL.DLLStorage == llvm::GlobalValue::DefaultStorageClass ||
+          IRL.DLLStorage == llvm::GlobalValue::DLLExportStorageClass);
 }
 
 /// Get or create an LLVM global variable with these linkage rules.
@@ -1591,8 +1652,10 @@
   auto var = new llvm::GlobalVariable(IGM.Module, storageType,
                                       /*constant*/ false, linkInfo.getLinkage(),
                                       /*initializer*/ nullptr, name);
-  var->setVisibility(linkInfo.getVisibility());
-  var->setDLLStorageClass(linkInfo.getDLLStorage());
+  ApplyIRLinkage({linkInfo.getLinkage(),
+                  linkInfo.getVisibility(),
+                  linkInfo.getDLLStorage()})
+      .to(var);
   var->setAlignment(alignment.getValue());
 
   // Everything externally visible is considered used in Swift.
@@ -1907,16 +1970,169 @@
   return clang::GlobalDecl(cast<clang::FunctionDecl>(decl));
 }
 
+static void addLLVMFunctionAttributes(SILFunction *f, Signature &signature) {
+  auto &attrs = signature.getMutableAttributes();
+  switch (f->getInlineStrategy()) {
+  case NoInline:
+    attrs = attrs.addAttribute(signature.getType()->getContext(),
+                               llvm::AttributeList::FunctionIndex,
+                               llvm::Attribute::NoInline);
+    break;
+  case AlwaysInline:
+    // FIXME: We do not currently transfer AlwaysInline since doing so results
+    // in test failures, which must be investigated first.
+  case InlineDefault:
+    break;
+  }
+
+  if (isReadOnlyFunction(f)) {
+    attrs = attrs.addAttribute(signature.getType()->getContext(),
+                               llvm::AttributeList::FunctionIndex,
+                               llvm::Attribute::ReadOnly);
+  }
+}
+
+/// Create a key entry for a dynamic function replacement. A key entry refers to
+/// the link entry for the dynamic replaceable function.
+/// struct KeyEntry {
+///   RelativeDirectPointer<LinkEntry> linkEntry;
+///   int32_t flags;
+/// }
+static llvm::GlobalVariable *createGlobalForDynamicReplacementFunctionKey(
+    IRGenModule &IGM, SILFunction *SILFn, llvm::GlobalVariable *linkEntry) {
+  LinkEntity keyEntity =
+      LinkEntity::forDynamicallyReplaceableFunctionKey(SILFn);
+  auto key = IGM.getGlobalForDynamicallyReplaceableThunk(
+      keyEntity, IGM.DynamicReplacementKeyTy, ForDefinition);
+
+  ConstantInitBuilder builder(IGM);
+  auto B = builder.beginStruct(IGM.DynamicReplacementKeyTy);
+  B.addRelativeAddress(linkEntry);
+  B.addInt32(0);
+  B.finishAndSetAsInitializer(key);
+  key->setConstant(true);
+  IGM.setTrueConstGlobal(key);
+  return key;
+}
+
+/// Emit the thunk that dispatches to the dynamically replaceable function.
+static void emitDynamicallyReplaceableThunk(IRGenModule &IGM,
+                                            SILFunction *SILFn,
+                                            llvm::Function *dispatchFn,
+                                            llvm::Function *implFn,
+                                            Signature &signature) {
+
+  // Create and initialize the first link entry for the chain of replacements.
+  // The first implementation is initialized with 'implFn'.
+  auto linkEntry = getChainEntryForDynamicReplacement(IGM, SILFn, implFn);
+
+  // Create the key data structure. This is used from other modules to refer to
+  // the chain of replacements.
+  createGlobalForDynamicReplacementFunctionKey(IGM, SILFn, linkEntry);
+
+  // We should never inline the implementation function.
+  implFn->addFnAttr(llvm::Attribute::NoInline);
+
+  // Load the function and dispatch to it forwarding our arguments.
+  llvm::BasicBlock *entryBB =
+      llvm::BasicBlock::Create(IGM.getLLVMContext(), "entry", dispatchFn);
+  IRBuilder B(IGM.getLLVMContext(), false);
+  B.SetInsertPoint(entryBB);
+  if (IGM.DebugInfo)
+    IGM.DebugInfo->emitArtificialFunction(B, dispatchFn);
+  llvm::Constant *indices[] = {llvm::ConstantInt::get(IGM.Int32Ty, 0),
+                               llvm::ConstantInt::get(IGM.Int32Ty, 0)};
+  auto *fnPtr = B.CreateLoad(
+      llvm::ConstantExpr::getInBoundsGetElementPtr(nullptr, linkEntry, indices),
+      IGM.getPointerAlignment());
+  auto *typeFnPtr = B.CreateBitOrPointerCast(fnPtr, implFn->getType());
+  SmallVector<llvm::Value *, 16> forwardedArgs;
+  for (auto &arg : dispatchFn->args())
+    forwardedArgs.push_back(&arg);
+  auto *Res =
+      B.CreateCall(FunctionPointer(typeFnPtr, signature), forwardedArgs);
+  if (implFn->getReturnType()->isVoidTy())
+    B.CreateRetVoid();
+  else
+    B.CreateRet(Res);
+}
+
+/// Calls the previous implementation before this dynamic replacement became
+/// active.
+void IRGenModule::emitDynamicReplacementOriginalFunctionThunk(SILFunction *f) {
+  assert(f->getDynamicallyReplacedFunction());
+
+  auto entity = LinkEntity::forSILFunction(f, true);
+
+  Signature signature = getSignature(f->getLoweredFunctionType());
+  addLLVMFunctionAttributes(f, signature);
+
+  LinkInfo implLink = LinkInfo::get(*this, entity, ForDefinition);
+  auto implFn =
+      createFunction(*this, implLink, signature, nullptr /*insertBefore*/,
+                     f->getOptimizationMode());
+  implFn->addFnAttr(llvm::Attribute::NoInline);
+
+  auto linkEntry =
+      getChainEntryForDynamicReplacement(*this, f, nullptr, NotForDefinition);
+
+  // Load the function and dispatch to it forwarding our arguments.
+  llvm::BasicBlock *entryBB =
+      llvm::BasicBlock::Create(getLLVMContext(), "entry", implFn);
+  IRBuilder B(getLLVMContext(), false);
+  B.SetInsertPoint(entryBB);
+  llvm::Constant *indices[] = {llvm::ConstantInt::get(Int32Ty, 0),
+                               llvm::ConstantInt::get(Int32Ty, 0)};
+
+  auto *fnPtr = B.CreateLoad(
+      llvm::ConstantExpr::getInBoundsGetElementPtr(nullptr, linkEntry, indices),
+      getPointerAlignment());
+  auto *typeFnPtr = B.CreateBitOrPointerCast(fnPtr, implFn->getType());
+
+  SmallVector<llvm::Value *, 16> forwardedArgs;
+  for (auto &arg : implFn->args())
+    forwardedArgs.push_back(&arg);
+  auto *Res =
+      B.CreateCall(FunctionPointer(typeFnPtr, signature), forwardedArgs);
+
+  if (implFn->getReturnType()->isVoidTy())
+    B.CreateRetVoid();
+  else
+    B.CreateRet(Res);
+}
+
 /// Find the entry point for a SIL function.
-llvm::Function *IRGenModule::getAddrOfSILFunction(SILFunction *f,
-                                                  ForDefinition_t forDefinition) {
-  LinkEntity entity = LinkEntity::forSILFunction(f);
+llvm::Function *IRGenModule::getAddrOfSILFunction(
+    SILFunction *f, ForDefinition_t forDefinition,
+    bool isDynamicallyReplaceableImplementation,
+    bool shouldCallPreviousImplementation) {
+  assert(forDefinition || !isDynamicallyReplaceableImplementation);
+  assert(!forDefinition || !shouldCallPreviousImplementation);
+
+  LinkEntity entity =
+      LinkEntity::forSILFunction(f, shouldCallPreviousImplementation);
 
   // Check whether we've created the function already.
   // FIXME: We should integrate this into the LinkEntity cache more cleanly.
-  llvm::Function *fn = Module.getFunction(f->getName());  
+  llvm::Function *fn = Module.getFunction(entity.mangleAsString());
   if (fn) {
-    if (forDefinition) updateLinkageForDefinition(*this, fn, entity);
+    if (forDefinition) {
+      updateLinkageForDefinition(*this, fn, entity);
+      if (isDynamicallyReplaceableImplementation) {
+        // Create the dynamically replacement thunk.
+        LinkEntity implEntity = LinkEntity::forSILFunction(f, true);
+        auto existingImpl = Module.getFunction(implEntity.mangleAsString());
+        assert(!existingImpl);
+        (void) existingImpl;
+        Signature signature = getSignature(f->getLoweredFunctionType());
+        addLLVMFunctionAttributes(f, signature);
+        LinkInfo implLink = LinkInfo::get(*this, implEntity, forDefinition);
+        auto implFn = createFunction(*this, implLink, signature, fn,
+                                     f->getOptimizationMode());
+        emitDynamicallyReplaceableThunk(*this, f, fn, implFn, signature);
+        return implFn;
+      }
+    }
     return fn;
   }
 
@@ -1930,7 +2146,8 @@
   }
 
   bool isDefinition = f->isDefinition();
-  bool hasOrderNumber = isDefinition;
+  bool hasOrderNumber =
+      isDefinition && !shouldCallPreviousImplementation;
   unsigned orderNumber = ~0U;
   llvm::Function *insertBefore = nullptr;
 
@@ -1967,28 +2184,10 @@
   }
 
   Signature signature = getSignature(f->getLoweredFunctionType());
-  auto &attrs = signature.getMutableAttributes();
+  addLLVMFunctionAttributes(f, signature);
 
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
 
-  switch (f->getInlineStrategy()) {
-  case NoInline:
-    attrs = attrs.addAttribute(signature.getType()->getContext(),
-                               llvm::AttributeList::FunctionIndex,
-                               llvm::Attribute::NoInline);
-    break;
-  case AlwaysInline:
-    // FIXME: We do not currently transfer AlwaysInline since doing so results
-    // in test failures, which must be investigated first.
-  case InlineDefault:
-    break;
-  }
-
-  if (isReadOnlyFunction(f)) {
-    attrs = attrs.addAttribute(signature.getType()->getContext(),
-                               llvm::AttributeList::FunctionIndex,
-                               llvm::Attribute::ReadOnly);
-  }
   fn = createFunction(*this, link, signature, insertBefore,
                       f->getOptimizationMode());
 
@@ -2004,6 +2203,16 @@
   if (hasOrderNumber) {
     EmittedFunctionsByOrder.insert(orderNumber, fn);
   }
+
+  if (isDynamicallyReplaceableImplementation && forDefinition) {
+    LinkEntity implEntity = LinkEntity::forSILFunction(f, true);
+    LinkInfo implLink = LinkInfo::get(*this, implEntity, forDefinition);
+    auto implFn = createFunction(*this, implLink, signature, insertBefore,
+                                 f->getOptimizationMode());
+
+    emitDynamicallyReplaceableThunk(*this, f, fn, implFn, signature);
+    return implFn;
+  }
   return fn;
 }
 
@@ -2036,6 +2245,20 @@
   return gotEquivalent;
 }
 
+llvm::Constant *IRGenModule::getOrCreateGOTEquivalent(llvm::Constant *global,
+                                                      LinkEntity entity) {
+  auto &gotEntry = GlobalGOTEquivalents[entity];
+  if (gotEntry) {
+    return gotEntry;
+  }
+
+  // Use the global as the initializer for an anonymous constant. LLVM can treat
+  // this as equivalent to the global's GOT entry.
+  auto gotEquivalent = createGOTEquivalent(*this, global, entity);
+  gotEntry = gotEquivalent;
+  return gotEquivalent;
+}
+
 static llvm::Constant *getElementBitCast(llvm::Constant *ptr,
                                          llvm::Type *newEltType) {
   auto ptrType = cast<llvm::PointerType>(ptr->getType());
@@ -2203,6 +2426,21 @@
 ConstantReference
 IRGenModule::getAddrOfLLVMVariableOrGOTEquivalent(LinkEntity entity,
                               ConstantReference::Directness forceIndirectness) {
+  // Handle SILFunctions specially, because unlike other entities they aren't
+  // variables and aren't kept in the GlobalVars table.
+  if (entity.isSILFunction()) {
+    auto *silFn = entity.getSILFunction();
+    auto fn = getAddrOfSILFunction(silFn, NotForDefinition);
+    if (silFn->isDefinition() &&
+        !isAvailableExternally(silFn->getLinkage()) &&
+        this == IRGen.getGenModule(silFn)) {
+      return {fn, ConstantReference::Direct};
+    }
+    
+    auto gotEquivalent = getOrCreateGOTEquivalent(fn, entity);
+    return {gotEquivalent, ConstantReference::Indirect};
+  }
+  
   // ObjC class references can always be directly referenced, even in
   // the weird cases where we don't see a definition.
   if (entity.isObjCClassRef()) {
@@ -2211,7 +2449,7 @@
     return { cast<llvm::Constant>(value.getAddress()),
              ConstantReference::Direct };
   }
-
+  
   // Ensure the variable is at least forward-declared.
   if (entity.isForeignTypeMetadataCandidate()) {
     auto foreignCandidate
@@ -2251,17 +2489,8 @@
   
   /// Returns an indirect reference.
   auto indirect = [&]() -> ConstantReference {
-    auto &gotEntry = GlobalGOTEquivalents[entity];
-    if (gotEntry) {
-      return {gotEntry, ConstantReference::Indirect};
-    }
-
-    // Look up the global variable.
-    auto global = cast<llvm::GlobalValue>(entry);
-    // Use it as the initializer for an anonymous constant. LLVM can treat this as
-    // equivalent to the global's GOT entry.
-    auto gotEquivalent = createGOTEquivalent(*this, global, entity);
-    gotEntry = gotEquivalent;
+    auto gotEquivalent = getOrCreateGOTEquivalent(
+      cast<llvm::GlobalValue>(entry), entity);
     return {gotEquivalent, ConstantReference::Indirect};
   };
   
@@ -2868,8 +3097,8 @@
   auto *alias = llvm::GlobalAlias::create(
       ptrTy->getElementType(), ptrTy->getAddressSpace(), link.getLinkage(),
       link.getName(), definition, &Module);
-  alias->setVisibility(link.getVisibility());
-  alias->setDLLStorageClass(link.getDLLStorage());
+  ApplyIRLinkage({link.getLinkage(), link.getVisibility(), link.getDLLStorage()})
+      .to(alias);
 
   if (link.isUsed()) {
     addUsedGlobal(alias);
@@ -3685,6 +3914,8 @@
   Signature signature(fnType, llvm::AttributeList(), DefaultCC);
   LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
   entry = createFunction(*this, link, signature);
+  ApplyIRLinkage({link.getLinkage(), link.getVisibility(), link.getDLLStorage()})
+      .to(entry);
   return entry;
 }
 
@@ -3797,9 +4028,7 @@
   if (!def) return nullptr;
   if (!def->empty()) return nullptr;
 
-  def->setLinkage(llvm::Function::LinkOnceODRLinkage);
-  def->setVisibility(llvm::Function::HiddenVisibility);
-  def->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass);
+  ApplyIRLinkage(IRLinkage::InternalLinkOnceODR).to(def);
   def->setDoesNotThrow();
   def->setCallingConv(IGM.DefaultCC);
   if (setIsNoInline)
diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp
index 03430df..adb46c1 100644
--- a/lib/IRGen/GenEnum.cpp
+++ b/lib/IRGen/GenEnum.cpp
@@ -1181,7 +1181,7 @@
     // discriminate enum cases.
     unsigned ExtraTagBitCount = ~0u;
     // The number of possible values for the extra tag bits that are used.
-    // Log2(NumExtraTagValues - 1) + 1 == ExtraTagBitCount
+    // Log2(NumExtraTagValues - 1) + 1 <= ExtraTagBitCount
     unsigned NumExtraTagValues = ~0u;
     
     APInt getExtraTagBitConstant(uint64_t value) const {
@@ -1473,7 +1473,7 @@
     auto func =
         llvm::Function::Create(consumeTy, llvm::GlobalValue::LinkOnceODRLinkage,
                                llvm::StringRef(name), IGM.getModule());
-    func->setVisibility(llvm::GlobalValue::HiddenVisibility);
+    ApplyIRLinkage(IRLinkage::InternalLinkOnceODR).to(func);
     func->setAttributes(IGM.constructInitialAttributes());
     func->setDoesNotThrow();
     func->setCallingConv(IGM.DefaultCC);
@@ -4817,15 +4817,74 @@
 
     /// \group Extra inhabitants
 
-    // TODO
+    // If we didn't use all of the available tag bit representations, offer
+    // the remaining ones as extra inhabitants.
 
-    bool mayHaveExtraInhabitants(IRGenModule &) const override { return false; }
+    bool mayHaveExtraInhabitants(IRGenModule &IGM) const override {
+      if (TIK >= Fixed)
+        return getFixedExtraInhabitantCount(IGM) > 0;
+      return true;
+    }
+    
+    /// Rounds the extra tag bit count up to the next byte size.
+    unsigned getExtraTagBitCountForExtraInhabitants() const {
+      if (!ExtraTagTy)
+        return 0;
+      return (ExtraTagTy->getBitWidth() + 7) & ~7;
+    }
+    
+    Address projectExtraTagBitsForExtraInhabitants(IRGenFunction &IGF,
+                                                   Address base) const {
+      auto addr = projectExtraTagBits(IGF, base);
+      if (ExtraTagTy->getBitWidth() != getExtraTagBitCountForExtraInhabitants()) {
+        addr = IGF.Builder.CreateBitCast(addr,
+             llvm::IntegerType::get(IGF.IGM.getLLVMContext(),
+                                     getExtraTagBitCountForExtraInhabitants())
+               ->getPointerTo());
+      }
+      return addr;
+    }
 
     llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF,
                                          Address src,
                                          SILType T,
                                          bool isOutlined) const override {
-      llvm_unreachable("extra inhabitants for multi-payload enums not implemented");
+      // For dynamic layouts, the runtime provides a value witness to do this.
+      if (TIK < Fixed) {
+        return emitGetExtraInhabitantIndexCall(IGF, T, src);
+      }
+      
+      llvm::Value *tag;
+      if (CommonSpareBits.count()) {
+        auto payload = EnumPayload::load(IGF, projectPayload(IGF, src),
+                                         PayloadSchema);
+        tag = payload.emitGatherSpareBits(IGF, CommonSpareBits, 0, 32);
+        if (getExtraTagBitCountForExtraInhabitants()) {
+          auto extraTagAddr = projectExtraTagBitsForExtraInhabitants(IGF, src);
+          auto extraTag = IGF.Builder.CreateLoad(extraTagAddr);
+          auto extraTagBits =
+            IGF.Builder.CreateZExtOrTrunc(extraTag, IGF.IGM.Int32Ty);
+          extraTagBits =
+            IGF.Builder.CreateShl(extraTagBits, CommonSpareBits.count());
+          tag = IGF.Builder.CreateOr(tag, extraTagBits);
+        }
+      } else {
+        auto extraTagAddr = projectExtraTagBitsForExtraInhabitants(IGF, src);
+        auto extraTag = IGF.Builder.CreateLoad(extraTagAddr);
+        tag = IGF.Builder.CreateZExtOrTrunc(extraTag, IGF.IGM.Int32Ty);
+      }
+      
+      // Check whether it really is an extra inhabitant.
+      auto tagBits = CommonSpareBits.count() + getExtraTagBitCountForExtraInhabitants();
+      auto maxTag = tagBits >= 32 ? ~0u : (1 << tagBits) - 1;
+      auto index = IGF.Builder.CreateSub(
+                               llvm::ConstantInt::get(IGF.IGM.Int32Ty, maxTag),
+                               tag);
+      auto isExtraInhabitant = IGF.Builder.CreateICmpULT(index,
+                 llvm::ConstantInt::get(IGF.IGM.Int32Ty,
+                                        getFixedExtraInhabitantCount(IGF.IGM)));
+      return IGF.Builder.CreateSelect(isExtraInhabitant,
+                            index, llvm::ConstantInt::get(IGF.IGM.Int32Ty, -1));
     }
 
     void storeExtraInhabitant(IRGenFunction &IGF,
@@ -4833,25 +4892,86 @@
                               Address dest,
                               SILType T,
                               bool isOutlined) const override {
-      llvm_unreachable("extra inhabitants for multi-payload enums not implemented");
+      // For dynamic layouts, the runtime provides a value witness to do this.
+      if (TIK < Fixed) {
+        emitStoreExtraInhabitantCall(IGF, T, index, dest);
+        return;
+      }
+
+      auto indexValue = IGF.Builder.CreateNot(index);
+      if (CommonSpareBits.count()) {
+        // Factor the index value into parts to scatter into the payload and
+        // to store in the extra tag bits, if any.
+        EnumPayload payload =
+          interleaveSpareBits(IGF, PayloadSchema, CommonSpareBits, indexValue);
+        payload.store(IGF, projectPayload(IGF, dest));
+        if (getExtraTagBitCountForExtraInhabitants() > 0) {
+          auto tagBits = IGF.Builder.CreateLShr(indexValue,
+              llvm::ConstantInt::get(IGF.IGM.Int32Ty, CommonSpareBits.count()));
+          auto tagAddr = projectExtraTagBitsForExtraInhabitants(IGF, dest);
+          tagBits = IGF.Builder.CreateZExtOrTrunc(tagBits,
+                      tagAddr.getAddress()->getType()->getPointerElementType());
+          IGF.Builder.CreateStore(tagBits, tagAddr);
+        }
+      } else {
+        // Only need to store the tag value.
+        auto tagAddr = projectExtraTagBitsForExtraInhabitants(IGF, dest);
+        indexValue = IGF.Builder.CreateZExtOrTrunc(indexValue,
+                      tagAddr.getAddress()->getType()->getPointerElementType());
+        IGF.Builder.CreateStore(indexValue, tagAddr);
+      }
     }
     
     APInt
     getFixedExtraInhabitantMask(IRGenModule &IGM) const override {
-      // TODO may not always be all-ones
-      return APInt::getAllOnesValue(
-                      cast<FixedTypeInfo>(TI)->getFixedSize().getValueInBits());
+      // The extra inhabitant goes into the tag bits.
+      auto tagBits = CommonSpareBits.asAPInt();
+      auto fixedTI = cast<FixedTypeInfo>(TI);
+      if (getExtraTagBitCountForExtraInhabitants() > 0) {
+        auto bitSize = fixedTI->getFixedSize().getValueInBits();
+        tagBits = tagBits.zext(bitSize);
+        auto extraTagMask = APInt::getAllOnesValue(bitSize)
+          .shl(CommonSpareBits.size());
+        tagBits |= extraTagMask;
+      }
+      return tagBits;
     }
     
     unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override {
-      return 0;
+      unsigned totalTagBits = CommonSpareBits.count() + getExtraTagBitCountForExtraInhabitants();
+      if (totalTagBits >= 32)
+        return INT_MAX;
+      unsigned totalTags = 1u << totalTagBits;
+      return totalTags - ElementsWithPayload.size() - NumEmptyElementTags;
     }
 
     APInt
     getFixedExtraInhabitantValue(IRGenModule &IGM,
                                  unsigned bits,
                                  unsigned index) const override {
-      llvm_unreachable("extra inhabitants for multi-payload enums not implemented");
+      // Count down from all-ones since a small negative number constant is
+      // likely to be easier to reify.
+      auto mask = ~index;
+      auto extraTagMask = getExtraTagBitCountForExtraInhabitants() >= 32
+        ? ~0u : (1 << getExtraTagBitCountForExtraInhabitants()) - 1;
+
+      if (auto payloadBitCount = CommonSpareBits.count()) {
+        auto payloadTagMask = payloadBitCount >= 32
+          ? ~0u : (1 << payloadBitCount) - 1;
+        auto payloadPart = mask & payloadTagMask;
+        auto payloadBits = interleaveSpareBits(IGM, CommonSpareBits,
+                                               bits, payloadPart, 0);
+        if (getExtraTagBitCountForExtraInhabitants() > 0) {
+          auto extraBits = APInt(bits,
+                                 (mask >> payloadBitCount) & extraTagMask)
+            .shl(CommonSpareBits.size());
+          payloadBits |= extraBits;
+        }
+        return payloadBits;
+      } else {
+        auto value = APInt(bits, mask & extraTagMask);
+        return value.shl(CommonSpareBits.size());
+      }
     }
 
     ClusteredBitVector
diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp
index 4a95710..6760890 100644
--- a/lib/IRGen/GenKeyPath.cpp
+++ b/lib/IRGen/GenKeyPath.cpp
@@ -28,6 +28,7 @@
 #include "GenericRequirement.h"
 #include "IRGenDebugInfo.h"
 #include "IRGenFunction.h"
+#include "IRGenMangler.h"
 #include "IRGenModule.h"
 #include "MetadataLayout.h"
 #include "ProtocolInfo.h"
@@ -116,13 +117,16 @@
     break;
   }
   
+  // If the accessor is not generic, and locally available, we can use it as is.
+  // If it's only externally available, we need a local thunk to relative-
+  // reference.
+  if (requirements.empty() &&
+      !isAvailableExternally(accessor->getLinkage()) &&
+      &IGM == IGM.IRGen.getGenModule(accessor)) {
+    return IGM.getAddrOfSILFunction(accessor, NotForDefinition);
+  }
   auto accessorFn = IGM.getAddrOfSILFunction(accessor, NotForDefinition);
   
-  // If the accessor is not generic, we can use it as is.
-  if (requirements.empty()) {
-    return accessorFn;
-  }
-
   auto accessorFnTy = cast<llvm::FunctionType>(
     accessorFn->getType()->getPointerElementType());;
   
@@ -235,12 +239,14 @@
     
     // Use the bound generic metadata to form a call to the original generic
     // accessor.
-    WitnessMetadata ignoreWitnessMetadata;
-    auto forwardingSubs = genericEnv->getForwardingSubstitutionMap();
-    emitPolymorphicArguments(IGF, accessor->getLoweredFunctionType(),
-                             forwardingSubs,
-                             &ignoreWitnessMetadata,
-                             forwardedArgs);
+    if (genericEnv) {
+      WitnessMetadata ignoreWitnessMetadata;
+      auto forwardingSubs = genericEnv->getForwardingSubstitutionMap();
+      emitPolymorphicArguments(IGF, accessor->getLoweredFunctionType(),
+                               forwardingSubs,
+                               &ignoreWitnessMetadata,
+                               forwardedArgs);
+    }
     auto fnPtr = FunctionPointer::forDirect(IGM, accessorFn,
                                           accessor->getLoweredFunctionType());
     auto call = IGF.Builder.CreateCall(fnPtr, forwardedArgs.claimAll());
@@ -338,19 +344,10 @@
                                     GenericEnvironment *genericEnv,
                                     ArrayRef<GenericRequirement> requirements) {
   // If the only thing we're capturing is generic environment, then we can
-  // use a prefab witness table from the runtime.
+  // use a prefab witness table from the runtime. A null reference will be
+  // filled in by the runtime.
   if (component.getSubscriptIndices().empty()) {
-    if (auto existing =
-          IGM.Module.getNamedGlobal("swift_keyPathGenericWitnessTable"))
-      return existing;
-
-    auto linkInfo = LinkInfo::get(UniversalLinkageInfo(IGM),
-                                  "swift_keyPathGenericWitnessTable",
-                                  SILLinkage::PublicExternal, NotForDefinition,
-                                  /*weak imported*/ false);
-
-    return createVariable(IGM, linkInfo,
-                          IGM.Int8PtrTy, IGM.getPointerAlignment());
+    return nullptr;
   }
   
   // Are the index values trivial?
@@ -653,53 +650,83 @@
 /// protocol conformance metadata record.
 /// TODO: It would be much better to emit typeref strings and use runtime
 /// demangling here.
-static llvm::Function *
+static llvm::Constant *
 emitGeneratorForKeyPath(IRGenModule &IGM,
                         StringRef name, CanType type, llvm::Type *returnType,
                         GenericEnvironment *genericEnv,
                         ArrayRef<GenericRequirement> requirements,
                         llvm::function_ref<void(IRGenFunction&,CanType)> emit) {
-  // TODO: Use the standard metadata accessor when there are no arguments
-  // and the metadata accessor is defined.
 
-  // Build a stub that loads the necessary bindings from the key path's
-  // argument buffer then fetches the metadata.
-  auto fnTy = llvm::FunctionType::get(returnType,
-                                      {IGM.Int8PtrTy}, /*vararg*/ false);
-  auto accessorThunk = llvm::Function::Create(fnTy,
-                                          llvm::GlobalValue::PrivateLinkage,
-                                          name, IGM.getModule());
-  accessorThunk->setAttributes(IGM.constructInitialAttributes());
-  {
-    IRGenFunction IGF(IGM, accessorThunk);
-    if (IGM.DebugInfo)
-      IGM.DebugInfo->emitArtificialFunction(IGF, accessorThunk);
-    
-    if (type->hasTypeParameter()) {
-      auto bindingsBufPtr = IGF.collectParameters().claimNext();
-      
-      bindFromGenericRequirementsBuffer(IGF, requirements,
-            Address(bindingsBufPtr, IGM.getPointerAlignment()),
-            MetadataState::Complete,
-            [&](CanType t) {
-              return genericEnv->mapTypeIntoContext(t)->getCanonicalType();
-            });
-      
-      type = genericEnv->mapTypeIntoContext(type)->getCanonicalType();
-    }
-    emit(IGF, type);
-  }
-  return accessorThunk;
+  return IGM.getAddrOfStringForMetadataRef(name,
+      /*shouldSetLowBit=*/true,
+      [&](ConstantInitBuilder &B) {
+        // Build a stub that loads the necessary bindings from the key path's
+        // argument buffer then fetches the metadata.
+        auto fnTy = llvm::FunctionType::get(returnType,
+                                            {IGM.Int8PtrTy}, /*vararg*/ false);
+        auto accessorThunk =
+          llvm::Function::Create(fnTy, llvm::GlobalValue::PrivateLinkage,
+                                 name, IGM.getModule());
+        accessorThunk->setAttributes(IGM.constructInitialAttributes());
+        {
+          IRGenFunction IGF(IGM, accessorThunk);
+          if (IGM.DebugInfo)
+            IGM.DebugInfo->emitArtificialFunction(IGF, accessorThunk);
+
+          if (type->hasTypeParameter()) {
+            auto bindingsBufPtr = IGF.collectParameters().claimNext();
+
+            bindFromGenericRequirementsBuffer(IGF, requirements,
+                Address(bindingsBufPtr, IGM.getPointerAlignment()),
+                MetadataState::Complete,
+                [&](CanType t) {
+                  return genericEnv->mapTypeIntoContext(t)->getCanonicalType();
+                });
+
+            type = genericEnv->mapTypeIntoContext(type)->getCanonicalType();
+          }
+          emit(IGF, type);
+        }
+
+        // Form the mangled name with its relative reference.
+        auto S = B.beginStruct();
+        S.setPacked(true);
+        S.add(llvm::ConstantInt::get(IGM.Int8Ty, 9));
+        S.addRelativeAddress(accessorThunk);
+
+        // And a null terminator!
+        S.addInt(IGM.Int8Ty, 0);
+
+        return S.finishAndCreateFuture();
+      });
 }
 
-static llvm::Function *
+static llvm::Constant *
 emitMetadataGeneratorForKeyPath(IRGenModule &IGM,
                                 CanType type,
                                 GenericEnvironment *genericEnv,
                                 ArrayRef<GenericRequirement> requirements) {
+  // If we have a non-dependent type, use a normal mangled type name.
+  if (!type->hasTypeParameter()) {
+    auto constant = IGM.getTypeRef(type, MangledTypeRefRole::Metadata);
+    auto bitConstant = llvm::ConstantInt::get(IGM.IntPtrTy, 1);
+    return llvm::ConstantExpr::getGetElementPtr(nullptr, constant, bitConstant);
+  }
+
+  // Otherwise, create an accessor.
+  CanGenericSignature genericSig;
+  if (genericEnv)
+    genericSig = genericEnv->getGenericSignature()->getCanonicalSignature();
+
+  IRGenMangler mangler;
+  std::string symbolName =
+    mangler.mangleSymbolNameForKeyPathMetadata(
+      "keypath_get_type", genericSig, type,
+      ProtocolConformanceRef::forInvalid());
+
   // TODO: Use the standard metadata accessor when there are no arguments
   // and the metadata accessor is defined.
-  return emitGeneratorForKeyPath(IGM, "keypath_get_type", type,
+  return emitGeneratorForKeyPath(IGM, symbolName, type,
     IGM.TypeMetadataPtrTy,
     genericEnv, requirements,
     [&](IRGenFunction &IGF, CanType substType) {
@@ -708,15 +735,24 @@
     });
 };
 
-static llvm::Function *
+static llvm::Constant *
 emitWitnessTableGeneratorForKeyPath(IRGenModule &IGM,
                                     CanType type,
                                     ProtocolConformanceRef conformance,
                                     GenericEnvironment *genericEnv,
                                     ArrayRef<GenericRequirement> requirements) {
+  CanGenericSignature genericSig;
+  if (genericEnv)
+    genericSig = genericEnv->getGenericSignature()->getCanonicalSignature();
+
+  IRGenMangler mangler;
+  std::string symbolName =
+    mangler.mangleSymbolNameForKeyPathMetadata(
+      "keypath_get_witness_table", genericSig, type, conformance);
+
   // TODO: Use the standard conformance accessor when there are no arguments
   // and the conformance accessor is defined.
-  return emitGeneratorForKeyPath(IGM, "keypath_get_witness_table", type,
+  return emitGeneratorForKeyPath(IGM, symbolName, type,
     IGM.WitnessTablePtrTy,
     genericEnv, requirements,
     [&](IRGenFunction &IGF, CanType substType) {
@@ -732,7 +768,7 @@
 static unsigned getClassFieldIndex(ClassDecl *classDecl, VarDecl *property) {
   SmallVector<ClassDecl *, 3> superclasses;
   for (auto *superDecl = classDecl; superDecl != nullptr;
-       superDecl = classDecl->getSuperclassDecl()) {
+       superDecl = superDecl->getSuperclassDecl()) {
     superclasses.push_back(superDecl);
   }
 
@@ -754,14 +790,14 @@
 emitKeyPathComponent(IRGenModule &IGM,
                      ConstantStructBuilder &fields,
                      const KeyPathPatternComponent &component,
-                     bool isInstantiableInPlace,
+                     bool isInstantiableOnce,
                      GenericEnvironment *genericEnv,
                      ArrayRef<GenericRequirement> requirements,
                      CanType baseTy,
                      ArrayRef<KeyPathIndexOperand> operands,
                      bool hasSubscriptIndices) {
-  assert(fields.getNextOffsetFromGlobal() % IGM.getPointerAlignment() == Size(0)
-         && "must be pointer-aligned here");
+  assert(fields.getNextOffsetFromGlobal() % Alignment(4) == Size(0)
+         && "must be 32-bit-aligned here");
 
   SILType loweredBaseTy;
   GenericContextScope scope(IGM,
@@ -839,9 +875,9 @@
         auto header = KeyPathComponentHeader
           ::forClassComponentWithUnresolvedIndirectOffset(property->isLet());
         fields.addInt32(header.getData());
-        fields.addAlignmentPadding(IGM.getPointerAlignment());
-        auto offsetVar = IGM.getAddrOfFieldOffset(property, NotForDefinition);
-        fields.add(cast<llvm::Constant>(offsetVar.getAddress()));
+        auto offsetRef = IGM.getAddrOfLLVMVariableOrGOTEquivalent(
+          LinkEntity::forFieldOffset(property));
+        fields.addRelativeAddress(offsetRef);
         break;
       }
       case FieldAccess::ConstantIndirect: {
@@ -897,11 +933,11 @@
       fields.addInt32(
         KeyPathComponentHeader::forExternalComponent(externalSubArgs.size())
           .getData());
-      fields.addAlignmentPadding(IGM.getPointerAlignment());
-      auto descriptor = IGM.getAddrOfPropertyDescriptor(externalDecl);
-      fields.add(descriptor);
+      auto descriptor = IGM.getAddrOfLLVMVariableOrGOTEquivalent(
+        LinkEntity::forPropertyDescriptor(externalDecl));
+      fields.addRelativeAddress(descriptor);
       for (auto *arg : externalSubArgs)
-        fields.add(arg);
+        fields.addRelativeAddress(arg);
     }
   
     // Encode the settability.
@@ -921,11 +957,17 @@
     llvm::Constant *idValue;
     bool idResolved;
     switch (id.getKind()) {
-    case KeyPathPatternComponent::ComputedPropertyId::Function:
+    case KeyPathPatternComponent::ComputedPropertyId::Function: {
       idKind = KeyPathComponentHeader::Pointer;
-      idValue = IGM.getAddrOfSILFunction(id.getFunction(), NotForDefinition);
-      idResolved = true;
+      auto idRef = IGM.getAddrOfLLVMVariableOrGOTEquivalent(
+        LinkEntity::forSILFunction(id.getFunction(), false));
+      
+      idValue = idRef.getValue();
+      // If we got an indirect reference, we'll need to resolve it at
+      // instantiation time.
+      idResolved = !idRef.isIndirect();
       break;
+    }
     case KeyPathPatternComponent::ComputedPropertyId::DeclRef: {
       auto declRef = id.getDeclRef();
     
@@ -951,8 +993,11 @@
             IGM.isResilient(cast<NominalTypeDecl>(dc),
                             ResilienceExpansion::Minimal)) {
           idKind = KeyPathComponentHeader::Pointer;
-          idValue = IGM.getAddrOfMethodDescriptor(declRef, NotForDefinition);
-          idResolved = true;
+          auto idRef = IGM.getAddrOfLLVMVariableOrGOTEquivalent(
+            LinkEntity::forMethodDescriptor(declRef));
+
+          idValue = idRef.getValue();
+          idResolved = !idRef.isIndirect();
           break;
         }
       
@@ -1010,51 +1055,61 @@
     }
     
     auto header = KeyPathComponentHeader::forComputedProperty(componentKind,
-                                  idKind, !isInstantiableInPlace, idResolved);
+                                      idKind, !isInstantiableOnce, idResolved);
     
     fields.addInt32(header.getData());
-    fields.addAlignmentPadding(IGM.getPointerAlignment());
-    fields.add(idValue);
-    
-    if (isInstantiableInPlace) {
-      // No generic arguments or indexes, so we can invoke the
-      // getter/setter as is.
-      fields.add(IGM.getAddrOfSILFunction(component.getComputedPropertyGetter(),
-                                          NotForDefinition));
-      if (settable)
-        fields.add(IGM.getAddrOfSILFunction(component.getComputedPropertySetter(),
-                                            NotForDefinition));
-    } else {
+    switch (idKind) {
+    case KeyPathComponentHeader::Pointer:
+      // Use a relative offset to the referent.
+      fields.addRelativeAddress(idValue);
+      break;
+
+    case KeyPathComponentHeader::VTableOffset:
+    case KeyPathComponentHeader::StoredPropertyIndex:
+      // Store the offset as an i32.
+      fields.add(llvm::ConstantExpr::getTruncOrBitCast(idValue, IGM.Int32Ty));
+      break;
+    }
+
+    // Push the accessors, possibly thunked to marshal generic environment.
+    fields.addRelativeAddress(
+      getAccessorForComputedComponent(IGM, component, Getter,
+                                      genericEnv, requirements,
+                                      hasSubscriptIndices));
+    if (settable)
+      fields.addRelativeAddress(
+        getAccessorForComputedComponent(IGM, component, Setter,
+                                        genericEnv, requirements,
+                                        hasSubscriptIndices));
+
+    if (!isInstantiableOnce) {
       // If there's generic context or subscript indexes, embed as
       // arguments in the component. Thunk the SIL-level accessors to give the
       // runtime implementation a polymorphically-callable interface.
-      
-      // Push the accessors, possibly thunked to marshal generic environment.
-      fields.add(getAccessorForComputedComponent(IGM, component, Getter,
-                                                 genericEnv, requirements,
-                                                 hasSubscriptIndices));
-      if (settable)
-        fields.add(getAccessorForComputedComponent(IGM, component, Setter,
-                                                   genericEnv, requirements,
-                                                   hasSubscriptIndices));
-      
-      fields.add(getLayoutFunctionForComputedComponent(IGM, component,
-                                                     genericEnv, requirements));
+
+      fields.addRelativeAddress(
+        getLayoutFunctionForComputedComponent(IGM, component,
+                                              genericEnv, requirements));
       
       // Set up a "witness table" for the component that handles copying,
       // destroying, equating, and hashing the captured contents of the
       // component.
-      // If there are only generic parameters, we can use a prefab witness
-      // table from the runtime.
-      // For subscripts we generate functions that dispatch out to
-      // the copy/destroy/equals/hash functionality of the subscript indexes.
-      fields.add(getWitnessTableForComputedComponent(IGM, component,
-                                                   genericEnv, requirements));
+      if (auto witnessTable =
+            getWitnessTableForComputedComponent(IGM, component,
+                                                genericEnv, requirements)) {
+        fields.addRelativeAddress(witnessTable);
+      } else {
+        // If there are only generic parameters, we can use a prefab witness
+        // table from the runtime. Leaving a null reference here will let
+        // the runtime fill it in.
+        fields.addInt32(0);
+      }
       
       // Add an initializer function that copies generic arguments out of the
       // pattern argument buffer into the instantiated object.
-      fields.add(getInitializerForComputedComponent(IGM, component, operands,
-                                                   genericEnv, requirements));
+      fields.addRelativeAddress(
+        getInitializerForComputedComponent(IGM, component, operands,
+                                           genericEnv, requirements));
     }
     break;
   }
@@ -1084,7 +1139,7 @@
 
   // Check for parameterization, whether by subscript indexes or by the generic
   // environment. If there isn't any, we can instantiate the pattern in-place.
-  bool isInstantiableInPlace = pattern->getNumOperands() == 0
+  bool isInstantiableOnce = pattern->getNumOperands() == 0
     && !pattern->getGenericSignature();
 
   // Collect the required parameters for the keypath's generic environment.
@@ -1101,50 +1156,39 @@
   ConstantInitBuilder builder(*this);
   ConstantStructBuilder fields = builder.beginStruct();
   fields.setPacked(true);
-  // Add a zero-initialized header we can use for lazy initialization.
-  fields.add(llvm::ConstantInt::get(SizeTy, 0));
+  // If the pattern has no parameterization, add a pointer to a cache variable
+  // that can be used for the one-time initialization of the key path.
+  if (isInstantiableOnce) {
+    auto onceVar = new llvm::GlobalVariable(Module, OnceTy,
+                                            /*constant*/ false,
+                                            llvm::GlobalValue::PrivateLinkage,
+                                            llvm::ConstantInt::get(OnceTy, 0),
+                                            "keypath_once");
+    onceVar->setAlignment(getPointerAlignment().getValue());
+    fields.addRelativeAddress(onceVar);
+  } else {
+    fields.addInt32(0);
+  }
 
-#ifndef NDEBUG
-  auto startOfObject = fields.getNextOffsetFromGlobal();
-#endif
-
-  // Store references to metadata generator functions to generate the metadata
-  // for the root and leaf. These sit in the "isa" and object header parts of
-  // the final object.
-  fields.add(emitMetadataGeneratorForKeyPath(*this, rootTy,
-                                             genericEnv, requirements));
-  fields.add(emitMetadataGeneratorForKeyPath(*this, valueTy,
-                                             genericEnv, requirements));
-  
-#ifndef NDEBUG
-  auto endOfObjectHeader = fields.getNextOffsetFromGlobal();
-  unsigned expectedObjectHeaderSize;
-  if (SizeTy == Int64Ty)
-    expectedObjectHeaderSize = SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_64;
-  else if (SizeTy == Int32Ty)
-    expectedObjectHeaderSize = SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_32;
-  else
-    llvm_unreachable("unexpected pointer size");
-  assert((endOfObjectHeader - startOfObject).getValue()
-            == expectedObjectHeaderSize
-       && "key path pattern header size doesn't match heap object header size");
-#endif
+  // Store type references for the root and leaf.
+  fields.addRelativeAddress(
+    emitMetadataGeneratorForKeyPath(*this, rootTy, genericEnv, requirements));
+  fields.addRelativeAddress(
+    emitMetadataGeneratorForKeyPath(*this, valueTy, genericEnv, requirements));
   
   // Add a pointer to the ObjC KVC compatibility string, if there is one, or
   // null otherwise.
-  llvm::Constant *objcString;
   if (!pattern->getObjCString().empty()) {
-    objcString = getAddrOfGlobalString(pattern->getObjCString());
+    auto objcString = getAddrOfGlobalString(pattern->getObjCString(),
+                                            /*relatively addressed*/ true);
+    fields.addRelativeAddress(objcString);
   } else {
-    objcString = llvm::ConstantPointerNull::get(Int8PtrTy);
+    fields.addInt32(0);
   }
-  fields.add(objcString);
   
   // Leave a placeholder for the buffer header, since we need to know the full
   // buffer size to fill it in.
   auto headerPlaceholder = fields.addPlaceholderWithSize(Int32Ty);
-  fields.addAlignmentPadding(getPointerAlignment());
-  
   auto startOfKeyPathBuffer = fields.getNextOffsetFromGlobal();
   
   // Build out the components.
@@ -1175,15 +1219,14 @@
   for (unsigned i : indices(pattern->getComponents())) {
     auto &component = pattern->getComponents()[i];
     
-    emitKeyPathComponent(*this, fields, component, isInstantiableInPlace,
+    emitKeyPathComponent(*this, fields, component, isInstantiableOnce,
                          genericEnv, requirements,
                          baseTy, operands,
                          !component.getSubscriptIndices().empty());
     
     // For all but the last component, we pack in the type of the component.
     if (i + 1 != pattern->getComponents().size()) {
-      fields.addAlignmentPadding(getPointerAlignment());
-      fields.add(
+      fields.addRelativeAddress(
         emitMetadataGeneratorForKeyPath(*this, component.getComponentType(),
                                         genericEnv, requirements));
     }
@@ -1195,7 +1238,7 @@
     - startOfKeyPathBuffer;
   
   // We now have enough info to build the header.
-  KeyPathBufferHeader header(componentSize.getValue(), isInstantiableInPlace,
+  KeyPathBufferHeader header(componentSize.getValue(), isInstantiableOnce,
                              /*reference prefix*/ false);
   // Add the header, followed by the components.
   fields.fillPlaceholder(headerPlaceholder,
@@ -1209,6 +1252,7 @@
                                           getPointerAlignment(),
                                           /*constant*/ false,
                                           llvm::GlobalVariable::PrivateLinkage);
+  setTrueConstGlobal(patternVar);
   KeyPathPatterns.insert({pattern, patternVar});
   return patternVar;
 }
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index c6a2bec..babdce2 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -788,15 +788,15 @@
           continue;
 
         auto witness = entry.getAssociatedTypeProtocolWitness().Witness;
-        return getDefaultAssociatedConformanceAccessFunction(
-                 AssociatedConformance(Proto, association, requirement),
-                 witness);
+        AssociatedConformance conformance(Proto, association, requirement);
+        defineDefaultAssociatedConformanceAccessFunction(conformance, witness);
+        return IGM.getMangledAssociatedConformance(nullptr, conformance);
       }
 
       return nullptr;
     }
 
-    llvm::Constant *getDefaultAssociatedConformanceAccessFunction(
+    void defineDefaultAssociatedConformanceAccessFunction(
                       AssociatedConformance requirement,
                       ProtocolConformanceRef conformance) {
       auto accessor =
@@ -839,7 +839,7 @@
                                                     conformance.getConcrete());
         auto returnValue = conformanceI->getTable(IGF, &associatedTypeMetadata);
         IGF.Builder.CreateRet(returnValue);
-        return accessor;
+        return;
       }
 
       // For an abstract table, emit a reference to the witness table.
@@ -852,7 +852,7 @@
             cast<ArchetypeType>(associatedTypeInContext),
             associatedProtocol);
       IGF.Builder.CreateRet(returnValue);
-      return accessor;
+      return;
     }
 
     void addAssociatedTypeNames() {
@@ -1511,7 +1511,7 @@
       auto flags = getMethodDescriptorFlags<Flags>(func);
 
       // Remember if the declaration was dynamic.
-      if (func->isDynamic())
+      if (func->isObjCDynamic())
         flags = flags.withIsDynamic(true);
 
       // TODO: final? open?
@@ -4103,31 +4103,6 @@
 // Generic requirements.
 //===----------------------------------------------------------------------===//
 
-/// Add a generic parameter reference to the given constant struct builder.
-static void addGenericParamRef(IRGenModule &IGM, ConstantStructBuilder &B,
-                               GenericSignature *sig, CanType type) {
-  // type should be either a generic parameter or dependent member type
-  // thereof.
-
-  if (auto genericParam = dyn_cast<GenericTypeParamType>(type)) {
-    // We can encode the ordinal of a direct type parameter reference
-    // inline.
-    auto ordinal = sig->getGenericParamOrdinal(genericParam);
-    B.addInt32(ordinal << 1);
-    return;
-  }
-
-  if (auto dmt = dyn_cast<DependentMemberType>(type)) {
-    // We have to encode the associated type path out-of-line.
-    auto assocTypeRecord = IGM.getAddrOfAssociatedTypeGenericParamRef(sig, dmt);
-
-    B.addTaggedRelativeOffset(IGM.Int32Ty, assocTypeRecord, 1);
-    return;
-  }
-
-  llvm_unreachable("not a generic parameter");
-}
-
 /// Add a generic requirement to the given constant struct builder.
 static void addGenericRequirement(IRGenModule &IGM, ConstantStructBuilder &B,
                                   GenericRequirementsMetadata &metadata,
@@ -4141,7 +4116,9 @@
     ++metadata.NumGenericExtraArguments;
 
   B.addInt(IGM.Int32Ty, flags.getIntValue());
-  addGenericParamRef(IGM, B, sig, paramType->getCanonicalType());
+  auto typeName =
+    IGM.getTypeRef(paramType->getCanonicalType(), MangledTypeRefRole::Metadata);
+  B.addRelativeAddress(typeName);
   addReference();
 }
 
diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp
index 6394035..2cedbaa 100644
--- a/lib/IRGen/GenObjC.cpp
+++ b/lib/IRGen/GenObjC.cpp
@@ -262,39 +262,6 @@
     ReferenceCounting getReferenceCounting() const {
       return ReferenceCounting::Bridge;
     }
-    
-    // BridgeObject exposes only null as an extra inhabitant for enum layout.
-    // Other representations are reserved for future use by the stdlib.
-    
-    bool mayHaveExtraInhabitants(IRGenModule &IGM) const override {
-      return true;
-    }
-    unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override {
-      return 1;
-    }
-    APInt getFixedExtraInhabitantValue(IRGenModule &IGM,
-                                       unsigned bits,
-                                       unsigned index) const override {
-      return APInt(bits, 0);
-    }
-    llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src,
-                                         SILType T,
-                                         bool isOutlined) const override {
-      src = IGF.Builder.CreateBitCast(src, IGF.IGM.SizeTy->getPointerTo());
-      auto val = IGF.Builder.CreateLoad(src);
-      auto isNonzero = IGF.Builder.CreateICmpNE(val,
-                                    llvm::ConstantInt::get(IGF.IGM.SizeTy, 0));
-      // We either have extra inhabitant 0 or no extra inhabitant (-1).
-      // Conveniently, this is just a sext i1 -> i32 away.
-      return IGF.Builder.CreateSExt(isNonzero, IGF.IGM.Int32Ty);
-    }
-    void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index,
-                              Address dest, SILType T, bool isOutlined)
-    const override {
-      // There's only one extra inhabitant, 0.
-      dest = IGF.Builder.CreateBitCast(dest, IGF.IGM.SizeTy->getPointerTo());
-      IGF.Builder.CreateStore(llvm::ConstantInt::get(IGF.IGM.SizeTy, 0), dest);
-    }
   };
 } // end anonymous namespace
 
@@ -959,12 +926,12 @@
 
 /// Create the LLVM function declaration for a thunk that acts like
 /// an Objective-C method for a Swift method implementation.
-static llvm::Constant *findSwiftAsObjCThunk(IRGenModule &IGM, SILDeclRef ref) {
-  SILFunction *SILFn = IGM.getSILModule().lookUpFunction(ref);
+static llvm::Constant *findSwiftAsObjCThunk(IRGenModule &IGM, SILDeclRef ref,
+                                            SILFunction *&SILFn) {
+  SILFn = IGM.getSILModule().lookUpFunction(ref);
   assert(SILFn && "no IR function for swift-as-objc thunk");
   auto fn = IGM.getAddrOfSILFunction(SILFn, NotForDefinition);
-  fn->setVisibility(llvm::GlobalValue::DefaultVisibility);
-  fn->setLinkage(llvm::GlobalValue::InternalLinkage);
+  ApplyIRLinkage(IRLinkage::Internal).to(fn);
   fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
   return llvm::ConstantExpr::getBitCast(fn, IGM.Int8PtrTy);
@@ -975,7 +942,8 @@
 ///
 /// Returns a value of type i8*.
 static llvm::Constant *getObjCGetterPointer(IRGenModule &IGM,
-                                            AbstractStorageDecl *property) {
+                                            AbstractStorageDecl *property,
+                                            SILFunction *&silFn) {
   // Protocol properties have no impl.
   if (isa<ProtocolDecl>(property->getDeclContext()))
     return llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
@@ -983,7 +951,7 @@
   SILDeclRef getter = SILDeclRef(property->getGetter(), SILDeclRef::Kind::Func)
     .asForeign();
 
-  return findSwiftAsObjCThunk(IGM, getter);
+  return findSwiftAsObjCThunk(IGM, getter, silFn);
 }
 
 /// Produce a function pointer, suitable for invocation by
@@ -991,7 +959,8 @@
 ///
 /// Returns a value of type i8*.
 static llvm::Constant *getObjCSetterPointer(IRGenModule &IGM,
-                                            AbstractStorageDecl *property) {
+                                            AbstractStorageDecl *property,
+                                            SILFunction *&silFn) {
   // Protocol properties have no impl.
   if (isa<ProtocolDecl>(property->getDeclContext()))
     return llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
@@ -1001,8 +970,7 @@
   
   SILDeclRef setter = SILDeclRef(property->getSetter(), SILDeclRef::Kind::Func)
     .asForeign();
-
-  return findSwiftAsObjCThunk(IGM, setter);
+  return findSwiftAsObjCThunk(IGM, setter, silFn);
 }
 
 /// Produce a function pointer, suitable for invocation by
@@ -1010,7 +978,8 @@
 ///
 /// Returns a value of type i8*.
 static llvm::Constant *getObjCMethodPointer(IRGenModule &IGM,
-                                            FuncDecl *method) {
+                                            FuncDecl *method,
+                                            SILFunction *&silFn) {
   // Protocol methods have no impl.
   if (isa<ProtocolDecl>(method->getDeclContext()))
     return llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
@@ -1018,7 +987,7 @@
   SILDeclRef declRef = SILDeclRef(method, SILDeclRef::Kind::Func)
     .asForeign();
 
-  return findSwiftAsObjCThunk(IGM, declRef);
+  return findSwiftAsObjCThunk(IGM, declRef, silFn);
 }
 
 /// Produce a function pointer, suitable for invocation by
@@ -1026,7 +995,8 @@
 ///
 /// Returns a value of type i8*.
 static llvm::Constant *getObjCMethodPointer(IRGenModule &IGM,
-                                            ConstructorDecl *constructor) {
+                                            ConstructorDecl *constructor,
+                                            SILFunction *&silFn) {
   // Protocol methods have no impl.
   if (isa<ProtocolDecl>(constructor->getDeclContext()))
     return llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
@@ -1034,7 +1004,7 @@
   SILDeclRef declRef = SILDeclRef(constructor, SILDeclRef::Kind::Initializer)
     .asForeign();
 
-  return findSwiftAsObjCThunk(IGM, declRef);
+  return findSwiftAsObjCThunk(IGM, declRef, silFn);
 }
 
 /// Produce a function pointer, suitable for invocation by
@@ -1042,11 +1012,12 @@
 ///
 /// Returns a value of type i8*.
 static llvm::Constant *getObjCMethodPointer(IRGenModule &IGM,
-                                            DestructorDecl *destructor) {
+                                            DestructorDecl *destructor,
+                                            SILFunction *&silFn) {
   SILDeclRef declRef = SILDeclRef(destructor, SILDeclRef::Kind::Deallocator)
     .asForeign();
 
-  return findSwiftAsObjCThunk(IGM, declRef);
+  return findSwiftAsObjCThunk(IGM, declRef, silFn);
 }
 
 static SILDeclRef getObjCMethodRef(AbstractFunctionDecl *method) {
@@ -1151,13 +1122,13 @@
 
 /// Emit the components of an Objective-C method descriptor: its selector,
 /// type encoding, and IMP pointer.
-void irgen::emitObjCMethodDescriptorParts(IRGenModule &IGM,
-                                          AbstractFunctionDecl *method,
-                                          bool extendedEncoding,
-                                          bool concrete,
-                                          llvm::Constant *&selectorRef,
-                                          llvm::Constant *&atEncoding,
-                                          llvm::Constant *&impl) {
+SILFunction *irgen::emitObjCMethodDescriptorParts(IRGenModule &IGM,
+                                                  AbstractFunctionDecl *method,
+                                                  bool extendedEncoding,
+                                                  bool concrete,
+                                                  llvm::Constant *&selectorRef,
+                                                  llvm::Constant *&atEncoding,
+                                                  llvm::Constant *&impl) {
   Selector selector(method);
   
   /// The first element is the selector.
@@ -1172,31 +1143,32 @@
   /// The third element is the method implementation pointer.
   if (!concrete) {
     impl = nullptr;
-    return;
+    return nullptr;
   }
-  
+  SILFunction *silFn = nullptr;
   if (auto func = dyn_cast<FuncDecl>(method))
-    impl = getObjCMethodPointer(IGM, func);
+    impl = getObjCMethodPointer(IGM, func, silFn);
   else if (auto ctor = dyn_cast<ConstructorDecl>(method))
-    impl = getObjCMethodPointer(IGM, ctor);
+    impl = getObjCMethodPointer(IGM, ctor, silFn);
   else
-    impl = getObjCMethodPointer(IGM, cast<DestructorDecl>(method));
+    impl = getObjCMethodPointer(IGM, cast<DestructorDecl>(method), silFn);
+  return silFn;
 }
 
 /// Emit the components of an Objective-C method descriptor for a
 /// property getter method.
-void irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
-                                          VarDecl *property,
-                                          llvm::Constant *&selectorRef,
-                                          llvm::Constant *&atEncoding,
-                                          llvm::Constant *&impl) {
+SILFunction *irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
+                                                  VarDecl *property,
+                                                  llvm::Constant *&selectorRef,
+                                                  llvm::Constant *&atEncoding,
+                                                  llvm::Constant *&impl) {
   Selector getterSel(property, Selector::ForGetter);
   selectorRef = IGM.getAddrOfObjCMethodName(getterSel.str());
   
   auto clangType = getObjCPropertyType(IGM, property);
   if (clangType.isNull()) {
     atEncoding = llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
-    return;
+    return nullptr;
   }
 
   auto &clangASTContext = IGM.getClangASTContext();
@@ -1210,27 +1182,31 @@
   TypeStr += "@0:";
   TypeStr += llvm::itostr(PtrSize.getValue());
   atEncoding = IGM.getAddrOfGlobalString(TypeStr.c_str());
-  impl = getObjCGetterPointer(IGM, property);
+  SILFunction *silFn = nullptr;
+  impl = getObjCGetterPointer(IGM, property, silFn);
+  return silFn;
 }
 
 /// Emit the components of an Objective-C method descriptor for a
 /// subscript getter method.
-void irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
-                                          SubscriptDecl *subscript,
-                                          llvm::Constant *&selectorRef,
-                                          llvm::Constant *&atEncoding,
-                                          llvm::Constant *&impl) {
+SILFunction *irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
+                                                  SubscriptDecl *subscript,
+                                                  llvm::Constant *&selectorRef,
+                                                  llvm::Constant *&atEncoding,
+                                                  llvm::Constant *&impl) {
   Selector getterSel(subscript, Selector::ForGetter);
   selectorRef = IGM.getAddrOfObjCMethodName(getterSel.str());
   atEncoding = llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
-  impl = getObjCGetterPointer(IGM, subscript);
+  SILFunction *silFn = nullptr;
+  impl = getObjCGetterPointer(IGM, subscript, silFn);
+  return silFn;
 }
 
-void irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
-                                          AbstractStorageDecl *decl,
-                                          llvm::Constant *&selectorRef,
-                                          llvm::Constant *&atEncoding,
-                                          llvm::Constant *&impl) {
+SILFunction *irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM,
+                                                  AbstractStorageDecl *decl,
+                                                  llvm::Constant *&selectorRef,
+                                                  llvm::Constant *&atEncoding,
+                                                  llvm::Constant *&impl) {
   if (auto sub = dyn_cast<SubscriptDecl>(decl)) {
     return emitObjCGetterDescriptorParts(IGM, sub,
                                          selectorRef, atEncoding, impl);
@@ -1240,15 +1216,16 @@
                                          selectorRef, atEncoding, impl);
   }
   llvm_unreachable("unknown storage!");
+  return nullptr;
 }
 
 /// Emit the components of an Objective-C method descriptor for a
 /// property getter method.
-void irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,
-                                          VarDecl *property,
-                                          llvm::Constant *&selectorRef,
-                                          llvm::Constant *&atEncoding,
-                                          llvm::Constant *&impl) {
+SILFunction *irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,
+                                                  VarDecl *property,
+                                                  llvm::Constant *&selectorRef,
+                                                  llvm::Constant *&atEncoding,
+                                                  llvm::Constant *&impl) {
   assert(property->isSettable(property->getDeclContext()) &&
          "not a settable property?!");
 
@@ -1266,7 +1243,7 @@
   clangType = getObjCPropertyType(IGM, property);
   if (clangType.isNull()) {
     atEncoding = llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
-    return;
+    return nullptr;
   }
   clang::CharUnits sz = clangASTContext.getObjCEncodingTypeSize(clangType);
   if (!sz.isZero())
@@ -1278,30 +1255,33 @@
   clangASTContext.getObjCEncodingForType(clangType, TypeStr);
   TypeStr += llvm::itostr(ParmOffset);
   atEncoding = IGM.getAddrOfGlobalString(TypeStr.c_str());
-
-  impl = getObjCSetterPointer(IGM, property);
+  SILFunction *silFn = nullptr;
+  impl = getObjCSetterPointer(IGM, property, silFn);
+  return silFn;
 }
 
 /// Emit the components of an Objective-C method descriptor for a
 /// subscript getter method.
-void irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,
-                                          SubscriptDecl *subscript,
-                                          llvm::Constant *&selectorRef,
-                                          llvm::Constant *&atEncoding,
-                                          llvm::Constant *&impl) {
+SILFunction *irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,
+                                                  SubscriptDecl *subscript,
+                                                  llvm::Constant *&selectorRef,
+                                                  llvm::Constant *&atEncoding,
+                                                  llvm::Constant *&impl) {
   assert(subscript->isSettable() && "not a settable subscript?!");
 
   Selector setterSel(subscript, Selector::ForSetter);
   selectorRef = IGM.getAddrOfObjCMethodName(setterSel.str());
   atEncoding = llvm::ConstantPointerNull::get(IGM.Int8PtrTy);
-  impl = getObjCSetterPointer(IGM, subscript);
+  SILFunction *silFn = nullptr;
+  impl = getObjCSetterPointer(IGM, subscript, silFn);
+  return silFn;
 }
 
-void irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,
-                                          AbstractStorageDecl *decl,
-                                          llvm::Constant *&selectorRef,
-                                          llvm::Constant *&atEncoding,
-                                          llvm::Constant *&impl) {
+SILFunction *irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM,
+                                                  AbstractStorageDecl *decl,
+                                                  llvm::Constant *&selectorRef,
+                                                  llvm::Constant *&atEncoding,
+                                                  llvm::Constant *&impl) {
   if (auto sub = dyn_cast<SubscriptDecl>(decl)) {
     return emitObjCSetterDescriptorParts(IGM, sub,
                                          selectorRef, atEncoding, impl);
@@ -1311,6 +1291,7 @@
                                          selectorRef, atEncoding, impl);
   }
   llvm_unreachable("unknown storage!");
+  return nullptr;
 }
 
 static void buildMethodDescriptor(ConstantArrayBuilder &descriptors,
@@ -1334,11 +1315,17 @@
                                      ConstantArrayBuilder &descriptors,
                                      AbstractFunctionDecl *method) {
   llvm::Constant *selectorRef, *atEncoding, *impl;
-  emitObjCMethodDescriptorParts(IGM, method,
+  auto silFn = emitObjCMethodDescriptorParts(IGM, method,
                                 /*extended*/ false,
                                 /*concrete*/ true,
                                 selectorRef, atEncoding, impl);
   buildMethodDescriptor(descriptors, selectorRef, atEncoding, impl);
+
+  if (silFn && silFn->hasObjCReplacement()) {
+    auto replacedSelector =
+        IGM.getAddrOfObjCMethodName(silFn->getObjCReplacement().str());
+    buildMethodDescriptor(descriptors, replacedSelector, atEncoding, impl);
+  }
 }
 
 void irgen::emitObjCIVarInitDestroyDescriptor(IRGenModule &IGM,
@@ -1395,18 +1382,28 @@
                                      ConstantArrayBuilder &descriptors,
                                      AbstractStorageDecl *storage) {
   llvm::Constant *selectorRef, *atEncoding, *impl;
-  emitObjCGetterDescriptorParts(IGM, storage,
-                                selectorRef, atEncoding, impl);
+  auto *silFn = emitObjCGetterDescriptorParts(IGM, storage, selectorRef,
+                                              atEncoding, impl);
   buildMethodDescriptor(descriptors, selectorRef, atEncoding, impl);
+  if (silFn && silFn->hasObjCReplacement()) {
+    auto replacedSelector =
+        IGM.getAddrOfObjCMethodName(silFn->getObjCReplacement().str());
+    buildMethodDescriptor(descriptors, replacedSelector, atEncoding, impl);
+  }
 }
 
 void irgen::emitObjCSetterDescriptor(IRGenModule &IGM,
                                      ConstantArrayBuilder &descriptors,
                                      AbstractStorageDecl *storage) {
   llvm::Constant *selectorRef, *atEncoding, *impl;
-  emitObjCSetterDescriptorParts(IGM, storage,
-                                selectorRef, atEncoding, impl);
+  auto *silFn = emitObjCSetterDescriptorParts(IGM, storage, selectorRef,
+                                              atEncoding, impl);
   buildMethodDescriptor(descriptors, selectorRef, atEncoding, impl);
+  if (silFn && silFn->hasObjCReplacement()) {
+    auto replacedSelector =
+        IGM.getAddrOfObjCMethodName(silFn->getObjCReplacement().str());
+    buildMethodDescriptor(descriptors, replacedSelector, atEncoding, impl);
+  }
 }
 
 bool irgen::requiresObjCMethodDescriptor(FuncDecl *method) {
diff --git a/lib/IRGen/GenObjC.h b/lib/IRGen/GenObjC.h
index b5f8e8f..6f00b50 100644
--- a/lib/IRGen/GenObjC.h
+++ b/lib/IRGen/GenObjC.h
@@ -107,57 +107,57 @@
 
   /// Build the components of an Objective-C method descriptor for the given
   /// method or constructor implementation.
-  void emitObjCMethodDescriptorParts(IRGenModule &IGM,
-                                     AbstractFunctionDecl *method,
-                                     bool extendedEncoding,
-                                     bool concrete,
-                                     llvm::Constant *&selectorRef,
-                                     llvm::Constant *&atEncoding,
-                                     llvm::Constant *&impl);
+  SILFunction *emitObjCMethodDescriptorParts(IRGenModule &IGM,
+                                             AbstractFunctionDecl *method,
+                                             bool extendedEncoding,
+                                             bool concrete,
+                                             llvm::Constant *&selectorRef,
+                                             llvm::Constant *&atEncoding,
+                                             llvm::Constant *&impl);
 
   /// Build the components of an Objective-C method descriptor for the given
   /// property's method implementations.
-  void emitObjCGetterDescriptorParts(IRGenModule &IGM,
-                                     VarDecl *property,
-                                     llvm::Constant *&selectorRef,
-                                     llvm::Constant *&atEncoding,
-                                     llvm::Constant *&impl);
+  SILFunction *emitObjCGetterDescriptorParts(IRGenModule &IGM,
+                                             VarDecl *property,
+                                             llvm::Constant *&selectorRef,
+                                             llvm::Constant *&atEncoding,
+                                             llvm::Constant *&impl);
 
   /// Build the components of an Objective-C method descriptor for the given
   /// subscript's method implementations.
-  void emitObjCGetterDescriptorParts(IRGenModule &IGM,
-                                     SubscriptDecl *subscript,
-                                     llvm::Constant *&selectorRef,
-                                     llvm::Constant *&atEncoding,
-                                     llvm::Constant *&impl);
+  SILFunction *emitObjCGetterDescriptorParts(IRGenModule &IGM,
+                                             SubscriptDecl *subscript,
+                                             llvm::Constant *&selectorRef,
+                                             llvm::Constant *&atEncoding,
+                                             llvm::Constant *&impl);
 
-  void emitObjCGetterDescriptorParts(IRGenModule &IGM,
-                                     AbstractStorageDecl *subscript,
-                                     llvm::Constant *&selectorRef,
-                                     llvm::Constant *&atEncoding,
-                                     llvm::Constant *&impl);
+  SILFunction *emitObjCGetterDescriptorParts(IRGenModule &IGM,
+                                             AbstractStorageDecl *subscript,
+                                             llvm::Constant *&selectorRef,
+                                             llvm::Constant *&atEncoding,
+                                             llvm::Constant *&impl);
 
   /// Build the components of an Objective-C method descriptor for the given
   /// property's method implementations.
-  void emitObjCSetterDescriptorParts(IRGenModule &IGM,
-                                     VarDecl *property,
-                                     llvm::Constant *&selectorRef,
-                                     llvm::Constant *&atEncoding,
-                                     llvm::Constant *&impl);
+  SILFunction *emitObjCSetterDescriptorParts(IRGenModule &IGM,
+                                             VarDecl *property,
+                                             llvm::Constant *&selectorRef,
+                                             llvm::Constant *&atEncoding,
+                                             llvm::Constant *&impl);
 
   /// Build the components of an Objective-C method descriptor for the given
   /// subscript's method implementations.
-  void emitObjCSetterDescriptorParts(IRGenModule &IGM,
-                                     SubscriptDecl *subscript,
-                                     llvm::Constant *&selectorRef,
-                                     llvm::Constant *&atEncoding,
-                                     llvm::Constant *&impl);
+  SILFunction *emitObjCSetterDescriptorParts(IRGenModule &IGM,
+                                             SubscriptDecl *subscript,
+                                             llvm::Constant *&selectorRef,
+                                             llvm::Constant *&atEncoding,
+                                             llvm::Constant *&impl);
 
-  void emitObjCSetterDescriptorParts(IRGenModule &IGM,
-                                     AbstractStorageDecl *subscript,
-                                     llvm::Constant *&selectorRef,
-                                     llvm::Constant *&atEncoding,
-                                     llvm::Constant *&impl);
+  SILFunction *emitObjCSetterDescriptorParts(IRGenModule &IGM,
+                                             AbstractStorageDecl *subscript,
+                                             llvm::Constant *&selectorRef,
+                                             llvm::Constant *&atEncoding,
+                                             llvm::Constant *&impl);
 
   /// Build an Objective-C method descriptor for the given method,
   /// constructor, or destructor implementation.
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index f70e4f9..06595be 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -986,26 +986,32 @@
   return false;
 }
 
-/// Is there anything about the given conformance that requires witness
-/// tables to be dependently-generated?
-bool irgen::isDependentConformance(const NormalProtocolConformance *conformance) {
+static bool isDependentConformance(
+              const NormalProtocolConformance *conformance,
+              llvm::SmallPtrSet<const NormalProtocolConformance *, 4> &visited){
+  if (!visited.insert(conformance).second)
+    return false;
+
   // If the conformance is resilient, this is always true.
   if (isResilientConformance(conformance))
     return true;
 
-  // Check whether any of the inherited conformances are dependent.
+  // Check whether any of the conformances are dependent.
   auto proto = conformance->getProtocol();
   for (const auto &req : proto->getRequirementSignature()) {
-    if (req.getKind() != RequirementKind::Conformance ||
-        !req.getFirstType()->isEqual(proto->getSelfInterfaceType()))
+    if (req.getKind() != RequirementKind::Conformance)
       continue;
 
-    auto inherited = req.getSecondType()->castTo<ProtocolType>()->getDecl();
-    if (inherited->isObjC())
+    auto assocProtocol = req.getSecondType()->castTo<ProtocolType>()->getDecl();
+    if (assocProtocol->isObjC())
       continue;
 
-    if (isDependentConformance(conformance->getInheritedConformance(inherited)
-                                 ->getRootNormalConformance()))
+    auto assocConformance =
+      conformance->getAssociatedConformance(req.getFirstType(), assocProtocol);
+    if (assocConformance.isAbstract() ||
+        isDependentConformance(assocConformance.getConcrete()
+                                 ->getRootNormalConformance(),
+                               visited))
       return true;
   }
 
@@ -1018,6 +1024,14 @@
       conformance, [](unsigned, CanType, ProtocolDecl *) { return true; });
 }
 
+/// Is there anything about the given conformance that requires witness
+/// tables to be dependently-generated?
+bool irgen::isDependentConformance(
+                                const NormalProtocolConformance *conformance) {
+  llvm::SmallPtrSet<const NormalProtocolConformance *, 4> visited;
+  return ::isDependentConformance(conformance, visited);
+}
+
 static llvm::Value *
 emitConditionalConformancesBuffer(IRGenFunction &IGF,
                                   const ProtocolConformance *conformance) {
@@ -1393,6 +1407,8 @@
           requirement.getAssociation(),
           requirement.getAssociatedRequirement());
 
+      if (requirement.getAssociation()->hasTypeParameter())
+        RequiresSpecialization = true;
 
 #ifndef NDEBUG
       assert(entry.getKind() == SILWitnessTable::AssociatedTypeProtocol
@@ -1409,11 +1425,10 @@
              "offset doesn't match ProtocolInfo layout");
 #endif
 
-      llvm::Constant *wtableAccessFunction =
-        getAssociatedTypeWitnessTableAccessFunction(requirement,
-                                                    associate,
-                                                    associatedConformance);
-      Table.addBitCast(wtableAccessFunction, IGM.Int8PtrTy);
+      llvm::Constant *witnessEntry =
+        getAssociatedConformanceWitness(requirement, associate,
+                                        associatedConformance);
+      Table.addBitCast(witnessEntry, IGM.Int8PtrTy);
     }
 
     /// Build the instantiation function that runs at the end of witness
@@ -1432,16 +1447,15 @@
       }
     }
 
-    llvm::Constant *
-    getAssociatedTypeWitnessTableAccessFunction(
+    void defineAssociatedTypeWitnessTableAccessFunction(
                                         AssociatedConformance requirement,
                                         CanType associatedType,
                                         ProtocolConformanceRef conformance);
 
-    void emitReturnOfCheckedLoadFromCache(IRGenFunction &IGF,
-                                          Address destTable,
-                                          llvm::Value *selfMetadata,
-                                   llvm::function_ref<MetadataResponse()> body);
+    llvm::Constant *getAssociatedConformanceWitness(
+                                    AssociatedConformance requirement,
+                                    CanType associatedType,
+                                    ProtocolConformanceRef conformance);
 
     /// Allocate another word of private data storage in the conformance table.
     unsigned getNextPrivateDataIndex() {
@@ -1524,27 +1538,6 @@
   return llvm::ConstantExpr::getIntToPtr(witness, Int8PtrTy);
 }
 
-/// Return a function which will return a particular witness table
-/// conformance.  The function will be passed the metadata for which
-/// the conformance is being requested; it may ignore this (perhaps
-/// implicitly by taking no arguments).
-static llvm::Constant *
-getOrCreateWitnessTableAccessFunction(IRGenModule &IGM,
-                                      ProtocolConformance *conformance) {
-  assert(!conformance->getType()->hasArchetype() &&
-         "cannot do this for dependent type");
-
-  // We always emit an access function for conformances, and in principle
-  // it is always possible to just use that here directly.  However,
-  // if it's dependent, doing so won't allow us to cache the result.
-  // For the specific use case of an associated type conformance, we could
-  // use a cache in the witness table; but that wastes space per conformance
-  // and won't let us re-use the cache with other non-dependent uses in
-  // the module.  Therefore, in this case, we use the address of the lazy-cache
-  // function.
-  return getWitnessTableLazyAccessFunction(IGM, conformance);
-}
-
 static void buildAssociatedTypeValueName(CanType depAssociatedType,
                                          SmallString<128> &name) {
   if (auto memberType = dyn_cast<DependentMemberType>(depAssociatedType)) {
@@ -1556,19 +1549,22 @@
   }
 }
 
-llvm::Constant *WitnessTableBuilder::
-getAssociatedTypeWitnessTableAccessFunction(AssociatedConformance requirement,
-                                            CanType associatedType,
+llvm::Constant *WitnessTableBuilder::getAssociatedConformanceWitness(
+                                AssociatedConformance requirement,
+                                CanType associatedType,
+                                ProtocolConformanceRef conformance) {
+  defineAssociatedTypeWitnessTableAccessFunction(requirement, associatedType,
+                                                 conformance);
+  return IGM.getMangledAssociatedConformance(&Conformance, requirement);
+}
+
+void WitnessTableBuilder::defineAssociatedTypeWitnessTableAccessFunction(
+                                AssociatedConformance requirement,
+                                CanType associatedType,
                                 ProtocolConformanceRef associatedConformance) {
   bool hasArchetype = associatedType->hasArchetype();
-  if (!hasArchetype && !ResilientConformance) {
-    assert(associatedConformance.isConcrete() &&
-           "no concrete conformance for non-dependent type");
-    return getOrCreateWitnessTableAccessFunction(IGM,
-                                          associatedConformance.getConcrete());
-  }
 
-  // Otherwise, emit an access function.
+  // Emit an access function.
   llvm::Function *accessor =
     IGM.getAddrOfAssociatedTypeWitnessTableAccessFunction(&Conformance,
                                                           requirement);
@@ -1610,24 +1606,18 @@
                                            associatedConformance.getConcrete());
 
     // If we can emit a constant table, do so.
-    // In principle, any time we can do this, we should try to re-use this
-    // function for other conformances.  But that should typically already
-    // be covered by the !hasArchetype() check above.
     if (auto constantTable =
           conformanceI->tryGetConstantTable(IGM, associatedType)) {
       IGF.Builder.CreateRet(constantTable);
-      return accessor;
+      return;
     }
   }
 
-  // If there are no archetypes, return a reference to the table. There is
-  // no need for a cache.
+  // If there are no archetypes, return a reference to the table.
   if (!hasArchetype) {
-    auto wtable = MetadataResponse::forComplete(
-                    conformanceI->getTable(IGF, &associatedTypeMetadata))
-        .getMetadata();
+    auto wtable = conformanceI->getTable(IGF, &associatedTypeMetadata);
     IGF.Builder.CreateRet(wtable);
-    return accessor;
+    return;
   }
 
   IGF.bindLocalTypeDataFromSelfWitnessTable(
@@ -1638,10 +1628,7 @@
                    ->getCanonicalType();
         });
 
-  // If the witness table is directly fulfillable from the type,
-  // we don't need a cache entry.
-  // TODO: maybe we should have a cache entry anyway if the fulfillment
-  // is expensive.
+  // If the witness table is directly fulfillable from the type, do so.
   if (auto fulfillment =
         getFulfillmentMap().getWitnessTable(associatedType,
                                             associatedProtocol)) {
@@ -1654,7 +1641,7 @@
                                                /*cache*/ nullptr)
                        .getMetadata();
     IGF.Builder.CreateRet(wtable);
-    return accessor;
+    return;
   }
 
   // Bind local type data from the metadata arguments.
@@ -1664,8 +1651,7 @@
   IGF.bindLocalTypeDataFromTypeMetadata(ConcreteType, IsExact, self,
                                         MetadataState::Abstract);
 
-  // For now, assume that finding an abstract conformance is always
-  // fast enough that it's not worth caching.
+  // Find abstract conformances.
   // TODO: provide an API to find the best metadata path to the conformance
   // and decide whether it's expensive enough to be worth caching.
   if (!conformanceI) {
@@ -1674,123 +1660,12 @@
       emitArchetypeWitnessTableRef(IGF, cast<ArchetypeType>(associatedType),
                                    associatedConformance.getAbstract());
     IGF.Builder.CreateRet(wtable);
-    return accessor;
+    return;
   }
 
-  // Otherwise, we need a cache entry.
-  emitReturnOfCheckedLoadFromCache(IGF, destTable, self,
-                                   [&]() -> MetadataResponse {
-    // Pretend that we have a response here.
-    return MetadataResponse::forComplete(
-             conformanceI->getTable(IGF, &associatedTypeMetadata));
-  });
-
-  return accessor;
-}
-
-void WitnessTableBuilder::
-emitReturnOfCheckedLoadFromCache(IRGenFunction &IGF, Address destTable,
-                                 llvm::Value *selfMetadata,
-                                 llvm::function_ref<MetadataResponse()> body) {
-  // Allocate a new cache slot and drill down to it.
-  auto cache =
-      getAddressOfPrivateDataSlot(IGF, destTable, getNextPrivateDataIndex());
-
-  llvm::Type *expectedTy = IGF.CurFn->getReturnType();
-
-  bool isReturningResponse = false;  
-  if (expectedTy == IGF.IGM.TypeMetadataResponseTy) {
-    isReturningResponse = true;
-    expectedTy = IGF.IGM.TypeMetadataPtrTy;
-  }
-  cache = IGF.Builder.CreateBitCast(cache, expectedTy->getPointerTo());
-
-  // Load and check whether it was null.
-  auto cachedResult = IGF.Builder.CreateLoad(cache);
-  // TODO: When LLVM supports Consume, we should use it here.
-  if (IGF.IGM.IRGen.Opts.Sanitizers & SanitizerKind::Thread)
-    cachedResult->setOrdering(llvm::AtomicOrdering::Acquire);
-  auto cacheIsEmpty = IGF.Builder.CreateIsNull(cachedResult);
-  llvm::BasicBlock *fetchBB = IGF.createBasicBlock("fetch");
-  llvm::BasicBlock *contBB = IGF.createBasicBlock("cont");
-  llvm::BasicBlock *entryBB = IGF.Builder.GetInsertBlock();
-  IGF.Builder.CreateCondBr(cacheIsEmpty, fetchBB, contBB);
-
-  unsigned expectedPHICount = (isReturningResponse ? 3 : 2);
-
-  // Create a phi in the continuation block and use the loaded value if
-  // we branched directly here.  Note that we arrange blocks so that we
-  // fall through into this.
-  IGF.Builder.emitBlock(contBB);
-  llvm::PHINode *result = IGF.Builder.CreatePHI(expectedTy, expectedPHICount);
-  result->addIncoming(cachedResult, entryBB);
-
-  llvm::Constant *completedState = nullptr;
-  llvm::PHINode *resultState = nullptr;
-  if (isReturningResponse) {
-    completedState = MetadataResponse::getCompletedState(IGF.IGM);
-
-    resultState = IGF.Builder.CreatePHI(IGF.IGM.SizeTy, expectedPHICount);
-    resultState->addIncoming(completedState, entryBB);
-
-    llvm::Value *returnValue =
-      MetadataResponse(result, resultState, MetadataState::Abstract)
-        .combine(IGF);
-    IGF.Builder.CreateRet(returnValue);
-  } else {
-    IGF.Builder.CreateRet(result);
-  }
-
-  // In the fetch block, evaluate the body.
-  IGF.Builder.emitBlock(fetchBB);
-  MetadataResponse response = body();
-
-  // The way we jam witness tables into this infrastructure involves
-  // pretending that they're statically-complete metadata.
-  assert(isReturningResponse || response.isStaticallyKnownComplete());
-
-  llvm::Value *fetchedState = nullptr;
-  if (isReturningResponse) {
-    response.ensureDynamicState(IGF);
-    fetchedState = response.getDynamicState();
-  }
-
-  llvm::Value *fetchedResult = response.getMetadata();
-
-  // Skip caching if we're working with responses and the fetched result
-  // is not complete.
-  if (isReturningResponse && !response.isStaticallyKnownComplete()) {
-    auto isCompleteBB = IGF.createBasicBlock("is_complete");
-    auto isComplete =
-      IGF.Builder.CreateICmpEQ(fetchedState, completedState);
-
-    auto fetchingBB = IGF.Builder.GetInsertBlock();
-    IGF.Builder.CreateCondBr(isComplete, isCompleteBB, contBB);
-    result->addIncoming(fetchedResult, fetchingBB);
-    resultState->addIncoming(fetchedState, fetchingBB);
-
-    IGF.Builder.emitBlock(isCompleteBB);
-
-  // If the fetched result is statically known to be complete, there is no
-  // patch which involves not returning the completed state, so destroy the
-  // PHI node we created for the state.
-  } else if (isReturningResponse) {
-    resultState->replaceAllUsesWith(completedState);
-    resultState->eraseFromParent();
-    resultState = nullptr;
-  }
-
-  // Store the fetched result back to the cache.
-  // We need to transitively ensure that any stores initializing the result
-  // that are visible to us are visible to callers.
-  IGF.Builder.CreateStore(fetchedResult, cache)->setOrdering(
-    llvm::AtomicOrdering::Release);
-
-  auto cachingBB = IGF.Builder.GetInsertBlock();
-  IGF.Builder.CreateBr(contBB);
-  result->addIncoming(fetchedResult, cachingBB);
-  if (resultState)
-    resultState->addIncoming(completedState, cachingBB);
+  // Handle concrete conformances involving archetypes.
+  auto wtable = conformanceI->getTable(IGF, &associatedTypeMetadata);
+  IGF.Builder.CreateRet(wtable);
 }
 
 void WitnessTableBuilder::collectResilientWitnesses(
@@ -1828,11 +1703,10 @@
                                         witness.Requirement,
                                         witness.Protocol);
 
-      llvm::Constant *wtableAccessFunction =
-        getAssociatedTypeWitnessTableAccessFunction(requirement,
-                                                    associate,
-                                                    associatedConformance);
-      resilientWitnesses.push_back(wtableAccessFunction);
+      llvm::Constant *witnessEntry =
+        getAssociatedConformanceWitness(requirement, associate,
+                                        associatedConformance);
+      resilientWitnesses.push_back(witnessEntry);
       continue;
     }
 
@@ -2244,14 +2118,14 @@
   for (const auto &entry : wt->getEntries()) {
     switch (entry.getKind()) {
     case SILWitnessTable::Invalid:
-    case SILWitnessTable::AssociatedTypeProtocol:
     case SILWitnessTable::BaseProtocol:
     case SILWitnessTable::Method:
       continue;
 
     case SILWitnessTable::AssociatedType:
-      // Associated types are cached in the witness table.
-      // FIXME: If we start emitting constant references to type metadata here,
+    case SILWitnessTable::AssociatedTypeProtocol:
+      // Associated types and conformances are cached in the witness table.
+      // FIXME: If we start emitting constant references to here,
       // we will need to ask the witness table builder for this information.
       return false;
     }
@@ -2295,7 +2169,7 @@
     isDependent
       ? getAddrOfWitnessTablePattern(conf, initializer)
       : getAddrOfWitnessTable(conf, initializer));
-  global->setConstant(isDependent || isConstantWitnessTable(wt));
+  global->setConstant(isConstantWitnessTable(wt));
   global->setAlignment(getWitnessTableAlignment().getValue());
 
   // Collect the information that will go into the protocol conformance
@@ -2505,39 +2379,20 @@
                                   AssociatedConformance conformance,
                                   llvm::Value *associatedTypeMetadata) {
   auto sourceProtocol = conformance.getSourceProtocol();
-  llvm::Value *witness;
-  if (IGF.IGM.isResilient(sourceProtocol, ResilienceExpansion::Maximal)) {
-    // For resilient protocols, use the associated conformance descriptor to
-    // determine the index.
-    auto assocConformanceDescriptor =
-      IGF.IGM.getAddrOfAssociatedConformanceDescriptor(conformance);
+  auto assocConformanceDescriptor =
+    IGF.IGM.getAddrOfAssociatedConformanceDescriptor(conformance);
+  auto baseDescriptor =
+    IGF.IGM.getAddrOfProtocolRequirementsBaseDescriptor(sourceProtocol);
 
-    auto index =
-      computeResilientWitnessTableIndex(IGF, sourceProtocol,
-                                        assocConformanceDescriptor);
-
-    witness = emitInvariantLoadOfOpaqueWitness(IGF, wtable, index);
-  } else {
-    // For non-resilient protocols, the index is a constant.
-    auto &pi = IGF.IGM.getProtocolInfo(sourceProtocol,
-                                       ProtocolInfoKind::RequirementSignature);
-
-    auto index = pi.getAssociatedConformanceIndex(conformance);
-    witness = emitInvariantLoadOfOpaqueWitness(IGF, wtable,
-                                               index.forProtocolWitnessTable());
-  }
-
-  // Cast the witness to the appropriate function type.
-  auto sig = IGF.IGM.getAssociatedTypeWitnessTableAccessFunctionSignature();
-  auto witnessTy = sig.getType();
-  witness = IGF.Builder.CreateBitCast(witness, witnessTy->getPointerTo());
-
-  FunctionPointer witnessFnPtr(witness, sig);
-
-  // Call the accessor.
-  auto call = IGF.Builder.CreateCall(witnessFnPtr,
-                            { associatedTypeMetadata, parentMetadata, wtable });
-
+  auto call =
+    IGF.Builder.CreateCall(IGF.IGM.getGetAssociatedConformanceWitnessFn(),
+                           {
+                             wtable, parentMetadata,
+                             associatedTypeMetadata,
+                             baseDescriptor, assocConformanceDescriptor
+                           });
+  call->setDoesNotThrow();
+  call->setDoesNotAccessMemory();
   return call;
 }
 
diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp
index a89284c..bd97e1e 100644
--- a/lib/IRGen/GenReflection.cpp
+++ b/lib/IRGen/GenReflection.cpp
@@ -185,6 +185,74 @@
   return getAddrOfStringForTypeRef(SymbolicName, role);
 }
 
+llvm::Constant *IRGenModule::getMangledAssociatedConformance(
+                                  const NormalProtocolConformance *conformance,
+                                  const AssociatedConformance &requirement) {
+  // Figure out the name of the symbol to be used for the conformance.
+  IRGenMangler mangler;
+  auto symbolName =
+    mangler.mangleSymbolNameForAssociatedConformanceWitness(
+      conformance, requirement.getAssociation(),
+      requirement.getAssociatedRequirement());
+
+  // See if we emitted the constant already.
+  auto &entry = StringsForTypeRef[symbolName];
+  if (entry.second) {
+    return entry.second;
+  }
+
+  // Get the accessor for this associated conformance.
+  llvm::Function *accessor;
+  unsigned char kind;
+  if (conformance) {
+    kind = 7;
+    accessor = getAddrOfAssociatedTypeWitnessTableAccessFunction(conformance,
+                                                                requirement);
+  } else {
+    kind = 8;
+    accessor = getAddrOfDefaultAssociatedConformanceAccessor(requirement);
+  }
+
+  // Form the mangled name with its relative reference.
+  ConstantInitBuilder B(*this);
+  auto S = B.beginStruct();
+  S.setPacked(true);
+  S.add(llvm::ConstantInt::get(Int8Ty, kind));
+  S.addRelativeAddress(accessor);
+
+  // And a null terminator!
+  S.addInt(Int8Ty, 0);
+
+  auto finished = S.finishAndCreateFuture();
+  auto var = new llvm::GlobalVariable(Module, finished.getType(),
+                                      /*constant*/ true,
+                                      llvm::GlobalValue::LinkOnceODRLinkage,
+                                      nullptr,
+                                      symbolName);
+  ApplyIRLinkage({llvm::GlobalValue::LinkOnceODRLinkage,
+                  llvm::GlobalValue::HiddenVisibility,
+                  llvm::GlobalValue::DefaultStorageClass})
+      .to(var);
+  var->setAlignment(2);
+  setTrueConstGlobal(var);
+  var->setSection(getReflectionTypeRefSectionName());
+
+  finished.installInGlobal(var);
+
+  // Drill down to the i8* at the beginning of the constant.
+  auto addr = llvm::ConstantExpr::getBitCast(var, Int8PtrTy);
+
+  // Set the low bit.
+  unsigned bit = ProtocolRequirementFlags::AssociatedTypeMangledNameBit;
+  auto bitConstant = llvm::ConstantInt::get(IntPtrTy, bit);
+  addr = llvm::ConstantExpr::getGetElementPtr(nullptr, addr, bitConstant);
+
+  // Update the entry.
+  entry = {var, addr};
+
+  return addr;
+}
+
 class ReflectionMetadataBuilder {
 protected:
   IRGenModule &IGM;
@@ -426,11 +494,11 @@
   }
 
   void layoutProtocol() {
-    auto protocolDecl = cast<ProtocolDecl>(NTD);
+    auto PD = cast<ProtocolDecl>(NTD);
     FieldDescriptorKind Kind;
-    if (protocolDecl->isObjC())
+    if (PD->isObjC())
       Kind = FieldDescriptorKind::ObjCProtocol;
-    else if (protocolDecl->requiresClass())
+    else if (PD->requiresClass())
       Kind = FieldDescriptorKind::ClassProtocol;
     else
       Kind = FieldDescriptorKind::Protocol;
@@ -446,8 +514,11 @@
     addNominalRef(NTD);
 
     auto *CD = dyn_cast<ClassDecl>(NTD);
+    auto *PD = dyn_cast<ProtocolDecl>(NTD);
     if (CD && CD->getSuperclass()) {
       addTypeRef(CD->getSuperclass()->getCanonicalType());
+    } else if (PD && PD->getDeclaredType()->getSuperclass()) {
+      addTypeRef(PD->getDeclaredType()->getSuperclass()->getCanonicalType());
     } else {
       B.addInt32(0);
     }
@@ -515,7 +586,13 @@
     addTypeRef(type);
 
     B.addInt32(ti->getFixedSize().getValue());
-    B.addInt32(ti->getFixedAlignment().getValue());
+
+    auto alignment = ti->getFixedAlignment().getValue();
+    unsigned bitwiseTakable =
+      (ti->isBitwiseTakable(ResilienceExpansion::Minimal) == IsBitwiseTakable
+       ? 1 : 0);
+    B.addInt32(alignment | (bitwiseTakable << 16));
+
     B.addInt32(ti->getFixedStride().getValue());
     B.addInt32(ti->getFixedExtraInhabitantCount(IGM));
   }
@@ -971,7 +1048,7 @@
                                           llvm::GlobalValue::LinkOnceODRLinkage,
                                           Init,
                                           "__swift_reflection_version");
-  Version->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  ApplyIRLinkage(IRLinkage::InternalLinkOnceODR).to(Version);
   addUsedGlobal(Version);
 }
 
diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp
index 2237042..589edae 100644
--- a/lib/IRGen/IRGen.cpp
+++ b/lib/IRGen/IRGen.cpp
@@ -822,6 +822,7 @@
       IGM.emitBuiltinReflectionMetadata();
       IGM.emitReflectionMetadataVersion();
       irgen.emitEagerClassInitialization();
+      irgen.emitDynamicReplacements();
     }
 
     // Emit symbols for eliminated dead methods.
@@ -981,6 +982,8 @@
 
   irgen.emitSwiftProtocols();
 
+  irgen.emitDynamicReplacements();
+
   irgen.emitProtocolConformances();
 
   irgen.emitTypeMetadataRecords();
diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp
index 053d87e..025eade 100644
--- a/lib/IRGen/IRGenDebugInfo.cpp
+++ b/lib/IRGen/IRGenDebugInfo.cpp
@@ -651,7 +651,7 @@
 
     Mangle::ASTMangler Mangler;
     std::string Name = Mangler.mangleTypeForDebugger(
-        Ty, DbgTy.getDeclContext(), DbgTy.getGenericEnvironment());
+        Ty, DbgTy.getDeclContext());
     return BumpAllocatedString(Name);
   }
 
diff --git a/lib/IRGen/IRGenMangler.cpp b/lib/IRGen/IRGenMangler.cpp
index ce58f0f..13b8d09 100644
--- a/lib/IRGen/IRGenMangler.cpp
+++ b/lib/IRGen/IRGenMangler.cpp
@@ -13,6 +13,8 @@
 #include "IRGenMangler.h"
 #include "swift/AST/ExistentialLayout.h"
 #include "swift/AST/IRGenOptions.h"
+#include "swift/AST/ProtocolAssociations.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Demangling/ManglingMacros.h"
 #include "swift/Demangling/Demangle.h"
 #include "swift/ABI/MetadataValues.h"
@@ -237,3 +239,44 @@
   
   return finalize();
 }
+
+std::string IRGenMangler::mangleSymbolNameForAssociatedConformanceWitness(
+                                  const NormalProtocolConformance *conformance,
+                                  CanType associatedType,
+                                  const ProtocolDecl *proto) {
+  beginManglingWithoutPrefix();
+  if (conformance) {
+    Buffer << "associated conformance ";
+    appendProtocolConformance(conformance);
+  } else {
+    Buffer << "default associated conformance";
+  }
+
+  bool isFirstAssociatedTypeIdentifier = true;
+  appendAssociatedTypePath(associatedType, isFirstAssociatedTypeIdentifier);
+  appendProtocolName(proto);
+  return finalize();
+}
+
+std::string IRGenMangler::mangleSymbolNameForKeyPathMetadata(
+                                           const char *kind,
+                                           CanGenericSignature genericSig,
+                                           CanType type,
+                                           ProtocolConformanceRef conformance) {
+  beginManglingWithoutPrefix();
+  Buffer << kind << " ";
+
+  if (genericSig)
+    appendGenericSignature(genericSig);
+
+  if (type)
+    appendType(type);
+
+  if (conformance.isConcrete())
+    appendConcreteProtocolConformance(conformance.getConcrete());
+  else if (conformance.isAbstract())
+    appendProtocolName(conformance.getAbstract());
+  else
+    assert(conformance.isInvalid() && "Unknown protocol conformance");
+  return finalize();
+}
diff --git a/lib/IRGen/IRGenMangler.h b/lib/IRGen/IRGenMangler.h
index aa2c8d1..fbcb329 100644
--- a/lib/IRGen/IRGenMangler.h
+++ b/lib/IRGen/IRGenMangler.h
@@ -282,17 +282,6 @@
     return finalize();
   }
 
-  std::string mangleAssociatedTypeGenericParamRef(unsigned baseOrdinal,
-                                                  CanType member) {
-    beginMangling();
-    bool isFirstAssociatedTypeIdentifier = true;
-    appendType(GenericTypeParamType::get(0, baseOrdinal,
-                                         member->getASTContext()));
-    appendAssociatedTypePath(member, isFirstAssociatedTypeIdentifier);
-    appendOperator("MXA");
-    return finalize();
-  }
-
   void appendAssociatedTypePath(CanType associatedType, bool &isFirst) {
     if (auto memberType = dyn_cast<DependentMemberType>(associatedType)) {
       appendAssociatedTypePath(memberType.getBase(), isFirst);
@@ -424,6 +413,18 @@
   std::string mangleSymbolNameForSymbolicMangling(
                                               const SymbolicMangling &mangling,
                                               MangledTypeRefRole role);
+
+  std::string mangleSymbolNameForAssociatedConformanceWitness(
+                                  const NormalProtocolConformance *conformance,
+                                  CanType associatedType,
+                                  const ProtocolDecl *proto);
+
+  std::string mangleSymbolNameForKeyPathMetadata(
+                                           const char *kind,
+                                           CanGenericSignature genericSig,
+                                           CanType type,
+                                           ProtocolConformanceRef conformance);
+
 protected:
   SymbolicMangling
   withSymbolicReferences(IRGenModule &IGM,
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index ca38053..6f2448f 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -458,6 +458,23 @@
   IsSwiftErrorInRegister =
     clang::CodeGen::swiftcall::isSwiftErrorLoweredInRegister(
       ClangCodeGen->CGM());
+
+  DynamicReplacementsTy =
+      llvm::StructType::get(getLLVMContext(), {Int8PtrPtrTy, Int8PtrTy});
+  DynamicReplacementsPtrTy = DynamicReplacementsTy->getPointerTo(DefaultAS);
+
+  DynamicReplacementLinkEntryTy =
+      llvm::StructType::create(getLLVMContext(), "swift.dyn_repl_link_entry");
+  DynamicReplacementLinkEntryPtrTy =
+      DynamicReplacementLinkEntryTy->getPointerTo(DefaultAS);
+  llvm::Type *linkEntryFields[] = {
+    Int8PtrTy, // function pointer.
+    DynamicReplacementLinkEntryPtrTy // next.
+  };
+  DynamicReplacementLinkEntryTy->setBody(linkEntryFields);
+
+  DynamicReplacementKeyTy = createStructType(*this, "swift.dyn_repl_key",
+                                             {RelativeAddressTy, Int32Ty});
 }
 
 IRGenModule::~IRGenModule() {
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 14737f2..b8cd20c 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -110,6 +110,7 @@
   class ClangTypeConverter;
   class ClassMetadataLayout;
   class ConformanceInfo;
+  class ConstantInitBuilder;
   struct ConstantIntegerLiteral;
   class ConstantIntegerLiteralMap;
   class DebugTypeInfo;
@@ -235,6 +236,8 @@
 
   llvm::SmallPtrSet<SILFunction*, 4> LazilyEmittedFunctions;
 
+  llvm::SetVector<SILFunction*> DynamicReplacements;
+
   struct FieldTypeMetadata {
     IRGenModule *IGM;
     std::vector<CanType> fieldTypes;
@@ -338,6 +341,9 @@
 
   void emitEagerClassInitialization();
 
+  // Emit the code to replace dynamicReplacement(for:) functions.
+  void emitDynamicReplacements();
+
   /// Checks if the metadata of \p Nominal can be emitted lazily.
   ///
   /// If yes, \p Nominal is added to eligibleLazyMetadata and true is returned.
@@ -348,6 +354,8 @@
 
   void addLazyFunction(SILFunction *f);
 
+  void addDynamicReplacement(SILFunction *f) { DynamicReplacements.insert(f); }
+
   void forceLocalEmitOfLazyFunction(SILFunction *f) {
     DefaultIGMForFunction[f] = CurrentIGM;
   }
@@ -640,6 +648,13 @@
   llvm::PointerType *WitnessTablePtrPtrTy;   /// i8***
   llvm::Type *FloatTy;
   llvm::Type *DoubleTy;
+  llvm::StructType *DynamicReplacementsTy; // { i8**, i8* }
+  llvm::PointerType *DynamicReplacementsPtrTy;
+
+  llvm::StructType *DynamicReplacementLinkEntryTy; // %link_entry = { i8*, %link_entry*}
+  llvm::PointerType
+      *DynamicReplacementLinkEntryPtrTy; // %link_entry*
+  llvm::StructType *DynamicReplacementKeyTy; // { i32, i32}
 
   llvm::GlobalVariable *TheTrivialPropertyDescriptor = nullptr;
 
@@ -866,8 +881,6 @@
                                            ForDefinition_t forDefinition);
   llvm::Constant *getAddrOfKeyPathPattern(KeyPathPattern *pattern,
                                           SILLocation diagLoc);
-  llvm::Constant *getAddrOfAssociatedTypeGenericParamRef(GenericSignature *sig,
-                                                    CanDependentMemberType dmt);
   ConstantReference getConstantReferenceForProtocolDescriptor(ProtocolDecl *proto);
 
   ConstantIntegerLiteral getConstantIntegerLiteral(APInt value);
@@ -929,6 +942,9 @@
                               StringRef funcName,
                               CopyAddrHelperGenerator generator);
 
+  llvm::Constant *getOrCreateGOTEquivalent(llvm::Constant *global,
+                                           LinkEntity entity);
+                                           
   llvm::DenseMap<LinkEntity, llvm::Constant*> GlobalVars;
   llvm::DenseMap<LinkEntity, llvm::Constant*> GlobalGOTEquivalents;
   llvm::DenseMap<LinkEntity, llvm::Function*> GlobalFuncs;
@@ -1050,10 +1066,31 @@
   llvm::SetVector<const StructDecl *> ImportedStructs;
 
   llvm::Constant *getTypeRef(CanType type, MangledTypeRefRole role);
+  llvm::Constant *getMangledAssociatedConformance(
+                                  const NormalProtocolConformance *conformance,
+                                  const AssociatedConformance &requirement);
   llvm::Constant *getAddrOfStringForTypeRef(StringRef mangling,
                                             MangledTypeRefRole role);
   llvm::Constant *getAddrOfStringForTypeRef(const SymbolicMangling &mangling,
                                             MangledTypeRefRole role);
+
+  /// Retrieve the address of a mangled string used for some kind of metadata
+  /// reference.
+  ///
+  /// \param symbolName The name of the symbol that describes the metadata
+  /// being referenced.
+  /// \param shouldSetLowBit Whether to set the low bit of the result
+  /// constant, which is used by some clients to indicate that the result is
+  /// a mangled name.
+  /// \param body The body of a function that will create the metadata value
+  /// itself, given a constant building and producing a future for the
+  /// initializer.
+  /// \returns the address of the global variable describing this metadata.
+  llvm::Constant *getAddrOfStringForMetadataRef(
+      StringRef symbolName,
+      bool shouldSetLowBit,
+      llvm::function_ref<ConstantInitFuture(ConstantInitBuilder &)> body);
+
   llvm::Constant *getAddrOfFieldName(StringRef Name);
   llvm::Constant *getAddrOfCaptureDescriptor(SILFunction &caller,
                                              CanSILFunctionType origCalleeType,
@@ -1314,11 +1351,17 @@
   Address getAddrOfObjCClassRef(ClassDecl *D);
   llvm::Constant *getAddrOfMetaclassObject(ClassDecl *D,
                                            ForDefinition_t forDefinition);
+
   llvm::Function *getAddrOfObjCMetadataUpdateFunction(ClassDecl *D,
                                                       ForDefinition_t forDefinition);
 
-  llvm::Function *getAddrOfSILFunction(SILFunction *f,
-                                       ForDefinition_t forDefinition);
+  llvm::Function *
+  getAddrOfSILFunction(SILFunction *f, ForDefinition_t forDefinition,
+                       bool isDynamicallyReplaceableImplementation = false,
+                       bool shouldCallPreviousImplementation = false);
+
+  void emitDynamicReplacementOriginalFunctionThunk(SILFunction *f);
+
   llvm::Function *getAddrOfContinuationPrototype(CanSILFunctionType fnType);
   Address getAddrOfSILGlobalVariable(SILGlobalVariable *var,
                                      const TypeInfo &ti,
@@ -1381,6 +1424,10 @@
 
   void ensureRelativeSymbolCollocation(SILWitnessTable &wt);
 
+  llvm::GlobalVariable *
+  getGlobalForDynamicallyReplaceableThunk(LinkEntity &entity, llvm::Type *type,
+                                          ForDefinition_t forDefinition);
+
 private:
   llvm::Constant *
   getAddrOfSharedContextDescriptor(LinkEntity entity,
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index 0f633df..1c006be 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -915,7 +915,10 @@
   void visitPartialApplyInst(PartialApplyInst *i);
   void visitBuiltinInst(BuiltinInst *i);
 
+  void visitFunctionRefBaseInst(FunctionRefBaseInst *i);
   void visitFunctionRefInst(FunctionRefInst *i);
+  void visitDynamicFunctionRefInst(DynamicFunctionRefInst *i);
+  void visitPreviousDynamicFunctionRefInst(PreviousDynamicFunctionRefInst *i);
   void visitAllocGlobalInst(AllocGlobalInst *i);
   void visitGlobalAddrInst(GlobalAddrInst *i);
   void visitGlobalValueInst(GlobalValueInst *i);
@@ -1207,12 +1210,13 @@
   llvm_unreachable("bad kind");
 }
 
-IRGenSILFunction::IRGenSILFunction(IRGenModule &IGM,
-                                   SILFunction *f)
-  : IRGenFunction(IGM, IGM.getAddrOfSILFunction(f, ForDefinition),
-                  f->getOptimizationMode(),
-                  f->getDebugScope(), f->getLocation()),
-    CurSILFn(f) {
+IRGenSILFunction::IRGenSILFunction(IRGenModule &IGM, SILFunction *f)
+    : IRGenFunction(IGM,
+                    IGM.getAddrOfSILFunction(f, ForDefinition,
+                                             f->isDynamicallyReplaceable()),
+                    f->getOptimizationMode(), f->getDebugScope(),
+                    f->getLocation()),
+      CurSILFn(f) {
   // Apply sanitizer attributes to the function.
   // TODO: Check if the function is supposed to be excluded from ASan either by
   // being in the external file or via annotations.
@@ -1237,6 +1241,11 @@
   if (f->getLoweredFunctionType()->isCoroutine()) {
     CurFn->addFnAttr(llvm::Attribute::NoInline);
   }
+  // Emit the thunk that calls the previous implementation if this is a dynamic
+  // replacement.
+  if (f->getDynamicallyReplacedFunction()) {
+    IGM.emitDynamicReplacementOriginalFunctionThunk(f);
+  }
 }
 
 IRGenSILFunction::~IRGenSILFunction() {
@@ -1618,6 +1627,9 @@
   
   assert(!CurSILFn->empty() && "function has no basic blocks?!");
 
+  if (CurSILFn->getDynamicallyReplacedFunction())
+    IGM.IRGen.addDynamicReplacement(CurSILFn);
+
   // Configure the dominance resolver.
   // TODO: consider re-using a dom analysis from the PassManager
   // TODO: consider using a cheaper analysis at -O0
@@ -1831,10 +1843,12 @@
   assert(Builder.hasPostTerminatorIP() && "SIL bb did not terminate block?!");
 }
 
-void IRGenSILFunction::visitFunctionRefInst(FunctionRefInst *i) {
+void IRGenSILFunction::visitFunctionRefBaseInst(FunctionRefBaseInst *i) {
   auto fn = i->getReferencedFunction();
 
-  llvm::Constant *fnPtr = IGM.getAddrOfSILFunction(fn, NotForDefinition);
+  llvm::Constant *fnPtr = IGM.getAddrOfSILFunction(
+      fn, NotForDefinition, false /*isDynamicallyReplaceableImplementation*/,
+      isa<PreviousDynamicFunctionRefInst>(i));
 
   auto sig = IGM.getSignature(fn->getLoweredFunctionType());
 
@@ -1848,6 +1862,19 @@
   setLoweredFunctionPointer(i, fp);
 }
 
+void IRGenSILFunction::visitFunctionRefInst(FunctionRefInst *i) {
+  visitFunctionRefBaseInst(i);
+}
+
+void IRGenSILFunction::visitDynamicFunctionRefInst(DynamicFunctionRefInst *i) {
+  visitFunctionRefBaseInst(i);
+}
+
+void IRGenSILFunction::visitPreviousDynamicFunctionRefInst(
+    PreviousDynamicFunctionRefInst *i) {
+  visitFunctionRefBaseInst(i);
+}
+
 void IRGenSILFunction::visitAllocGlobalInst(AllocGlobalInst *i) {
   SILGlobalVariable *var = i->getReferencedGlobal();
   SILType loweredTy = var->getLoweredType();
@@ -2934,14 +2961,13 @@
 
 // FIXME: We could lower select_enum directly to LLVM select in a lot of cases.
 // For now, just emit a switch and phi nodes, like a chump.
-template<class C, class T>
+template <class C, class T, class B>
 static llvm::BasicBlock *
-emitBBMapForSelect(IRGenSILFunction &IGF,
-                   Explosion &resultPHI,
-                   SmallVectorImpl<std::pair<T, llvm::BasicBlock*>> &BBs,
+emitBBMapForSelect(IRGenSILFunction &IGF, Explosion &resultPHI,
+                   SmallVectorImpl<std::pair<T, llvm::BasicBlock *>> &BBs,
                    llvm::BasicBlock *&defaultBB,
-                   SelectInstBase<C, T> *inst) {
-  
+                   SelectInstBase<C, T, B> *inst) {
+
   auto origBB = IGF.Builder.GetInsertBlock();
 
   // Set up a continuation BB and phi nodes to receive the result value.
@@ -3072,10 +3098,10 @@
   return result;
 }
 
-template <class C, class T>
-static LoweredValue
-getLoweredValueForSelect(IRGenSILFunction &IGF,
-                         Explosion &result, SelectInstBase<C, T> *inst) {
+template <class C, class T, class B>
+static LoweredValue getLoweredValueForSelect(IRGenSILFunction &IGF,
+                                             Explosion &result,
+                                             SelectInstBase<C, T, B> *inst) {
   if (inst->getType().isAddress())
     // FIXME: Loses potentially better alignment info we might have.
     return LoweredValue(Address(result.claimNext(),
diff --git a/lib/IRGen/Linking.cpp b/lib/IRGen/Linking.cpp
index c4aaebe..dbe37d6 100644
--- a/lib/IRGen/Linking.cpp
+++ b/lib/IRGen/Linking.cpp
@@ -31,6 +31,18 @@
 using namespace irgen;
 using namespace Mangle;
 
+const IRLinkage IRLinkage::InternalLinkOnceODR = {
+  llvm::GlobalValue::LinkOnceODRLinkage,
+  llvm::GlobalValue::HiddenVisibility,
+  llvm::GlobalValue::DefaultStorageClass,
+};
+
+const IRLinkage IRLinkage::Internal = {
+  llvm::GlobalValue::InternalLinkage,
+  llvm::GlobalValue::DefaultVisibility,
+  llvm::GlobalValue::DefaultStorageClass,
+};
+
 bool swift::irgen::useDllStorage(const llvm::Triple &triple) {
   return triple.isOSBinFormatCOFF() && !triple.isOSCygMing();
 }
@@ -264,8 +276,65 @@
     return Result;
   }
 
-  case Kind::SILFunction:
-    return getSILFunction()->getName();
+  case Kind::SILFunction: {
+    std::string Result(getSILFunction()->getName());
+    if (isDynamicallyReplaceable()) {
+      Result.append("TI");
+    }
+    return Result;
+  }
+  case Kind::DynamicallyReplaceableFunctionImpl: {
+    assert(isa<AbstractFunctionDecl>(getDecl()));
+    std::string Result;
+    if (auto *Constructor = dyn_cast<ConstructorDecl>(getDecl())) {
+      Result = mangler.mangleConstructorEntity(Constructor, true,
+                                               /*isCurried=*/false);
+    } else  {
+      Result = mangler.mangleEntity(getDecl(), /*isCurried=*/false);
+    }
+    Result.append("TI");
+    return Result;
+  }
+
+  case Kind::DynamicallyReplaceableFunctionVariable: {
+    std::string Result(getSILFunction()->getName());
+    Result.append("TX");
+    return Result;
+  }
+
+  case Kind::DynamicallyReplaceableFunctionKey: {
+    std::string Result(getSILFunction()->getName());
+    Result.append("Tx");
+    return Result;
+  }
+
+
+  case Kind::DynamicallyReplaceableFunctionVariableAST: {
+    assert(isa<AbstractFunctionDecl>(getDecl()));
+    std::string Result;
+    if (auto *Constructor = dyn_cast<ConstructorDecl>(getDecl())) {
+      Result = mangler.mangleConstructorEntity(Constructor, true,
+                                               /*isCurried=*/false);
+    } else  {
+      Result = mangler.mangleEntity(getDecl(), /*isCurried=*/false);
+    }
+    Result.append("TX");
+    return Result;
+  }
+
+  case Kind::DynamicallyReplaceableFunctionKeyAST: {
+    assert(isa<AbstractFunctionDecl>(getDecl()));
+    std::string Result;
+    if (auto *Constructor = dyn_cast<ConstructorDecl>(getDecl())) {
+      Result = mangler.mangleConstructorEntity(Constructor, true,
+                                               /*isCurried=*/false);
+    } else  {
+      Result = mangler.mangleEntity(getDecl(), /*isCurried=*/false);
+    }
+    Result.append("Tx");
+    return Result;
+  }
+
   case Kind::SILGlobalVariable:
     return getSILGlobalVariable()->getName();
 
@@ -280,24 +349,6 @@
   llvm_unreachable("bad entity kind!");
 }
 
-/// Get SIL-linkage for something that's not required to be visible
-/// and doesn't actually need to be uniqued.
-static SILLinkage getNonUniqueSILLinkage(FormalLinkage linkage,
-                                         ForDefinition_t forDefinition) {
-  switch (linkage) {
-  case FormalLinkage::PublicUnique:
-  case FormalLinkage::PublicNonUnique:
-    return (forDefinition ? SILLinkage::Shared : SILLinkage::PublicExternal);
-
-  case FormalLinkage::HiddenUnique:
-    return (forDefinition ? SILLinkage::Shared : SILLinkage::HiddenExternal);
-
-  case FormalLinkage::Private:
-    return SILLinkage::Private;
-  }
-  llvm_unreachable("bad formal linkage");
-}
-
 SILLinkage LinkEntity::getLinkage(ForDefinition_t forDefinition) const {
   // For when `this` is a protocol conformance of some kind.
   auto getLinkageAsConformance = [&] {
@@ -389,9 +440,12 @@
     llvm_unreachable("bad kind");
 
   // ...but we don't actually expose individual value witnesses (right now).
-  case Kind::ValueWitness:
-    return getNonUniqueSILLinkage(getDeclLinkage(getType().getAnyNominal()),
-                                  forDefinition);
+  case Kind::ValueWitness: {
+    auto *nominal = getType().getAnyNominal();
+    if (getDeclLinkage(nominal) == FormalLinkage::PublicNonUnique)
+      return SILLinkage::Shared;
+    return forDefinition ? SILLinkage::Private : SILLinkage::PrivateExternal;
+  }
 
   // Foreign type metadata candidates are always shared; the runtime
   // does the uniquing.
@@ -491,9 +545,20 @@
   case Kind::GenericProtocolWitnessTableInstantiationFunction:
     return SILLinkage::Private;
 
+  case Kind::DynamicallyReplaceableFunctionKey:
   case Kind::SILFunction:
     return getSILFunction()->getEffectiveSymbolLinkage();
 
+  case Kind::DynamicallyReplaceableFunctionImpl:
+  case Kind::DynamicallyReplaceableFunctionKeyAST:
+    return getSILLinkage(getDeclLinkage(getDecl()), forDefinition);
+
+
+  case Kind::DynamicallyReplaceableFunctionVariable:
+    return getSILFunction()->getEffectiveSymbolLinkage();
+  case Kind::DynamicallyReplaceableFunctionVariableAST:
+    return getSILLinkage(getDeclLinkage(getDecl()), forDefinition);
+
   case Kind::SILGlobalVariable:
     return getSILGlobalVariable()->getLinkage();
 
@@ -519,6 +584,11 @@
   llvm_unreachable("bad link entity kind");
 }
 
+static bool isAvailableExternally(IRGenModule &IGM, SILFunction *F) {
+  // TODO
+  return true;
+}
+
 static bool isAvailableExternally(IRGenModule &IGM, const DeclContext *dc) {
   dc = dc->getModuleScopeContext();
   if (isa<ClangModuleUnit>(dc) ||
@@ -618,22 +688,36 @@
   case Kind::TypeMetadataPattern:
   case Kind::DefaultAssociatedConformanceAccessor:
     return false;
+  case Kind::DynamicallyReplaceableFunctionKey:
+  case Kind::DynamicallyReplaceableFunctionVariable:
+    return true;
 
+  case Kind::SILFunction:
+    return ::isAvailableExternally(IGM, getSILFunction());
+
+  case Kind::FieldOffset: {
+    return ::isAvailableExternally(IGM,
+                                   cast<VarDecl>(getDecl())
+                                     ->getDeclContext()
+                                     ->getInnermostTypeContext());
+  }
+  
   case Kind::ObjCMetadataUpdateFunction:
   case Kind::ValueWitness:
   case Kind::TypeMetadataAccessFunction:
   case Kind::TypeMetadataLazyCacheVariable:
-  case Kind::FieldOffset:
   case Kind::ProtocolWitnessTableLazyAccessFunction:
   case Kind::ProtocolWitnessTableLazyCacheVariable:
   case Kind::AssociatedTypeWitnessTableAccessFunction:
   case Kind::GenericProtocolWitnessTableInstantiationFunction:
-  case Kind::SILFunction:
   case Kind::SILGlobalVariable:
   case Kind::ReflectionBuiltinDescriptor:
   case Kind::ReflectionFieldDescriptor:
   case Kind::ReflectionAssociatedTypeDescriptor:
   case Kind::CoroutineContinuationPrototype:
+  case Kind::DynamicallyReplaceableFunctionVariableAST:
+  case Kind::DynamicallyReplaceableFunctionImpl:
+  case Kind::DynamicallyReplaceableFunctionKeyAST:
     llvm_unreachable("Relative reference to unsupported link entity");
   }
   llvm_unreachable("bad link entity kind");
@@ -714,7 +798,10 @@
   case Kind::MethodDescriptorInitializer:
   case Kind::MethodDescriptorAllocator:
     return IGM.MethodDescriptorStructTy;
-    
+  case Kind::DynamicallyReplaceableFunctionKey:
+    return IGM.DynamicReplacementKeyTy;
+  case Kind::DynamicallyReplaceableFunctionVariable:
+    return IGM.DynamicReplacementLinkEntryTy;
   default:
     llvm_unreachable("declaration LLVM type not specified");
   }
@@ -755,6 +842,8 @@
   case Kind::ProtocolWitnessTablePattern:
   case Kind::ObjCMetaclass:
   case Kind::SwiftMetaclassStub:
+  case Kind::DynamicallyReplaceableFunctionVariable:
+  case Kind::DynamicallyReplaceableFunctionKey:
     return IGM.getPointerAlignment();
   case Kind::SILFunction:
     return Alignment(1);
@@ -769,7 +858,8 @@
     if (getSILGlobalVariable()->getDecl())
       return getSILGlobalVariable()->getDecl()->isWeakImported(module);
     return false;
-
+  case Kind::DynamicallyReplaceableFunctionKey:
+  case Kind::DynamicallyReplaceableFunctionVariable:
   case Kind::SILFunction: {
     // For imported functions check the Clang declaration.
     if (auto clangOwner = getSILFunction()->getClangNodeOwner())
@@ -820,6 +910,9 @@
   case Kind::ProtocolDescriptor:
   case Kind::ProtocolRequirementsBaseDescriptor:
   case Kind::AssociatedTypeDescriptor:
+  case Kind::DynamicallyReplaceableFunctionKeyAST:
+  case Kind::DynamicallyReplaceableFunctionVariableAST:
+  case Kind::DynamicallyReplaceableFunctionImpl:
     return getDecl()->isWeakImported(module);
 
   // TODO: Revisit some of the below, for weak conformances.
@@ -892,12 +985,17 @@
   case Kind::AssociatedTypeDescriptor:
   case Kind::AssociatedConformanceDescriptor:
   case Kind::DefaultAssociatedConformanceAccessor:
+  case Kind::DynamicallyReplaceableFunctionVariableAST:
+  case Kind::DynamicallyReplaceableFunctionKeyAST:
+  case Kind::DynamicallyReplaceableFunctionImpl:
     sf = getSourceFileForDeclContext(getDecl()->getDeclContext());
     if (!sf)
       return nullptr;
     break;
   
   case Kind::SILFunction:
+  case Kind::DynamicallyReplaceableFunctionVariable:
+  case Kind::DynamicallyReplaceableFunctionKey:
     sf = getSourceFileForDeclContext(getSILFunction()->getDeclContext());
     if (!sf)
       return nullptr;
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 7ecc1b2..a401163 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -520,6 +520,8 @@
   SmallVector<TermInst *, 8> returnInsts;
   // All (large type) return instructions that are modified
   SmallVector<ReturnInst *, 8> modReturnInsts;
+  // All (large type) yield instructions that are modified
+  SmallVector<YieldInst *, 8> modYieldInsts;
   // All destroy_value instrs should be replaced with _addr version
   SmallVector<SILInstruction *, 16> destroyValueInstsToMod;
   // All debug instructions.
@@ -529,6 +531,26 @@
   StructLoweringState(SILFunction *F, irgen::IRGenModule &Mod,
                       LargeSILTypeMapper &Mapper)
       : F(F), Mod(Mod), Mapper(Mapper) {}
+
+  bool isLargeLoadableType(SILType type) {
+    return ::isLargeLoadableType(F->getGenericEnvironment(), type, Mod);
+  }
+
+  SILType getNewSILType(SILType type) {
+    return Mapper.getNewSILType(F->getGenericEnvironment(), type, Mod);
+  }
+
+  bool hasLargeLoadableYields() {
+    auto fnType = F->getLoweredFunctionType();
+    if (!fnType->isCoroutine()) return false;
+
+    auto env = F->getGenericEnvironment();
+    for (auto yield : fnType->getYields()) {
+      if (Mapper.shouldTransformParameter(env, yield, Mod))
+        return true;
+    }
+    return false;
+  }
 };
 } // end anonymous namespace
 
@@ -695,11 +717,10 @@
   if (!modifiableApply(applySite, pass.Mod)) {
     return visitInstr(applySite.getInstruction());
   }
-  GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
   for (Operand &operand : applySite.getArgumentOperands()) {
     SILValue currOperand = operand.get();
     SILType silType = currOperand->getType();
-    SILType newSilType = pass.Mapper.getNewSILType(genEnv, silType, pass.Mod);
+    SILType newSilType = pass.getNewSILType(silType);
     if (silType != newSilType ||
         std::find(pass.largeLoadableArgs.begin(), pass.largeLoadableArgs.end(),
                   currOperand) != pass.largeLoadableArgs.end() ||
@@ -715,8 +736,7 @@
   if (auto beginApply = dyn_cast<BeginApplyInst>(applySite)) {
     for (auto yield : beginApply->getYieldedValues()) {
       auto oldYieldType = yield->getType();
-      auto newYieldType =
-          pass.Mapper.getNewSILType(genEnv, oldYieldType, pass.Mod);
+      auto newYieldType = pass.getNewSILType(oldYieldType);
       if (oldYieldType != newYieldType) {
         pass.applies.push_back(applySite.getInstruction());
         return;
@@ -726,9 +746,9 @@
   }
 
   SILType currType = applySite.getType();
-  SILType newType = pass.Mapper.getNewSILType(genEnv, currType, pass.Mod);
+  SILType newType = pass.getNewSILType(currType);
   // We only care about function type results
-  if (!isLargeLoadableType(genEnv, currType, pass.Mod) &&
+  if (!pass.isLargeLoadableType(currType) &&
       (currType != newType)) {
     pass.applies.push_back(applySite.getInstruction());
     return;
@@ -822,9 +842,7 @@
     for (SILArgument *arg : currBB->getArguments()) {
       if (pass.Mapper.shouldConvertBBArg(arg, pass.Mod)) {
         SILType storageType = arg->getType();
-        auto *genEnv = instr->getFunction()->getGenericEnvironment();
-        SILType newSILType =
-            pass.Mapper.getNewSILType(genEnv, storageType, pass.Mod);
+        SILType newSILType = pass.getNewSILType(storageType);
         if (newSILType.isAddress()) {
           pass.switchEnumInstsToMod.push_back(instr);
           return;
@@ -881,9 +899,8 @@
 }
 
 void LargeValueVisitor::visitResultTyInst(SingleValueInstruction *instr) {
-  GenericEnvironment *genEnv = instr->getFunction()->getGenericEnvironment();
   SILType currSILType = instr->getType().getObjectType();
-  SILType newSILType = pass.Mapper.getNewSILType(genEnv, currSILType, pass.Mod);
+  SILType newSILType = pass.getNewSILType(currSILType);
   if (currSILType != newSILType) {
     pass.resultTyInstsToMod.insert(instr);
   }
@@ -942,6 +959,8 @@
 void LargeValueVisitor::visitYieldInst(YieldInst *instr) {
   if (!modYieldType(pass.F, pass.Mod, pass.Mapper)) {
     visitInstr(instr);
+  } else {
+    pass.modYieldInsts.push_back(instr);
   } // else: function signature return instructions remain as-is
 }
 
@@ -976,16 +995,17 @@
 
 namespace {
 class LoadableStorageAllocation {
+public:
   StructLoweringState &pass;
 
-public:
   explicit LoadableStorageAllocation(StructLoweringState &pass) : pass(pass) {}
 
   void allocateLoadableStorage();
-  void replaceLoadWithCopyAddr(LoadInst *optimizableLoad);
-  void replaceLoadWithCopyAddrForModifiable(LoadInst *unoptimizableLoad);
+  void replaceLoad(LoadInst *unoptimizableLoad);
 
 protected:
+  void replaceLoadWithCopyAddr(LoadInst *optimizableLoad);
+  void replaceLoadWithCopyAddrForModifiable(LoadInst *unoptimizableLoad);
   void convertIndirectFunctionArgs();
   void insertIndirectReturnArgs();
   void convertIndirectFunctionPointerArgsForUnmodifiable();
@@ -998,6 +1018,43 @@
 };
 } // end anonymous namespace
 
+static AllocStackInst *allocate(StructLoweringState &pass,
+                                SILLocation loc, SILType type) {
+  assert(type.isObject());
+
+  // Insert an alloc_stack at the beginning of the function.
+  SILBuilderWithScope allocBuilder(&*pass.F->begin());
+  AllocStackInst *alloc = allocBuilder.createAllocStack(loc, type);
+
+  // Insert dealloc_stack at the end(s) of the function.
+  for (TermInst *termInst : pass.returnInsts) {
+    SILBuilderWithScope deallocBuilder(termInst);
+    deallocBuilder.createDeallocStack(loc, alloc);
+  }
+
+  return alloc;
+}
+
+static StoreOwnershipQualifier
+getStoreInitOwnership(StructLoweringState &pass, SILType type) {
+  if (!pass.F->hasQualifiedOwnership()) {
+    return StoreOwnershipQualifier::Unqualified;
+  } else if (type.isTrivial(pass.F->getModule())) {
+    return StoreOwnershipQualifier::Trivial;
+  } else {
+    return StoreOwnershipQualifier::Init;
+  }
+}
+
+static StoreInst *createStoreInit(StructLoweringState &pass,
+                                  SILBasicBlock::iterator where,
+                                  SILLocation loc,
+                                  SILValue value, SILValue address) {
+  SILBuilderWithScope storeBuilder(where);
+  return storeBuilder.createStore(loc, value, address,
+                                 getStoreInitOwnership(pass, value->getType()));
+}
+
 static SILInstruction *createOutlinedCopyCall(SILBuilder &copyBuilder,
                                               SILValue src, SILValue tgt,
                                               StructLoweringState &pass,
@@ -1012,19 +1069,12 @@
     LoadInst *optimizableLoad) {
   SILValue value = optimizableLoad->getOperand();
 
-  SILBuilderWithScope allocBuilder(&*pass.F->begin());
-  AllocStackInst *allocInstr =
-      allocBuilder.createAllocStack(value.getLoc(), value->getType());
+  auto allocInstr = allocate(pass, value.getLoc(),
+                             value->getType().getObjectType());
 
   SILBuilderWithScope outlinedBuilder(optimizableLoad);
   createOutlinedCopyCall(outlinedBuilder, value, allocInstr, pass);
 
-  // Insert stack deallocations.
-  for (TermInst *termInst : pass.returnInsts) {
-    SILBuilderWithScope deallocBuilder(termInst);
-    deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
-  }
-
   for (auto *user : optimizableLoad->getUses()) {
     SILInstruction *userIns = user->getUser();
     switch (userIns->getKind()) {
@@ -1041,38 +1091,36 @@
       }
       break;
     }
+    case SILInstructionKind::YieldInst:
+      // The rewrite is enough.
+      break;
     case SILInstructionKind::RetainValueInst: {
-      auto *insToInsert = dyn_cast<RetainValueInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<RetainValueInst>(userIns);
       pass.retainInstsToMod.push_back(insToInsert);
       break;
     }
     case SILInstructionKind::ReleaseValueInst: {
-      auto *insToInsert = dyn_cast<ReleaseValueInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<ReleaseValueInst>(userIns);
       pass.releaseInstsToMod.push_back(insToInsert);
       break;
     }
     case SILInstructionKind::StoreInst: {
-      auto *insToInsert = dyn_cast<StoreInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<StoreInst>(userIns);
       pass.storeInstsToMod.push_back(insToInsert);
       break;
     }
     case SILInstructionKind::DebugValueInst: {
-      auto *insToInsert = dyn_cast<DebugValueInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<DebugValueInst>(userIns);
       pass.debugInstsToMod.push_back(insToInsert);
       break;
     }
     case SILInstructionKind::DestroyValueInst: {
-      auto *insToInsert = dyn_cast<DestroyValueInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<DestroyValueInst>(userIns);
       pass.destroyValueInstsToMod.push_back(insToInsert);
       break;
     }
     case SILInstructionKind::StructExtractInst: {
-      auto *instToInsert = dyn_cast<StructExtractInst>(userIns);
+      auto *instToInsert = cast<StructExtractInst>(userIns);
       if (std::find(pass.structExtractInstsToMod.begin(),
                     pass.structExtractInstsToMod.end(),
                     instToInsert) == pass.structExtractInstsToMod.end()) {
@@ -1081,7 +1129,7 @@
       break;
     }
     case SILInstructionKind::SwitchEnumInst: {
-      auto *instToInsert = dyn_cast<SwitchEnumInst>(userIns);
+      auto *instToInsert = cast<SwitchEnumInst>(userIns);
       if (std::find(pass.switchEnumInstsToMod.begin(),
                     pass.switchEnumInstsToMod.end(),
                     instToInsert) == pass.switchEnumInstsToMod.end()) {
@@ -1098,10 +1146,16 @@
   optimizableLoad->getParent()->erase(optimizableLoad);
 }
 
-static bool usesContainApplies(LoadInst *unoptimizableLoad,
-                               irgen::IRGenModule &Mod,
-                               LargeSILTypeMapper &Mapper) {
-  for (auto *user : unoptimizableLoad->getUses()) {
+static bool isYieldUseRewriteable(StructLoweringState &pass,
+                                  YieldInst *inst, Operand *operand) {
+  assert(inst == operand->getUser());
+  return pass.isLargeLoadableType(operand->get()->getType());
+}
+
+/// Does the value's uses contain instructions that *must* be rewrites?
+static bool hasMandatoryRewriteUse(StructLoweringState &pass,
+                                   SILValue value) {
+  for (auto *user : value->getUses()) {
     SILInstruction *userIns = user->getUser();
     switch (userIns->getKind()) {
     case SILInstructionKind::ApplyInst:
@@ -1110,18 +1164,20 @@
     case SILInstructionKind::PartialApplyInst: {
       ApplySite site(userIns);
       SILValue callee = site.getCallee();
-      if (callee == unoptimizableLoad) {
+      if (callee == value) {
         break;
       }
-      SILType currType = unoptimizableLoad->getType().getObjectType();
-      GenericEnvironment *genEnv =
-          unoptimizableLoad->getFunction()->getGenericEnvironment();
-      SILType newSILType = Mapper.getNewSILType(genEnv, currType, Mod);
+      SILType currType = value->getType().getObjectType();
+      SILType newSILType = pass.getNewSILType(currType);
       if (currType == newSILType) {
         break;
       }
       return true;
     }
+    case SILInstructionKind::YieldInst:
+      if (isYieldUseRewriteable(pass, cast<YieldInst>(userIns), user))
+        return true;
+      break;
     default:
       break;
     }
@@ -1131,27 +1187,20 @@
 
 void LoadableStorageAllocation::replaceLoadWithCopyAddrForModifiable(
     LoadInst *unoptimizableLoad) {
-  if (!usesContainApplies(unoptimizableLoad, pass.Mod, pass.Mapper)) {
+  if (!hasMandatoryRewriteUse(pass, unoptimizableLoad)) {
     return;
   }
   SILValue value = unoptimizableLoad->getOperand();
 
-  SILBuilderWithScope allocBuilder(&*pass.F->begin());
-  AllocStackInst *allocInstr =
-      allocBuilder.createAllocStack(value.getLoc(), value->getType());
+  AllocStackInst *alloc = allocate(pass, value.getLoc(),
+                                   value->getType().getObjectType());
 
   SILBuilderWithScope outlinedBuilder(unoptimizableLoad);
-  createOutlinedCopyCall(outlinedBuilder, value, allocInstr, pass);
+  createOutlinedCopyCall(outlinedBuilder, value, alloc, pass);
 
-  // Insert stack deallocations.
-  for (TermInst *termInst : pass.returnInsts) {
-    SILBuilderWithScope deallocBuilder(termInst);
-    deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
-  }
-
-  SmallVector<Operand *, 8> usersToMod;
-  for (auto *user : unoptimizableLoad->getUses()) {
-    SILInstruction *userIns = user->getUser();
+  SmallVector<Operand *, 8> usesToMod;
+  for (auto *use : unoptimizableLoad->getUses()) {
+    SILInstruction *userIns = use->getUser();
     switch (userIns->getKind()) {
     case SILInstructionKind::CopyAddrInst:
     case SILInstructionKind::DeallocStackInst:
@@ -1169,10 +1218,7 @@
         break;
       }
       SILType currType = unoptimizableLoad->getType().getObjectType();
-      GenericEnvironment *genEnv =
-          userIns->getFunction()->getGenericEnvironment();
-      SILType newSILType =
-          pass.Mapper.getNewSILType(genEnv, currType, pass.Mod);
+      SILType newSILType = pass.getNewSILType(currType);
       if (currType == newSILType) {
         break;
       }
@@ -1180,63 +1226,63 @@
           pass.applies.end()) {
         pass.applies.push_back(userIns);
       }
-      usersToMod.push_back(user);
+      usesToMod.push_back(use);
+      break;
+    }
+    case SILInstructionKind::YieldInst: {
+      if (isYieldUseRewriteable(pass, cast<YieldInst>(userIns), use))
+        usesToMod.push_back(use);
       break;
     }
     case SILInstructionKind::RetainValueInst: {
-      auto *insToInsert = dyn_cast<RetainValueInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<RetainValueInst>(userIns);
       pass.retainInstsToMod.push_back(insToInsert);
-      usersToMod.push_back(user);
+      usesToMod.push_back(use);
       break;
     }
     case SILInstructionKind::ReleaseValueInst: {
-      auto *insToInsert = dyn_cast<ReleaseValueInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<ReleaseValueInst>(userIns);
       pass.releaseInstsToMod.push_back(insToInsert);
-      usersToMod.push_back(user);
+      usesToMod.push_back(use);
       break;
     }
     case SILInstructionKind::StoreInst: {
-      auto *insToInsert = dyn_cast<StoreInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<StoreInst>(userIns);
       pass.storeInstsToMod.push_back(insToInsert);
-      usersToMod.push_back(user);
+      usesToMod.push_back(use);
       break;
     }
     case SILInstructionKind::DebugValueInst: {
-      auto *insToInsert = dyn_cast<DebugValueInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<DebugValueInst>(userIns);
       pass.debugInstsToMod.push_back(insToInsert);
-      usersToMod.push_back(user);
+      usesToMod.push_back(use);
       break;
     }
     case SILInstructionKind::DestroyValueInst: {
-      auto *insToInsert = dyn_cast<DestroyValueInst>(userIns);
-      assert(insToInsert && "Unexpected cast failure");
+      auto *insToInsert = cast<DestroyValueInst>(userIns);
       pass.destroyValueInstsToMod.push_back(insToInsert);
-      usersToMod.push_back(user);
+      usesToMod.push_back(use);
       break;
     }
     case SILInstructionKind::StructExtractInst: {
-      auto *instToInsert = dyn_cast<StructExtractInst>(userIns);
+      auto *instToInsert = cast<StructExtractInst>(userIns);
       pass.structExtractInstsToMod.push_back(instToInsert);
-      usersToMod.push_back(user);
+      usesToMod.push_back(use);
       break;
     }
     case SILInstructionKind::SwitchEnumInst: {
-      auto *instToInsert = dyn_cast<SwitchEnumInst>(userIns);
+      auto *instToInsert = cast<SwitchEnumInst>(userIns);
       pass.switchEnumInstsToMod.push_back(instToInsert);
-      usersToMod.push_back(user);
+      usesToMod.push_back(use);
       break;
     }
     default:
       break;
     }
   }
-  while (!usersToMod.empty()) {
-    auto *currUser = usersToMod.pop_back_val();
-    currUser->set(allocInstr);
+  while (!usesToMod.empty()) {
+    auto *use = usesToMod.pop_back_val();
+    use->set(alloc);
   }
 }
 
@@ -1313,16 +1359,13 @@
   SILBasicBlock *entry = pass.F->getEntryBlock();
   SILBuilderWithScope argBuilder(entry->begin());
 
-  GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
-
   for (SILArgument *arg : entry->getArguments()) {
     SILType storageType = arg->getType();
-    SILType newSILType =
-        pass.Mapper.getNewSILType(genEnv, storageType, pass.Mod);
+    SILType newSILType = pass.getNewSILType(storageType);
     if (newSILType != storageType) {
       ValueOwnershipKind ownership = arg->getOwnershipKind();
       arg = replaceArgType(argBuilder, arg, newSILType);
-      if (isLargeLoadableType(genEnv, storageType, pass.Mod)) {
+      if (pass.isLargeLoadableType(storageType)) {
         // Add to largeLoadableArgs if and only if it wasn't a modified function
         // signature arg
         pass.largeLoadableArgs.push_back(arg);
@@ -1372,7 +1415,7 @@
         continue;
       }
       auto resultStorageType = origSILFunctionType->getAllResultsType();
-      if (!isLargeLoadableType(genEnv, resultStorageType, pass.Mod)) {
+      if (!pass.isLargeLoadableType(resultStorageType)) {
         // Make sure it contains a function type
         auto numFuncTy = llvm::count_if(origSILFunctionType->getResults(),
             [](const SILResultInfo &origResult) {
@@ -1393,8 +1436,7 @@
         (void)numFuncTy;
         continue;
       }
-      auto newSILType =
-          pass.Mapper.getNewSILType(genEnv, resultStorageType, pass.Mod);
+      auto newSILType = pass.getNewSILType(resultStorageType);
       auto *newVal = allocateForApply(currIns, newSILType.getObjectType());
       if (auto apply = dyn_cast<ApplyInst>(currIns)) {
         apply->replaceAllUsesWith(newVal);
@@ -1422,8 +1464,7 @@
   for (SILArgument *arg : entry->getArguments()) {
     SILType storageType = arg->getType();
     GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
-    SILType newSILType =
-        pass.Mapper.getNewSILType(genEnv, storageType, pass.Mod);
+    SILType newSILType = pass.getNewSILType(storageType);
     if (containsFunctionSignature(genEnv, pass.Mod, storageType, newSILType)) {
       auto *castInstr = argBuilder.createUncheckedBitCast(
           RegularLocation(const_cast<ValueDecl *>(arg->getDecl())), arg,
@@ -1436,7 +1477,6 @@
 
 void LoadableStorageAllocation::convertIndirectBasicBlockArgs() {
   SILBasicBlock *entry = pass.F->getEntryBlock();
-  GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
   for (SILBasicBlock &BB : *pass.F) {
     if (&BB == entry) {
       // Already took care of function args
@@ -1448,8 +1488,7 @@
         continue;
       }
       SILType storageType = arg->getType();
-      SILType newSILType =
-          pass.Mapper.getNewSILType(genEnv, storageType, pass.Mod);
+      SILType newSILType = pass.getNewSILType(storageType);
       convertBBArgType(argBuilder, newSILType, arg);
     }
   }
@@ -1584,111 +1623,86 @@
 };
 } // end anonymous namespace
 
-static void setInstrUsers(StructLoweringState &pass, AllocStackInst *allocInstr,
-                          SILValue instrOperand, StoreInst *store) {
-  SmallVector<Operand *, 8> uses(instrOperand->getUses());
-  for (Operand *userOp : uses) {
-    SILInstruction *user = userOp->getUser();
-    if (user == store) {
-      continue;
-    }
+/// Given that we've allocated space to hold a scalar value, try to rewrite
+/// the uses of the scalar to be uses of the address.
+static void rewriteUsesOfSscalar(StructLoweringState &pass,
+                                 SILValue address, SILValue scalar,
+                                 StoreInst *storeToAddress) {
+  // Copy the uses, since we're going to edit them.
+  SmallVector<Operand *, 8> uses(scalar->getUses());
+  for (Operand *scalarUse : uses) {
+    SILInstruction *user = scalarUse->getUser();
+
     if (ApplySite::isa(user)) {
       ApplySite site(user);
       if (modifiableApply(site, pass.Mod)) {
-        userOp->set(allocInstr);
+        // Just rewrite the operand in-place.  This will produce a temporary
+        // type error, but we should fix that up when we rewrite the apply's
+        // function type.
+        scalarUse->set(address);
       }
+    } else if (isa<YieldInst>(user)) {
+      // The rules for the yield are changing anyway, so we can just rewrite
+      // it in-place.
+      scalarUse->set(address);
     } else if (auto *storeUser = dyn_cast<StoreInst>(user)) {
+      // Don't rewrite the store to the allocation.
+      if (storeUser == storeToAddress)
+        continue;
+
       // Optimization: replace with copy_addr to reduce code size
       assert(std::find(pass.storeInstsToMod.begin(), pass.storeInstsToMod.end(),
                        storeUser) == pass.storeInstsToMod.end() &&
              "Did not expect this instr in storeInstsToMod");
       SILBuilderWithScope copyBuilder(storeUser);
-      SILValue tgt = storeUser->getDest();
-      createOutlinedCopyCall(copyBuilder, allocInstr, tgt, pass);
+      SILValue dest = storeUser->getDest();
+      createOutlinedCopyCall(copyBuilder, address, dest, pass);
       storeUser->eraseFromParent();
     } else if (auto *dbgInst = dyn_cast<DebugValueInst>(user)) {
       SILBuilderWithScope dbgBuilder(dbgInst);
       // Rewrite the debug_value to point to the variable in the alloca.
-      dbgBuilder.createDebugValueAddr(dbgInst->getLoc(), allocInstr,
+      dbgBuilder.createDebugValueAddr(dbgInst->getLoc(), address,
                                       *dbgInst->getVarInfo());
       dbgInst->eraseFromParent();
     }
   }
 }
 
-static void allocateAndSetForInstrOperand(StructLoweringState &pass,
-                                          SingleValueInstruction *instrOperand){
-  assert(instrOperand->getType().isObject());
-  SILBuilderWithScope allocBuilder(&*pass.F->begin());
-  AllocStackInst *allocInstr = allocBuilder.createAllocStack(
-      instrOperand->getLoc(), instrOperand->getType());
+static void allocateAndSetForInstResult(StructLoweringState &pass,
+                                        SILValue instResult,
+                                        SILInstruction *inst) {
+  auto alloc = allocate(pass, inst->getLoc(), instResult->getType());
 
-  auto II = instrOperand->getIterator();
+  auto II = inst->getIterator();
   ++II;
-  SILBuilderWithScope storeBuilder(II);
-  StoreInst *store = nullptr;
-  if (pass.F->hasQualifiedOwnership()) {
-    store = storeBuilder.createStore(instrOperand->getLoc(), instrOperand,
-                                     allocInstr, StoreOwnershipQualifier::Init);
-  } else {
-    store = storeBuilder.createStore(instrOperand->getLoc(), instrOperand,
-                                     allocInstr,
-                                     StoreOwnershipQualifier::Unqualified);
-  }
+  auto store = createStoreInit(pass, II, inst->getLoc(), instResult, alloc);
 
-  // Insert stack deallocations.
-  for (TermInst *termInst : pass.returnInsts) {
-    SILBuilderWithScope deallocBuilder(termInst);
-    deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
-  }
-
-  // Traverse all the uses of instrOperand - see if we can replace
-  setInstrUsers(pass, allocInstr, instrOperand, store);
+  // Traverse all the uses of instResult - see if we can replace
+  rewriteUsesOfSscalar(pass, alloc, instResult, store);
 }
 
-static void allocateAndSetForArgumentOperand(StructLoweringState &pass,
-                                             SILValue value,
-                                             SILInstruction *applyInst) {
-  assert(value->getType().isObject());
-  auto *arg = dyn_cast<SILArgument>(value);
-  assert(arg && "non-instr operand must be an argument");
+static void allocateAndSetForArgument(StructLoweringState &pass,
+                                      SILArgument *value,
+                                      SILInstruction *user) {
+  AllocStackInst *alloc = allocate(pass, user->getLoc(), value->getType());
 
-  SILBuilderWithScope allocBuilder(&*pass.F->begin());
-  AllocStackInst *allocInstr =
-      allocBuilder.createAllocStack(applyInst->getLoc(), value->getType());
+  SILLocation loc = user->getLoc();
+  loc.markAutoGenerated();
 
-  auto storeIt = arg->getParent()->begin();
-  if (storeIt == pass.F->begin()->begin()) {
-    // Store should happen *after* allocInstr
-    ++storeIt;
+  // Store the value into the allocation.
+  auto II = value->getParent()->begin();
+  if (II == alloc->getParent()->begin()) {
+    // Store should happen *after* the allocation.
+    ++II;
   }
-  SILBuilderWithScope storeBuilder(storeIt);
-  SILLocation Loc = applyInst->getLoc();
-  Loc.markAutoGenerated();
+  auto store = createStoreInit(pass, II, loc, value, alloc);
 
-  StoreInst *store = nullptr;
-  if (pass.F->hasQualifiedOwnership()) {
-    store = storeBuilder.createStore(Loc, value, allocInstr,
-                                     StoreOwnershipQualifier::Init);
-  } else {
-    store = storeBuilder.createStore(Loc, value, allocInstr,
-                                     StoreOwnershipQualifier::Unqualified);
-  }
-
-  // Insert stack deallocations.
-  for (TermInst *termInst : pass.returnInsts) {
-    SILBuilderWithScope deallocBuilder(termInst);
-    deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
-  }
-
-  // Traverse all the uses of instrOperand - see if we can replace
-  setInstrUsers(pass, allocInstr, value, store);
+  // Traverse all the uses of value - see if we can replace
+  rewriteUsesOfSscalar(pass, alloc, value, store);
 }
 
-static bool allUsesAreReplaceable(SingleValueInstruction *instr,
-                                  irgen::IRGenModule &Mod,
-                                  LargeSILTypeMapper &Mapper) {
-  bool allUsesAreReplaceable = true;
+static bool allUsesAreReplaceable(StructLoweringState &pass,
+                                  SingleValueInstruction *instr) {
   for (auto *user : instr->getUses()) {
     SILInstruction *userIns = user->getUser();
     switch (userIns->getKind()) {
@@ -1704,32 +1718,72 @@
     case SILInstructionKind::PartialApplyInst: {
       // Replaceable only if it is not the function pointer
       ApplySite site(userIns);
-      if (!modifiableApply(site, Mod)) {
-        allUsesAreReplaceable = false;
-        break;
+      if (!modifiableApply(site, pass.Mod)) {
+        return false;
       }
       SILValue callee = site.getCallee();
       if (callee == instr) {
-        allUsesAreReplaceable = false;
+        return false;
       }
       SILType currType = instr->getType().getObjectType();
-      GenericEnvironment *genEnv =
-          instr->getFunction()->getGenericEnvironment();
-      SILType newSILType = Mapper.getNewSILType(genEnv, currType, Mod);
+      SILType newSILType = pass.getNewSILType(currType);
       if (currType == newSILType) {
-        allUsesAreReplaceable = false;
+        return false;
       }
       break;
     }
-    case SILInstructionKind::StructExtractInst:
-    case SILInstructionKind::SwitchEnumInst: {
+    case SILInstructionKind::YieldInst:
+      if (!isYieldUseRewriteable(pass, cast<YieldInst>(userIns), user))
+        return false;
       break;
-    }
+    case SILInstructionKind::StructExtractInst:
+    case SILInstructionKind::SwitchEnumInst:
+      break;
     default:
-      allUsesAreReplaceable = false;
+      return false;
     }
   }
-  return allUsesAreReplaceable;
+  return true;
+}
+
+void LoadableStorageAllocation::replaceLoad(LoadInst *load) {
+  if (allUsesAreReplaceable(pass, load)) {
+    replaceLoadWithCopyAddr(load);
+  } else {
+    replaceLoadWithCopyAddrForModifiable(load);
+  }
+}
+
+static void allocateAndSet(StructLoweringState &pass,
+                           LoadableStorageAllocation &allocator,
+                           SILValue operand, SILInstruction *user) {
+  auto inst = operand->getDefiningInstruction();
+  if (!inst) {
+    allocateAndSetForArgument(pass, cast<SILArgument>(operand), user);
+    return;
+  }
+
+  if (auto *load = dyn_cast<LoadInst>(operand)) {
+    allocator.replaceLoad(load);
+  } else {
+    // TODO: peephole: special handling of known cases:
+    // ApplyInst, TupleExtractInst
+    allocateAndSetForInstResult(pass, operand, inst);
+  }
+}
+
+/// Rewrite all of the large-loadable operands in the given list.
+static void allocateAndSetAll(StructLoweringState &pass,
+                              LoadableStorageAllocation &allocator,
+                              SILInstruction *user,
+                              MutableArrayRef<Operand> operands) {
+  for (Operand &operand : operands) {
+    SILValue value = operand.get();
+    SILType silType = value->getType();
+    if (pass.isLargeLoadableType(silType)) {
+      allocateAndSet(pass, allocator, value, user);
+    }
+  }
 }
 
 static void castTupleInstr(SingleValueInstruction *instr, IRGenModule &Mod,
@@ -1774,38 +1828,18 @@
   auto value = orig->getOperand();
   auto type = value->getType();
   if (type.isObject()) {
-    SILBuilderWithScope allocBuilder(&*pass.F->begin());
-
     // support for non-address operands / enums
-    auto *allocInstr = allocBuilder.createAllocStack(orig->getLoc(), type);
-    SILBuilderWithScope storeBuilder(orig);
-    StoreInst *store = nullptr;
-    if (pass.F->hasQualifiedOwnership()) {
-      store = storeBuilder.createStore(orig->getLoc(), value, allocInstr,
-                                       StoreOwnershipQualifier::Init);
-    } else {
-      store = storeBuilder.createStore(orig->getLoc(), value, allocInstr,
-                                       StoreOwnershipQualifier::Unqualified);
-    }
-    // Insert stack deallocations.
-    for (TermInst *termInst : pass.returnInsts) {
-      SILBuilderWithScope deallocBuilder(termInst);
-      deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
-    }
-    value = allocInstr;
+    auto *alloc = allocate(pass, orig->getLoc(), type);
+    createStoreInit(pass, orig->getIterator(), orig->getLoc(), value, alloc);
+    return alloc;
   }
-  SILBuilderWithScope allocBuilder(&*pass.F->begin());
-  auto *allocInstr = allocBuilder.createAllocStack(value.getLoc(), type);
+
+  auto alloc = allocate(pass, value.getLoc(), type.getObjectType());
 
   SILBuilderWithScope copyBuilder(orig);
-  createOutlinedCopyCall(copyBuilder, value, allocInstr, pass);
+  createOutlinedCopyCall(copyBuilder, value, alloc, pass);
 
-  for (TermInst *termInst : pass.returnInsts) {
-    SILBuilderWithScope deallocBuilder(termInst);
-    deallocBuilder.createDeallocStack(allocInstr->getLoc(), allocInstr);
-  }
-
-  return allocInstr;
+  return alloc;
 }
 
 static void createResultTyInstrAndLoad(LoadableStorageAllocation &allocator,
@@ -1839,11 +1873,8 @@
     return;
   }
 
-  if (allUsesAreReplaceable(loadArg, pass.Mod, pass.Mapper)) {
-    allocator.replaceLoadWithCopyAddr(loadArg);
-  } else {
-    allocator.replaceLoadWithCopyAddrForModifiable(loadArg);
-  }
+  allocator.replaceLoad(loadArg);
+
   if (updateResultTy) {
     pass.resultTyInstsToMod.insert(newInstr);
   }
@@ -1852,8 +1883,6 @@
 static void rewriteFunction(StructLoweringState &pass,
                             LoadableStorageAllocation &allocator) {
 
-  GenericEnvironment *genEnv = pass.F->getGenericEnvironment();
-
   bool repeat = false;
   llvm::SetVector<SILInstruction *> currentModApplies;
   do {
@@ -1873,8 +1902,7 @@
         EnumElementDecl *decl = currCase.first;
         for (SILArgument *arg : currBB->getArguments()) {
           SILType storageType = arg->getType();
-          SILType newSILType =
-              pass.Mapper.getNewSILType(genEnv, storageType, pass.Mod);
+          SILType newSILType = pass.getNewSILType(storageType);
           if (storageType == newSILType) {
             newSILType = newSILType.getAddressType();
           }
@@ -1901,11 +1929,7 @@
             continue;
           }
 
-          if (allUsesAreReplaceable(loadArg, pass.Mod, pass.Mapper)) {
-            allocator.replaceLoadWithCopyAddr(loadArg);
-          } else {
-            allocator.replaceLoadWithCopyAddrForModifiable(loadArg);
-          }
+          allocator.replaceLoad(loadArg);
         }
         caseBBs.push_back(std::make_pair(decl, currBB));
       }
@@ -1927,33 +1951,10 @@
         currentModApplies.insert(applyInst);
       }
       ApplySite applySite = ApplySite(applyInst);
-      for (Operand &operand : applySite.getArgumentOperands()) {
-        SILValue currOperand = operand.get();
-        SILType silType = currOperand->getType();
-        if (isLargeLoadableType(genEnv, silType, pass.Mod)) {
-          auto currOperandInstr = dyn_cast<SingleValueInstruction>(currOperand);
-          // Get its storage location as a new operand
-          if (!currOperandInstr) {
-            allocateAndSetForArgumentOperand(pass, currOperand, applyInst);
-          } else if (auto *load = dyn_cast<LoadInst>(currOperandInstr)) {
-            // If the load is of a function type - do not replace it.
-            if (isFuncOrOptionalFuncType(load->getType())) {
-              continue;
-            }
-
-            if (allUsesAreReplaceable(load, pass.Mod, pass.Mapper)) {
-              allocator.replaceLoadWithCopyAddr(load);
-            } else {
-              allocator.replaceLoadWithCopyAddrForModifiable(load);
-            }
-          } else {
-            // TODO: peephole: special handling of known cases:
-            // ApplyInst, TupleExtractInst
-            allocateAndSetForInstrOperand(pass, currOperandInstr);
-          }
-        }
-      }
+      allocateAndSetAll(pass, allocator, applyInst,
+                        applySite.getArgumentOperands());
     }
+
     repeat = !pass.switchEnumInstsToMod.empty() ||
              !pass.structExtractInstsToMod.empty();
     assert(pass.applies.empty());
@@ -1982,8 +1983,7 @@
     auto *instr = pass.allocStackInstsToMod.pop_back_val();
     SILBuilderWithScope allocBuilder(instr);
     SILType currSILType = instr->getType();
-    SILType newSILType =
-        pass.Mapper.getNewSILType(genEnv, currSILType, pass.Mod);
+    SILType newSILType = pass.getNewSILType(currSILType);
     auto *newInstr = allocBuilder.createAllocStack(instr->getLoc(), newSILType,
                                                    instr->getVarInfo());
     instr->replaceAllUsesWith(newInstr);
@@ -1994,8 +1994,7 @@
     auto *instr = pass.pointerToAddrkInstsToMod.pop_back_val();
     SILBuilderWithScope pointerBuilder(instr);
     SILType currSILType = instr->getType();
-    SILType newSILType =
-        pass.Mapper.getNewSILType(genEnv, currSILType, pass.Mod);
+    SILType newSILType = pass.getNewSILType(currSILType);
     auto *newInstr = pointerBuilder.createPointerToAddress(
         instr->getLoc(), instr->getOperand(), newSILType.getAddressType(),
         instr->isStrict());
@@ -2071,8 +2070,7 @@
     // Update the return type of these instrs
     // Note: The operand was already updated!
     SILType currSILType = instr->getType().getObjectType();
-    SILType newSILType =
-        pass.Mapper.getNewSILType(genEnv, currSILType, pass.Mod);
+    SILType newSILType = pass.getNewSILType(currSILType);
     SILBuilderWithScope resultTyBuilder(instr);
     SILLocation Loc = instr->getLoc();
     SingleValueInstruction *newInstr = nullptr;
@@ -2206,13 +2204,8 @@
       SILBuilderWithScope retCopyBuilder(II);
       createOutlinedCopyCall(retCopyBuilder, retOp, retArg, pass, &regLoc);
     } else {
-      if (pass.F->hasQualifiedOwnership()) {
-        retBuilder.createStore(regLoc, retOp, retArg,
-                               StoreOwnershipQualifier::Init);
-      } else {
-        retBuilder.createStore(regLoc, retOp, retArg,
-                               StoreOwnershipQualifier::Unqualified);
-      }
+      retBuilder.createStore(regLoc, retOp, retArg,
+                             getStoreInitOwnership(pass, retOp->getType()));
     }
     auto emptyTy = retBuilder.getModule().Types.getLoweredType(
         TupleType::getEmpty(retBuilder.getModule().getASTContext()));
@@ -2220,6 +2213,11 @@
     retBuilder.createReturn(newRetTuple->getLoc(), newRetTuple);
     instr->eraseFromParent();
   }
+
+  while (!pass.modYieldInsts.empty()) {
+    YieldInst *inst = pass.modYieldInsts.pop_back_val();
+    allocateAndSetAll(pass, allocator, inst, inst->getAllOperands());
+  }
 }
 
 // Rewrite function return argument if it is a "function pointer"
@@ -2230,9 +2228,9 @@
   auto loweredTy = pass.F->getLoweredFunctionType();
   SILFunction *F = pass.F;
   SILType resultTy = loweredTy->getAllResultsType();
-  SILType newSILType = pass.Mapper.getNewSILType(genEnv, resultTy, pass.Mod);
+  SILType newSILType = pass.getNewSILType(resultTy);
   // We (currently) only care about function signatures
-  if (isLargeLoadableType(genEnv, resultTy, pass.Mod)) {
+  if (pass.isLargeLoadableType(resultTy)) {
     return true;
   } else if (containsFunctionSignature(genEnv, pass.Mod, resultTy,
                                        newSILType) &&
@@ -2310,8 +2308,10 @@
 
   // If we modified the function arguments - add to list of functions to clone
   if (modifiableFunction(funcType) &&
-      (rewrittenReturn || !pass.largeLoadableArgs.empty() ||
-       !pass.funcSigArgs.empty())) {
+      (rewrittenReturn ||
+       !pass.largeLoadableArgs.empty() ||
+       !pass.funcSigArgs.empty() ||
+       pass.hasLargeLoadableYields())) {
     modFuncs.insert(F);
   }
   // If we modified any applies - add them to the global list for recreation
@@ -2697,11 +2697,11 @@
   }
 
   // Scan the module for all references of the modified functions:
-  llvm::SetVector<FunctionRefInst *> funcRefs;
+  llvm::SetVector<FunctionRefBaseInst *> funcRefs;
   for (SILFunction &CurrF : *getModule()) {
     for (SILBasicBlock &BB : CurrF) {
       for (SILInstruction &I : BB) {
-        if (auto *FRI = dyn_cast<FunctionRefInst>(&I)) {
+        if (auto *FRI = dyn_cast<FunctionRefBaseInst>(&I)) {
           SILFunction *RefF = FRI->getReferencedFunction();
           if (modFuncs.count(RefF) != 0) {
             // Go over the uses and add them to lists to modify
@@ -2806,11 +2806,11 @@
   // Note: We don't need to update the witness tables and vtables
   // They just contain a pointer to the function
   // The pointer does not change
-  for (FunctionRefInst *instr : funcRefs) {
+  for (auto *instr : funcRefs) {
     SILFunction *F = instr->getReferencedFunction();
     SILBuilderWithScope refBuilder(instr);
-    FunctionRefInst *newInstr =
-        refBuilder.createFunctionRef(instr->getLoc(), F);
+    SingleValueInstruction *newInstr =
+        refBuilder.createFunctionRef(instr->getLoc(), F, instr->getKind());
     instr->replaceAllUsesWith(newInstr);
     instr->getParent()->erase(instr);
   }
diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp
index a62180e..d9b7e6b 100644
--- a/lib/IRGen/MetadataRequest.cpp
+++ b/lib/IRGen/MetadataRequest.cpp
@@ -218,6 +218,52 @@
 }
 
 
+llvm::Constant *IRGenModule::getAddrOfStringForMetadataRef(
+    StringRef symbolName,
+    bool shouldSetLowBit,
+    llvm::function_ref<ConstantInitFuture (ConstantInitBuilder &)> body) {
+  // Call this to form the return value.
+  auto returnValue = [&](llvm::Constant *addr) {
+    if (!shouldSetLowBit)
+      return addr;
+
+    auto bitConstant = llvm::ConstantInt::get(IntPtrTy, 1);
+    return llvm::ConstantExpr::getGetElementPtr(nullptr, addr, bitConstant);
+  };
+
+  // Check whether we already have an entry with this name.
+  auto &entry = StringsForTypeRef[symbolName];
+  if (entry.second) {
+    return returnValue(entry.second);
+  }
+
+  // Construct the initializer.
+  ConstantInitBuilder builder(*this);
+  auto finished = body(builder);
+
+  auto var = new llvm::GlobalVariable(Module, finished.getType(),
+                                      /*constant*/ true,
+                                      llvm::GlobalValue::LinkOnceODRLinkage,
+                                      nullptr,
+                                      symbolName);
+
+  ApplyIRLinkage({llvm::GlobalValue::LinkOnceODRLinkage,
+    llvm::GlobalValue::HiddenVisibility,
+    llvm::GlobalValue::DefaultStorageClass})
+  .to(var);
+  var->setAlignment(2);
+  setTrueConstGlobal(var);
+  var->setSection(getReflectionTypeRefSectionName());
+
+  finished.installInGlobal(var);
+
+  // Drill down to the i8* at the beginning of the constant.
+  auto addr = llvm::ConstantExpr::getBitCast(var, Int8PtrTy);
+  StringsForTypeRef[symbolName] = { var, addr };
+
+  return returnValue(addr);
+}
+
 llvm::Constant *IRGenModule::getAddrOfStringForTypeRef(StringRef str,
                                                        MangledTypeRefRole role){
   return getAddrOfStringForTypeRef(SymbolicMangling{str, {}}, role);
@@ -317,7 +363,7 @@
                                       llvm::GlobalValue::LinkOnceODRLinkage,
                                       nullptr,
                                       symbolName);
-  var->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  ApplyIRLinkage(IRLinkage::InternalLinkOnceODR).to(var);
   var->setAlignment(2);
   setTrueConstGlobal(var);
   var->setSection(getReflectionTypeRefSectionName());
diff --git a/lib/Immediate/REPL.cpp b/lib/Immediate/REPL.cpp
index d15f85a..a18bf7a 100644
--- a/lib/Immediate/REPL.cpp
+++ b/lib/Immediate/REPL.cpp
@@ -171,18 +171,17 @@
 
   ModuleDecl::ImportedModule ImportOfMostRecentModule{
       /*AccessPath*/{}, MostRecentModule};
-  REPLInputFile.addImports(std::make_pair(ImportOfMostRecentModule,
-                                          SourceFile::ImportOptions()));
+  REPLInputFile.addImports(SourceFile::ImportedModuleDesc(
+      ImportOfMostRecentModule, SourceFile::ImportOptions()));
 
   SmallVector<ModuleDecl::ImportedModule, 8> Imports;
   MostRecentModule->getImportedModules(Imports,
                                        ModuleDecl::ImportFilter::Private);
   if (!Imports.empty()) {
-    SmallVector<std::pair<ModuleDecl::ImportedModule,
-                          SourceFile::ImportOptions>, 8> ImportsWithOptions;
+    SmallVector<SourceFile::ImportedModuleDesc, 8> ImportsWithOptions;
     for (auto Import : Imports) {
-      ImportsWithOptions.emplace_back(Import,
-                                      SourceFile::ImportFlags::Exported);
+      ImportsWithOptions.emplace_back(SourceFile::ImportedModuleDesc(
+          Import, SourceFile::ImportFlags::Exported));
     }
     REPLInputFile.addImports(ImportsWithOptions);
   }
diff --git a/lib/Option/SanitizerOptions.cpp b/lib/Option/SanitizerOptions.cpp
index 287ab90..5cd32bf 100644
--- a/lib/Option/SanitizerOptions.cpp
+++ b/lib/Option/SanitizerOptions.cpp
@@ -37,6 +37,8 @@
     return "thread";
   case SanitizerKind::Fuzzer:
     return "fuzzer";
+  case SanitizerKind::Undefined:
+    return "undefined";
   }
   llvm_unreachable("Unsupported sanitizer");
 }
@@ -49,6 +51,8 @@
     return "tsan";
   case SanitizerKind::Fuzzer:
     return "fuzzer";
+  case SanitizerKind::Undefined:
+    return "ubsan";
   }
   llvm_unreachable("Unsupported sanitizer");
 }
@@ -134,6 +138,7 @@
         .Case("address", SanitizerKind::Address)
         .Case("thread", SanitizerKind::Thread)
         .Case("fuzzer", SanitizerKind::Fuzzer)
+        .Case("undefined", SanitizerKind::Undefined)
         .Default(None);
     bool isShared = kind && *kind != SanitizerKind::Fuzzer;
     if (!kind) {
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 1b10de1..d46cfb4 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -307,27 +307,6 @@
   return FoundTopLevelCodeToExecute;
 }
 
-static Optional<StringRef>
-getStringLiteralIfNotInterpolated(Parser &P, SourceLoc Loc, const Token &Tok,
-                                  StringRef DiagText) {
-  // FIXME: Support extended escaping string literal.
-  if (Tok.getCustomDelimiterLen()) {
-    P.diagnose(Loc, diag::attr_extended_escaping_string, DiagText);
-    return None;
-  }
-
-  SmallVector<Lexer::StringSegment, 1> Segments;
-  P.L->getStringLiteralSegments(Tok, Segments);
-  if (Segments.size() != 1 ||
-      Segments.front().Kind == Lexer::StringSegment::Expr) {
-   P.diagnose(Loc, diag::attr_interpolated_string, DiagText);
-   return None;
-  }
-
-  return P.SourceMgr.extractText(CharSourceRange(Segments.front().Loc,
-                                                 Segments.front().Length));
-}
-
 ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
     SourceLoc AtLoc, SourceLoc AttrLoc, StringRef AttrName) {
   // Check 'Tok', return false if ':' or '=' cannot be found.
@@ -439,8 +418,8 @@
         break;
       }
 
-      auto Value = getStringLiteralIfNotInterpolated(*this, AttrLoc, Tok,
-                                                     ArgumentKindStr);
+      auto Value = getStringLiteralIfNotInterpolated(
+          AttrLoc, ("'" + ArgumentKindStr + "'").str());
       consumeToken();
       if (!Value) {
         AnyArgumentInvalid = true;
@@ -1155,8 +1134,8 @@
       return false;
     }
 
-    Optional<StringRef> AsmName =
-      getStringLiteralIfNotInterpolated(*this, Loc, Tok, AttrName);
+    Optional<StringRef> AsmName = getStringLiteralIfNotInterpolated(
+        Loc, ("'" + AttrName + "'").str());
 
     consumeToken(tok::string_literal);
 
@@ -1269,7 +1248,8 @@
       return false;
     }
 
-    auto Value = getStringLiteralIfNotInterpolated(*this, Loc, Tok, AttrName);
+    auto Value = getStringLiteralIfNotInterpolated(
+        Loc, ("'" + AttrName + "'").str());
 
     consumeToken(tok::string_literal);
 
@@ -1418,7 +1398,58 @@
     }
     break;
   }
+  case DAK_PrivateImport: {
+    // Parse the leading '('.
+    if (Tok.isNot(tok::l_paren)) {
+      diagnose(Loc, diag::attr_expected_lparen, AttrName,
+               DeclAttribute::isDeclModifier(DK));
+      return false;
+    }
+    SourceLoc LParenLoc = consumeToken(tok::l_paren);
+    Optional<StringRef> filename;
+    {
+      SyntaxParsingContext ContentContext(
+          SyntaxContext, SyntaxKind::NamedAttributeStringArgument);
 
+      // Parse 'sourceFile'.
+      if (Tok.getText() != "sourceFile") {
+        diagnose(LParenLoc, diag::attr_private_import_expected_sourcefile);
+        return false;
+      }
+      auto ForLoc = consumeToken();
+
+      // Parse ':'.
+      if (Tok.getKind() != tok::colon) {
+        diagnose(ForLoc, diag::attr_private_import_expected_colon);
+        return false;
+      }
+      auto ColonLoc = consumeToken(tok::colon);
+
+      // Parse '"'function-name'"'
+      if (Tok.isNot(tok::string_literal)) {
+        diagnose(ColonLoc, diag::attr_private_import_expected_sourcefile_name);
+        return false;
+      }
+      filename = getStringLiteralIfNotInterpolated(Loc, "_private");
+      if (!filename.hasValue()) {
+        diagnose(ColonLoc, diag::attr_private_import_expected_sourcefile_name);
+        return false;
+      }
+      consumeToken(tok::string_literal);
+    }
+    // Parse the matching ')'.
+    SourceLoc RParenLoc;
+    bool Invalid = parseMatchingToken(tok::r_paren, RParenLoc,
+                                      diag::attr_private_import_expected_rparen,
+                                      LParenLoc);
+    if (Invalid)
+      return false;
+    auto *attr = PrivateImportAttr::create(Context, AtLoc, Loc, LParenLoc,
+                                           *filename, RParenLoc);
+    Attributes.add(attr);
+
+    break;
+  }
   case DAK_ObjC: {
     // Unnamed @objc attribute.
     if (Tok.isNot(tok::l_paren)) {
@@ -1464,6 +1495,62 @@
     break;
   }
 
+
+  case DAK_DynamicReplacement: {
+    // Parse the leading '('.
+    if (Tok.isNot(tok::l_paren)) {
+      diagnose(Loc, diag::attr_expected_lparen, AttrName,
+               DeclAttribute::isDeclModifier(DK));
+      return false;
+    }
+
+    SourceLoc LParenLoc = consumeToken(tok::l_paren);
+    DeclName replacedFunction;
+    {
+      SyntaxParsingContext ContentContext(
+          SyntaxContext, SyntaxKind::NamedAttributeStringArgument);
+
+      // Parse 'for'.
+      if (Tok.getText() != "for") {
+        diagnose(Loc, diag::attr_dynamic_replacement_expected_for);
+        return false;
+      }
+      auto ForLoc = consumeToken();
+
+      // Parse ':'.
+      if (Tok.getText() != ":") {
+        diagnose(ForLoc, diag::attr_dynamic_replacement_expected_colon);
+        return false;
+      }
+      consumeToken(tok::colon);
+      {
+        SyntaxParsingContext ContentContext(SyntaxContext,
+                                            SyntaxKind::DeclName);
+
+        DeclNameLoc loc;
+        replacedFunction = parseUnqualifiedDeclName(
+            true, loc, diag::attr_dynamic_replacement_expected_function,
+            /*allowOperators*/ true, /*allowZeroArgCompoundNames*/ true,
+            /*allowDeinitAndSubscript*/ true);
+      }
+    }
+
+    // Parse the matching ')'.
+    SourceLoc RParenLoc;
+    bool Invalid = parseMatchingToken(
+        tok::r_paren, RParenLoc, diag::attr_dynamic_replacement_expected_rparen,
+        LParenLoc);
+    if (Invalid) {
+      return false;
+    }
+
+
+    DynamicReplacementAttr *attr = DynamicReplacementAttr::create(
+        Context, AtLoc, Loc, LParenLoc, replacedFunction, RParenLoc);
+    Attributes.add(attr);
+    break;
+  }
+
   case DAK_Specialize: {
     if (Tok.isNot(tok::l_paren)) {
       diagnose(Loc, diag::attr_expected_lparen, AttrName,
@@ -2809,7 +2896,10 @@
   if (auto SF = CurDeclContext->getParentSourceFile()) {
     if (!getScopeInfo().isInactiveConfigBlock()) {
       for (auto Attr : Attributes) {
-        if (isa<ObjCAttr>(Attr) || isa<DynamicAttr>(Attr))
+        if (isa<ObjCAttr>(Attr) ||
+            /* Pre Swift 5 dymamic implied @objc */
+            (!Context.LangOpts.isSwiftVersionAtLeast(5) &&
+             isa<DynamicAttr>(Attr)))
           SF->AttrsRequiringFoundation.insert(Attr);
       }
     }
@@ -3607,7 +3697,7 @@
       }
 
       Filename =
-          getStringLiteralIfNotInterpolated(*this, Loc, Tok, "#sourceLocation");
+          getStringLiteralIfNotInterpolated(Loc, "'#sourceLocation'");
       if (!Filename.hasValue())
         return makeParserError();
       consumeToken(tok::string_literal);
@@ -3668,8 +3758,7 @@
       return makeParserError();
     }
     
-    Filename = getStringLiteralIfNotInterpolated(*this, Loc, Tok,
-                                                 "#line");
+    Filename = getStringLiteralIfNotInterpolated(Loc, "'#line'");
     if (!Filename.hasValue())
       return makeParserError();
   }
@@ -3917,7 +4006,6 @@
                                     SourceLoc StaticLoc,
                                     Parser::ParseDeclOptions Flags,
                                     AccessorKind Kind,
-                                    AddressorKind addressorKind,
                                     AbstractStorageDecl *storage,
                                     Parser *P, SourceLoc AccessorKeywordLoc) {
   // First task, set up the value argument list.  This is the "newValue" name
@@ -3953,6 +4041,7 @@
                                      storageParam->getName(),
                                      P->CurDeclContext);
         accessorParam->setVariadic(storageParam->isVariadic());
+        accessorParam->setAutoClosure(storageParam->isAutoClosure());
 
         // The cloned parameter is implicit.
         accessorParam->setImplicit();
@@ -3981,7 +4070,7 @@
   auto *D = AccessorDecl::create(P->Context,
                                  /*FIXME FuncLoc=*/DeclLoc,
                                  AccessorKeywordLoc,
-                                 Kind, addressorKind, storage,
+                                 Kind, storage,
                                  StaticLoc, StaticSpellingKind::None,
                                  /*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
                                  (GenericParams
@@ -4108,7 +4197,6 @@
 
 /// Returns a descriptive name for the given accessor/addressor kind.
 static StringRef getAccessorNameForDiagnostic(AccessorKind accessorKind,
-                                              AddressorKind addressorKind,
                                               bool article) {
   switch (accessorKind) {
   case AccessorKind::Get:
@@ -4134,13 +4222,11 @@
 static StringRef getAccessorNameForDiagnostic(AccessorDecl *accessor,
                                               bool article) {
   return getAccessorNameForDiagnostic(accessor->getAccessorKind(),
-                                      accessor->getAddressorKind(),
                                       article);
 }
 
 static void diagnoseRedundantAccessors(Parser &P, SourceLoc loc,
                                        AccessorKind accessorKind,
-                                       AddressorKind addressorKind,
                                        bool isSubscript,
                                        AccessorDecl *previous) {
   assert(accessorKind == previous->getAccessorKind());
@@ -4215,7 +4301,6 @@
 static bool parseAccessorIntroducer(Parser &P,
                                     DeclAttributes &Attributes,
                                     AccessorKind &Kind,
-                                    AddressorKind &addressorKind,
                                     SourceLoc &Loc) {
   assert(Attributes.isEmpty());
   bool FoundCCToken;
@@ -4246,11 +4331,6 @@
   else if (P.Tok.getRawText() == #KEYWORD) {                                   \
     Kind = AccessorKind::ID;                                                   \
   }
-#define ANY_ADDRESSOR(ID, ADDRESSOR_ID, KEYWORD)                               \
-  else if (P.Tok.getRawText() == #KEYWORD) {                                   \
-    Kind = AccessorKind::ID;                                                   \
-    addressorKind = AddressorKind::ADDRESSOR_ID;                               \
-  }
 #include "swift/AST/AccessorKinds.def"
   else {
     return true;
@@ -4303,8 +4383,8 @@
     auto getter =
         createAccessorFunc(Tok.getLoc(), /*ValueNamePattern*/ nullptr,
                            GenericParams, Indices, ElementTy, StaticLoc, Flags,
-                           AccessorKind::Get, AddressorKind::NotAddressor,
-                           storage, this, /*AccessorKeywordLoc*/ SourceLoc());
+                           AccessorKind::Get, storage, this,
+                           /*AccessorKeywordLoc*/ SourceLoc());
     accessors.add(getter);
     parseAbstractFunctionBody(getter);
     accessors.RBLoc = getter->getEndLoc();
@@ -4325,10 +4405,9 @@
     // Parse introducer if possible.
     DeclAttributes Attributes;
     AccessorKind Kind = AccessorKind::Get;
-    AddressorKind addressorKind = AddressorKind::NotAddressor;
     SourceLoc Loc;
     bool NotAccessor = parseAccessorIntroducer(
-        *this, Attributes, Kind, addressorKind, Loc);
+        *this, Attributes, Kind, Loc);
     if (NotAccessor) {
       AccessorCtx->setTransparent();
       AccessorCtx.reset();
@@ -4342,8 +4421,7 @@
             auto getter = createAccessorFunc(
                 accessors.LBLoc, /*ValueNamePattern*/ nullptr, GenericParams,
                 Indices, ElementTy, StaticLoc, Flags, AccessorKind::Get,
-                AddressorKind::NotAddressor, storage, this,
-                /*AccessorKeywordLoc*/ SourceLoc());
+                storage, this, /*AccessorKeywordLoc*/ SourceLoc());
             accessors.add(getter);
             CodeCompletion->setParsedDecl(getter);
           } else {
@@ -4400,12 +4478,12 @@
     // Set up a function declaration.
     auto accessor = createAccessorFunc(Loc, ValueNamePattern, GenericParams,
                                        Indices, ElementTy, StaticLoc, Flags,
-                                       Kind, addressorKind, storage, this, Loc);
+                                       Kind, storage, this, Loc);
     accessor->getAttrs() = Attributes;
 
     // Collect this accessor and detect conflicts.
     if (auto existingAccessor = accessors.add(accessor)) {
-      diagnoseRedundantAccessors(*this, Loc, Kind, addressorKind,
+      diagnoseRedundantAccessors(*this, Loc, Kind,
                                  /*subscript*/Indices != nullptr,
                                  existingAccessor);
     }
@@ -4594,7 +4672,7 @@
   }
 
   // Reject accessors on 'let's after parsing them (for better recovery).
-  if (PrimaryVar->isLet() && !Attributes.hasAttribute<SILStoredAttr>()) {
+  if (PrimaryVar->isLet() && !Attributes.hasAttribute<HasStorageAttr>()) {
     Diag<> DiagID;
     if (accessors.WillSet || accessors.DidSet)
       DiagID = diag::let_cannot_be_observing_property;
@@ -4715,7 +4793,6 @@
     // We never use this to create addressors.
     assert(kind != AccessorKind::Address &&
            kind != AccessorKind::MutableAddress);
-    auto addressorKind = AddressorKind::NotAddressor;
 
     // Create the paramter list for a setter.
     ParameterList *argList = nullptr;
@@ -4730,7 +4807,7 @@
 
     auto accessor = createAccessorFunc(SourceLoc(), argList,
                                        genericParams, indices, elementTy,
-                                       staticLoc, flags, kind, addressorKind,
+                                       staticLoc, flags, kind,
                                        storage, &P, SourceLoc());
     accessor->setImplicit();
     add(accessor);
@@ -4858,9 +4935,9 @@
     readWriteImpl = ReadWriteImplKind::Immutable;
   }
 
-  // Allow the sil_stored attribute to override all the accessors we parsed
+  // Allow the _hasStorage attribute to override all the accessors we parsed
   // when making the final classification.
-  if (attrs.hasAttribute<SILStoredAttr>()) {
+  if (attrs.hasAttribute<HasStorageAttr>()) {
     return StorageImplInfo::getSimpleStored(StorageIsMutable_t(Set != nullptr));
   }
 
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 860ef80..17c73ed 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2122,7 +2122,8 @@
                                           DeclNameLoc &loc,
                                           const Diagnostic &diag,
                                           bool allowOperators,
-                                          bool allowZeroArgCompoundNames) {
+                                          bool allowZeroArgCompoundNames,
+                                          bool allowDeinitAndSubscript) {
   // Consume the base name.
   DeclBaseName baseName;
   SourceLoc baseNameLoc;
@@ -2137,6 +2138,10 @@
     // not as a keyword.
     if (Tok.is(tok::kw_init))
       baseName = DeclBaseName::createConstructor();
+    else if (allowDeinitAndSubscript &&Tok.is(tok::kw_deinit))
+      baseName = DeclBaseName::createDestructor();
+    else if (allowDeinitAndSubscript &&Tok.is(tok::kw_subscript))
+      baseName = DeclBaseName::createSubscript();
     else
       baseName = Context.getIdentifier(Tok.getText());
     Tok.setKind(tok::identifier);
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index a3dcbcc..b8af9b3 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -483,6 +483,14 @@
                                                              parsingEnumElt);
       }
       param->getTypeLoc() = TypeLoc(type);
+
+      // If there is `@autoclosure` attribute associated with the type
+      // let's mark that in the declaration as well, because it
+      // belongs to both type flags and declaration.
+      if (auto *ATR = dyn_cast<AttributedTypeRepr>(type)) {
+        auto &attrs = ATR->getAttrs();
+        param->setAutoClosure(attrs.has(TypeAttrKind::TAK_autoclosure));
+      }
     } else if (paramContext != Parser::ParameterContextKind::Closure) {
       // Non-closure parameters require a type.
       if (!param->isInvalid())
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 0c6b36e..f6709b7 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -53,6 +53,7 @@
   case tok::kw_case:
   case tok::kw_default:
   case tok::kw_yield:
+  case tok::pound_assert:
   case tok::pound_if:
   case tok::pound_warning:
   case tok::pound_error:
@@ -636,6 +637,10 @@
     return makeParserResult(
         new (Context) FallthroughStmt(consumeToken(tok::kw_fallthrough)));
   }
+  case tok::pound_assert:
+    if (LabelInfo) diagnose(LabelInfo.Loc, diag::invalid_label_on_stmt);
+    if (tryLoc.isValid()) diagnose(tryLoc, diag::try_on_stmt, Tok.getText());
+    return parseStmtPoundAssert();
   }
 }
 
@@ -2400,3 +2405,53 @@
                                !BoundDecls.empty(), UnknownAttrLoc, ColonLoc,
                                Body));
 }
+
+/// stmt-pound-assert:
+///   '#assert' '(' expr (',' string_literal)? ')'
+ParserResult<Stmt> Parser::parseStmtPoundAssert() {
+  SyntaxContext->setCreateSyntax(SyntaxKind::PoundAssertStmt);
+
+  SourceLoc startLoc = consumeToken(tok::pound_assert);
+  SourceLoc endLoc;
+
+  if (Tok.isNot(tok::l_paren)) {
+    diagnose(Tok, diag::pound_assert_expected_lparen);
+    return makeParserError();
+  }
+  SourceLoc LBLoc = consumeToken(tok::l_paren);
+
+  auto conditionExprResult = parseExpr(diag::pound_assert_expected_expression);
+  if (conditionExprResult.isParseError())
+    return ParserStatus(conditionExprResult);
+
+  StringRef message;
+  if (consumeIf(tok::comma)) {
+    if (Tok.isNot(tok::string_literal)) {
+      diagnose(Tok.getLoc(), diag::pound_assert_expected_string_literal);
+      return makeParserError();
+    }
+
+    auto messageOpt = getStringLiteralIfNotInterpolated(Tok.getLoc(),
+                                                        "'#assert' message");
+    consumeToken();
+    if (!messageOpt)
+      return makeParserError();
+
+    message = *messageOpt;
+  }
+
+  if (parseMatchingToken(tok::r_paren, endLoc,
+                         diag::pound_assert_expected_rparen, LBLoc)) {
+    return makeParserError();
+  }
+
+  // We check this after consuming everything, so that the SyntaxContext
+  // understands this statement even when the feature is disabled.
+  if (!Context.LangOpts.EnableExperimentalStaticAssert) {
+    diagnose(startLoc, diag::pound_assert_disabled);
+    return makeParserError();
+  }
+
+  return makeParserResult<Stmt>(new (Context) PoundAssertStmt(
+      SourceRange(startLoc, endLoc), conditionExprResult.get(), message));
+}
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index fe48ebe..ea3f509 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -1014,6 +1014,29 @@
   diagnose(Prev->getLoc(), diag::previous_decldef, Prev->getBaseName());
 }
 
+Optional<StringRef>
+Parser::getStringLiteralIfNotInterpolated(SourceLoc Loc,
+                                          StringRef DiagText) {
+  assert(Tok.is(tok::string_literal));
+
+  // FIXME: Support extended escaping string literal.
+  if (Tok.getCustomDelimiterLen()) {
+    diagnose(Loc, diag::forbidden_extended_escaping_string, DiagText);
+    return None;
+  }
+
+  SmallVector<Lexer::StringSegment, 1> Segments;
+  L->getStringLiteralSegments(Tok, Segments);
+  if (Segments.size() != 1 ||
+      Segments.front().Kind == Lexer::StringSegment::Expr) {
+    diagnose(Loc, diag::forbidden_interpolated_string, DiagText);
+    return None;
+  }
+
+  return SourceMgr.extractText(CharSourceRange(Segments.front().Loc,
+                                               Segments.front().Length));
+}
+
 struct ParserUnit::Implementation {
   LangOptions LangOpts;
   SearchPathOptions SearchPathOpts;
diff --git a/lib/Parse/SyntaxParsingCache.cpp b/lib/Parse/SyntaxParsingCache.cpp
index fdaa653..1da6f86 100644
--- a/lib/Parse/SyntaxParsingCache.cpp
+++ b/lib/Parse/SyntaxParsingCache.cpp
@@ -16,6 +16,13 @@
 using namespace swift;
 using namespace swift::syntax;
 
+void SyntaxParsingCache::addEdit(size_t Start, size_t End,
+                                 size_t ReplacementLength) {
+  assert((Edits.empty() || Edits.back().End <= Start) &&
+         "'Start' must be greater than or equal to 'End' of the previous edit");
+  Edits.emplace_back(Start, End, ReplacementLength);
+}
+
 bool SyntaxParsingCache::nodeCanBeReused(const Syntax &Node, size_t NodeStart,
                                          size_t Position,
                                          SyntaxKind Kind) const {
@@ -80,23 +87,31 @@
   return llvm::None;
 }
 
-size_t SyntaxParsingCache::translateToPreEditPosition(
-    size_t PostEditPosition, llvm::SmallVector<SourceEdit, 4> Edits) {
+Optional<size_t>
+SyntaxParsingCache::translateToPreEditPosition(size_t PostEditPosition,
+                                               ArrayRef<SourceEdit> Edits) {
   size_t Position = PostEditPosition;
-  for (auto I = Edits.begin(), E = Edits.end(); I != E; ++I) {
-    auto Edit = *I;
-    if (Edit.End + Edit.ReplacementLength - Edit.originalLength() <= Position) {
-      Position = Position - Edit.ReplacementLength + Edit.originalLength();
-    }
+  for (auto &Edit : Edits) {
+    if (Edit.Start > Position)
+      // Remaining edits doesn't affect the position. (Edits are sorted)
+      break;
+    if (Edit.Start + Edit.ReplacementLength > Position)
+      // This is a position inserted by the edit, and thus doesn't exist in the
+      // pre-edit version of the file.
+      return None;
+
+    Position = Position - Edit.ReplacementLength + Edit.originalLength();
   }
   return Position;
 }
 
 llvm::Optional<Syntax> SyntaxParsingCache::lookUp(size_t NewPosition,
                                                   SyntaxKind Kind) {
-  size_t OldPosition = translateToPreEditPosition(NewPosition, Edits);
+  Optional<size_t> OldPosition = translateToPreEditPosition(NewPosition, Edits);
+  if (!OldPosition.hasValue())
+    return None;
 
-  auto Node = lookUpFrom(OldSyntaxTree, /*NodeStart=*/0, OldPosition, Kind);
+  auto Node = lookUpFrom(OldSyntaxTree, /*NodeStart=*/0, *OldPosition, Kind);
   if (Node.hasValue()) {
     ReusedNodeIds.insert(Node->getId());
   }
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index e7df5b1..b244900 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -264,7 +264,7 @@
         return true;
       }
 
-      Result = ValueOwnershipKind(*Iter);
+      Result = T(*Iter);
       return false;
     }
 
@@ -901,7 +901,11 @@
 static bool parseDeclSILOptional(bool *isTransparent,
                                  IsSerialized_t *isSerialized,
                                  bool *isCanonical,
-                                 IsThunk_t *isThunk, bool *isGlobalInit,
+                                 IsThunk_t *isThunk,
+                                 IsDynamicallyReplaceable_t *isDynamic,
+                                 SILFunction **dynamicallyReplacedFunction,
+                                 Identifier *objCReplacementFor,
+                                 bool *isGlobalInit,
                                  Inline_t *inlineStrategy,
                                  OptimizationMode *optimizationMode,
                                  bool *isLet, bool *isWeakLinked,
@@ -909,7 +913,8 @@
                                  SmallVectorImpl<std::string> *Semantics,
                                  SmallVectorImpl<ParsedSpecAttr> *SpecAttrs,
                                  ValueDecl **ClangDecl,
-                                 EffectsKind *MRK, SILParser &SP) {
+                                 EffectsKind *MRK, SILParser &SP,
+                                 SILModule &M) {
   while (SP.P.consumeIf(tok::l_square)) {
     if (isLet && SP.P.Tok.is(tok::kw_let)) {
       *isLet = true;
@@ -924,6 +929,8 @@
       *isTransparent = true;
     else if (isSerialized && SP.P.Tok.getText() == "serialized")
       *isSerialized = IsSerialized;
+    else if (isDynamic && SP.P.Tok.getText() == "dynamically_replacable")
+      *isDynamic = IsDynamic;
     else if (isSerialized && SP.P.Tok.getText() == "serializable")
       *isSerialized = IsSerializable;
     else if (isCanonical && SP.P.Tok.getText() == "canonical")
@@ -959,7 +966,41 @@
       *MRK = EffectsKind::ReadWrite;
     else if (MRK && SP.P.Tok.getText() == "releasenone")
       *MRK = EffectsKind::ReleaseNone;
-    else if (Semantics && SP.P.Tok.getText() == "_semantics") {
+    else if  (dynamicallyReplacedFunction && SP.P.Tok.getText() == "dynamic_replacement_for") {
+      SP.P.consumeToken(tok::identifier);
+      if (SP.P.Tok.getKind() != tok::string_literal) {
+        SP.P.diagnose(SP.P.Tok, diag::expected_in_attribute_list);
+        return true;
+      }
+      // Drop the double quotes.
+      StringRef replacedFunc = SP.P.Tok.getText().drop_front().drop_back();
+      SILFunction *Func = M.lookUpFunction(replacedFunc.str());
+      if (!Func) {
+        Identifier Id = SP.P.Context.getIdentifier(replacedFunc);
+        SP.P.diagnose(SP.P.Tok, diag::sil_dynamically_replaced_func_not_found,
+                      Id);
+        return true;
+      }
+      *dynamicallyReplacedFunction = Func;
+      SP.P.consumeToken(tok::string_literal);
+
+      SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
+      continue;
+    } else if (objCReplacementFor &&
+               SP.P.Tok.getText() == "objc_replacement_for") {
+      SP.P.consumeToken(tok::identifier);
+      if (SP.P.Tok.getKind() != tok::string_literal) {
+        SP.P.diagnose(SP.P.Tok, diag::expected_in_attribute_list);
+        return true;
+      }
+      // Drop the double quotes.
+      StringRef replacedFunc = SP.P.Tok.getText().drop_front().drop_back();
+      *objCReplacementFor = SP.P.Context.getIdentifier(replacedFunc);
+      SP.P.consumeToken(tok::string_literal);
+
+      SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
+      continue;
+    } else if (Semantics && SP.P.Tok.getText() == "_semantics") {
       SP.P.consumeToken(tok::identifier);
       if (SP.P.Tok.getKind() != tok::string_literal) {
         SP.P.diagnose(SP.P.Tok, diag::expected_in_attribute_list);
@@ -973,8 +1014,7 @@
 
       SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
       continue;
-    }
-    else if (SpecAttrs && SP.P.Tok.getText() == "_specialize") {
+    } else if (SpecAttrs && SP.P.Tok.getText() == "_specialize") {
       SourceLoc AtLoc = SP.P.Tok.getLoc();
       SourceLoc Loc(AtLoc);
 
@@ -2555,6 +2595,22 @@
     ResultVal = B.createFunctionRef(InstLoc, Fn);
     break;
   }
+  case SILInstructionKind::DynamicFunctionRefInst: {
+    SILFunction *Fn;
+    if (parseSILFunctionRef(InstLoc, Fn) ||
+        parseSILDebugLocation(InstLoc, B))
+      return true;
+    ResultVal = B.createDynamicFunctionRef(InstLoc, Fn);
+    break;
+  }
+  case SILInstructionKind::PreviousDynamicFunctionRefInst: {
+    SILFunction *Fn;
+    if (parseSILFunctionRef(InstLoc, Fn) ||
+        parseSILDebugLocation(InstLoc, B))
+      return true;
+    ResultVal = B.createPreviousDynamicFunctionRef(InstLoc, Fn);
+    break;
+  }
   case SILInstructionKind::BuiltinInst: {
     if (P.Tok.getKind() != tok::string_literal) {
       P.diagnose(P.Tok, diag::expected_tok_in_sil_instr,"builtin name");
@@ -5168,6 +5224,7 @@
     F->setUnqualifiedOwnership();
   }
   B.setInsertionPoint(BB);
+  B.setHasOwnership(F->hasQualifiedOwnership());
   do {
     if (parseSILInstruction(B))
       return true;
@@ -5209,6 +5266,7 @@
   bool isTransparent = false;
   IsSerialized_t isSerialized = IsNotSerialized;
   bool isCanonical = false;
+  IsDynamicallyReplaceable_t isDynamic = IsNotDynamic;
   IsThunk_t isThunk = IsNotThunk;
   bool isGlobalInit = false, isWeakLinked = false;
   bool isWithoutActuallyEscapingThunk = false;
@@ -5218,13 +5276,15 @@
   SmallVector<ParsedSpecAttr, 4> SpecAttrs;
   ValueDecl *ClangDecl = nullptr;
   EffectsKind MRK = EffectsKind::Unspecified;
+  SILFunction *DynamicallyReplacedFunction = nullptr;
+  Identifier objCReplacementFor;
   if (parseSILLinkage(FnLinkage, P) ||
       parseDeclSILOptional(&isTransparent, &isSerialized, &isCanonical,
-                           &isThunk, &isGlobalInit,
-                           &inlineStrategy, &optimizationMode, nullptr,
-                           &isWeakLinked, &isWithoutActuallyEscapingThunk,
-                           &Semantics, &SpecAttrs,
-                           &ClangDecl, &MRK, FunctionState) ||
+                           &isThunk, &isDynamic, &DynamicallyReplacedFunction,
+                           &objCReplacementFor, &isGlobalInit, &inlineStrategy,
+                           &optimizationMode, nullptr, &isWeakLinked,
+                           &isWithoutActuallyEscapingThunk, &Semantics,
+                           &SpecAttrs, &ClangDecl, &MRK, FunctionState, M) ||
       P.parseToken(tok::at_sign, diag::expected_sil_function_name) ||
       P.parseIdentifier(FnName, FnNameLoc, diag::expected_sil_function_name) ||
       P.parseToken(tok::colon, diag::expected_sil_type))
@@ -5249,6 +5309,11 @@
     FunctionState.F->setSerialized(IsSerialized_t(isSerialized));
     FunctionState.F->setWasDeserializedCanonical(isCanonical);
     FunctionState.F->setThunk(IsThunk_t(isThunk));
+    FunctionState.F->setIsDynamic(isDynamic);
+    FunctionState.F->setDynamicallyReplacedFunction(
+        DynamicallyReplacedFunction);
+    if (!objCReplacementFor.empty())
+      FunctionState.F->setObjCReplacement(objCReplacementFor);
     FunctionState.F->setGlobalInit(isGlobalInit);
     FunctionState.F->setWeakLinked(isWeakLinked);
     FunctionState.F->setWithoutActuallyEscapingThunk(
@@ -5431,8 +5496,9 @@
   SILParser State(P);
   if (parseSILLinkage(GlobalLinkage, P) ||
       parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr,
-                           nullptr, nullptr, &isLet, nullptr, nullptr, nullptr,
-                           nullptr, nullptr, nullptr, State) ||
+                           nullptr, nullptr, nullptr, nullptr, nullptr, &isLet,
+                           nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+                           State, M) ||
       P.parseToken(tok::at_sign, diag::expected_sil_value_name) ||
       P.parseIdentifier(GlobalName, NameLoc, diag::expected_sil_value_name) ||
       P.parseToken(tok::colon, diag::expected_sil_type))
@@ -5480,7 +5546,8 @@
   IsSerialized_t Serialized = IsNotSerialized;
   if (parseDeclSILOptional(nullptr, &Serialized, nullptr, nullptr, nullptr,
                            nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
-                           nullptr, nullptr, nullptr, SP))
+                           nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+                           SP, M))
     return true;
   
   ValueDecl *VD;
@@ -5548,7 +5615,8 @@
   IsSerialized_t Serialized = IsNotSerialized;
   if (parseDeclSILOptional(nullptr, &Serialized, nullptr, nullptr, nullptr,
                            nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
-                           nullptr, nullptr, nullptr, VTableState))
+                           nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+                           VTableState, M))
     return true;
 
   // Parse the class name.
@@ -6070,7 +6138,8 @@
   IsSerialized_t isSerialized = IsNotSerialized;
   if (parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr,
                            nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
-                           nullptr, nullptr, nullptr, WitnessState))
+                           nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+                           WitnessState, M))
     return true;
 
   Scope S(&P, ScopeKind::TopLevel);
diff --git a/lib/ParseSIL/SILParserFunctionBuilder.h b/lib/ParseSIL/SILParserFunctionBuilder.h
index 23273e9..1714056 100644
--- a/lib/ParseSIL/SILParserFunctionBuilder.h
+++ b/lib/ParseSIL/SILParserFunctionBuilder.h
@@ -26,9 +26,9 @@
   SILFunction *createFunctionForForwardReference(StringRef name,
                                                  CanSILFunctionType ty,
                                                  SILLocation loc) {
-    auto *result =
-        builder.createFunction(SILLinkage::Private, name, ty, nullptr, loc,
-                               IsNotBare, IsNotTransparent, IsNotSerialized);
+    auto *result = builder.createFunction(
+        SILLinkage::Private, name, ty, nullptr, loc, IsNotBare,
+        IsNotTransparent, IsNotSerialized, IsNotDynamic);
     result->setDebugScope(new (builder.mod) SILDebugScope(loc, result));
     return result;
   }
diff --git a/lib/RemoteAST/RemoteAST.cpp b/lib/RemoteAST/RemoteAST.cpp
index 26ee17a..0dc38eb 100644
--- a/lib/RemoteAST/RemoteAST.cpp
+++ b/lib/RemoteAST/RemoteAST.cpp
@@ -75,7 +75,6 @@
 
   static IRGenOptions createIRGenOptions() {
     IRGenOptions IROpts;
-    IROpts.EnableResilienceBypass = true;
     return IROpts;
   }
 
@@ -185,7 +184,7 @@
     VarDecl *member = findField(typeDecl, memberName);
 
     // If we found a member, try to find its offset statically.
-    if (member) {
+    if (member && member->hasStorage() && !typeDecl->isResilient()) {
       if (auto irgen = getIRGen()) {
         return getOffsetOfFieldFromIRGen(irgen->IGM, type, typeDecl,
                                           optMetadata, member);
diff --git a/lib/SIL/CMakeLists.txt b/lib/SIL/CMakeLists.txt
index c85aab0..76b095b 100644
--- a/lib/SIL/CMakeLists.txt
+++ b/lib/SIL/CMakeLists.txt
@@ -44,6 +44,7 @@
   SILWitnessTable.cpp
   TypeLowering.cpp
   ValueOwnership.cpp
+  ValueUtils.cpp
   LINK_LIBRARIES
     swiftSerialization
     swiftSema
diff --git a/lib/SIL/InstructionUtils.cpp b/lib/SIL/InstructionUtils.cpp
index a027166..9319610 100644
--- a/lib/SIL/InstructionUtils.cpp
+++ b/lib/SIL/InstructionUtils.cpp
@@ -296,6 +296,10 @@
   }
 }
 
+bool swift::mayCheckRefCount(SILInstruction *User) {
+  return isa<IsUniqueInst>(User) || isa<IsEscapingClosureInst>(User);
+}
+
 bool swift::isSanitizerInstrumentation(SILInstruction *Instruction) {
   auto *BI = dyn_cast<BuiltinInst>(Instruction);
   if (!BI)
diff --git a/lib/SIL/Linker.cpp b/lib/SIL/Linker.cpp
index 3405ef4..ee67081 100644
--- a/lib/SIL/Linker.cpp
+++ b/lib/SIL/Linker.cpp
@@ -173,6 +173,16 @@
   maybeAddFunctionToWorklist(FRI->getReferencedFunction());
 }
 
+void SILLinkerVisitor::visitDynamicFunctionRefInst(
+    DynamicFunctionRefInst *FRI) {
+  maybeAddFunctionToWorklist(FRI->getReferencedFunction());
+}
+
+void SILLinkerVisitor::visitPreviousDynamicFunctionRefInst(
+    PreviousDynamicFunctionRefInst *FRI) {
+  maybeAddFunctionToWorklist(FRI->getReferencedFunction());
+}
+
 // Eagerly visiting all used conformances leads to a large blowup
 // in the amount of SIL we read in. For optimization purposes we can defer
 // reading in most conformances until we need them for devirtualization.
diff --git a/lib/SIL/Linker.h b/lib/SIL/Linker.h
index 093578e..12ad57a 100644
--- a/lib/SIL/Linker.h
+++ b/lib/SIL/Linker.h
@@ -66,6 +66,8 @@
   void visitTryApplyInst(TryApplyInst *TAI);
   void visitPartialApplyInst(PartialApplyInst *PAI);
   void visitFunctionRefInst(FunctionRefInst *FRI);
+  void visitDynamicFunctionRefInst(DynamicFunctionRefInst *FRI);
+  void visitPreviousDynamicFunctionRefInst(PreviousDynamicFunctionRefInst *FRI);
   void visitProtocolConformance(ProtocolConformanceRef C,
                                 const Optional<SILDeclRef> &Member);
   void visitApplySubstitutions(SubstitutionMap subs);
diff --git a/lib/SIL/MemAccessUtils.cpp b/lib/SIL/MemAccessUtils.cpp
index ad14e36..5d98739 100644
--- a/lib/SIL/MemAccessUtils.cpp
+++ b/lib/SIL/MemAccessUtils.cpp
@@ -287,15 +287,31 @@
         return AccessedStorage(address, AccessedStorage::Unidentified);
       return AccessedStorage();
 
-    // A block argument may be a box value projected out of
-    // switch_enum. Address-type block arguments are not allowed.
-    case ValueKind::SILPhiArgument:
+    case ValueKind::SILPhiArgument: {
+      auto *phiArg = cast<SILPhiArgument>(address);
+      bool allValsMatch = true;
+      SmallVector<SILValue, 8> incomingPhis;
+      phiArg->getIncomingPhiValues(incomingPhis);
+      if (!incomingPhis.empty()) {
+        auto firstVal = incomingPhis.front();
+        for (auto val : incomingPhis) {
+          if (val != firstVal) {
+            allValsMatch = false;
+            break;
+          }
+        }
+        if (allValsMatch) {
+          return findAccessedStorage(firstVal);
+        }
+      }
+      // A block argument may be a box value projected out of
+      // switch_enum. Address-type block arguments are not allowed.
       if (address->getType().isAddress())
         return AccessedStorage();
 
       checkSwitchEnumBlockArg(cast<SILPhiArgument>(address));
       return AccessedStorage(address, AccessedStorage::Unidentified);
-
+    }
     // Load a box from an indirect payload of an opaque enum.
     // We must have peeked past the project_box earlier in this loop.
     // (the indirectness makes it a box, the load is for address-only).
diff --git a/lib/SIL/OperandOwnership.cpp b/lib/SIL/OperandOwnership.cpp
index f7843d1..155d6fe 100644
--- a/lib/SIL/OperandOwnership.cpp
+++ b/lib/SIL/OperandOwnership.cpp
@@ -123,6 +123,8 @@
 NO_OPERAND_INST(AllocStack)
 NO_OPERAND_INST(FloatLiteral)
 NO_OPERAND_INST(FunctionRef)
+NO_OPERAND_INST(DynamicFunctionRef)
+NO_OPERAND_INST(PreviousDynamicFunctionRef)
 NO_OPERAND_INST(GlobalAddr)
 NO_OPERAND_INST(GlobalValue)
 NO_OPERAND_INST(IntegerLiteral)
@@ -1149,6 +1151,7 @@
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, ZExtOrBitCast)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, ZeroInitializer)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, Swift3ImplicitObjCEntrypoint)
+CONSTANT_OWNERSHIP_BUILTIN(Trivial, MustBeLive, PoundAssert)
 #undef CONSTANT_OWNERSHIP_BUILTIN
 
 // Builtins that should be lowered to SIL instructions so we should never see
diff --git a/lib/SIL/OwnershipUtils.cpp b/lib/SIL/OwnershipUtils.cpp
index a3d6109..108bee9 100644
--- a/lib/SIL/OwnershipUtils.cpp
+++ b/lib/SIL/OwnershipUtils.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "swift/SIL/OwnershipUtils.h"
+#include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILInstruction.h"
 
 using namespace swift;
@@ -75,3 +76,54 @@
 bool swift::isOwnershipForwardingInst(SILInstruction *i) {
   return isOwnershipForwardingValueKind(SILNodeKind(i->getKind()));
 }
+
+bool swift::getUnderlyingBorrowIntroducers(SILValue inputValue,
+                                           SmallVectorImpl<SILValue> &out) {
+  if (inputValue.getOwnershipKind() != ValueOwnershipKind::Guaranteed)
+    return false;
+
+  SmallVector<SILValue, 32> worklist;
+  worklist.emplace_back(inputValue);
+
+  while (!worklist.empty()) {
+    SILValue v = worklist.pop_back_val();
+
+    // First check if v is an introducer. If so, stash it and continue.
+    if (isa<LoadBorrowInst>(v) ||
+        isa<BeginBorrowInst>(v)) {
+      out.push_back(v);
+      continue;
+    }
+
+    // If we have a function argument with guaranteed convention, it is also an
+    // introducer.
+    if (auto *arg = dyn_cast<SILFunctionArgument>(v)) {
+      if (arg->getOwnershipKind() == ValueOwnershipKind::Guaranteed) {
+        out.push_back(v);
+        continue;
+      }
+
+      // Otherwise, we do not know how to handle this function argument, so
+      // bail.
+      return false;
+    }
+
+    // Otherwise if v is an ownership forwarding value, add its defining
+    // instruction
+    if (isGuaranteedForwardingValue(v)) {
+      auto *i = v->getDefiningInstruction();
+      assert(i);
+      transform(i->getAllOperands(), std::back_inserter(worklist),
+                [](const Operand &op) -> SILValue { return op.get(); });
+      continue;
+    }
+
+    // If v produces any ownership, then we can ignore it. Otherwise, we need to
+    // return false since this is an introducer we do not understand.
+    if (v.getOwnershipKind() != ValueOwnershipKind::Any &&
+        v.getOwnershipKind() != ValueOwnershipKind::Trivial)
+      return false;
+  }
+
+  return true;
+}
diff --git a/lib/SIL/Projection.cpp b/lib/SIL/Projection.cpp
index d450907..b826c58 100644
--- a/lib/SIL/Projection.cpp
+++ b/lib/SIL/Projection.cpp
@@ -599,20 +599,7 @@
 
     LLVM_DEBUG(llvm::dbgs() << "Visiting type: " << Ty << "\n");
 
-    // Get the first level projection of the current type.
-    Projections.clear();
-    Projection::getFirstLevelProjections(Ty, *Mod, Projections);
-
-    // Reached the end of the projection tree, this field can not be expanded
-    // anymore.
-    if (Projections.empty()) {
-      LLVM_DEBUG(llvm::dbgs() << "    No projections. "
-                 "Finished projection list\n");
-      Paths.push_back(PP);
-      continue;
-    }
-
-    // If this is a class type, we also have reached the end of the type
+    // If this is a class type, we have reached the end of the type
     // tree for this type.
     //
     // We do not push its next level projection into the worklist,
@@ -635,6 +622,19 @@
       continue;
     }
 
+    // Get the first level projection of the current type.
+    Projections.clear();
+    Projection::getFirstLevelProjections(Ty, *Mod, Projections);
+
+    // Reached the end of the projection tree, this field can not be expanded
+    // anymore.
+    if (Projections.empty()) {
+      LLVM_DEBUG(llvm::dbgs() << "    No projections. "
+                 "Finished projection list\n");
+      Paths.push_back(PP);
+      continue;
+    }
+
     // Keep expanding the location.
     for (auto &P : Projections) {
       ProjectionPath X(B);
diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp
index 7fec2ff..3c93f29 100644
--- a/lib/SIL/SILBuilder.cpp
+++ b/lib/SIL/SILBuilder.cpp
@@ -24,7 +24,7 @@
 SILBuilder::SILBuilder(SILGlobalVariable *GlobVar,
                        SmallVectorImpl<SILInstruction *> *InsertedInstrs)
     : TempContext(GlobVar->getModule(), InsertedInstrs), C(TempContext),
-      F(nullptr) {
+      F(nullptr), hasOwnership(false) {
   setInsertionPoint(&GlobVar->StaticInitializerBlock);
 }
 
diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp
index 25badfa..9e0fd73 100644
--- a/lib/SIL/SILDeclRef.cpp
+++ b/lib/SIL/SILDeclRef.cpp
@@ -41,8 +41,9 @@
   auto dc = method->getDeclContext();
 
   if (dc->getSelfClassDecl()) {
-    if (method->isDynamic())
+    if (method->isObjCDynamic()) {
       return MethodDispatch::Class;
+    }
 
     // Final methods can be statically referenced.
     if (method->isFinal())
@@ -87,8 +88,9 @@
 bool swift::requiresForeignEntryPoint(ValueDecl *vd) {
   assert(!isa<AbstractStorageDecl>(vd));
 
-  if (vd->isDynamic())
+  if (vd->isObjCDynamic()) {
     return true;
+  }
 
   if (vd->isObjC() && isa<ProtocolDecl>(vd->getDeclContext()))
     return true;
@@ -526,26 +528,47 @@
   return IsNotSerialized;
 }
 
-/// \brief True if the function has noinline attribute.
+/// \brief True if the function has an @inline(never) attribute.
 bool SILDeclRef::isNoinline() const {
   if (!hasDecl())
     return false;
-  if (auto InlineA = getDecl()->getAttrs().getAttribute<InlineAttr>())
-    if (InlineA->getKind() == InlineKind::Never)
+
+  auto *decl = getDecl();
+  if (auto *attr = decl->getAttrs().getAttribute<InlineAttr>())
+    if (attr->getKind() == InlineKind::Never)
       return true;
-  if (auto *semanticsA = getDecl()->getAttrs().getAttribute<SemanticsAttr>())
-    if (semanticsA->Value.equals("keypath.entry"))
+
+  if (auto *accessorDecl = dyn_cast<AccessorDecl>(decl)) {
+    auto *storage = accessorDecl->getStorage();
+    if (auto *attr = storage->getAttrs().getAttribute<InlineAttr>())
+      if (attr->getKind() == InlineKind::Never)
+        return true;
+  }
+
+  if (auto *attr = decl->getAttrs().getAttribute<SemanticsAttr>())
+    if (attr->Value.equals("keypath.entry"))
       return true;
+
   return false;
 }
 
-/// \brief True if the function has noinline attribute.
+/// \brief True if the function has the @inline(__always) attribute.
 bool SILDeclRef::isAlwaysInline() const {
   if (!hasDecl())
     return false;
-  if (auto InlineA = getDecl()->getAttrs().getAttribute<InlineAttr>())
-    if (InlineA->getKind() == InlineKind::Always)
+
+  auto *decl = getDecl();
+  if (auto attr = decl->getAttrs().getAttribute<InlineAttr>())
+    if (attr->getKind() == InlineKind::Always)
       return true;
+
+  if (auto *accessorDecl = dyn_cast<AccessorDecl>(decl)) {
+    auto *storage = accessorDecl->getStorage();
+    if (auto *attr = storage->getAttrs().getAttribute<InlineAttr>())
+      if (attr->getKind() == InlineKind::Always)
+        return true;
+  }
+
   return false;
 }
 
@@ -704,7 +727,6 @@
   case SILDeclRef::Kind::GlobalAccessor:
     assert(!isCurried);
     return mangler.mangleAccessorEntity(AccessorKind::MutableAddress,
-                                        AddressorKind::Unsafe,
                                         cast<AbstractStorageDecl>(getDecl()),
                                         /*isStatic*/ false,
                                         SKind);
@@ -777,7 +799,7 @@
     if (overridden.kind == SILDeclRef::Kind::Initializer) {
       return SILDeclRef();
     }
-    if (overridden.getDecl()->isDynamic()) {
+    if (overridden.getDecl()->isObjCDynamic()) {
       return SILDeclRef();
     }
     
@@ -785,8 +807,9 @@
       auto *asd = accessor->getStorage();
       if (asd->hasClangNode())
         return SILDeclRef();
-      if (asd->isDynamic())
+      if (asd->isObjCDynamic()) {
         return SILDeclRef();
+      }
     }
 
     // If we overrode a decl from an extension, it won't be in a vtable
@@ -880,7 +903,7 @@
   DeclContext *context = FD->getDeclContext();
 
   // Methods from extensions don't go into vtables (yet).
-  if (context->isExtensionContext())
+  if (isa<ExtensionDecl>(context))
     return SubclassScope::NotApplicable;
 
   // Various forms of thunks don't either.
@@ -909,6 +932,8 @@
   case AccessLevel::Public:
     return SubclassScope::Internal;
   case AccessLevel::Open:
+    if (classType->isResilient())
+      return SubclassScope::Internal;
     return SubclassScope::External;
   }
 
@@ -933,3 +958,19 @@
     llvm_unreachable("Unhandled ValueDecl for SILDeclRef");
   }
 }
+
+bool SILDeclRef::isDynamicallyReplaceable() const {
+  if (isStoredPropertyInitializer())
+    return false;
+
+  if (kind == SILDeclRef::Kind::Destroyer ||
+      kind == SILDeclRef::Kind::Initializer) {
+    return false;
+  }
+
+  if (!hasDecl())
+    return false;
+
+  auto decl = getDecl();
+  return decl->isDynamic() && !decl->isObjC();
+}
diff --git a/lib/SIL/SILFunction.cpp b/lib/SIL/SILFunction.cpp
index cf6817f..067d0b1 100644
--- a/lib/SIL/SILFunction.cpp
+++ b/lib/SIL/SILFunction.cpp
@@ -56,14 +56,16 @@
   }
 }
 
-SILFunction *SILFunction::create(
-    SILModule &M, SILLinkage linkage, StringRef name,
-    CanSILFunctionType loweredType, GenericEnvironment *genericEnv,
-    Optional<SILLocation> loc, IsBare_t isBareSILFunction,
-    IsTransparent_t isTrans, IsSerialized_t isSerialized,
-    ProfileCounter entryCount, IsThunk_t isThunk,
-    SubclassScope classSubclassScope, Inline_t inlineStrategy, EffectsKind E,
-    SILFunction *insertBefore, const SILDebugScope *debugScope) {
+SILFunction *
+SILFunction::create(SILModule &M, SILLinkage linkage, StringRef name,
+                    CanSILFunctionType loweredType,
+                    GenericEnvironment *genericEnv, Optional<SILLocation> loc,
+                    IsBare_t isBareSILFunction, IsTransparent_t isTrans,
+                    IsSerialized_t isSerialized, ProfileCounter entryCount,
+                    IsDynamicallyReplaceable_t isDynamic, IsThunk_t isThunk,
+                    SubclassScope classSubclassScope, Inline_t inlineStrategy,
+                    EffectsKind E, SILFunction *insertBefore,
+                    const SILDebugScope *debugScope) {
   // Get a StringMapEntry for the function.  As a sop to error cases,
   // allow the name to have an empty string.
   llvm::StringMapEntry<SILFunction*> *entry = nullptr;
@@ -77,7 +79,7 @@
   auto fn = new (M) SILFunction(M, linkage, name, loweredType, genericEnv, loc,
                                 isBareSILFunction, isTrans, isSerialized,
                                 entryCount, isThunk, classSubclassScope,
-                                inlineStrategy, E, insertBefore, debugScope);
+                                inlineStrategy, E, insertBefore, debugScope, isDynamic);
 
   if (entry) entry->setValue(fn);
   return fn;
@@ -92,7 +94,8 @@
                          SubclassScope classSubclassScope,
                          Inline_t inlineStrategy, EffectsKind E,
                          SILFunction *InsertBefore,
-                         const SILDebugScope *DebugScope)
+                         const SILDebugScope *DebugScope,
+                         IsDynamicallyReplaceable_t isDynamic)
     : Module(Module), Name(Name), LoweredType(LoweredType),
       GenericEnv(genericEnv), SpecializationInfo(nullptr),
       DebugScope(DebugScope), Bare(isBareSILFunction), Transparent(isTrans),
@@ -100,8 +103,9 @@
       ClassSubclassScope(unsigned(classSubclassScope)), GlobalInitFlag(false),
       InlineStrategy(inlineStrategy), Linkage(unsigned(Linkage)),
       HasCReferences(false), IsWeakLinked(false),
-      OptMode(OptimizationMode::NotSet), EffectsKindAttr(E),
-      EntryCount(entryCount) {
+      IsDynamicReplaceable(isDynamic), OptMode(OptimizationMode::NotSet),
+      EffectsKindAttr(E), EntryCount(entryCount) {
+  assert(!Transparent || !IsDynamicReplaceable);
   validateSubclassScope(classSubclassScope, isThunk, nullptr);
 
   if (InsertBefore)
@@ -124,6 +128,11 @@
   // an allocator that may recycle freed memory.
   dropAllReferences();
 
+  if (ReplacedFunction) {
+    ReplacedFunction->decrementRefCount();
+    ReplacedFunction = nullptr;
+  }
+
   auto &M = getModule();
   for (auto &BB : *this) {
     for (auto I = BB.begin(), E = BB.end(); I != E;) {
@@ -485,6 +494,9 @@
   if (linkage == SILLinkage::Hidden && hasCReferences())
     return true;
 
+  if (ReplacedFunction)
+    return true;
+
   return swift::isPossiblyUsedExternally(linkage, getModule().isWholeModule());
 }
 
@@ -513,6 +525,24 @@
   return !hasSemanticsAttr("verify.ownership.sil.never");
 }
 
+static Identifier getIdentifierForObjCSelector(ObjCSelector selector, ASTContext &Ctxt) {
+  SmallVector<char, 64> buffer;
+  auto str = selector.getString(buffer);
+  return Ctxt.getIdentifier(str);
+}
+
+void SILFunction::setObjCReplacement(AbstractFunctionDecl *replacedFunc) {
+  assert(ReplacedFunction == nullptr && ObjCReplacementFor.empty());
+  assert(replacedFunc != nullptr);
+  ObjCReplacementFor = getIdentifierForObjCSelector(
+      replacedFunc->getObjCSelector(), getASTContext());
+}
+
+void SILFunction::setObjCReplacement(Identifier replacedFunc) {
+  assert(ReplacedFunction == nullptr && ObjCReplacementFor.empty());
+  ObjCReplacementFor = replacedFunc;
+}
+
 // See swift/Basic/Statistic.h for declaration: this enables tracing
 // SILFunctions, is defined here to avoid too much layering violation / circular
 // linkage dependency.
diff --git a/lib/SIL/SILFunctionBuilder.cpp b/lib/SIL/SILFunctionBuilder.cpp
index 71213aa..ec5fbac 100644
--- a/lib/SIL/SILFunctionBuilder.cpp
+++ b/lib/SIL/SILFunctionBuilder.cpp
@@ -11,14 +11,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "swift/SIL/SILFunctionBuilder.h"
-
+#include "swift/AST/Decl.h"
 using namespace swift;
 
 SILFunction *SILFunctionBuilder::getOrCreateFunction(
     SILLocation loc, StringRef name, SILLinkage linkage,
     CanSILFunctionType type, IsBare_t isBareSILFunction,
     IsTransparent_t isTransparent, IsSerialized_t isSerialized,
-    ProfileCounter entryCount, IsThunk_t isThunk, SubclassScope subclassScope) {
+    IsDynamicallyReplaceable_t isDynamic, ProfileCounter entryCount,
+    IsThunk_t isThunk, SubclassScope subclassScope) {
   assert(!type->isNoEscape() && "Function decls always have escaping types.");
   if (auto fn = mod.lookUpFunction(name)) {
     assert(fn->getLoweredFunctionType() == type);
@@ -29,13 +30,16 @@
 
   auto fn = SILFunction::create(mod, linkage, name, type, nullptr, loc,
                                 isBareSILFunction, isTransparent, isSerialized,
-                                entryCount, isThunk, subclassScope);
+                                entryCount, isDynamic, isThunk, subclassScope);
   fn->setDebugScope(new (mod) SILDebugScope(loc, fn));
   return fn;
 }
 
-static void addFunctionAttributes(SILFunction *F, DeclAttributes &Attrs,
-                                  SILModule &M) {
+void SILFunctionBuilder::addFunctionAttributes(SILFunction *F,
+                                               DeclAttributes &Attrs,
+                                               SILModule &M,
+                                               SILDeclRef constant) {
+
   for (auto *A : Attrs.getAttributes<SemanticsAttr>())
     F->addSemanticsAttr(cast<SemanticsAttr>(A)->Value);
 
@@ -57,6 +61,38 @@
   // @_silgen_name and @_cdecl functions may be called from C code somewhere.
   if (Attrs.hasAttribute<SILGenNameAttr>() || Attrs.hasAttribute<CDeclAttr>())
     F->setHasCReferences(true);
+
+  // Propagate @_dynamicReplacement(for:).
+  if (constant.isNull())
+    return;
+  auto *decl = constant.getDecl();
+
+  // Only emit replacements for the objc entry point of objc methods.
+  if (decl->isObjC() &&
+      F->getLoweredFunctionType()->getExtInfo().getRepresentation() !=
+          SILFunctionTypeRepresentation::ObjCMethod)
+    return;
+
+  auto *replacedFuncAttr = Attrs.getAttribute<DynamicReplacementAttr>();
+  if (!replacedFuncAttr)
+    return;
+
+  auto *replacedDecl = replacedFuncAttr->getReplacedFunction();
+  assert(replacedDecl);
+
+  if (decl->isObjC()) {
+    F->setObjCReplacement(replacedDecl);
+    return;
+  }
+
+  if (constant.isInitializerOrDestroyer())
+    return;
+
+  SILDeclRef declRef(replacedDecl, constant.kind, false);
+  auto *replacedFunc =
+      getOrCreateFunction(replacedDecl, declRef, NotForDefinition);
+  assert(replacedFunc->getLoweredFunctionType() == F->getLoweredFunctionType());
+  F->setDynamicallyReplacedFunction(replacedFunc);
 }
 
 SILFunction *
@@ -99,10 +135,16 @@
     inlineStrategy = AlwaysInline;
 
   StringRef name = mod.allocateCopy(nameTmp);
-  auto *F =
-      SILFunction::create(mod, linkage, name, constantType, nullptr, None,
-                          IsNotBare, IsTrans, IsSer, entryCount, IsNotThunk,
-                          constant.getSubclassScope(), inlineStrategy, EK);
+  IsDynamicallyReplaceable_t IsDyn = IsNotDynamic;
+  if (constant.isDynamicallyReplaceable()) {
+    IsDyn = IsDynamic;
+    IsTrans = IsNotTransparent;
+  }
+
+  auto *F = SILFunction::create(mod, linkage, name, constantType, nullptr, None,
+                                IsNotBare, IsTrans, IsSer, entryCount, IsDyn,
+                                IsNotThunk, constant.getSubclassScope(),
+                                inlineStrategy, EK);
   F->setDebugScope(new (mod) SILDebugScope(loc, F));
 
   F->setGlobalInit(constant.isGlobal());
@@ -120,7 +162,7 @@
       // Add attributes for e.g. computed properties.
       addFunctionAttributes(F, storage->getAttrs(), mod);
     }
-    addFunctionAttributes(F, decl->getAttrs(), mod);
+    addFunctionAttributes(F, decl->getAttrs(), mod, constant);
   }
 
   return F;
@@ -129,21 +171,24 @@
 SILFunction *SILFunctionBuilder::getOrCreateSharedFunction(
     SILLocation loc, StringRef name, CanSILFunctionType type,
     IsBare_t isBareSILFunction, IsTransparent_t isTransparent,
-    IsSerialized_t isSerialized, ProfileCounter entryCount, IsThunk_t isThunk) {
+    IsSerialized_t isSerialized, ProfileCounter entryCount, IsThunk_t isThunk,
+    IsDynamicallyReplaceable_t isDynamic) {
   return getOrCreateFunction(loc, name, SILLinkage::Shared, type,
                              isBareSILFunction, isTransparent, isSerialized,
-                             entryCount, isThunk, SubclassScope::NotApplicable);
+                             isDynamic, entryCount, isThunk,
+                             SubclassScope::NotApplicable);
 }
 
 SILFunction *SILFunctionBuilder::createFunction(
     SILLinkage linkage, StringRef name, CanSILFunctionType loweredType,
     GenericEnvironment *genericEnv, Optional<SILLocation> loc,
     IsBare_t isBareSILFunction, IsTransparent_t isTrans,
-    IsSerialized_t isSerialized, ProfileCounter entryCount, IsThunk_t isThunk,
-    SubclassScope subclassScope, Inline_t inlineStrategy, EffectsKind EK,
-    SILFunction *InsertBefore, const SILDebugScope *DebugScope) {
+    IsSerialized_t isSerialized, IsDynamicallyReplaceable_t isDynamic,
+    ProfileCounter entryCount, IsThunk_t isThunk, SubclassScope subclassScope,
+    Inline_t inlineStrategy, EffectsKind EK, SILFunction *InsertBefore,
+    const SILDebugScope *DebugScope) {
   return SILFunction::create(mod, linkage, name, loweredType, genericEnv, loc,
                              isBareSILFunction, isTrans, isSerialized,
-                             entryCount, isThunk, subclassScope, inlineStrategy,
-                             EK, InsertBefore, DebugScope);
+                             entryCount, isDynamic, isThunk, subclassScope,
+                             inlineStrategy, EK, InsertBefore, DebugScope);
 }
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 35124178..670acfc 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -2645,7 +2645,6 @@
   }
 
   SILFunctionTypeRepresentation rep = extInfo.getSILRepresentation();
-  assert(!extInfo.isAutoClosure() && "autoclosures cannot be curried");
   assert(rep != SILFunctionType::Representation::Block
          && "objc blocks cannot be curried");
 
diff --git a/lib/SIL/SILInstruction.cpp b/lib/SIL/SILInstruction.cpp
index ba09889..159c252 100644
--- a/lib/SIL/SILInstruction.cpp
+++ b/lib/SIL/SILInstruction.cpp
@@ -155,7 +155,7 @@
 
   // If we have a function ref inst, we need to especially drop its function
   // argument so that it gets a proper ref decrement.
-  if (auto *FRI = dyn_cast<FunctionRefInst>(this)) {
+  if (auto *FRI = dyn_cast<FunctionRefBaseInst>(this)) {
     if (!FRI->getReferencedFunction())
       return;
     FRI->dropReferencedFunction();
@@ -451,6 +451,15 @@
       auto *X = cast<FunctionRefInst>(LHS);
       return X->getReferencedFunction() == RHS->getReferencedFunction();
     }
+    bool visitDynamicFunctionRefInst(const DynamicFunctionRefInst *RHS) {
+      auto *X = cast<DynamicFunctionRefInst>(LHS);
+      return X->getReferencedFunction() == RHS->getReferencedFunction();
+    }
+    bool visitPreviousDynamicFunctionRefInst(
+        const PreviousDynamicFunctionRefInst *RHS) {
+      auto *X = cast<PreviousDynamicFunctionRefInst>(LHS);
+      return X->getReferencedFunction() == RHS->getReferencedFunction();
+    }
 
     bool visitAllocGlobalInst(const AllocGlobalInst *RHS) {
       auto *X = cast<AllocGlobalInst>(LHS);
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index 21a1fe6..296a69b 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -500,7 +500,7 @@
 }
 
 bool swift::doesApplyCalleeHaveSemantics(SILValue callee, StringRef semantics) {
-  if (auto *FRI = dyn_cast<FunctionRefInst>(callee))
+  if (auto *FRI = dyn_cast<FunctionRefBaseInst>(callee))
     if (auto *F = FRI->getReferencedFunction())
       return F->hasSemanticsAttr(semantics);
   return false;
@@ -577,21 +577,40 @@
                                      normalBB, errorBB, specializationInfo);
 }
 
-FunctionRefInst::FunctionRefInst(SILDebugLocation Loc, SILFunction *F)
-    : InstructionBase(Loc, F->getLoweredType()),
-      Function(F) {
+FunctionRefBaseInst::FunctionRefBaseInst(SILInstructionKind Kind,
+                                         SILDebugLocation DebugLoc,
+                                         SILFunction *F)
+    : LiteralInst(Kind, DebugLoc, F->getLoweredType()), f(F) {
   F->incrementRefCount();
 }
 
-FunctionRefInst::~FunctionRefInst() {
-  if (Function)
+void FunctionRefBaseInst::dropReferencedFunction() {
+  if (auto *Function = getReferencedFunction())
     Function->decrementRefCount();
+  f = nullptr;
 }
 
-void FunctionRefInst::dropReferencedFunction() {
-  if (Function)
-    Function->decrementRefCount();
-  Function = nullptr;
+FunctionRefBaseInst::~FunctionRefBaseInst() {
+  if (getReferencedFunction())
+    getReferencedFunction()->decrementRefCount();
+}
+
+FunctionRefInst::FunctionRefInst(SILDebugLocation Loc, SILFunction *F)
+    : FunctionRefBaseInst(SILInstructionKind::FunctionRefInst, Loc, F) {
+  assert(!F->isDynamicallyReplaceable());
+}
+
+DynamicFunctionRefInst::DynamicFunctionRefInst(SILDebugLocation Loc,
+                                               SILFunction *F)
+    : FunctionRefBaseInst(SILInstructionKind::DynamicFunctionRefInst, Loc, F) {
+  assert(F->isDynamicallyReplaceable());
+}
+
+PreviousDynamicFunctionRefInst::PreviousDynamicFunctionRefInst(
+    SILDebugLocation Loc, SILFunction *F)
+    : FunctionRefBaseInst(SILInstructionKind::PreviousDynamicFunctionRefInst,
+                          Loc, F) {
+  assert(!F->isDynamicallyReplaceable());
 }
 
 AllocGlobalInst::AllocGlobalInst(SILDebugLocation Loc,
@@ -854,31 +873,38 @@
       Operands(this, src, dest), SourceType(srcType), TargetType(targetType) {}
 
 StructInst *StructInst::create(SILDebugLocation Loc, SILType Ty,
-                               ArrayRef<SILValue> Elements, SILModule &M) {
+                               ArrayRef<SILValue> Elements, SILModule &M,
+                               bool HasOwnership) {
   auto Size = totalSizeToAlloc<swift::Operand>(Elements.size());
   auto Buffer = M.allocateInst(Size, alignof(StructInst));
-  return ::new(Buffer) StructInst(Loc, Ty, Elements);
+  return ::new (Buffer) StructInst(Loc, Ty, Elements, HasOwnership);
 }
 
 StructInst::StructInst(SILDebugLocation Loc, SILType Ty,
-                       ArrayRef<SILValue> Elems)
-    : InstructionBaseWithTrailingOperands(Elems, Loc, Ty) {
+                       ArrayRef<SILValue> Elems, bool HasOwnership)
+    : InstructionBaseWithTrailingOperands(
+          Elems, Loc, Ty,
+          HasOwnership ? *mergeSILValueOwnership(Elems)
+                       : ValueOwnershipKind(ValueOwnershipKind::Any)) {
   assert(!Ty.getStructOrBoundGenericStruct()->hasUnreferenceableStorage());
 }
 
 ObjectInst *ObjectInst::create(SILDebugLocation Loc, SILType Ty,
                                ArrayRef<SILValue> Elements,
-                               unsigned NumBaseElements, SILModule &M) {
+                               unsigned NumBaseElements, SILModule &M,
+                               bool HasOwnership) {
   auto Size = totalSizeToAlloc<swift::Operand>(Elements.size());
   auto Buffer = M.allocateInst(Size, alignof(ObjectInst));
-  return ::new(Buffer) ObjectInst(Loc, Ty, Elements, NumBaseElements);
+  return ::new (Buffer)
+      ObjectInst(Loc, Ty, Elements, NumBaseElements, HasOwnership);
 }
 
 TupleInst *TupleInst::create(SILDebugLocation Loc, SILType Ty,
-                             ArrayRef<SILValue> Elements, SILModule &M) {
+                             ArrayRef<SILValue> Elements, SILModule &M,
+                             bool HasOwnership) {
   auto Size = totalSizeToAlloc<swift::Operand>(Elements.size());
   auto Buffer = M.allocateInst(Size, alignof(TupleInst));
-  return ::new(Buffer) TupleInst(Loc, Ty, Elements);
+  return ::new (Buffer) TupleInst(Loc, Ty, Elements, HasOwnership);
 }
 
 bool TupleExtractInst::isTrivialEltOfOneRCIDTuple() const {
@@ -1303,11 +1329,20 @@
   return ::new (buf) SwitchValueInst(Loc, Operand, DefaultBB, Cases, BBs);
 }
 
+SelectValueInst::SelectValueInst(SILDebugLocation DebugLoc, SILValue Operand,
+                                 SILType Type, SILValue DefaultResult,
+                                 ArrayRef<SILValue> CaseValuesAndResults,
+                                 bool HasOwnership)
+    : InstructionBaseWithTrailingOperands(
+          Operand, CaseValuesAndResults, DebugLoc, Type,
+          HasOwnership ? *mergeSILValueOwnership(CaseValuesAndResults)
+                       : ValueOwnershipKind(ValueOwnershipKind::Any)) {}
+
 SelectValueInst *
 SelectValueInst::create(SILDebugLocation Loc, SILValue Operand, SILType Type,
                         SILValue DefaultResult,
                         ArrayRef<std::pair<SILValue, SILValue>> CaseValues,
-                        SILFunction &F) {
+                        SILModule &M, bool HasOwnership) {
   // Allocate enough room for the instruction with tail-allocated data for all
   // the case values and the SILSuccessor arrays. There are `CaseBBs.size()`
   // SILValues and `CaseBBs.size() + (DefaultBB ? 1 : 0)` successors.
@@ -1321,17 +1356,17 @@
     CaseValuesAndResults.push_back(DefaultResult);
 
   auto Size = totalSizeToAlloc<swift::Operand>(CaseValuesAndResults.size() + 1);
-  auto Buf = F.getModule().allocateInst(Size, alignof(SelectValueInst));
+  auto Buf = M.allocateInst(Size, alignof(SelectValueInst));
   return ::new (Buf) SelectValueInst(Loc, Operand, Type, DefaultResult,
-                                     CaseValuesAndResults);
+                                     CaseValuesAndResults, HasOwnership);
 }
 
 template <typename SELECT_ENUM_INST>
 SELECT_ENUM_INST *SelectEnumInstBase::createSelectEnum(
     SILDebugLocation Loc, SILValue Operand, SILType Ty, SILValue DefaultValue,
     ArrayRef<std::pair<EnumElementDecl *, SILValue>> DeclsAndValues,
-    SILFunction &F, Optional<ArrayRef<ProfileCounter>> CaseCounts,
-    ProfileCounter DefaultCount) {
+    SILModule &Mod, Optional<ArrayRef<ProfileCounter>> CaseCounts,
+    ProfileCounter DefaultCount, bool HasOwnership) {
   // Allocate enough room for the instruction with tail-allocated
   // EnumElementDecl and operand arrays. There are `CaseBBs.size()` decls
   // and `CaseBBs.size() + (DefaultBB ? 1 : 0)` values.
@@ -1348,31 +1383,34 @@
   auto Size = SELECT_ENUM_INST::template
     totalSizeToAlloc<swift::Operand, EnumElementDecl*>(CaseValues.size() + 1,
                                                        CaseDecls.size());
-  auto Buf = F.getModule().allocateInst(Size + sizeof(ProfileCounter),
-                                        alignof(SELECT_ENUM_INST));
-  return ::new (Buf) SELECT_ENUM_INST(Loc, Operand, Ty, bool(DefaultValue),
-                                      CaseValues, CaseDecls, CaseCounts,
-                                      DefaultCount);
+  auto Buf = Mod.allocateInst(Size + sizeof(ProfileCounter),
+                              alignof(SELECT_ENUM_INST));
+  return ::new (Buf)
+      SELECT_ENUM_INST(Loc, Operand, Ty, bool(DefaultValue), CaseValues,
+                       CaseDecls, CaseCounts, DefaultCount, HasOwnership);
 }
 
 SelectEnumInst *SelectEnumInst::create(
     SILDebugLocation Loc, SILValue Operand, SILType Type, SILValue DefaultValue,
-    ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues, SILFunction &F,
-    Optional<ArrayRef<ProfileCounter>> CaseCounts,
-    ProfileCounter DefaultCount) {
+    ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues, SILModule &M,
+    Optional<ArrayRef<ProfileCounter>> CaseCounts, ProfileCounter DefaultCount,
+    bool HasOwnership) {
   return createSelectEnum<SelectEnumInst>(Loc, Operand, Type, DefaultValue,
-                                          CaseValues, F, CaseCounts,
-                                          DefaultCount);
+                                          CaseValues, M, CaseCounts,
+                                          DefaultCount, HasOwnership);
 }
 
 SelectEnumAddrInst *SelectEnumAddrInst::create(
     SILDebugLocation Loc, SILValue Operand, SILType Type, SILValue DefaultValue,
-    ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues, SILFunction &F,
+    ArrayRef<std::pair<EnumElementDecl *, SILValue>> CaseValues, SILModule &M,
     Optional<ArrayRef<ProfileCounter>> CaseCounts,
     ProfileCounter DefaultCount) {
-  return createSelectEnum<SelectEnumAddrInst>(Loc, Operand, Type, DefaultValue,
-                                              CaseValues, F, CaseCounts,
-                                              DefaultCount);
+  // We always pass in false since SelectEnumAddrInst doesn't use ownership. We
+  // have to pass something in since SelectEnumInst /does/ need to consider
+  // ownership and both use the same creation function.
+  return createSelectEnum<SelectEnumAddrInst>(
+      Loc, Operand, Type, DefaultValue, CaseValues, M, CaseCounts, DefaultCount,
+      false /*HasOwnership*/);
 }
 
 SwitchEnumInstBase::SwitchEnumInstBase(
@@ -1773,9 +1811,13 @@
     OpenedExistentialAccess AccessKind)
     : UnaryInstructionBase(DebugLoc, Operand, SelfTy), ForAccess(AccessKind) {}
 
-OpenExistentialRefInst::OpenExistentialRefInst(
-    SILDebugLocation DebugLoc, SILValue Operand, SILType Ty)
-    : UnaryInstructionBase(DebugLoc, Operand, Ty) {
+OpenExistentialRefInst::OpenExistentialRefInst(SILDebugLocation DebugLoc,
+                                               SILValue Operand, SILType Ty,
+                                               bool HasOwnership)
+    : UnaryInstructionBase(DebugLoc, Operand, Ty,
+                           HasOwnership
+                               ? Operand.getOwnershipKind()
+                               : ValueOwnershipKind(ValueOwnershipKind::Any)) {
   assert(Operand->getType().isObject() && "Operand must be an object.");
   assert(Ty.isObject() && "Result type must be an object type.");
 }
diff --git a/lib/SIL/SILModule.cpp b/lib/SIL/SILModule.cpp
index ad2870c..40a72e7 100644
--- a/lib/SIL/SILModule.cpp
+++ b/lib/SIL/SILModule.cpp
@@ -111,8 +111,10 @@
   // need to worry about sil_witness_tables since witness tables reference each
   // other via protocol conformances and sil_vtables don't reference each other
   // at all.
-  for (SILFunction &F : *this)
+  for (SILFunction &F : *this) {
     F.dropAllReferences();
+    F.dropDynamicallyReplacedFunction();
+  }
 }
 
 std::unique_ptr<SILModule>
@@ -436,6 +438,7 @@
   // This opens dead-function-removal opportunities for called functions.
   // (References are not needed anymore.)
   F->dropAllReferences();
+  F->dropDynamicallyReplacedFunction();
 }
 
 void SILModule::invalidateFunctionInSILCache(SILFunction *F) {
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index 87fb19c..dad73ea 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -832,6 +832,14 @@
       *this << "  // function_ref "
             << demangleSymbol(FRI->getReferencedFunction()->getName())
             << "\n";
+    else if (auto *FRI = dyn_cast<DynamicFunctionRefInst>(I))
+      *this << "  // dynamic_function_ref "
+            << demangleSymbol(FRI->getReferencedFunction()->getName())
+            << "\n";
+    else if (auto *FRI = dyn_cast<PreviousDynamicFunctionRefInst>(I))
+      *this << "  // prev_dynamic_function_ref "
+            << demangleSymbol(FRI->getReferencedFunction()->getName())
+            << "\n";
 
     *this << "  ";
 
@@ -1130,7 +1138,16 @@
     FRI->getReferencedFunction()->printName(PrintState.OS);
     *this << " : " << FRI->getType();
   }
-  
+  void visitDynamicFunctionRefInst(DynamicFunctionRefInst *FRI) {
+    FRI->getReferencedFunction()->printName(PrintState.OS);
+    *this << " : " << FRI->getType();
+  }
+  void
+  visitPreviousDynamicFunctionRefInst(PreviousDynamicFunctionRefInst *FRI) {
+    FRI->getReferencedFunction()->printName(PrintState.OS);
+    *this << " : " << FRI->getType();
+  }
+
   void visitBuiltinInst(BuiltinInst *BI) {
     *this << QuotedString(BI->getName().str());
     printSubstitutions(BI->getSubstitutions());
@@ -2269,6 +2286,9 @@
     break;
   case IsReabstractionThunk: OS << "[reabstraction_thunk] "; break;
   }
+  if (isDynamicallyReplaceable()) {
+    OS << "[dynamically_replacable] ";
+  }
   if (isWithoutActuallyEscapingThunk())
     OS << "[without_actually_escaping] ";
 
@@ -2299,6 +2319,18 @@
   else if (getEffectsKind() == EffectsKind::ReleaseNone)
     OS << "[releasenone] ";
 
+  if (auto *replacedFun = getDynamicallyReplacedFunction()) {
+    OS << "[dynamic_replacement_for \"";
+    OS << replacedFun->getName();
+    OS << "\"] ";
+  }
+
+  if (hasObjCReplacement()) {
+    OS << "[objc_replacement_for \"";
+    OS << getObjCReplacement().str();
+    OS << "\"] ";
+  }
+
   for (auto &Attr : getSemanticsAttrs())
     OS << "[_semantics \"" << Attr << "\"] ";
 
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 3253b68..c8d41a7 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -1391,7 +1391,7 @@
       verifyLLVMIntrinsic(BI, BI->getIntrinsicInfo().ID);
   }
   
-  void checkFunctionRefInst(FunctionRefInst *FRI) {
+  void checkFunctionRefBaseInst(FunctionRefBaseInst *FRI) {
     auto fnType = requireObjectType(SILFunctionType, FRI,
                                     "result of function_ref");
     require(!fnType->getExtInfo().hasContext(),
@@ -1402,6 +1402,22 @@
 
     SILFunction *RefF = FRI->getReferencedFunction();
 
+    if (isa<FunctionRefInst>(FRI))
+      require(
+          !RefF->isDynamicallyReplaceable(),
+          "function_ref cannot reference a [dynamically_replaceable] function");
+    else if (isa<PreviousDynamicFunctionRefInst>(FRI)) {
+      require(!RefF->isDynamicallyReplaceable(),
+              "previous_function_ref cannot reference a "
+              "[dynamically_replaceable] function");
+      require(RefF->getDynamicallyReplacedFunction(),
+              "previous_function_ref must reference a "
+              "[dynamic_replacement_for:...] function");
+    } else if (isa<DynamicFunctionRefInst>(FRI))
+      require(RefF->isDynamicallyReplaceable(),
+              "dynamic_function_ref cannot reference a "
+              "[dynamically_replaceable] function");
+
     // In canonical SIL, direct reference to a shared_external declaration
     // is an error; we should have deserialized a body. In raw SIL, we may
     // not have deserialized the body yet.
@@ -1427,6 +1443,18 @@
     verifySILFunctionType(fnType);
   }
 
+  void checkFunctionRefInst(FunctionRefInst *FRI) {
+    checkFunctionRefBaseInst(FRI);
+  }
+
+  void checkDynamicFunctionRefInst(DynamicFunctionRefInst *FRI) {
+    checkFunctionRefBaseInst(FRI);
+  }
+
+  void checkPreviousDynamicFunctionRefInst(PreviousDynamicFunctionRefInst *FRI) {
+    checkFunctionRefBaseInst(FRI);
+  }
+
   void checkAllocGlobalInst(AllocGlobalInst *AGI) {
     if (F.isSerialized()) {
       SILGlobalVariable *RefG = AGI->getReferencedGlobal();
diff --git a/lib/SIL/SILWitnessTable.cpp b/lib/SIL/SILWitnessTable.cpp
index 083992e..1b77afe 100644
--- a/lib/SIL/SILWitnessTable.cpp
+++ b/lib/SIL/SILWitnessTable.cpp
@@ -151,21 +151,21 @@
   }
 }
 
-bool SILWitnessTable::conformanceIsSerialized(ProtocolConformance *conformance) {
+bool SILWitnessTable::conformanceIsSerialized(
+    const NormalProtocolConformance *conformance) {
+  if (conformance->isResilient())
+    return false;
+
   // Serialize witness tables for conformances synthesized by
   // the ClangImporter.
   if (isa<ClangModuleUnit>(conformance->getDeclContext()->getModuleScopeContext()))
     return true;
 
+  if (conformance->getProtocol()->getEffectiveAccess() < AccessLevel::Public)
+    return false;
+
   auto *nominal = conformance->getType()->getAnyNominal();
-  // Only serialize witness tables for fixed layout types.
-  //
-  // FIXME: This is not the right long term solution. We need an explicit
-  // mechanism for declaring conformances as 'fragile'.
-  auto protocolIsPublic =
-      conformance->getProtocol()->getEffectiveAccess() >= AccessLevel::Public;
-  auto typeIsPublic = nominal->getEffectiveAccess() >= AccessLevel::Public;
-  return !nominal->isResilient() && protocolIsPublic && typeIsPublic;
+  return nominal->getEffectiveAccess() >= AccessLevel::Public;
 }
 
 bool SILWitnessTable::enumerateWitnessTableConditionalConformances(
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index 4af17f2..c06a919 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -957,7 +957,8 @@
 
     SILValue emitCopyValue(SILBuilder &B, SILLocation loc,
                            SILValue value) const override {
-      if (isa<FunctionRefInst>(value))
+      if (isa<FunctionRefInst>(value) || isa<DynamicFunctionRefInst>(value) ||
+          isa<PreviousDynamicFunctionRefInst>(value))
         return value;
 
       if (B.getFunction().hasQualifiedOwnership())
@@ -1619,7 +1620,7 @@
                                                      ValueDecl *VD,
                                                      DeclContext *DC,
                                                      unsigned DefaultArgIndex) {
-  auto resultTy = getDefaultArgumentInfo(VD, DefaultArgIndex).second;
+  auto resultTy = getParameterAt(VD, DefaultArgIndex)->getInterfaceType();
   assert(resultTy && "Didn't find default argument?");
 
   // The result type might be written in terms of type parameters
diff --git a/lib/SIL/ValueOwnership.cpp b/lib/SIL/ValueOwnership.cpp
index 7784232..dbfbf46 100644
--- a/lib/SIL/ValueOwnership.cpp
+++ b/lib/SIL/ValueOwnership.cpp
@@ -46,11 +46,6 @@
 #define CONSTANT_OWNERSHIP_INST(OWNERSHIP, INST)                               \
   ValueOwnershipKind ValueOwnershipKindClassifier::visit##INST##Inst(          \
       INST##Inst *Arg) {                                                       \
-    if (ValueOwnershipKind::OWNERSHIP == ValueOwnershipKind::Trivial) {        \
-      assert((Arg->getType().isAddress() ||                                    \
-              Arg->getType().isTrivial(Arg->getModule())) &&                   \
-             "Trivial ownership requires a trivial type or an address");       \
-    }                                                                          \
     return ValueOwnershipKind::OWNERSHIP;                                      \
   }
 
@@ -104,6 +99,8 @@
 CONSTANT_OWNERSHIP_INST(Trivial, ExistentialMetatype)
 CONSTANT_OWNERSHIP_INST(Trivial, FloatLiteral)
 CONSTANT_OWNERSHIP_INST(Trivial, FunctionRef)
+CONSTANT_OWNERSHIP_INST(Trivial, DynamicFunctionRef)
+CONSTANT_OWNERSHIP_INST(Trivial, PreviousDynamicFunctionRef)
 CONSTANT_OWNERSHIP_INST(Trivial, GlobalAddr)
 CONSTANT_OWNERSHIP_INST(Trivial, IndexAddr)
 CONSTANT_OWNERSHIP_INST(Trivial, IndexRawPointer)
@@ -257,7 +254,7 @@
 #define FORWARDING_OWNERSHIP_INST(INST)                                        \
   ValueOwnershipKind ValueOwnershipKindClassifier::visit##INST##Inst(          \
       INST##Inst *I) {                                                         \
-    return visitForwardingInst(I);                                             \
+    return I->getOwnershipKind();                                              \
   }
 FORWARDING_OWNERSHIP_INST(BridgeObjectToRef)
 FORWARDING_OWNERSHIP_INST(ConvertFunction)
@@ -273,29 +270,16 @@
 FORWARDING_OWNERSHIP_INST(Upcast)
 FORWARDING_OWNERSHIP_INST(MarkUninitialized)
 FORWARDING_OWNERSHIP_INST(UncheckedEnumData)
+FORWARDING_OWNERSHIP_INST(SelectEnum)
+FORWARDING_OWNERSHIP_INST(Enum)
 #undef FORWARDING_OWNERSHIP_INST
 
 ValueOwnershipKind
-ValueOwnershipKindClassifier::visitSelectEnumInst(SelectEnumInst *SEI) {
-  // We handle this specially, since a select enum forwards only its case
-  // values. We drop the first element since that is the condition element.
-  return visitForwardingInst(SEI, SEI->getAllOperands().drop_front());
-}
-
-ValueOwnershipKind
 ValueOwnershipKindClassifier::visitUncheckedOwnershipConversionInst(
     UncheckedOwnershipConversionInst *I) {
   return I->getConversionOwnershipKind();
 }
 
-// An enum without payload is trivial. One with non-trivial payload is
-// forwarding.
-ValueOwnershipKind ValueOwnershipKindClassifier::visitEnumInst(EnumInst *EI) {
-  if (!EI->hasOperand())
-    return ValueOwnershipKind::Trivial;
-  return visitForwardingInst(EI);
-}
-
 ValueOwnershipKind ValueOwnershipKindClassifier::visitSILUndef(SILUndef *Arg) {
   return ValueOwnershipKind::Any;
 }
@@ -394,8 +378,6 @@
                                         llvm::Intrinsic::ID ID) {
     // LLVM intrinsics do not traffic in ownership, so if we have a result, it
     // must be trivial.
-    assert(BI->getType().isTrivial(BI->getModule()) &&
-           "LLVM intrinsics should always be trivial");
     return ValueOwnershipKind::Trivial;
   }
 
@@ -409,13 +391,6 @@
 #define CONSTANT_OWNERSHIP_BUILTIN(OWNERSHIP, ID)                              \
   ValueOwnershipKind ValueOwnershipKindBuiltinVisitor::visit##ID(              \
       BuiltinInst *BI, StringRef Attr) {                                       \
-    if (ValueOwnershipKind::OWNERSHIP == ValueOwnershipKind::Trivial) {        \
-      assert(BI->getType().isTrivial(BI->getModule()) &&                       \
-             "Only trivial types can have trivial ownership");                 \
-    } else {                                                                   \
-      assert(!BI->getType().isTrivial(BI->getModule()) &&                      \
-             "Only non trivial types can have non trivial ownership");         \
-    }                                                                          \
     return ValueOwnershipKind::OWNERSHIP;                                      \
   }
 // This returns a value at +1 that is destroyed strictly /after/ the
@@ -541,6 +516,7 @@
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, OnceWithContext)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, TSanInoutAccess)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, Swift3ImplicitObjCEntrypoint)
+CONSTANT_OWNERSHIP_BUILTIN(Trivial, PoundAssert)
 
 #undef CONSTANT_OWNERSHIP_BUILTIN
 
diff --git a/lib/SIL/ValueUtils.cpp b/lib/SIL/ValueUtils.cpp
new file mode 100644
index 0000000..8486181
--- /dev/null
+++ b/lib/SIL/ValueUtils.cpp
@@ -0,0 +1,55 @@
+//===--- ValueUtils.cpp ---------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 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 "swift/SIL/ValueUtils.h"
+#include "swift/Basic/STLExtras.h"
+#include "swift/SIL/SILFunction.h"
+
+using namespace swift;
+
+Optional<ValueOwnershipKind>
+swift::mergeSILValueOwnership(ArrayRef<SILValue> values) {
+  // A forwarding inst without operands must be trivial.
+  if (values.empty())
+    return Optional<ValueOwnershipKind>(ValueOwnershipKind::Trivial);
+
+  // Find the first index where we have a trivial value.
+  auto iter = find_if(values, [](SILValue v) -> bool {
+    return v.getOwnershipKind() != ValueOwnershipKind::Trivial;
+  });
+  // All trivial.
+  if (iter == values.end()) {
+    return Optional<ValueOwnershipKind>(ValueOwnershipKind::Trivial);
+  }
+
+  // See if we have any Any. If we do, just return that for now.
+  if (any_of(values, [](SILValue v) -> bool {
+        return v.getOwnershipKind() == ValueOwnershipKind::Any;
+      }))
+    return Optional<ValueOwnershipKind>(ValueOwnershipKind::Any);
+
+  unsigned index = std::distance(values.begin(), iter);
+  ValueOwnershipKind base = values[index].getOwnershipKind();
+
+  for (SILValue v : values.slice(index + 1)) {
+    auto opKind = v.getOwnershipKind();
+    if (opKind.merge(ValueOwnershipKind::Trivial))
+      continue;
+
+    auto mergedValue = base.merge(opKind.Value);
+    if (!mergedValue.hasValue()) {
+      return None;
+    }
+  }
+
+  return base;
+}
diff --git a/lib/SILGen/LValue.h b/lib/SILGen/LValue.h
index c65e345..00076b8 100644
--- a/lib/SILGen/LValue.h
+++ b/lib/SILGen/LValue.h
@@ -106,7 +106,7 @@
     AddressorKind,              // var/subscript addressor
     CoroutineAccessorKind,      // coroutine accessor
     ValueKind,                  // random base pointer as an lvalue
-    KeyPathApplicationKind,     // applying a key path
+    PhysicalKeyPathApplicationKind, // applying a key path
 
     // Logical LValue kinds
     GetterSetterKind,           // property or subscript getter/setter
@@ -115,6 +115,7 @@
     AutoreleasingWritebackKind, // autorelease pointer on set
     WritebackPseudoKind,        // a fake component to customize writeback
     OpenNonOpaqueExistentialKind,  // opened class or metatype existential
+    LogicalKeyPathApplicationKind, // applying a key path
     // Translation LValue kinds (a subtype of logical)
     OrigToSubstKind,            // generic type substitution
     SubstToOrigKind,            // generic type substitution
@@ -437,7 +438,8 @@
                              bool isSuper,
                              SGFAccessKind accessKind,
                              AccessStrategy accessStrategy,
-                             CanType formalRValueType);
+                             CanType formalRValueType,
+                             bool isOnSelf = false);
 
   void addMemberSubscriptComponent(SILGenFunction &SGF, SILLocation loc,
                                    SubscriptDecl *subscript,
@@ -448,7 +450,8 @@
                                    AccessStrategy accessStrategy,
                                    CanType formalRValueType,
                                    PreparedArguments &&indices,
-                                   Expr *indexExprForDiagnostics);
+                                   Expr *indexExprForDiagnostics,
+                                   bool isOnSelfParameter = false);
 
   /// Add a subst-to-orig reabstraction component.  That is, given
   /// that this l-value trafficks in values following the substituted
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index 5458c0f..5a3e11c 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -381,6 +381,93 @@
   return *NSErrorConformanceToError;
 }
 
+SILFunction *
+SILGenModule::getKeyPathProjectionCoroutine(bool isReadAccess,
+                                            KeyPathTypeKind typeKind) {
+  bool isBaseInout;
+  bool isResultInout;
+  StringRef functionName;
+  NominalTypeDecl *keyPathDecl;
+  if (isReadAccess) {
+    assert(typeKind == KPTK_KeyPath ||
+           typeKind == KPTK_WritableKeyPath ||
+           typeKind == KPTK_ReferenceWritableKeyPath);
+    functionName = "swift_readAtKeyPath";
+    isBaseInout = false;
+    isResultInout = false;
+    keyPathDecl = getASTContext().getKeyPathDecl();
+  } else if (typeKind == KPTK_WritableKeyPath) {
+    functionName = "swift_modifyAtWritableKeyPath";
+    isBaseInout = true;
+    isResultInout = true;
+    keyPathDecl = getASTContext().getWritableKeyPathDecl();
+  } else if (typeKind == KPTK_ReferenceWritableKeyPath) {
+    functionName = "swift_modifyAtReferenceWritableKeyPath";
+    isBaseInout = false;
+    isResultInout = true;
+    keyPathDecl = getASTContext().getReferenceWritableKeyPathDecl();
+  } else {
+    llvm_unreachable("bad combination");
+  }
+
+  auto fn = M.lookUpFunction(functionName);
+  if (fn) return fn;
+
+  auto rootType = CanGenericTypeParamType::get(0, 0, getASTContext());
+  auto valueType = CanGenericTypeParamType::get(0, 1, getASTContext());
+
+  // Build the generic signature <A, B>.
+  auto sig = GenericSignature::get({rootType, valueType}, {});
+
+  auto keyPathTy = BoundGenericType::get(keyPathDecl, Type(),
+                                         { rootType, valueType })
+    ->getCanonicalType();
+
+  // (@in_guaranteed/@inout Root, @guaranteed KeyPath<Root, Value>)
+  SILParameterInfo params[] = {
+    { rootType,
+      isBaseInout ? ParameterConvention::Indirect_Inout
+                  : ParameterConvention::Indirect_In_Guaranteed },
+    { keyPathTy, ParameterConvention::Direct_Guaranteed },
+  };
+
+  // -> @yields @in_guaranteed/@inout Value
+  SILYieldInfo yields[] = {
+    { valueType,
+      isResultInout ? ParameterConvention::Indirect_Inout
+                    : ParameterConvention::Indirect_In_Guaranteed },
+  };
+
+  auto extInfo =
+    SILFunctionType::ExtInfo(SILFunctionTypeRepresentation::Thin,
+                             /*pseudogeneric*/false,
+                             /*non-escaping*/false);
+
+  auto functionTy = SILFunctionType::get(sig, extInfo,
+                                         SILCoroutineKind::YieldOnce,
+                                         ParameterConvention::Direct_Unowned,
+                                         params,
+                                         yields,
+                                         /*results*/ {},
+                                         /*error result*/ {},
+                                         getASTContext());
+
+  auto env = sig->createGenericEnvironment();
+
+  SILGenFunctionBuilder builder(*this);
+  fn = builder.createFunction(SILLinkage::PublicExternal,
+                              functionName,
+                              functionTy,
+                              env,
+                              /*location*/ None,
+                              IsNotBare,
+                              IsNotTransparent,
+                              IsNotSerialized,
+                              IsNotDynamic);
+
+  return fn;
+}
+
 
 SILFunction *SILGenModule::emitTopLevelFunction(SILLocation Loc) {
   ASTContext &C = M.getASTContext();
@@ -441,8 +528,8 @@
   SILGenFunctionBuilder builder(*this);
   return builder.createFunction(
       SILLinkage::Public, SWIFT_ENTRY_POINT_FUNCTION, topLevelType, nullptr,
-      Loc, IsBare, IsNotTransparent, IsNotSerialized, ProfileCounter(),
-      IsNotThunk, SubclassScope::NotApplicable);
+      Loc, IsBare, IsNotTransparent, IsNotSerialized, IsNotDynamic,
+      ProfileCounter(), IsNotThunk, SubclassScope::NotApplicable);
 }
 
 SILFunction *SILGenModule::getEmittedFunction(SILDeclRef constant,
@@ -507,7 +594,7 @@
   // distinct files. For extensions, just pass in the constructor, because
   // there are no stored property initializers to visit.
   Decl *decl = nullptr;
-  if (ctx->isExtensionContext())
+  if (isa<ExtensionDecl>(ctx))
     decl = cd;
   else
     decl = ctx->getSelfNominalTypeDecl();
@@ -1058,9 +1145,9 @@
   auto initSILType = getLoweredType(initType).castTo<SILFunctionType>();
 
   SILGenFunctionBuilder builder(*this);
-  auto *f = builder.createFunction(SILLinkage::Private, funcName, initSILType,
-                                   nullptr, SILLocation(binding), IsNotBare,
-                                   IsNotTransparent, IsNotSerialized);
+  auto *f = builder.createFunction(
+      SILLinkage::Private, funcName, initSILType, nullptr, SILLocation(binding),
+      IsNotBare, IsNotTransparent, IsNotSerialized, IsNotDynamic);
   f->setDebugScope(new (M) SILDebugScope(RegularLocation(binding), f));
   auto dc = binding->getDeclContext();
   SILGenFunction(*this, *f, dc).emitLazyGlobalInitializer(binding, pbdEntry);
diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h
index 9d3b967..6692ff8 100644
--- a/lib/SILGen/SILGen.h
+++ b/lib/SILGen/SILGen.h
@@ -407,6 +407,9 @@
   /// Retrieve the conformance of NSError to the Error protocol.
   ProtocolConformance *getNSErrorConformanceToError();
 
+  SILFunction *getKeyPathProjectionCoroutine(bool isReadAccess,
+                                             KeyPathTypeKind typeKind);
+
   /// Report a diagnostic.
   template<typename...T, typename...U>
   InFlightDiagnostic diagnose(SourceLoc loc, Diag<T...> diag,
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index a51e1d2..618702f 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -150,8 +150,7 @@
   
   // Extension methods currently must be statically dispatched, unless they're
   // @objc or dynamic.
-  if (funcDecl->getDeclContext()->isExtensionContext()
-      && !constant.isForeign)
+  if (isa<ExtensionDecl>(funcDecl->getDeclContext()) && !constant.isForeign)
     return true;
 
   // We cannot form a direct reference to a method body defined in
@@ -264,6 +263,10 @@
     /// A direct standalone function call, referenceable by a FunctionRefInst.
     StandaloneFunction,
 
+    /// A direct standalone function call, referenceable by a
+    /// PreviousDynamicFunctionRefInst.
+    StandaloneFunctionDynamicallyReplaceableImpl,
+
     /// Enum case constructor call.
     EnumElement,
 
@@ -344,17 +347,16 @@
 
   /// Constructor for Callee::forDirect.
   Callee(SILGenFunction &SGF, SILDeclRef standaloneFunction,
-         AbstractionPattern origFormalType,
-         CanAnyFunctionType substFormalType,
-         SubstitutionMap subs, SILLocation l)
-    : kind(Kind::StandaloneFunction), Constant(standaloneFunction),
-      OrigFormalInterfaceType(origFormalType),
-      SubstFormalInterfaceType(getSubstFormalInterfaceType(substFormalType,
-                                                           subs)),
-      Substitutions(subs),
-      Loc(l)
-  {
-  }
+         AbstractionPattern origFormalType, CanAnyFunctionType substFormalType,
+         SubstitutionMap subs, SILLocation l,
+         bool callDynamicallyReplaceableImpl = false)
+      : kind(callDynamicallyReplaceableImpl
+                 ? Kind::StandaloneFunctionDynamicallyReplaceableImpl
+                 : Kind::StandaloneFunction),
+        Constant(standaloneFunction), OrigFormalInterfaceType(origFormalType),
+        SubstFormalInterfaceType(
+            getSubstFormalInterfaceType(substFormalType, subs)),
+        Substitutions(subs), Loc(l) {}
 
   /// Constructor called by all for* factory methods except forDirect and
   /// forIndirect.
@@ -377,10 +379,13 @@
   }
   static Callee forDirect(SILGenFunction &SGF, SILDeclRef c,
                           SubstitutionMap subs,
-                          SILLocation l) {
+                          SILLocation l,
+                          bool callPreviousDynamicReplaceableImpl = false) {
     auto &ci = SGF.getConstantInfo(c);
-    return Callee(SGF, c, ci.FormalPattern, ci.FormalType, subs, l);
+    return Callee(SGF, c, ci.FormalPattern, ci.FormalType, subs, l,
+                  callPreviousDynamicReplaceableImpl);
   }
+
   static Callee forEnumElement(SILGenFunction &SGF, SILDeclRef c,
                                SubstitutionMap subs,
                                SILLocation l) {
@@ -485,6 +490,7 @@
       return 1;
 
     case Kind::StandaloneFunction:
+    case Kind::StandaloneFunctionDynamicallyReplaceableImpl:
     case Kind::EnumElement:
     case Kind::ClassMethod:
     case Kind::SuperMethod:
@@ -500,6 +506,7 @@
     switch (kind) {
     case Kind::IndirectValue:
     case Kind::StandaloneFunction:
+    case Kind::StandaloneFunctionDynamicallyReplaceableImpl:
     case Kind::EnumElement:
       return false;
     case Kind::WitnessMethod:
@@ -586,6 +593,12 @@
       SILValue ref = SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo);
       return ManagedValue::forUnmanaged(ref);
     }
+    case Kind::StandaloneFunctionDynamicallyReplaceableImpl: {
+      auto constantInfo = SGF.getConstantInfo(*constant);
+      SILValue ref =
+          SGF.emitGlobalFunctionRef(Loc, *constant, constantInfo, true);
+      return ManagedValue::forUnmanaged(ref);
+    }
     case Kind::EnumElement:
       llvm_unreachable("Should have been curried");
     case Kind::ClassMethod: {
@@ -685,6 +698,7 @@
       assert(Substitutions.empty());
       return createCalleeTypeInfo(SGF, constant, IndirectValue.getType());
 
+    case Kind::StandaloneFunctionDynamicallyReplaceableImpl:
     case Kind::StandaloneFunction: {
       auto constantInfo = SGF.getConstantInfo(*constant);
       return createCalleeTypeInfo(SGF, constant, constantInfo.getSILType());
@@ -737,6 +751,7 @@
     case Kind::SuperMethod:
     case Kind::WitnessMethod:
     case Kind::DynamicMethod:
+    case Kind::StandaloneFunctionDynamicallyReplaceableImpl:
       return None;
     }
     llvm_unreachable("bad callee kind");
@@ -745,6 +760,22 @@
 
 } // end anonymous namespace
 
+/// Is this a call to the dynamically replaced function inside of a
+/// '@_dynamicReplacement(for:)' function.
+bool isCallToReplacedInDynamicReplacement(SILGenFunction &SGF,
+                                          AbstractFunctionDecl *afd,
+                                          bool &isObjCReplacementSelfCall) {
+  if (auto *func =
+          dyn_cast_or_null<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl())) {
+    auto *repl = func->getAttrs().getAttribute<DynamicReplacementAttr>();
+    if (repl && repl->getReplacedFunction() == afd) {
+      isObjCReplacementSelfCall = afd->isObjC();
+      return true;
+    }
+  }
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 //                           SILGenApply ASTVisitor
 //===----------------------------------------------------------------------===//
@@ -1031,6 +1062,26 @@
       setSelfParam(std::move(selfArgSource), thisCallSite);
     }
 
+    // Directly dispatch to calls of the replaced function inside of
+    // '@_dynamicReplacement(for:)' methods.
+    bool isObjCReplacementCall = false;
+    if (isCallToReplacedInDynamicReplacement(SGF, afd, isObjCReplacementCall) &&
+        thisCallSite->getArg()->isSelfExprOf(
+            cast<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl()), false)) {
+      auto constant = SILDeclRef(afd, kind).asForeign(
+          !isObjCReplacementCall && requiresForeignEntryPoint(e->getDecl()));
+      auto subs = e->getDeclRef().getSubstitutions();
+      if (isObjCReplacementCall)
+        setCallee(Callee::forDirect(SGF, constant, subs, e));
+      else
+        setCallee(Callee::forDirect(
+            SGF,
+            SILDeclRef(cast<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl()),
+                       kind),
+            subs, e, true));
+      return;
+    }
+
     auto constant = SILDeclRef(afd, kind)
                         .asForeign(requiresForeignEntryPoint(afd));
 
@@ -1082,8 +1133,27 @@
         !captureInfo.hasGenericParamCaptures())
       subs = SubstitutionMap();
 
-    setCallee(Callee::forDirect(SGF, constant, subs, e));
-    
+    // Check whether we have to dispatch to the original implementation of a
+    // dynamically_replaceable inside of a dynamic_replacement(for:) function.
+    ApplyExpr *thisCallSite = callSites.back();
+    bool isObjCReplacementSelfCall = false;
+    bool isSelfCallToReplacedInDynamicReplacement =
+        isCallToReplacedInDynamicReplacement(
+            SGF, cast<AbstractFunctionDecl>(constant.getDecl()),
+            isObjCReplacementSelfCall) &&
+        (afd->getDeclContext()->isModuleScopeContext() ||
+         thisCallSite->getArg()->isSelfExprOf(
+             cast<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl()), false));
+
+    if (isSelfCallToReplacedInDynamicReplacement && !isObjCReplacementSelfCall)
+      setCallee(Callee::forDirect(
+          SGF,
+          SILDeclRef(cast<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl()),
+                     constant.kind),
+          subs, e, true));
+    else
+      setCallee(Callee::forDirect(SGF, constant, subs, e));
+
     // If the decl ref requires captures, emit the capture params.
     if (!captureInfo.getCaptures().empty()) {
       SmallVector<ManagedValue, 4> captures;
@@ -1393,7 +1463,17 @@
                          ? SILDeclRef::Kind::Allocator
                          : SILDeclRef::Kind::Initializer);
 
-    constant = constant.asForeign(requiresForeignEntryPoint(ctorRef->getDecl()));
+    bool isObjCReplacementSelfCall = false;
+    bool isSelfCallToReplacedInDynamicReplacement =
+        isCallToReplacedInDynamicReplacement(
+            SGF, cast<AbstractFunctionDecl>(constant.getDecl()),
+            isObjCReplacementSelfCall) &&
+        arg->isSelfExprOf(
+            cast<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl()), false);
+
+    constant =
+        constant.asForeign(!isObjCReplacementSelfCall &&
+                           requiresForeignEntryPoint(ctorRef->getDecl()));
 
     // Determine the callee. This is normally the allocating
     // entry point, unless we're delegating to an ObjC initializer.
@@ -1402,15 +1482,24 @@
       setCallee(Callee::forWitnessMethod(
           SGF, self.getType().getASTType(),
           constant, subs, expr));
-    } else if ((useAllocatingCtor || constant.isForeign)
-            && getMethodDispatch(ctorRef->getDecl()) == MethodDispatch::Class) {
+    } else if ((useAllocatingCtor || constant.isForeign) &&
+               !isSelfCallToReplacedInDynamicReplacement &&
+               getMethodDispatch(ctorRef->getDecl()) == MethodDispatch::Class) {
       // Dynamic dispatch to the initializer.
       Scope S(SGF, expr);
       setCallee(Callee::forClassMethod(
           SGF, constant, subs, fn));
     } else {
       // Directly call the peer constructor.
-      setCallee(Callee::forDirect(SGF, constant, subs, fn));
+      if (isObjCReplacementSelfCall ||
+          !isSelfCallToReplacedInDynamicReplacement)
+        setCallee(Callee::forDirect(SGF, constant, subs, fn));
+      else
+        setCallee(Callee::forDirect(
+            SGF,
+            SILDeclRef(cast<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl()),
+                       constant.kind),
+            subs, fn, true));
     }
 
     setSelfParam(std::move(selfArgSource), expr);
@@ -4255,10 +4344,21 @@
 
   auto fnValue = callee.getFnValue(SGF, isCurried, borrowedSelf);
 
-  // Emit the uncurried call.
+  return SGF.emitBeginApply(uncurriedLoc.getValue(), fnValue,
+                            callee.getSubstitutions(), uncurriedArgs,
+                            calleeTypeInfo.substFnType, options, yields);
+}
+
+CleanupHandle
+SILGenFunction::emitBeginApply(SILLocation loc, ManagedValue fn,
+                               SubstitutionMap subs,
+                               ArrayRef<ManagedValue> args,
+                               CanSILFunctionType substFnType,
+                               ApplyOptions options,
+                               SmallVectorImpl<ManagedValue> &yields) {
+  // Emit the call.
   SmallVector<SILValue, 4> rawResults;
-  emitRawApply(SGF, uncurriedLoc.getValue(), fnValue, callee.getSubstitutions(),
-               uncurriedArgs, calleeTypeInfo.substFnType, options,
+  emitRawApply(*this, loc, fn, subs, args, substFnType, options,
                /*indirect results*/ {}, rawResults);
 
   auto token = rawResults.pop_back_val();
@@ -4266,11 +4366,11 @@
 
   // Push a cleanup to end the application.
   // TODO: destroy all the arguments at exactly this point?
-  SGF.Cleanups.pushCleanup<EndCoroutineApply>(token);
-  auto endApplyHandle = SGF.getTopCleanup();
+  Cleanups.pushCleanup<EndCoroutineApply>(token);
+  auto endApplyHandle = getTopCleanup();
 
   // Manage all the yielded values.
-  auto yieldInfos = calleeTypeInfo.substFnType->getYields();
+  auto yieldInfos = substFnType->getYields();
   assert(yieldValues.size() == yieldInfos.size());
   for (auto i : indices(yieldValues)) {
     auto value = yieldValues[i];
@@ -4278,7 +4378,7 @@
     if (info.isIndirectInOut()) {
       yields.push_back(ManagedValue::forLValue(value));
     } else if (info.isConsumed()) {
-      yields.push_back(SGF.emitManagedRValueWithCleanup(value));
+      yields.push_back(emitManagedRValueWithCleanup(value));
     } else if (info.isDirectGuaranteed()) {
       yields.push_back(ManagedValue::forBorrowedRValue(value));
     } else {
@@ -5026,11 +5126,12 @@
   return normalBB->createPhiArgument(resultType, ValueOwnershipKind::Owned);
 }
 
-SILValue SILGenFunction::emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
-                                                   SILType substFnType,
-                                                   SubstitutionMap subs,
-                                                   ArrayRef<SILValue> args,
-                                            SmallVectorImpl<SILValue> &yields) {
+std::pair<SILValue, CleanupHandle>
+SILGenFunction::emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
+                                          SILType substFnType,
+                                          SubstitutionMap subs,
+                                          ArrayRef<SILValue> args,
+                                          SmallVectorImpl<SILValue> &yields) {
   // TODO: adjust this to create try_begin_apply when appropriate.
   assert(!substFnType.castTo<SILFunctionType>()->hasErrorResult());
 
@@ -5039,7 +5140,12 @@
   auto yieldResults = beginApply->getYieldedValues();
   yields.append(yieldResults.begin(), yieldResults.end());
 
-  return beginApply->getTokenResult();
+  auto token = beginApply->getTokenResult();
+
+  Cleanups.pushCleanup<EndCoroutineApply>(token);
+  auto abortCleanup = Cleanups.getTopCleanup();
+
+  return { token, abortCleanup };
 }
 
 void SILGenFunction::emitEndApplyWithRethrow(SILLocation loc, SILValue token) {
@@ -5540,9 +5646,20 @@
                                          ArgumentSource &selfValue,
                                          bool isSuper,
                                          bool isDirectUse,
-                                         SubstitutionMap subs) {
+                                         SubstitutionMap subs,
+                                         bool isOnSelfParameter) {
   auto *decl = cast<AbstractFunctionDecl>(constant.getDecl());
 
+  bool isObjCReplacementSelfCall = false;
+  if (isOnSelfParameter && isCallToReplacedInDynamicReplacement(
+                               SGF, decl, isObjCReplacementSelfCall)) {
+    return Callee::forDirect(
+        SGF,
+        SILDeclRef(cast<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl()),
+                   constant.kind),
+        subs, loc, true);
+  }
+
   // The accessor might be a local function that does not capture any
   // generic parameters, in which case we don't want to pass in any
   // substitutions.
@@ -5598,13 +5715,14 @@
                                    SubstitutionMap substitutions,
                                    ArgumentSource &selfValue,
                                    bool isSuper,
-                                   bool isDirectUse)
+                                   bool isDirectUse,
+                                   bool isOnSelfParameter)
 {
   // Get the accessor function. The type will be a polymorphic function if
   // the Self type is generic.
   Callee callee = getBaseAccessorFunctionRef(SGF, loc, constant, selfValue,
                                              isSuper, isDirectUse,
-                                             substitutions);
+                                             substitutions, isOnSelfParameter);
   
   // Collect captures if the accessor has them.
   auto accessorFn = cast<AbstractFunctionDecl>(constant.getDecl());
@@ -5890,18 +6008,18 @@
 }
 
 /// Emit a call to a getter.
-RValue SILGenFunction::
-emitGetAccessor(SILLocation loc, SILDeclRef get,
-                SubstitutionMap substitutions,
-                ArgumentSource &&selfValue,
-                bool isSuper, bool isDirectUse,
-                PreparedArguments &&subscriptIndices, SGFContext c) {
+RValue SILGenFunction::emitGetAccessor(SILLocation loc, SILDeclRef get,
+                                       SubstitutionMap substitutions,
+                                       ArgumentSource &&selfValue, bool isSuper,
+                                       bool isDirectUse,
+                                       PreparedArguments &&subscriptIndices,
+                                       SGFContext c, bool isOnSelfParameter) {
   // Scope any further writeback just within this operation.
   FormalEvaluationScope writebackScope(*this);
 
-  Callee getter = emitSpecializedAccessorFunctionRef(*this, loc, get,
-                                                     substitutions, selfValue,
-                                                     isSuper, isDirectUse);
+  Callee getter = emitSpecializedAccessorFunctionRef(
+      *this, loc, get, substitutions, selfValue, isSuper, isDirectUse,
+      isOnSelfParameter);
   bool hasSelf = (bool)selfValue;
   CanAnyFunctionType accessType = getter.getSubstFormalType();
 
@@ -5927,13 +6045,14 @@
                                      ArgumentSource &&selfValue,
                                      bool isSuper, bool isDirectUse,
                                      PreparedArguments &&subscriptIndices,
-                                     ArgumentSource &&setValue) {
+                                     ArgumentSource &&setValue,
+                                     bool isOnSelfParameter) {
   // Scope any further writeback just within this operation.
   FormalEvaluationScope writebackScope(*this);
 
-  Callee setter = emitSpecializedAccessorFunctionRef(*this, loc, set,
-                                                     substitutions, selfValue,
-                                                     isSuper, isDirectUse);
+  Callee setter = emitSpecializedAccessorFunctionRef(
+      *this, loc, set, substitutions, selfValue, isSuper, isDirectUse,
+      isOnSelfParameter);
   bool hasSelf = (bool)selfValue;
   CanAnyFunctionType accessType = setter.getSubstFormalType();
 
@@ -5969,23 +6088,18 @@
 
 /// Emit a call to an addressor.
 ///
-/// The first return value is the address, which will always be an
-/// l-value managed value.  The second return value is the owner
-/// pointer, if applicable.
-std::pair<ManagedValue, ManagedValue> SILGenFunction::
-emitAddressorAccessor(SILLocation loc, SILDeclRef addressor,
-                      SubstitutionMap substitutions,
-                      ArgumentSource &&selfValue,
-                      bool isSuper, bool isDirectUse,
-                      PreparedArguments &&subscriptIndices,
-                      SILType addressType) {
+/// Returns an l-value managed value.
+ManagedValue SILGenFunction::emitAddressorAccessor(
+    SILLocation loc, SILDeclRef addressor, SubstitutionMap substitutions,
+    ArgumentSource &&selfValue, bool isSuper, bool isDirectUse,
+    PreparedArguments &&subscriptIndices, SILType addressType,
+    bool isOnSelfParameter) {
   // Scope any further writeback just within this operation.
   FormalEvaluationScope writebackScope(*this);
 
-  Callee callee =
-    emitSpecializedAccessorFunctionRef(*this, loc, addressor,
-                                       substitutions, selfValue,
-                                       isSuper, isDirectUse);
+  Callee callee = emitSpecializedAccessorFunctionRef(
+      *this, loc, addressor, substitutions, selfValue, isSuper, isDirectUse,
+      isOnSelfParameter);
   bool hasSelf = (bool)selfValue;
   CanAnyFunctionType accessType = callee.getSubstFormalType();
 
@@ -6009,23 +6123,8 @@
   SmallVector<ManagedValue, 2> results;
   emission.apply().getAll(results);
 
-  SILValue pointer;
-  ManagedValue owner;
-  switch (cast<AccessorDecl>(addressor.getDecl())->getAddressorKind()) {
-  case AddressorKind::NotAddressor:
-    llvm_unreachable("not an addressor!");
-  case AddressorKind::Unsafe:
-    assert(results.size() == 1);
-    pointer = results[0].getUnmanagedValue();
-    owner = ManagedValue();
-    break;
-  case AddressorKind::Owning:
-  case AddressorKind::NativeOwning:
-    assert(results.size() == 2);
-    pointer = results[0].getUnmanagedValue();
-    owner = results[1];
-    break;
-  }
+  assert(results.size() == 1);
+  auto pointer = results[0].getUnmanagedValue();
 
   // Drill down to the raw pointer using intrinsic knowledge of those types.
   auto pointerType =
@@ -6042,20 +6141,7 @@
                                               /*isStrict*/ true,
                                               /*isInvariant*/ false);
 
-  // Mark dependence as necessary.
-  switch (cast<AccessorDecl>(addressor.getDecl())->getAddressorKind()) {
-  case AddressorKind::NotAddressor:
-    llvm_unreachable("not an addressor!");
-  case AddressorKind::Unsafe:
-    // TODO: we should probably mark dependence on the base.
-    break;
-  case AddressorKind::Owning:
-  case AddressorKind::NativeOwning:
-    address = B.createMarkDependence(loc, address, owner.getValue());
-    break;
-  }
-
-  return { ManagedValue::forLValue(address), owner };
+  return ManagedValue::forLValue(address);
 }
 
 CleanupHandle
@@ -6064,11 +6150,12 @@
                                       ArgumentSource &&selfValue,
                                       bool isSuper, bool isDirectUse,
                                       PreparedArguments &&subscriptIndices,
-                                      SmallVectorImpl<ManagedValue> &yields) {
+                                      SmallVectorImpl<ManagedValue> &yields,
+                                      bool isOnSelfParameter) {
   Callee callee =
     emitSpecializedAccessorFunctionRef(*this, loc, accessor,
                                        substitutions, selfValue,
-                                       isSuper, isDirectUse);
+                                       isSuper, isDirectUse, isOnSelfParameter);
 
   // We're already in a full formal-evaluation scope.
   // Make a dead writeback scope; applyCoroutine won't try to pop this.
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index 5f63ffb..eba396c 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -601,8 +601,8 @@
   auto storage = emitTemporaryAllocation(loc, storageAddrTy);
   auto capture = B.createProjectBlockStorage(loc, storage);
   B.createStore(loc, fn, capture, StoreOwnershipQualifier::Init);
-  auto invokeFn = B.createFunctionRef(loc, thunk);
-  
+  auto invokeFn = B.createFunctionRefFor(loc, thunk);
+
   auto stackBlock = B.createInitBlockStorageHeader(loc, storage, invokeFn,
                               SILType::getPrimitiveObjectType(loweredBlockTy),
                                                    subs);
@@ -959,7 +959,7 @@
   }
 
   // Create it in the current function.
-  auto thunkValue = B.createFunctionRef(loc, thunk);
+  auto thunkValue = B.createFunctionRefFor(loc, thunk);
   ManagedValue thunkedFn = B.createPartialApply(
       loc, thunkValue, SILType::getPrimitiveObjectType(substFnTy),
       interfaceSubs, block,
@@ -1433,7 +1433,7 @@
       // If @objc was inferred based on the Swift 3 @objc inference rules, emit
       // a call to Builtin.swift3ImplicitObjCEntrypoint() to enable runtime
       // logging of the uses of such entrypoints.
-      if (attr->isSwift3Inferred() && !decl->isDynamic()) {
+      if (attr->isSwift3Inferred() && !decl->isObjCDynamic()) {
         // Get the starting source location of the declaration so we can say
         // exactly where to stick '@objc'.
         SourceLoc objcInsertionLoc =
diff --git a/lib/SILGen/SILGenBuilder.cpp b/lib/SILGen/SILGenBuilder.cpp
index 983fb97..cb9d2ae 100644
--- a/lib/SILGen/SILGenBuilder.cpp
+++ b/lib/SILGen/SILGenBuilder.cpp
@@ -712,7 +712,7 @@
 
 ManagedValue SILGenBuilder::createManagedFunctionRef(SILLocation loc,
                                                      SILFunction *f) {
-  return ManagedValue::forUnmanaged(createFunctionRef(loc, f));
+  return ManagedValue::forUnmanaged(createFunctionRefFor(loc, f));
 }
 
 ManagedValue SILGenBuilder::createTupleElementAddr(SILLocation Loc,
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index f985f2b..951706f 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -904,9 +904,9 @@
     SILGenFunctionBuilder builder(SGF);
     thunkFn = builder.getOrCreateFunction(
         SILLocation(behaviorVar), behaviorInitName, SILLinkage::PrivateExternal,
-        initConstantTy, IsBare, IsTransparent, IsSerialized);
+        initConstantTy, IsBare, IsTransparent, IsSerialized, IsNotDynamic);
   }
-  return SGF.B.createFunctionRef(behaviorVar, thunkFn);
+  return SGF.B.createFunctionRefFor(behaviorVar, thunkFn);
 }
 
 static SILValue getBehaviorSetterFn(SILGenFunction &SGF, VarDecl *behaviorVar) {
@@ -915,7 +915,7 @@
 
   // TODO: The setter may need to be a thunk, to implode tuples or perform
   // reabstractions.
-  return SGF.B.createFunctionRef(behaviorVar, setFn);
+  return SGF.B.createFunctionRefFor(behaviorVar, setFn);
 }
 
 static Type getInitializationTypeInContext(
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 2432dc9..4896e45 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -903,252 +903,6 @@
   return RValue(*this, loc, refType, result);
 }
 
-static AbstractionPattern
-getFormalStorageAbstractionPattern(SILGenFunction &SGF, AbstractStorageDecl *field) {
-  if (auto var = dyn_cast<VarDecl>(field)) {
-    auto origType = SGF.SGM.Types.getAbstractionPattern(var);
-    return origType.getReferenceStorageReferentType();
-  }
-  auto sub = cast<SubscriptDecl>(field);
-  return SGF.SGM.Types.getAbstractionPattern(sub);
-}
-
-static SILDeclRef getRValueAccessorDeclRef(SILGenFunction &SGF,
-                                           AbstractStorageDecl *storage,
-                                           AccessStrategy strategy) {
-  switch (strategy.getKind()) {
-  case AccessStrategy::BehaviorStorage:
-    llvm_unreachable("shouldn't load an rvalue via behavior storage!");
-  
-  case AccessStrategy::Storage:
-    llvm_unreachable("should already have been filtered out!");
-
-  case AccessStrategy::MaterializeToTemporary:
-    llvm_unreachable("never used for read accesses");    
-
-  case AccessStrategy::DirectToAccessor:
-  case AccessStrategy::DispatchToAccessor: {
-    auto accessor = strategy.getAccessor();
-    return SGF.SGM.getAccessorDeclRef(storage->getAccessor(accessor));
-  }
-  }
-  llvm_unreachable("should already have been filtered out!");
-}
-
-static RValue getTargetRValue(SILGenFunction &SGF, SILLocation loc,
-                              ManagedValue value,
-                              AbstractionPattern origFormalType,
-                              CanType substFormalType,
-                              SGFContext C) {
-  SILType loweredSubstType = SGF.getLoweredType(substFormalType);
-
-  bool hasAbstraction =
-    (loweredSubstType.getObjectType() != value.getType().getObjectType());
-
-  if (value.isLValue() ||
-      (value.getType().isAddress() && !loweredSubstType.isAddress())) {
-    auto isTake =
-      IsTake_t(!value.isLValue() && !value.isPlusZeroRValueOrTrivial());
-    value = SGF.emitLoad(loc,
-                         (isTake ? value.forward(SGF)
-                                 : value.getUnmanagedValue()),
-                         SGF.getTypeLowering(value.getType()),
-                         (hasAbstraction ? SGFContext() : C),
-                         isTake);
-  }
-
-  RValue result(SGF, loc, substFormalType, value);
-  if (hasAbstraction) {
-    result = SGF.emitOrigToSubstValue(loc, std::move(result), origFormalType,
-                                      substFormalType, C);
-  }
-  return result;
-}
-
-static RValue
-emitRValueWithAccessor(SILGenFunction &SGF, SILLocation loc,
-                       AbstractStorageDecl *storage,
-                       SubstitutionMap substitutions,
-                       ArgumentSource &&baseRV,
-                       PreparedArguments &&subscriptIndices,
-                       bool isSuper, AccessStrategy strategy,
-                       SILDeclRef accessor,
-                       AbstractionPattern origFormalType,
-                       CanType substFormalType,
-                       SGFContext C) {
-  assert(strategy.getKind() == AccessStrategy::DirectToAccessor ||
-         strategy.getKind() == AccessStrategy::DispatchToAccessor);
-  bool isDirectUse = (strategy.getKind() == AccessStrategy::DirectToAccessor);
-
-  // The easy path here is if we don't need to use an addressor.
-  if (strategy.getAccessor() == AccessorKind::Get) {
-    return SGF.emitGetAccessor(loc, accessor, substitutions,
-                               std::move(baseRV), isSuper, isDirectUse,
-                               std::move(subscriptIndices), C);
-  }
-
-  assert(strategy.getAccessor() == AccessorKind::Address);
-
-  auto &storageTL = SGF.getTypeLowering(origFormalType, substFormalType);
-  SILType storageType = storageTL.getLoweredType().getAddressType();
-
-  auto addressorResult =
-    SGF.emitAddressorAccessor(loc, accessor, substitutions,
-                              std::move(baseRV), isSuper, isDirectUse,
-                              std::move(subscriptIndices), storageType);
-
-  RValue result = getTargetRValue(SGF, loc, addressorResult.first,
-                                  origFormalType, substFormalType, C);
-
-  switch (cast<AccessorDecl>(accessor.getDecl())->getAddressorKind()) {
-  case AddressorKind::NotAddressor: llvm_unreachable("inconsistent");
-  case AddressorKind::Unsafe:
-    // Nothing to do.
-    break;
-  case AddressorKind::Owning:
-  case AddressorKind::NativeOwning:
-    // Emit the release immediately.
-    SGF.B.emitDestroyValueOperation(loc, addressorResult.second.forward(SGF));
-    break;
-  }
-  
-  return result;
-}
-
-/// Produce a singular RValue for a load from the specified property.  This is
-/// designed to work with RValue ManagedValue bases that are either +0 or +1.
-RValue SILGenFunction::emitRValueForStorageLoad(
-    SILLocation loc, ManagedValue base, CanType baseFormalType,
-    bool isSuper, AbstractStorageDecl *storage,
-    PreparedArguments &&subscriptIndices,
-    SubstitutionMap substitutions,
-    AccessSemantics semantics, Type propTy, SGFContext C,
-    bool isBaseGuaranteed) {
-  AccessStrategy strategy =
-    storage->getAccessStrategy(semantics, AccessKind::Read, FunctionDC);
-
-  // If we should call an accessor of some kind, do so.
-  if (strategy.getKind() != AccessStrategy::Storage) {
-    auto accessor = getRValueAccessorDeclRef(*this, storage, strategy);
-    ArgumentSource baseRV = prepareAccessorBaseArg(loc, base,
-                                                   baseFormalType,
-                                                   accessor);
-
-    AbstractionPattern origFormalType =
-      getFormalStorageAbstractionPattern(*this, storage);
-    auto substFormalType = propTy->getCanonicalType();
-
-    return emitRValueWithAccessor(*this, loc, storage, substitutions,
-                                  std::move(baseRV),
-                                  std::move(subscriptIndices),
-                                  isSuper, strategy, accessor,
-                                  origFormalType, substFormalType, C);
-  }
-  assert(isa<VarDecl>(storage) && "only properties should have storage");
-  auto field = cast<VarDecl>(storage);
-  assert(field->hasStorage() &&
-         "Cannot directly access value without storage");
-
-  // For static variables, emit a reference to the global variable backing
-  // them.
-  // FIXME: This has to be dynamically looked up for classes, and
-  // dynamically instantiated for generics.
-  if (field->isStatic()) {
-    auto baseMeta = base.getType().castTo<MetatypeType>().getInstanceType();
-    (void)baseMeta;
-    assert(!baseMeta->is<BoundGenericType>() &&
-           "generic static stored properties not implemented");
-    if (field->getDeclContext()->getSelfClassDecl() &&
-        field->hasStorage())
-      // FIXME: don't need to check hasStorage, already done above
-      assert(field->isFinal() && "non-final class stored properties not implemented");
-
-    return emitRValueForDecl(loc, field, propTy, semantics, C);
-  }
-
-
-  // rvalue MemberRefExprs are produced in two cases: when accessing a 'let'
-  // decl member, and when the base is a (non-lvalue) struct.
-  assert(baseFormalType->getAnyNominal() &&
-         base.getType().getASTType()->getAnyNominal() &&
-         "The base of an rvalue MemberRefExpr should be an rvalue value");
-
-  // If the accessed field is stored, emit a StructExtract on the base.
-
-  auto substFormalType = propTy->getCanonicalType();
-  auto &lowering = getTypeLowering(substFormalType);
-
-  // Check for an abstraction difference.
-  AbstractionPattern origFormalType = getFormalStorageAbstractionPattern(*this, field);
-  bool hasAbstractionChange = false;
-  auto &abstractedTL = getTypeLowering(origFormalType, substFormalType);
-  if (!origFormalType.isExactType(substFormalType)) {
-    hasAbstractionChange =
-        (abstractedTL.getLoweredType() != lowering.getLoweredType());
-  }
-
-  // If the base is a reference type, just handle this as loading the lvalue.
-  ManagedValue result;
-  if (baseFormalType->hasReferenceSemantics()) {
-    LValue LV = emitPropertyLValue(loc, base, baseFormalType, field,
-                                   LValueOptions(),
-                                   SGFAccessKind::OwnedObjectRead,
-                                   AccessSemantics::DirectToStorage);
-    auto loaded = emitLoadOfLValue(loc, std::move(LV), C, isBaseGuaranteed);
-    // If we don't have to reabstract, the load is sufficient.
-    if (!hasAbstractionChange)
-      return loaded;
-    
-    // Otherwise, bring the component up to +1 so we can reabstract it.
-    result = std::move(loaded).getAsSingleValue(*this, loc)
-                              .copyUnmanaged(*this, loc);
-  } else if (!base.getType().isAddress()) {
-    // For non-address-only structs, we emit a struct_extract sequence.
-    result = B.createStructExtract(loc, base, field);
-
-    if (result.getType().is<ReferenceStorageType>()) {
-      // For weak and unowned types, convert the reference to the right
-      // pointer, producing a +1.
-      result = emitConversionToSemanticRValue(loc, result, lowering);
-
-    } else if (hasAbstractionChange ||
-               (!C.isImmediatePlusZeroOk() &&
-                !(C.isGuaranteedPlusZeroOk() && isBaseGuaranteed))) {
-      // If we have an abstraction change or if we have to produce a result at
-      // +1, then copy the value. If we know that our base will stay alive for
-      // the entire usage of this value, we can borrow the value at +0 for a
-      // guaranteed consumer. Otherwise, since we do not have enough information
-      // to know if the base's lifetime last's as long as our use of the access,
-      // we can only emit at +0 for immediate clients.
-      result = result.copyUnmanaged(*this, loc);
-    }
-  } else {
-    // Create a tiny unenforced access scope around a load from local memory. No
-    // cleanup is necessary since we directly emit the load here. This will
-    // probably go away with opaque values.
-    UnenforcedAccess access;
-    SILValue accessAddress =
-      access.beginAccess(*this, loc, base.getValue(), SILAccessKind::Read);
-
-    // For address-only sequences, the base is in memory.  Emit a
-    // struct_element_addr to get to the field, and then load the element as an
-    // rvalue.
-    SILValue ElementPtr = B.createStructElementAddr(loc, accessAddress, field);
-
-    result = emitLoad(loc, ElementPtr, abstractedTL,
-                      hasAbstractionChange ? SGFContext() : C, IsNotTake);
-    access.endAccess(*this);
-  }
-
-  // If we're accessing this member with an abstraction change, perform that
-  // now.
-  if (hasAbstractionChange)
-    result =
-        emitOrigToSubstValue(loc, result, origFormalType, substFormalType, C);
-  return RValue(*this, loc, substFormalType, result);
-}
-
-
 RValue RValueEmitter::visitDeclRefExpr(DeclRefExpr *E, SGFContext C) {
   return SGF.emitRValueForDecl(E, E->getDeclRef(), E->getType(),
                                E->getAccessSemantics(), C);
@@ -2863,6 +2617,14 @@
   return indexValues;
 }
 
+static AccessorDecl *
+getRepresentativeAccessorForKeyPath(AbstractStorageDecl *storage) {
+  if (storage->requiresOpaqueGetter())
+    return storage->getGetter();
+  assert(storage->requiresOpaqueReadCoroutine());
+  return storage->getReadCoroutine();
+}
+
 static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
                          SILLocation loc,
                          AbstractStorageDecl *property,
@@ -2875,16 +2637,16 @@
   // back to the declaration whose getter introduced the witness table
   // entry.
   if (isa<ProtocolDecl>(property->getDeclContext())) {
-    auto getter = property->getGetter();
-    if (!SILDeclRef::requiresNewWitnessTableEntry(getter)) {
+    auto accessor = getRepresentativeAccessorForKeyPath(property);
+    if (!SILDeclRef::requiresNewWitnessTableEntry(accessor)) {
       // Find the getter that does have a witness table entry.
-      auto wtableGetter =
-        cast<AccessorDecl>(SILDeclRef::getOverriddenWitnessTableEntry(getter));
+      auto wtableAccessor =
+        cast<AccessorDecl>(SILDeclRef::getOverriddenWitnessTableEntry(accessor));
 
       // Substitute the 'Self' type of the base protocol.
       subs = SILGenModule::mapSubstitutionsForWitnessOverride(
-              getter, wtableGetter, subs);
-      property = wtableGetter->getStorage();
+              accessor, wtableAccessor, subs);
+      property = wtableAccessor->getStorage();
     }
   }
 
@@ -2936,7 +2698,7 @@
   SILGenFunctionBuilder builder(SGM);
   auto thunk = builder.getOrCreateSharedFunction(
       loc, name, signature, IsBare, IsNotTransparent, IsNotSerialized,
-      ProfileCounter(), IsThunk);
+      ProfileCounter(), IsThunk, IsNotDynamic);
   if (!thunk->empty())
     return thunk;
   
@@ -3076,7 +2838,7 @@
   SILGenFunctionBuilder builder(SGM);
   auto thunk = builder.getOrCreateSharedFunction(
       loc, name, signature, IsBare, IsNotTransparent, IsNotSerialized,
-      ProfileCounter(), IsThunk);
+      ProfileCounter(), IsThunk, IsNotDynamic);
   if (!thunk->empty())
     return thunk;
   
@@ -3235,7 +2997,7 @@
     SILGenFunctionBuilder builder(SGM);
     equals = builder.getOrCreateSharedFunction(
         loc, name, signature, IsBare, IsNotTransparent, IsNotSerialized,
-        ProfileCounter(), IsThunk);
+        ProfileCounter(), IsThunk, IsNotDynamic);
     if (!equals->empty()) {
       return;
     }
@@ -3400,9 +3162,9 @@
     auto name = Mangle::ASTMangler().mangleKeyPathHashHelper(indexTypes,
                                                              genericSig);
     SILGenFunctionBuilder builder(SGM);
-    hash = builder.getOrCreateSharedFunction(loc, name, signature, IsBare,
-                                             IsNotTransparent, IsNotSerialized,
-                                             ProfileCounter(), IsThunk);
+    hash = builder.getOrCreateSharedFunction(
+        loc, name, signature, IsBare, IsNotTransparent, IsNotSerialized,
+        ProfileCounter(), IsThunk, IsNotDynamic);
     if (!hash->empty()) {
       return;
     }
@@ -3412,30 +3174,28 @@
     auto entry = hash->begin();
     auto indexPtr = entry->createFunctionArgument(params[0].getSILStorageType());
 
-    Scope scope(subSGF, loc);
-
-    auto hashMethod = cast<VarDecl>(
-      hashableProto->lookupDirect(C.Id_hashValue)[0])
-                   ->getGetter();
-    auto hashRef = SILDeclRef(hashMethod);
-    auto hashTy = subSGF.SGM.Types.getConstantType(hashRef);
-
     SILValue hashCode;
 
+    // For now, just use the hash value of the first index.
     // TODO: Combine hashes of the indexes using an inout Hasher
     {
+      ArgumentScope scope(subSGF, loc);
+
       auto &index = indexes[0];
       
+      // Extract the index value.
       SILValue indexAddr = subSGF.B.createPointerToAddress(loc, indexPtr,
                                              indexLoweredTy.getAddressType(),
                                              /*isStrict*/ false);
       if (indexes.size() > 1) {
         indexAddr = subSGF.B.createTupleElementAddr(loc, indexAddr, 0);
       }
-      
+
+      VarDecl *hashValueVar =
+        cast<VarDecl>(hashableProto->lookupDirect(C.Id_hashValue)[0]);
+
       auto formalTy = index.FormalType;
       auto hashable = index.Hashable;
-      SubstitutionMap hashableSubsMap;
       if (genericEnv) {
         formalTy = genericEnv->mapTypeIntoContext(formalTy)->getCanonicalType();
         hashable = hashable.subst(index.FormalType,
@@ -3443,52 +3203,31 @@
           LookUpConformanceInSignature(*genericSig));
       }
 
-      if (auto genericSig =
-              hashTy.castTo<SILFunctionType>()->getGenericSignature()) {
-        hashableSubsMap = SubstitutionMap::get(
-          genericSig,
+      // Set up a substitution of Self => IndexType.
+      auto hashGenericSig =
+        hashValueVar->getDeclContext()->getGenericSignatureOfContext();
+      assert(hashGenericSig);
+      SubstitutionMap hashableSubsMap = SubstitutionMap::get(
+          hashGenericSig,
           [&](SubstitutableType *type) -> Type { return formalTy; },
           [&](CanType dependentType, Type replacementType,
               ProtocolDecl *proto)->Optional<ProtocolConformanceRef> {
             return hashable;
           });
-      }
 
-      auto hashWitness = subSGF.B.createWitnessMethod(loc,
-        formalTy, hashable,
-        hashRef, hashTy);
+      // Read the storage.
+      ManagedValue base = ManagedValue::forBorrowedAddressRValue(indexAddr);
+      hashCode =
+        subSGF.emitRValueForStorageLoad(loc, base, formalTy, /*super*/ false,
+                                        hashValueVar, PreparedArguments(),
+                                        hashableSubsMap,
+                                        AccessSemantics::Ordinary,
+                                        intTy, SGFContext())
+              .getUnmanagedSingleValue(subSGF, loc);
 
-      auto hashSubstTy = hashTy.castTo<SILFunctionType>()
-        ->substGenericArgs(SGM.M, hashableSubsMap);
-      auto hashInfo = CalleeTypeInfo(hashSubstTy,
-                                     AbstractionPattern(intTy), intTy,
-                                     None,
-                                     ImportAsMemberStatus());
-
-      auto arg = subSGF.emitLoad(loc, indexAddr,
-        subSGF.getTypeLowering(AbstractionPattern::getOpaque(), formalTy),
-        SGFContext(), IsNotTake);
-      
-      if (!arg.getType().isAddress()) {
-        auto buf = subSGF.emitTemporaryAllocation(loc, arg.getType());
-        arg.forwardInto(subSGF, loc, buf);
-        arg = subSGF.emitManagedBufferWithCleanup(buf);
-      }
-      
-      {
-        auto hashResultPlan = ResultPlanBuilder::computeResultPlan(subSGF,
-          hashInfo, loc, SGFContext());
-        ArgumentScope argScope(subSGF, loc);
-        hashCode =
-            subSGF
-                .emitApply(std::move(hashResultPlan), std::move(argScope), loc,
-                           ManagedValue::forUnmanaged(hashWitness),
-                           hashableSubsMap,
-                           {arg}, hashInfo, ApplyOptions::None, SGFContext())
-                .getUnmanagedSingleValue(subSGF, loc);
-      }
+      scope.pop();
     }
-    scope.pop();
+
     subSGF.B.createReturn(loc, hashCode);
   }();
   
@@ -3508,7 +3247,7 @@
     // observed property into a stored property.
     strategy = strategy.getReadStrategy();
     if (strategy.getKind() != AccessStrategy::Storage ||
-        !storage->getGetter()) {
+        !getRepresentativeAccessorForKeyPath(storage)) {
       return getIdForKeyPathComponentComputedProperty(SGM, storage, strategy);
     }
     LLVM_FALLTHROUGH;
@@ -3519,12 +3258,13 @@
     // TODO: If the getter has shared linkage (say it's synthesized for a
     // Clang-imported thing), we'll need some other sort of
     // stable identifier.
-    auto getterRef = SILDeclRef(storage->getGetter(), SILDeclRef::Kind::Func);
+    auto getterRef = SILDeclRef(getRepresentativeAccessorForKeyPath(storage),
+                                SILDeclRef::Kind::Func);
     return SGM.getFunction(getterRef, NotForDefinition);
   }
   case AccessStrategy::DispatchToAccessor: {
     // Identify the property by its vtable or wtable slot.
-    return SGM.getAccessorDeclRef(storage->getGetter());
+    return SGM.getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage));
   }
   case AccessStrategy::BehaviorStorage:
     llvm_unreachable("unpossible");
@@ -3605,7 +3345,8 @@
         // Properties that only dispatch via ObjC lookup do not have nor need
         // property descriptors, since the selector identifies the storage.
         && (!storage->hasAnyAccessors()
-            || !getAccessorDeclRef(storage->getGetter()).isForeign);
+            || !getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage))
+                  .isForeign);
     };
   
   auto strategy = storage->getAccessStrategy(AccessSemantics::Ordinary,
@@ -3903,60 +3644,10 @@
 
 RValue RValueEmitter::
 visitKeyPathApplicationExpr(KeyPathApplicationExpr *E, SGFContext C) {
-  // An rvalue key path application always occurs as a read-only projection of
-  // the base. The base is received maximally abstracted.
-  auto root = SGF.emitMaterializedRValueAsOrig(E->getBase(),
-                                               AbstractionPattern::getOpaque());
-  auto keyPath = SGF.emitRValueAsSingleValue(E->getKeyPath());
+  FormalEvaluationScope scope(SGF);
 
-  auto keyPathDecl = E->getKeyPath()->getType()->getAnyNominal();
-  FuncDecl *projectFn;
-
-  SmallVector<Type, 2> replacementTypes;
-  if (keyPathDecl == SGF.getASTContext().getAnyKeyPathDecl()) {
-    // Invoke projectKeyPathAny with the type of the base value.
-    // The result is always `Any?`.
-    projectFn = SGF.getASTContext().getProjectKeyPathAny(nullptr);
-    replacementTypes.push_back(E->getBase()->getType());
-  } else {
-    auto keyPathTy = E->getKeyPath()->getType()->castTo<BoundGenericType>();
-    if (keyPathDecl == SGF.getASTContext().getPartialKeyPathDecl()) {
-      // Invoke projectKeyPathPartial with the type of the base value.
-      // The result is always `Any`.
-      projectFn = SGF.getASTContext().getProjectKeyPathPartial(nullptr);
-      replacementTypes.push_back(keyPathTy->getGenericArgs()[0]);
-    } else {
-      projectFn = SGF.getASTContext().getProjectKeyPathReadOnly(nullptr);
-      // Get the root and leaf type from the key path type.
-      replacementTypes.push_back(keyPathTy->getGenericArgs()[0]);
-      replacementTypes.push_back(keyPathTy->getGenericArgs()[1]);
-
-      // Upcast the keypath to KeyPath<T, U> if it isn't already.
-      if (keyPathTy->getDecl() != SGF.getASTContext().getKeyPathDecl()) {
-        auto castToTy = BoundGenericType::get(
-                                          SGF.getASTContext().getKeyPathDecl(),
-                                          nullptr,
-                                          keyPathTy->getGenericArgs())
-          ->getCanonicalType();
-        keyPath = SGF.B.createUpcast(SILLocation(E), keyPath,
-                                     SILType::getPrimitiveObjectType(castToTy));
-      }
-    }
-  }
-
-  auto projectionGenericSig = projectFn->getGenericSignature();
-  auto genericArgsMap = SubstitutionMap::get(
-      projectionGenericSig,
-      [&](SubstitutableType *type) -> Type {
-        auto genericParam = cast<GenericTypeParamType>(type);
-        auto index =
-            projectionGenericSig->getGenericParamOrdinal(genericParam);
-        return replacementTypes[index];
-      },
-      LookUpConformanceInSignature(*projectionGenericSig));
-
-  return SGF.emitApplyOfLibraryIntrinsic(SILLocation(E),
-                        projectFn, genericArgsMap, {root, keyPath}, C);
+  auto lv = SGF.emitLValue(E, SGFAccessKind::OwnedObjectRead);
+  return SGF.emitLoadOfLValue(E, std::move(lv), C);
 }
 
 RValue RValueEmitter::
@@ -4623,6 +4314,19 @@
     // also prevents us from getting into that case.
     if (dest->getType()->isEqual(srcLoad->getSubExpr()->getType())) {
       assert(!dest->getType()->is<TupleType>());
+
+      dest = dest->getSemanticsProvidingExpr();
+      if (isa<DiscardAssignmentExpr>(dest)) {
+        // The logical thing to do here would be emitIgnoredExpr, but that
+        // changed some test results in a way I wanted to avoid, so instead
+        // we're doing this.
+        FormalEvaluationScope writeback(SGF);
+        auto srcLV = SGF.emitLValue(srcLoad->getSubExpr(),
+                                    SGFAccessKind::IgnoredRead);
+        (void) SGF.emitLoadOfLValue(loc, std::move(srcLV), SGFContext());
+        return;
+      }
+
       FormalEvaluationScope writeback(SGF);
       auto destLV = SGF.emitLValue(dest, SGFAccessKind::Write);
       auto srcLV = SGF.emitLValue(srcLoad->getSubExpr(),
diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp
index ac949ba..28f7590 100644
--- a/lib/SILGen/SILGenFunction.cpp
+++ b/lib/SILGen/SILGenFunction.cpp
@@ -140,7 +140,7 @@
   // If the method is dynamic, access it through runtime-hookable virtual
   // dispatch (viz. objc_msgSend for now).
   if (methodConstant.hasDecl()
-      && methodConstant.getDecl()->isDynamic()) {
+      && methodConstant.getDecl()->isObjCDynamic()) {
     methodValue = emitDynamicMethodRef(
                       loc, methodConstant,
                       SGM.Types.getConstantInfo(methodConstant).SILFnType)
@@ -495,7 +495,8 @@
                   ctx);
     auto NSStringFromClassFn = builder.getOrCreateFunction(
         mainClass, "NSStringFromClass", SILLinkage::PublicExternal,
-        NSStringFromClassType, IsBare, IsTransparent, IsNotSerialized);
+        NSStringFromClassType, IsBare, IsTransparent, IsNotSerialized,
+        IsNotDynamic);
     auto NSStringFromClass = B.createFunctionRef(mainClass, NSStringFromClassFn);
     SILValue metaTy = B.createMetatype(mainClass,
                              SILType::getPrimitiveObjectType(mainClassMetaty));
@@ -584,7 +585,8 @@
     SILGenFunctionBuilder builder(SGM);
     auto NSApplicationMainFn = builder.getOrCreateFunction(
         mainClass, "NSApplicationMain", SILLinkage::PublicExternal,
-        NSApplicationMainType, IsBare, IsTransparent, IsNotSerialized);
+        NSApplicationMainType, IsBare, IsTransparent, IsNotSerialized,
+        IsNotDynamic);
 
     auto NSApplicationMain = B.createFunctionRef(mainClass, NSApplicationMainFn);
     SILValue args[] = { argc, argv };
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index a178a95..8e44269 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -172,6 +172,13 @@
   return uint8_t(kind) >= uint8_t(SGFAccessKind::OwnedAddressRead);
 }
 
+/// Given a read access kind, does it require an address result?
+static inline bool isReadAccessResultAddress(SGFAccessKind kind) {
+  assert(isReadAccess(kind));
+  return kind == SGFAccessKind::BorrowedAddressRead ||
+         kind == SGFAccessKind::OwnedAddressRead;
+}
+
 /// Return an address-preferring version of the given access kind.
 static inline SGFAccessKind getAddressAccessKind(SGFAccessKind kind) {
   switch (kind) {
@@ -1152,9 +1159,11 @@
   SILValue emitGlobalFunctionRef(SILLocation loc, SILDeclRef constant) {
     return emitGlobalFunctionRef(loc, constant, getConstantInfo(constant));
   }
-  SILValue emitGlobalFunctionRef(SILLocation loc, SILDeclRef constant,
-                                 SILConstantInfo constantInfo);
-  
+  SILValue
+  emitGlobalFunctionRef(SILLocation loc, SILDeclRef constant,
+                        SILConstantInfo constantInfo,
+                        bool callPreviousDynamicReplaceableImpl = false);
+
   /// Returns a reference to a function value that dynamically dispatches
   /// the function in a runtime-modifiable way.
   ManagedValue emitDynamicMethodRef(SILLocation loc, SILDeclRef constant,
@@ -1222,16 +1231,18 @@
 
   RValue emitGetAccessor(SILLocation loc, SILDeclRef getter,
                          SubstitutionMap substitutions,
-                         ArgumentSource &&optionalSelfValue,
-                         bool isSuper, bool isDirectAccessorUse,
-                         PreparedArguments &&optionalSubscripts, SGFContext C);
+                         ArgumentSource &&optionalSelfValue, bool isSuper,
+                         bool isDirectAccessorUse,
+                         PreparedArguments &&optionalSubscripts, SGFContext C,
+                         bool isOnSelfParameter);
 
   void emitSetAccessor(SILLocation loc, SILDeclRef setter,
                        SubstitutionMap substitutions,
                        ArgumentSource &&optionalSelfValue,
                        bool isSuper, bool isDirectAccessorUse,
                        PreparedArguments &&optionalSubscripts,
-                       ArgumentSource &&value);
+                       ArgumentSource &&value,
+                       bool isOnSelfParameter);
 
   bool maybeEmitMaterializeForSetThunk(ProtocolConformanceRef conformance,
                                        SILLinkage linkage,
@@ -1241,21 +1252,19 @@
                                        AccessorDecl *witness,
                                        SubstitutionMap witnessSubs);
 
-  std::pair<ManagedValue,ManagedValue>
-  emitAddressorAccessor(SILLocation loc, SILDeclRef addressor,
-                        SubstitutionMap substitutions,
-                        ArgumentSource &&optionalSelfValue,
-                        bool isSuper, bool isDirectAccessorUse,
-                        PreparedArguments &&optionalSubscripts,
-                        SILType addressType);
+  ManagedValue emitAddressorAccessor(
+      SILLocation loc, SILDeclRef addressor, SubstitutionMap substitutions,
+      ArgumentSource &&optionalSelfValue, bool isSuper,
+      bool isDirectAccessorUse, PreparedArguments &&optionalSubscripts,
+      SILType addressType, bool isOnSelfParameter);
 
-  CleanupHandle
-  emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
-                        SubstitutionMap substitutions,
-                        ArgumentSource &&optionalSelfValue,
-                        bool isSuper, bool isDirectAccessorUse,
-                        PreparedArguments &&optionalSubscripts,
-                        SmallVectorImpl<ManagedValue> &yields);
+  CleanupHandle emitCoroutineAccessor(SILLocation loc, SILDeclRef accessor,
+                                      SubstitutionMap substitutions,
+                                      ArgumentSource &&optionalSelfValue,
+                                      bool isSuper, bool isDirectAccessorUse,
+                                      PreparedArguments &&optionalSubscripts,
+                                      SmallVectorImpl<ManagedValue> &yields,
+                                      bool isOnSelfParameter);
 
   RValue emitApplyConversionFunction(SILLocation loc,
                                      Expr *funcExpr,
@@ -1462,16 +1471,21 @@
                                      ArrayRef<ManagedValue> args,
                                      SGFContext ctx);
 
+  CleanupHandle emitBeginApply(SILLocation loc, ManagedValue fn,
+                               SubstitutionMap subs, ArrayRef<ManagedValue> args,
+                               CanSILFunctionType substFnType,
+                               ApplyOptions options,
+                               SmallVectorImpl<ManagedValue> &yields);
+
   SILValue emitApplyWithRethrow(SILLocation loc, SILValue fn,
                                 SILType substFnType,
                                 SubstitutionMap subs,
                                 ArrayRef<SILValue> args);
 
-  SILValue emitBeginApplyWithRethrow(SILLocation loc, SILValue fn,
-                                     SILType substFnType,
-                                     SubstitutionMap subs,
-                                     ArrayRef<SILValue> args,
-                                     SmallVectorImpl<SILValue> &yields);
+  std::pair<SILValue, CleanupHandle>
+  emitBeginApplyWithRethrow(SILLocation loc, SILValue fn, SILType substFnType,
+                            SubstitutionMap subs, ArrayRef<SILValue> args,
+                            SmallVectorImpl<SILValue> &yields);
   void emitEndApplyWithRethrow(SILLocation loc, SILValue token);
 
   /// Emit a literal that applies the various initializers.
diff --git a/lib/SILGen/SILGenGlobalVariable.cpp b/lib/SILGen/SILGenGlobalVariable.cpp
index c875c5e..88f9572 100644
--- a/lib/SILGen/SILGenGlobalVariable.cpp
+++ b/lib/SILGen/SILGenGlobalVariable.cpp
@@ -67,7 +67,7 @@
     SILFunction *accessorFn = SGM.getFunction(
                             SILDeclRef(var, SILDeclRef::Kind::GlobalAccessor),
                                                   NotForDefinition);
-    SILValue accessor = B.createFunctionRef(loc, accessorFn);
+    SILValue accessor = B.createFunctionRefFor(loc, accessorFn);
     auto accessorTy = accessor->getType().castTo<SILFunctionType>();
     (void)accessorTy;
     assert(!accessorTy->isPolymorphic()
@@ -247,7 +247,7 @@
                                                rawPointerSILTy);
 
   // Emit a reference to the function to execute.
-  SILValue onceFuncRef = SGF.B.createFunctionRef(global, onceFunc);
+  SILValue onceFuncRef = SGF.B.createFunctionRefFor(global, onceFunc);
 
   // Call Builtin.once.
   SILValue onceArgs[] = {onceTokenAddr, onceFuncRef};
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index 9a3d718..ea54dcf 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -120,6 +120,7 @@
 
   // If the decls match, then this could conflict.
   if (lhsStorage->Storage != rhsStorage->Storage ||
+      !lhsStorage->Storage ||
       lhsStorage->IsSuper != rhsStorage->IsSuper)
     return;
 
@@ -198,12 +199,10 @@
   return expr->getType()->getRValueType()->getCanonicalType();
 }
 
-static LValueTypeData getLogicalStorageTypeData(SILGenModule &SGM,
-                                                SGFAccessKind accessKind,
-                                                CanType substFormalType) {
-  assert(!isa<ReferenceStorageType>(substFormalType));
-  AbstractionPattern origFormalType(
-      substFormalType.getReferenceStorageReferent());
+static LValueTypeData getAbstractedTypeData(SILGenModule &SGM,
+                                            SGFAccessKind accessKind,
+                                            AbstractionPattern origFormalType,
+                                            CanType substFormalType) {
   return {
     accessKind,
     origFormalType,
@@ -212,6 +211,15 @@
   };
 }
 
+static LValueTypeData getLogicalStorageTypeData(SILGenModule &SGM,
+                                                SGFAccessKind accessKind,
+                                                CanType substFormalType) {
+  assert(!isa<ReferenceStorageType>(substFormalType));
+  AbstractionPattern origFormalType(
+      substFormalType.getReferenceStorageReferent());
+  return getAbstractedTypeData(SGM, accessKind, origFormalType, substFormalType);
+}
+
 static LValueTypeData getPhysicalStorageTypeData(SILGenModule &SGM,
                                                  SGFAccessKind accessKind,
                                                  AbstractStorageDecl *storage,
@@ -219,12 +227,7 @@
   assert(!isa<ReferenceStorageType>(substFormalType));
   auto origFormalType = SGM.Types.getAbstractionPattern(storage)
                                  .getReferenceStorageReferentType();
-  return {
-    accessKind,
-    origFormalType,
-    substFormalType,
-    SGM.Types.getLoweredType(origFormalType, substFormalType).getObjectType()
-  };
+  return getAbstractedTypeData(SGM, accessKind, origFormalType, substFormalType);
 }
 
 static bool shouldUseUnsafeEnforcement(VarDecl *var) {
@@ -322,17 +325,17 @@
   assert(isReadAccess(accessKind));
 
   const TypeLowering &RValueTL = SGF.getTypeLowering(getTypeOfRValue());
-  TemporaryInitializationPtr tempInit;
-  RValue rvalue;
 
   // If the access doesn't require us to make an owned address, don't
   // force a materialization.
-  if (accessKind != SGFAccessKind::OwnedAddressRead &&
-      accessKind != SGFAccessKind::BorrowedAddressRead) {
+  if (!isReadAccessResultAddress(accessKind)) {
     auto rvalue = std::move(*this).get(SGF, loc, base, SGFContext());
     return std::move(rvalue).getAsSingleValue(SGF, loc);
   }
 
+  TemporaryInitializationPtr tempInit;
+  RValue rvalue;
+
   // If the RValue type has an openedExistential, then the RValue must be
   // materialized before allocating a temporary for the RValue type. In that
   // case, the RValue cannot be emitted directly into the temporary.
@@ -387,7 +390,7 @@
   // Push a writeback for the temporary.
   pushWriteback(SGF, loc, std::move(clonedComponent), base,
                 MaterializedLValue(temp));
-  return temp.unmanagedBorrow();
+  return ManagedValue::forLValue(temp.getValue());
 }
 
 void LogicalPathComponent::writeback(SILGenFunction &SGF, SILLocation loc,
@@ -900,9 +903,11 @@
       auto refType = base.getType().getObjectType();
       auto &TL = SGF.getTypeLowering(refType);
 
-      // Load the original value.
-      auto result = SGF.emitLoad(loc, base.getValue(), TL,
-                                 SGFContext(), IsNotTake);
+      // Load the original value if necessary.
+      auto result = base.getType().isAddress()
+                      ? SGF.emitLoad(loc, base.getValue(), TL,
+                                     SGFContext(), IsNotTake)
+                      : base;
 
       assert(refType.isAnyExistentialType() &&
              "base for open existential component must be an existential");
@@ -1218,23 +1223,23 @@
     SILDeclRef Accessor;
     bool IsSuper;
     bool IsDirectAccessorUse;
+    bool IsOnSelfParameter;
     SubstitutionMap Substitutions;
 
   public:
     AccessorBasedComponent(PathComponent::KindTy kind,
-                           AbstractStorageDecl *decl,
-                           SILDeclRef accessor,
+                           AbstractStorageDecl *decl, SILDeclRef accessor,
                            bool isSuper, bool isDirectAccessorUse,
                            SubstitutionMap substitutions,
-                           CanType baseFormalType,
-                           LValueTypeData typeData,
+                           CanType baseFormalType, LValueTypeData typeData,
                            Expr *indexExprForDiagnostics,
-                           PreparedArguments &&indices)
-      : super(kind, decl, baseFormalType, typeData,
-              indexExprForDiagnostics, std::move(indices)),
-        Accessor(accessor), IsSuper(isSuper),
-        IsDirectAccessorUse(isDirectAccessorUse),
-        Substitutions(substitutions) {}
+                           PreparedArguments &&indices,
+                           bool isOnSelfParameter = false)
+        : super(kind, decl, baseFormalType, typeData, indexExprForDiagnostics,
+                std::move(indices)),
+          Accessor(accessor), IsSuper(isSuper),
+          IsDirectAccessorUse(isDirectAccessorUse),
+          IsOnSelfParameter(isOnSelfParameter), Substitutions(substitutions) {}
 
     AccessorBasedComponent(const AccessorBasedComponent &copied,
                            SILGenFunction &SGF,
@@ -1243,6 +1248,7 @@
         Accessor(copied.Accessor),
         IsSuper(copied.IsSuper),
         IsDirectAccessorUse(copied.IsDirectAccessorUse),
+        IsOnSelfParameter(copied.IsOnSelfParameter),
         Substitutions(copied.Substitutions) {}
 
     AccessorDecl *getAccessorDecl() const {
@@ -1261,11 +1267,12 @@
                            CanType baseFormalType,
                            LValueTypeData typeData,
                            Expr *subscriptIndexExpr,
-                           PreparedArguments &&indices)
+                           PreparedArguments &&indices,
+                           bool isOnSelfParameter)
       : AccessorBasedComponent(GetterSetterKind, decl, accessor, isSuper,
                                isDirectAccessorUse, substitutions,
                                baseFormalType, typeData, subscriptIndexExpr,
-                               std::move(indices))
+                               std::move(indices), isOnSelfParameter)
     {
       assert(getAccessorDecl()->isGetterOrSetter());
     }
@@ -1289,13 +1296,15 @@
       bool isDirectAccessorUse = this->IsDirectAccessorUse;
       auto indices = std::move(this->Indices);
       auto baseFormalType = this->BaseFormalType;
+      bool isOnSelfParameter = this->IsOnSelfParameter;
 
       // Drop this component from the l-value.
       dest.dropLastComponent(*this);
 
       return emitAssignWithSetter(SGF, loc, std::move(dest), baseFormalType,
-                                  isSuper, setter, isDirectAccessorUse,
-                                  subs, std::move(indices), std::move(value));
+                                  isSuper, setter, isDirectAccessorUse, subs,
+                                  std::move(indices), std::move(value),
+                                  isOnSelfParameter);
     }
 
     static void emitAssignWithSetter(SILGenFunction &SGF, SILLocation loc,
@@ -1304,7 +1313,8 @@
                                      bool isDirectAccessorUse,
                                      SubstitutionMap subs,
                                      PreparedArguments &&indices,
-                                     ArgumentSource &&value) {
+                                     ArgumentSource &&value,
+                                     bool isSelfParameter) {
       ArgumentSource self = [&] {
         if (!baseLV.isValid()) {
           return ArgumentSource();
@@ -1317,9 +1327,9 @@
         }
       }();
 
-      return SGF.emitSetAccessor(loc, setter, subs, std::move(self),
-                                 isSuper, isDirectAccessorUse,
-                                 std::move(indices), std::move(value));
+      return SGF.emitSetAccessor(loc, setter, subs, std::move(self), isSuper,
+                                 isDirectAccessorUse, std::move(indices),
+                                 std::move(value), isSelfParameter);
     }
 
     void set(SILGenFunction &SGF, SILLocation loc,
@@ -1334,9 +1344,8 @@
 
       return SGF.emitSetAccessor(loc, setter, Substitutions,
                                  std::move(args.base), IsSuper,
-                                 IsDirectAccessorUse,
-                                 std::move(args.Indices),
-                                 std::move(value));
+                                 IsDirectAccessorUse, std::move(args.Indices),
+                                 std::move(value), IsOnSelfParameter);
     }
 
     ManagedValue project(SILGenFunction &SGF, SILLocation loc,
@@ -1355,11 +1364,10 @@
 
       auto args =
         std::move(*this).prepareAccessorArgs(SGF, loc, base, getter);
-      
-      return SGF.emitGetAccessor(loc, getter, Substitutions,
-                                 std::move(args.base), IsSuper,
-                                 IsDirectAccessorUse,
-                                 std::move(args.Indices), c);
+
+      return SGF.emitGetAccessor(
+          loc, getter, Substitutions, std::move(args.base), IsSuper,
+          IsDirectAccessorUse, std::move(args.Indices), c, IsOnSelfParameter);
     }
     
     std::unique_ptr<LogicalPathComponent>
@@ -1390,6 +1398,7 @@
     AccessStrategy WriteStrategy;
     LValueOptions Options;
     bool IsSuper;
+    bool IsOnSelfParameter;
 
   public:
     MaterializeToTemporaryComponent(AbstractStorageDecl *storage,
@@ -1400,12 +1409,14 @@
                                     CanType baseFormalType,
                                     LValueTypeData typeData,
                                     Expr *indexExprForDiagnostics,
-                                    PreparedArguments &&indices)
+                                    PreparedArguments &&indices,
+                                    bool isOnSelfParameter)
       : AccessComponent(MaterializeToTemporaryKind, storage, baseFormalType,
                         typeData, indexExprForDiagnostics, std::move(indices)),
         Substitutions(subs),
         ReadStrategy(readStrategy), WriteStrategy(writeStrategy),
-        Options(options), IsSuper(isSuper) {}
+        Options(options), IsSuper(isSuper), IsOnSelfParameter(isOnSelfParameter)
+        {}
 
 
     std::unique_ptr<LogicalPathComponent>
@@ -1418,7 +1429,8 @@
                                             ReadStrategy, WriteStrategy,
                                             BaseFormalType, getTypeData(),
                                             IndexExprForDiagnostics,
-                                            std::move(clonedIndices));
+                                            std::move(clonedIndices),
+                                            IsOnSelfParameter);
       return std::unique_ptr<LogicalPathComponent>(clone);
     }
 
@@ -1494,11 +1506,12 @@
                         CanType baseFormalType, LValueTypeData typeData,
                         SILType substFieldType,
                         Expr *indexExprForDiagnostics,
-                        PreparedArguments &&indices)
+                        PreparedArguments &&indices, bool isOnSelfParameter)
       : AccessorBasedComponent(AddressorKind, decl, accessor, isSuper,
                                isDirectAccessorUse, substitutions,
                                baseFormalType, typeData,
-                               indexExprForDiagnostics, std::move(indices)),
+                               indexExprForDiagnostics, std::move(indices),
+                               isOnSelfParameter),
         SubstFieldType(substFieldType)
     {
       assert(getAccessorDecl()->isAnyAddressor());
@@ -1509,36 +1522,19 @@
       assert(SGF.isInFormalEvaluationScope() &&
              "offsetting l-value for modification without writeback scope");
 
-      std::pair<ManagedValue, ManagedValue> result;
+      ManagedValue addr;
       {
         FormalEvaluationScope scope(SGF);
 
         auto args =
             std::move(*this).prepareAccessorArgs(SGF, loc, base, Accessor);
-        result = SGF.emitAddressorAccessor(
-            loc, Accessor, Substitutions, std::move(args.base),
-            IsSuper, IsDirectAccessorUse,
-            std::move(args.Indices), SubstFieldType);
-      }
-
-      switch (getAccessorDecl()->getAddressorKind()) {
-      case AddressorKind::NotAddressor:
-        llvm_unreachable("not an addressor!");
-
-      // For unsafe addressors, we have no owner pointer to manage.
-      case AddressorKind::Unsafe:
-        assert(!result.second);
-        break;
-
-      // For owning addressors, we can just let the owner get released
-      // at an appropriate point.
-      case AddressorKind::Owning:
-      case AddressorKind::NativeOwning:
-        break;
+        addr = SGF.emitAddressorAccessor(
+            loc, Accessor, Substitutions, std::move(args.base), IsSuper,
+            IsDirectAccessorUse, std::move(args.Indices), SubstFieldType,
+            IsOnSelfParameter);
       }
 
       // Enter an unsafe access scope for the access.
-      auto addr = result.first;
       addr = enterAccessScope(SGF, loc, addr, getTypeData(), getAccessKind(),
                               SILAccessEnforcement::Unsafe);
 
@@ -1592,24 +1588,42 @@
                              IndexExprForDiagnostics};
     }
   };
+}
+
+static void pushEndApplyWriteback(SILGenFunction &SGF, SILLocation loc,
+                                  CleanupHandle endApplyHandle,
+                                  LValueTypeData typeData,
+                                  ManagedValue base = ManagedValue(),
+                                  AbstractStorageDecl *storage = nullptr,
+                                  bool isSuper = false,
+                                  PreparedArguments &&indices
+                                    = PreparedArguments(),
+                                  Expr *indexExprForDiagnostics = nullptr) {
+  std::unique_ptr<LogicalPathComponent>
+    component(new EndApplyPseudoComponent(typeData, endApplyHandle,
+                                          storage, isSuper, std::move(indices),
+                                          indexExprForDiagnostics));
+  pushWriteback(SGF, loc, std::move(component), /*for diagnostics*/ base,
+                MaterializedLValue());
+}
+
+namespace {
 
   /// A physical component which involves calling coroutine accessors.
   class CoroutineAccessorComponent
       : public AccessorBasedComponent<PhysicalPathComponent> {
   public:
-    CoroutineAccessorComponent(AbstractStorageDecl *decl,
-                               SILDeclRef accessor,
+    CoroutineAccessorComponent(AbstractStorageDecl *decl, SILDeclRef accessor,
                                bool isSuper, bool isDirectAccessorUse,
                                SubstitutionMap substitutions,
-                               CanType baseFormalType,
-                               LValueTypeData typeData,
+                               CanType baseFormalType, LValueTypeData typeData,
                                Expr *indexExprForDiagnostics,
-                               PreparedArguments &&indices)
-      : AccessorBasedComponent(CoroutineAccessorKind,
-                               decl, accessor, isSuper, isDirectAccessorUse,
-                               substitutions, baseFormalType, typeData,
-                               indexExprForDiagnostics, std::move(indices)) {
-    }
+                               PreparedArguments &&indices,
+                               bool isOnSelfParameter)
+        : AccessorBasedComponent(
+              CoroutineAccessorKind, decl, accessor, isSuper,
+              isDirectAccessorUse, substitutions, baseFormalType, typeData,
+              indexExprForDiagnostics, std::move(indices), isOnSelfParameter) {}
 
     using AccessorBasedComponent::AccessorBasedComponent;
 
@@ -1624,19 +1638,15 @@
         std::move(*this).prepareAccessorArgs(SGF, loc, base, Accessor);
       auto peekedIndices = args.Indices.copyForDiagnostics();
       SmallVector<ManagedValue, 4> yields;
-      auto endApplyHandle =
-        SGF.emitCoroutineAccessor(
+      auto endApplyHandle = SGF.emitCoroutineAccessor(
           loc, Accessor, Substitutions, std::move(args.base), IsSuper,
-          IsDirectAccessorUse, std::move(args.Indices), yields);
+          IsDirectAccessorUse, std::move(args.Indices), yields,
+          IsOnSelfParameter);
 
       // Push a writeback that ends the access.
-      std::unique_ptr<LogicalPathComponent>
-        component(new EndApplyPseudoComponent(getTypeData(), endApplyHandle,
-                                              Storage, IsSuper,
-                                              std::move(peekedIndices),
-                                              IndexExprForDiagnostics));
-      pushWriteback(SGF, loc, std::move(component), /*for diagnostics*/ base,
-                    MaterializedLValue());
+      pushEndApplyWriteback(SGF, loc, endApplyHandle, getTypeData(),
+                            base, Storage, IsSuper, std::move(peekedIndices),
+                            IndexExprForDiagnostics);
 
       auto decl = cast<AccessorDecl>(Accessor.getFuncDecl());
 
@@ -1652,7 +1662,10 @@
       // Use the yield value directly if it's the right type.
       if (!getOrigFormalType().isTuple()) {
         assert(yields.size() == 1);
-        return yields[0];
+        auto value = yields[0];
+        if (value.getType().isAddress() ||
+            !isReadAccessResultAddress(getAccessKind()))
+          return value;
       }
 
       // Otherwise, we need to make a temporary.
@@ -1671,208 +1684,214 @@
       printBase(OS, indent, "CoroutineAccessorComponent");
     }
   };
-  
-  /// A physical component which involves applying a key path.
-  class KeyPathApplicationComponent final : public PhysicalPathComponent {
-    ArgumentSource KeyPath;
+}
+
+static ManagedValue
+makeBaseConsumableMaterializedRValue(SILGenFunction &SGF,
+                                     SILLocation loc, ManagedValue base) {
+  if (base.isLValue()) {
+    auto tmp = SGF.emitTemporaryAllocation(loc, base.getType());
+    SGF.B.createCopyAddr(loc, base.getValue(), tmp,
+                         IsNotTake, IsInitialization);
+    return SGF.emitManagedBufferWithCleanup(tmp);
+  }
+
+  bool isBorrowed = base.isPlusZeroRValueOrTrivial()
+    && !base.getType().isTrivial(SGF.SGM.M);
+  if (!base.getType().isAddress() || isBorrowed) {
+    auto tmp = SGF.emitTemporaryAllocation(loc, base.getType());
+    if (isBorrowed)
+      base.copyInto(SGF, tmp, loc);
+    else
+      base.forwardInto(SGF, loc, tmp);
+    return SGF.emitManagedBufferWithCleanup(tmp);
+  }
+
+  return base;
+}
+
+static ManagedValue
+emitUpcastToKeyPath(SILGenFunction &SGF, SILLocation loc,
+                    KeyPathTypeKind typeKind, ManagedValue keyPath) {
+  if (typeKind == KPTK_KeyPath) return keyPath;
+  assert(typeKind == KPTK_WritableKeyPath ||
+         typeKind == KPTK_ReferenceWritableKeyPath);
+
+  auto derivedKeyPathTy = keyPath.getType().castTo<BoundGenericType>();
+  auto baseKeyPathTy =
+    BoundGenericType::get(SGF.getASTContext().getKeyPathDecl(),
+                          Type(), derivedKeyPathTy->getGenericArgs())
+      ->getCanonicalType();
+  return SGF.B.createUpcast(loc, keyPath,
+                            SILType::getPrimitiveObjectType(baseKeyPathTy));
+}
+
+namespace {
+  class LogicalKeyPathApplicationComponent final
+      : public LogicalPathComponent {
+    KeyPathTypeKind TypeKind;
+    ManagedValue KeyPath;
+    Type BaseFormalType;
   public:
-    KeyPathApplicationComponent(LValueTypeData typeData,
-                                ArgumentSource &&KeyPath)
-      : PhysicalPathComponent(typeData, KeyPathApplicationKind),
-        KeyPath(std::move(KeyPath))
-    {}
-  
-    // An rvalue base object is passed indirectly +1 so needs to be
-    // materialized if the base we have is +0 or a loaded value.
-    void makeBaseConsumableMaterializedRValue(SILGenFunction &SGF,
-                                              SILLocation loc,
-                                              ManagedValue &base) {
-      if (base.isLValue()) {
-        auto tmp = SGF.emitTemporaryAllocation(loc, base.getType());
-        SGF.B.createCopyAddr(loc, base.getValue(), tmp,
-                             IsNotTake, IsInitialization);
-        base = SGF.emitManagedBufferWithCleanup(tmp);
-        return;
-      }
-
-      bool isBorrowed = base.isPlusZeroRValueOrTrivial()
-        && !base.getType().isTrivial(SGF.SGM.M);
-      if (!base.getType().isAddress() || isBorrowed) {
-        auto tmp = SGF.emitTemporaryAllocation(loc, base.getType());
-        if (isBorrowed)
-          base.copyInto(SGF, tmp, loc);
-        else
-          base.forwardInto(SGF, loc, tmp);
-        base = SGF.emitManagedBufferWithCleanup(tmp);
-      }
+    LogicalKeyPathApplicationComponent(LValueTypeData typeData,
+                                       KeyPathTypeKind typeKind,
+                                       ManagedValue keyPath,
+                                       Type baseFormalType)
+      : LogicalPathComponent(typeData, LogicalKeyPathApplicationKind),
+        TypeKind(typeKind), KeyPath(keyPath), BaseFormalType(baseFormalType) {
+      assert(isReadAccess(getAccessKind()) ||
+             typeKind == KPTK_WritableKeyPath ||
+             typeKind == KPTK_ReferenceWritableKeyPath);
     }
-  
-    ManagedValue mutableOffset(
-                   SILGenFunction &SGF, SILLocation loc, ManagedValue base) && {
-      auto &C = SGF.getASTContext();
-      auto keyPathTy = KeyPath.getSubstRValueType()->castTo<BoundGenericType>();
 
-      FuncDecl *projectionFunction;
-      if (keyPathTy->getDecl() == C.getWritableKeyPathDecl()) {
-        // Turn the base lvalue into a pointer to pass to the projection
-        // function.
-        // This is OK since the materialized base is exclusive-borrowed for the
-        // duration of the access.
-        auto baseRawPtr = SGF.B.createAddressToPointer(loc,
-                              base.getValue(),
-                              SILType::getRawPointerType(SGF.getASTContext()));
-        auto basePtrTy = BoundGenericType::get(C.getUnsafeMutablePointerDecl(),
-                                               nullptr,
-                                               keyPathTy->getGenericArgs()[0])
-          ->getCanonicalType();
-        auto basePtr = SGF.B.createStruct(loc,
-                                    SILType::getPrimitiveObjectType(basePtrTy),
-                                    SILValue(baseRawPtr));
-        base = ManagedValue::forUnmanaged(basePtr);
-        projectionFunction = C.getProjectKeyPathWritable(nullptr);
-      } else if (keyPathTy->getDecl() == C.getReferenceWritableKeyPathDecl()) {
-        projectionFunction = C.getProjectKeyPathReferenceWritable(nullptr);
-        makeBaseConsumableMaterializedRValue(SGF, loc, base);
+    RValue get(SILGenFunction &SGF, SILLocation loc,
+               ManagedValue base, SGFContext C) && override {
+      assert(isReadAccess(getAccessKind()));
+      FuncDecl *projectFn;
+
+      auto keyPathValue = KeyPath;
+
+      SmallVector<Type, 2> typeArgs;
+      typeArgs.push_back(BaseFormalType);
+      if (TypeKind == KPTK_AnyKeyPath) {
+        projectFn = SGF.getASTContext().getGetAtAnyKeyPath(nullptr);
+      } else if (TypeKind == KPTK_PartialKeyPath) {
+        projectFn = SGF.getASTContext().getGetAtPartialKeyPath(nullptr);
+      } else if (TypeKind == KPTK_KeyPath ||
+                 TypeKind == KPTK_WritableKeyPath ||
+                 TypeKind == KPTK_ReferenceWritableKeyPath) {
+        projectFn = SGF.getASTContext().getGetAtKeyPath(nullptr);
+
+        auto keyPathTy = keyPathValue.getType().castTo<BoundGenericType>();
+        assert(keyPathTy->getGenericArgs().size() == 2);
+        assert(keyPathTy->getGenericArgs()[0]->getCanonicalType() ==
+               BaseFormalType->getCanonicalType());
+        typeArgs.push_back(keyPathTy->getGenericArgs()[1]);
+
+        keyPathValue = emitUpcastToKeyPath(SGF, loc, TypeKind, keyPathValue);
       } else {
-        llvm_unreachable("not a writable key path type?!");
+        llvm_unreachable("bad key path kind for this component");
       }
-      
-      auto projectionGenericSig = projectionFunction->getGenericSignature();
-      auto subMap = SubstitutionMap::get(
-          projectionGenericSig,
-          [&](SubstitutableType *type) -> Type {
-            auto genericParam = cast<GenericTypeParamType>(type);
-            auto index =
-                projectionGenericSig->getGenericParamOrdinal(genericParam);
-            return keyPathTy->getGenericArgs()[index];
-          },
-          LookUpConformanceInSignature(*projectionGenericSig));
 
-      // The projection function behaves like an owning addressor, returning
-      // a pointer to the projected value and an owner reference that keeps
-      // it alive.
-      auto keyPathValue = std::move(KeyPath).getAsSingleValue(SGF);
-      auto resultTuple = SGF.emitApplyOfLibraryIntrinsic(loc,
-                                                         projectionFunction,
-                                                         subMap,
-                                                         {base, keyPathValue},
-                                                         SGFContext());
-      SmallVector<ManagedValue, 2> members;
-      std::move(resultTuple).getAll(members);
-      auto projectedPtr = members[0];
-      auto projectedOwner = members[1];
+      auto subs = SubstitutionMap::get(projectFn->getGenericSignature(),
+                                       ArrayRef<Type>(typeArgs),
+                                       ArrayRef<ProtocolConformanceRef>());
 
-      // Pass along the projected pointer.
-      auto rawValueField = *C.getUnsafeMutablePointerDecl()
-        ->getStoredProperties().begin();
-      auto projectedRawPtr = SGF.B.createStructExtract(loc,
-                                               projectedPtr.getUnmanagedValue(),
-                                               rawValueField,
-                                               SILType::getRawPointerType(C));
-      SILValue projectedAddr = SGF.B.createPointerToAddress(loc,
-                                            projectedRawPtr,
-                                            getTypeOfRValue().getAddressType(),
-                                            /*strict*/ true);
-      // Mark the projected address's dependence on the owner.
-      projectedAddr = SGF.B.createMarkDependence(loc, projectedAddr,
-                                                 projectedOwner.getValue());
-      
-      // Push a cleanup to destroy the owner object. We don't want to leave
-      // it to release whenever because the key path implementation hangs
-      // the writeback operations specific to the traversal onto the destruction
-      // of the owner.
-      struct DestroyOwnerPseudoComponent : WritebackPseudoComponent {
-        ManagedValue owner;
-        
-        DestroyOwnerPseudoComponent(const LValueTypeData &typeData,
-                                    ManagedValue owner)
-          : WritebackPseudoComponent(typeData), owner(owner)
-        {}
-        
-        void writeback(SILGenFunction &SGF, SILLocation loc,
-                       ManagedValue base,
-                       MaterializedLValue materialized,
-                       bool isFinal) override {
-          // Just let the cleanup get emitted normally if the writeback is for
-          // an unwind.
-          if (!isFinal) return;
+      base = makeBaseConsumableMaterializedRValue(SGF, loc, base);
 
-          SGF.Cleanups.popAndEmitCleanup(owner.getCleanup(),
-                                         CleanupLocation::get(loc),
-                                         NotForUnwind);
-        }
-        
-        void dump(raw_ostream &OS, unsigned indent) const override {
-          OS << "DestroyOwnerPseudoComponent";
-        }
-      };
-      
-      std::unique_ptr<LogicalPathComponent> component(
-        new DestroyOwnerPseudoComponent(getTypeData(), projectedOwner));
-      
-      pushWriteback(SGF, loc, std::move(component), base, MaterializedLValue());
-
-      return ManagedValue::forLValue(projectedAddr);
+      return SGF.emitApplyOfLibraryIntrinsic(loc, projectFn, subs,
+                                             {base, keyPathValue}, C);
     }
 
-    ManagedValue readOnlyOffset(
-                   SILGenFunction &SGF, SILLocation loc, ManagedValue base) && {
-      auto &C = SGF.getASTContext();
-      
-      makeBaseConsumableMaterializedRValue(SGF, loc, base);
-      auto keyPathValue = std::move(KeyPath).getAsSingleValue(SGF);
-      // Upcast the key path operand to the base KeyPath type, as expected by
-      // the read-only projection function.
-      BoundGenericType *keyPathTy
-        = keyPathValue.getType().castTo<BoundGenericType>();
-      if (keyPathTy->getDecl() != C.getKeyPathDecl()) {
-        keyPathTy = BoundGenericType::get(C.getKeyPathDecl(), Type(),
-                                          keyPathTy->getGenericArgs());
-        keyPathValue = SGF.B.createUpcast(loc, keyPathValue,
-                SILType::getPrimitiveObjectType(keyPathTy->getCanonicalType()));
+    void set(SILGenFunction &SGF, SILLocation loc,
+             ArgumentSource &&value, ManagedValue base) && override {
+      assert(!isReadAccess(getAccessKind()));
+
+      auto keyPathValue = KeyPath;
+      FuncDecl *setFn;
+      if (TypeKind == KPTK_WritableKeyPath) {
+        setFn = SGF.getASTContext().getSetAtWritableKeyPath(nullptr);
+        assert(base.isLValue());
+      } else if (TypeKind == KPTK_ReferenceWritableKeyPath) {
+        setFn = SGF.getASTContext().getSetAtReferenceWritableKeyPath(nullptr);
+        base = makeBaseConsumableMaterializedRValue(SGF, loc, base);
+      } else {
+        llvm_unreachable("bad writable type kind");
       }
-      
-      auto projectFn = C.getProjectKeyPathReadOnly(nullptr);
 
-      auto projectionGenericSig = projectFn->getGenericSignature();
-      auto subMap = SubstitutionMap::get(
-          projectionGenericSig,
-          [&](SubstitutableType *type) -> Type {
-            auto genericParam = cast<GenericTypeParamType>(type);
-            auto index =
-                projectionGenericSig->getGenericParamOrdinal(genericParam);
-            return keyPathTy->getGenericArgs()[index];
-          },
-          LookUpConformanceInSignature(*projectionGenericSig));
+      auto keyPathTy = keyPathValue.getType().castTo<BoundGenericType>();
+      auto subs = SubstitutionMap::get(setFn->getGenericSignature(),
+                                       keyPathTy->getGenericArgs(),
+                                       ArrayRef<ProtocolConformanceRef>());
 
-      // Allocate a temporary to own the projected value.
-      auto &resultTL = SGF.getTypeLowering(keyPathTy->getGenericArgs()[1]);
-      auto resultInit = SGF.emitTemporary(loc, resultTL);
+      auto setValue =
+        std::move(value).getAsSingleValue(SGF, AbstractionPattern::getOpaque());
+      if (!setValue.getType().isAddress()) {
+        setValue = setValue.materialize(SGF, loc);
+      }
 
-      auto result = SGF.emitApplyOfLibraryIntrinsic(loc, projectFn,
-        subMap, {base, keyPathValue}, SGFContext(resultInit.get()));
-      if (!result.isInContext())
-        std::move(result).forwardInto(SGF, loc, resultInit.get());
-      
-      // Result should be a temporary we own. Return its address as an lvalue.
-      return ManagedValue::forLValue(resultInit->getAddress());
+      SGF.emitApplyOfLibraryIntrinsic(loc, setFn, subs,
+                                      {base, keyPathValue, setValue},
+                                      SGFContext());
     }
-  
+
+    Optional<AccessedStorage> getAccessedStorage() const override {
+      return None;
+    }
+
+    std::unique_ptr<LogicalPathComponent>
+    clone(SILGenFunction &SGF, SILLocation l) const override {
+      llvm_unreachable("can't be cloned");
+    }
+
+    void dump(raw_ostream &OS, unsigned indent) const override {
+      OS.indent(indent) << "LogicalKeyPathApplicationComponent\n";
+    }
+  };
+
+  /// A physical component which involves applying a key path.
+  class PhysicalKeyPathApplicationComponent final
+      : public PhysicalPathComponent {
+    KeyPathTypeKind TypeKind;
+    ManagedValue KeyPath;
+  public:
+    PhysicalKeyPathApplicationComponent(LValueTypeData typeData,
+                                        KeyPathTypeKind typeKind,
+                                        ManagedValue keyPath)
+      : PhysicalPathComponent(typeData, PhysicalKeyPathApplicationKind),
+        TypeKind(typeKind), KeyPath(keyPath) {
+      assert(typeKind == KPTK_KeyPath ||
+             typeKind == KPTK_WritableKeyPath ||
+             typeKind == KPTK_ReferenceWritableKeyPath);
+      assert(typeKind != KPTK_KeyPath || isReadAccess(getAccessKind()));
+    }
+
     ManagedValue project(SILGenFunction &SGF, SILLocation loc,
                          ManagedValue base) && override {
       assert(SGF.isInFormalEvaluationScope() &&
              "offsetting l-value for modification without writeback scope");
-      if (isReadAccess(getAccessKind())) {
-        // For a read-only access, project the key path as if immutable,
-        // so that we don't trigger captured writebacks or observers or other
-        // operations that might be enqueued by a mutable projection.
-        return std::move(*this).readOnlyOffset(SGF, loc, base);
+
+      bool isRead = isReadAccess(getAccessKind());
+
+      // Set up the base and key path values correctly.
+      auto keyPathValue = KeyPath;
+      if (isRead) {
+        keyPathValue = emitUpcastToKeyPath(SGF, loc, TypeKind, keyPathValue);
+        base = makeBaseConsumableMaterializedRValue(SGF, loc, base);
+      } else if (TypeKind == KPTK_WritableKeyPath) {
+        // nothing to do
+      } else if (TypeKind == KPTK_ReferenceWritableKeyPath) {
+        base = makeBaseConsumableMaterializedRValue(SGF, loc, base);
       } else {
-        return std::move(*this).mutableOffset(SGF, loc, base);
+        llvm_unreachable("bad combination");
       }
+
+      SILFunction *projectFn =
+        SGF.SGM.getKeyPathProjectionCoroutine(isRead, TypeKind);
+      auto projectFnRef = SGF.B.createManagedFunctionRef(loc, projectFn);
+      auto projectFnType = projectFn->getLoweredFunctionType();
+
+      auto keyPathTy = keyPathValue.getType().castTo<BoundGenericType>();
+      auto subs = SubstitutionMap::get(projectFnType->getGenericSignature(),
+                                       keyPathTy->getGenericArgs(), {});
+
+      auto substFnType = projectFnType->substGenericArgs(SGF.SGM.M, subs);
+
+      // Perform the begin_apply.
+      SmallVector<ManagedValue, 1> yields;
+      auto cleanup =
+        SGF.emitBeginApply(loc, projectFnRef, subs, { base, keyPathValue },
+                           substFnType, ApplyOptions(), yields);
+
+      // Push an operation to do the end_apply.
+      pushEndApplyWriteback(SGF, loc, cleanup, getTypeData());
+
+      assert(yields.size() == 1);
+      return yields[0];
     }
+
     void dump(raw_ostream &OS, unsigned indent) const override {
-      OS.indent(indent) << "KeyPathApplicationComponent\n";
+      OS.indent(indent) << "PhysicalKeyPathApplicationComponent\n";
     }
   };
 } // end anonymous namespace
@@ -1997,11 +2016,17 @@
     RValue get(SILGenFunction &SGF, SILLocation loc,
                ManagedValue base, SGFContext c) && override {
       assert(base && "ownership component must not be root of lvalue path");
+
       auto &TL = SGF.getTypeLowering(getTypeOfRValue());
 
-      // Load the original value.
-      ManagedValue result = SGF.emitLoad(loc, base.getValue(), TL,
-                                         SGFContext(), IsNotTake);
+      ManagedValue result;
+      if (base.getType().isObject()) {
+        result = SGF.emitConversionToSemanticRValue(loc, base, TL);
+      } else {
+        result = SGF.emitLoad(loc, base.getValue(), TL, SGFContext(),
+                              IsNotTake);
+      }
+
       return RValue(SGF, loc, getSubstFormalType(), result);
     }
 
@@ -2428,34 +2453,35 @@
         SGF.SGM.Types.getLoweredType(Storage->getType()).getAddressType();
       LV.add<AddressorComponent>(Storage, addressor,
                                  /*isSuper=*/false, isDirect, getSubs(),
-                                 CanType(), typeData, storageType,
-                                 nullptr, PreparedArguments());
+                                 CanType(), typeData, storageType, nullptr,
+                                 PreparedArguments(),
+                                 /* isOnSelfParameter */ false);
     }
 
     void emitUsingCoroutineAccessor(SILDeclRef accessor, bool isDirect,
                                     LValueTypeData typeData) {
-      LV.add<CoroutineAccessorComponent>(Storage, accessor,
-                                         /*isSuper*/ false, isDirect, getSubs(),
-                                         CanType(), typeData,
-                                         nullptr, PreparedArguments());
+      LV.add<CoroutineAccessorComponent>(
+          Storage, accessor,
+          /*isSuper*/ false, isDirect, getSubs(), CanType(), typeData, nullptr,
+          PreparedArguments(), /*isOnSelfParameter*/ false);
     }
 
     void emitUsingGetterSetter(SILDeclRef accessor, bool isDirect,
                                LValueTypeData typeData) {
-      LV.add<GetterSetterComponent>(Storage, accessor,
-                                    /*isSuper=*/false, isDirect, getSubs(),
-                                    CanType(), typeData,
-                                    nullptr, PreparedArguments());
+      LV.add<GetterSetterComponent>(
+          Storage, accessor,
+          /*isSuper=*/false, isDirect, getSubs(), CanType(), typeData, nullptr,
+          PreparedArguments(), /* isOnSelfParameter */ false);
     }
 
     void emitUsingMaterialization(AccessStrategy readStrategy,
                                   AccessStrategy writeStrategy,
                                   LValueTypeData typeData) {
-      LV.add<MaterializeToTemporaryComponent>(Storage, /*super*/false,
-                                              getSubs(), Options,
-                                              readStrategy, writeStrategy,
-                                              /*base type*/CanType(), typeData,
-                                              nullptr, PreparedArguments());
+      LV.add<MaterializeToTemporaryComponent>(
+          Storage, /*super*/ false, getSubs(), Options, readStrategy,
+          writeStrategy,
+          /*base type*/ CanType(), typeData, nullptr, PreparedArguments(),
+          /* isOnSelfParameter */ false);
     }
 
     void emitUsingStorage(LValueTypeData typeData) {
@@ -2791,16 +2817,57 @@
   return baseExpr->getType()->getWithoutSpecifierType()->getCanonicalType();
 }
 
+bool isCallToReplacedInDynamicReplacement(SILGenFunction &SGF,
+                                          AbstractFunctionDecl *afd,
+                                          bool &isObjCReplacementSelfCall);
+
+static bool isCallToSelfOfCurrentFunction(SILGenFunction &SGF, LookupExpr *e) {
+  return SGF.FunctionDC->getAsDecl() &&
+         isa<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl()) &&
+         e->getBase()->isSelfExprOf(
+             cast<AbstractFunctionDecl>(SGF.FunctionDC->getAsDecl()), false);
+}
+
+static bool isCurrentFunctionReadAccess(SILGenFunction &SGF) {
+  auto *contextAccessorDecl =
+      dyn_cast_or_null<AccessorDecl>(SGF.FunctionDC->getAsDecl());
+  return contextAccessorDecl &&
+         contextAccessorDecl->getAccessorKind() == AccessorKind::Read;
+}
+
 LValue SILGenLValue::visitMemberRefExpr(MemberRefExpr *e,
                                         SGFAccessKind accessKind,
                                         LValueOptions options) {
   // MemberRefExpr can refer to type and function members, but the only case
   // that can be an lvalue is a VarDecl.
   VarDecl *var = cast<VarDecl>(e->getMember().getDecl());
+
+  auto accessSemantics = e->getAccessSemantics();
   AccessStrategy strategy =
-    var->getAccessStrategy(e->getAccessSemantics(),
+    var->getAccessStrategy(accessSemantics,
                            getFormalAccessKind(accessKind), SGF.FunctionDC);
 
+  bool isOnSelfParameter = isCallToSelfOfCurrentFunction(SGF, e);
+
+  bool isContextRead = isCurrentFunctionReadAccess(SGF);
+
+  // If we are inside _read, calling self.get, and the _read we are inside of is
+  // the same as the as self's variable and the current function is a
+  // dynamic replacement directly call the implementation.
+  if (isContextRead && isOnSelfParameter && strategy.hasAccessor() &&
+      strategy.getAccessor() == AccessorKind::Get &&
+      var->getAccessor(AccessorKind::Read)) {
+    bool isObjC = false;
+    auto readAccessor =
+        SGF.SGM.getAccessorDeclRef(var->getAccessor(AccessorKind::Read));
+    if (isCallToReplacedInDynamicReplacement(
+            SGF, readAccessor.getAbstractFunctionDecl(), isObjC)) {
+      accessSemantics = AccessSemantics::DirectToImplementation;
+      strategy = var->getAccessStrategy(
+          accessSemantics, getFormalAccessKind(accessKind), SGF.FunctionDC);
+    }
+  }
+
   LValue lv = visitRec(e->getBase(),
                        getBaseAccessKind(SGF.SGM, var, accessKind, strategy,
                                          getBaseFormalType(e->getBase())),
@@ -2808,10 +2875,9 @@
   assert(lv.isValid());
 
   CanType substFormalRValueType = getSubstFormalRValueType(e);
-  lv.addMemberVarComponent(SGF, e, var,
-                           e->getMember().getSubstitutions(),
-                           options, e->isSuper(), accessKind,
-                           strategy, substFormalRValueType);
+  lv.addMemberVarComponent(SGF, e, var, e->getMember().getSubstitutions(),
+                           options, e->isSuper(), accessKind, strategy,
+                           substFormalRValueType, isOnSelfParameter);
   return lv;
 }
 
@@ -2828,26 +2894,23 @@
   LValueOptions Options;
   SILLocation Loc;
   bool IsSuper;
+  bool IsOnSelfParameter; // Is self the self parameter in context.
   CanType BaseFormalType;
   SubstitutionMap Subs;
   Expr *IndexExprForDiagnostics;
   PreparedArguments Indices;
 
   MemberStorageAccessEmitter(SILGenFunction &SGF, SILLocation loc,
-                             StorageType *storage,
-                             SubstitutionMap subs,
-                             bool isSuper,
-                             SGFAccessKind accessKind,
-                             CanType formalRValueType,
-                             LValueOptions options,
-                             LValue &lv,
-                             Expr *indexExprForDiagnostics,
-                             PreparedArguments &&indices)
-    : super(SGF, storage, accessKind, formalRValueType),
-      LV(lv), Options(options), Loc(loc), IsSuper(isSuper),
-      BaseFormalType(lv.getSubstFormalType()), Subs(subs),
-      IndexExprForDiagnostics(indexExprForDiagnostics),
-      Indices(std::move(indices)) {}
+                             StorageType *storage, SubstitutionMap subs,
+                             bool isSuper, SGFAccessKind accessKind,
+                             CanType formalRValueType, LValueOptions options,
+                             LValue &lv, Expr *indexExprForDiagnostics,
+                             PreparedArguments &&indices, bool isSelf = false)
+      : super(SGF, storage, accessKind, formalRValueType), LV(lv),
+        Options(options), Loc(loc), IsSuper(isSuper), IsOnSelfParameter(isSelf),
+        BaseFormalType(lv.getSubstFormalType()), Subs(subs),
+        IndexExprForDiagnostics(indexExprForDiagnostics),
+        Indices(std::move(indices)) {}
 
   void emitUsingAddressor(SILDeclRef addressor, bool isDirect,
                           LValueTypeData typeData) {
@@ -2856,32 +2919,31 @@
 
     LV.add<AddressorComponent>(Storage, addressor, IsSuper, isDirect, Subs,
                                BaseFormalType, typeData, varStorageType,
-                               IndexExprForDiagnostics, std::move(Indices));
+                               IndexExprForDiagnostics, std::move(Indices),
+                               IsOnSelfParameter);
   }
 
   void emitUsingCoroutineAccessor(SILDeclRef accessor, bool isDirect,
                                   LValueTypeData typeData) {
-    LV.add<CoroutineAccessorComponent>(Storage, accessor, IsSuper, isDirect,
-                                       Subs, BaseFormalType, typeData,
-                                       IndexExprForDiagnostics,
-                                       std::move(Indices));
+    LV.add<CoroutineAccessorComponent>(
+        Storage, accessor, IsSuper, isDirect, Subs, BaseFormalType, typeData,
+        IndexExprForDiagnostics, std::move(Indices), IsOnSelfParameter);
   }
 
   void emitUsingGetterSetter(SILDeclRef accessor, bool isDirect,
                              LValueTypeData typeData) {
-    LV.add<GetterSetterComponent>(Storage, accessor, IsSuper, isDirect,
-                                  Subs, BaseFormalType, typeData,
-                                  IndexExprForDiagnostics, std::move(Indices));
+    LV.add<GetterSetterComponent>(
+        Storage, accessor, IsSuper, isDirect, Subs, BaseFormalType, typeData,
+        IndexExprForDiagnostics, std::move(Indices), IsOnSelfParameter);
   }
 
   void emitUsingMaterialization(AccessStrategy readStrategy,
                                 AccessStrategy writeStrategy,
                                 LValueTypeData typeData) {
-    LV.add<MaterializeToTemporaryComponent>(Storage, IsSuper, Subs, Options,
-                                            readStrategy, writeStrategy,
-                                            BaseFormalType, typeData,
-                                            IndexExprForDiagnostics,
-                                            std::move(Indices));
+    LV.add<MaterializeToTemporaryComponent>(
+        Storage, IsSuper, Subs, Options, readStrategy, writeStrategy,
+        BaseFormalType, typeData, IndexExprForDiagnostics, std::move(Indices),
+        IsOnSelfParameter);
   }
 };
 } // end anonymous namespace
@@ -2893,7 +2955,8 @@
                                    bool isSuper,
                                    SGFAccessKind accessKind,
                                    AccessStrategy strategy,
-                                   CanType formalRValueType) {
+                                   CanType formalRValueType,
+                                   bool isOnSelfParameter) {
   struct MemberVarAccessEmitter
       : MemberStorageAccessEmitter<MemberVarAccessEmitter, VarDecl> {
     using MemberStorageAccessEmitter::MemberStorageAccessEmitter;
@@ -2944,7 +3007,8 @@
     }
   } emitter(SGF, loc, var, subs, isSuper, accessKind,
             formalRValueType, options, *this,
-            /*indices for diags*/ nullptr, /*indices*/ PreparedArguments());
+            /*indices for diags*/ nullptr, /*indices*/ PreparedArguments(),
+            isOnSelfParameter);
 
   emitter.emitUsingStrategy(strategy);
 }
@@ -2955,11 +3019,32 @@
   auto decl = cast<SubscriptDecl>(e->getDecl().getDecl());
   auto subs = e->getDecl().getSubstitutions();
 
+
   auto accessSemantics = e->getAccessSemantics();
   auto strategy =
     decl->getAccessStrategy(accessSemantics,
                             getFormalAccessKind(accessKind), SGF.FunctionDC);
-  
+
+  bool isOnSelfParameter = isCallToSelfOfCurrentFunction(SGF, e);
+  bool isContextRead = isCurrentFunctionReadAccess(SGF);
+
+  // If we are inside _read, calling self.get, and the _read we are inside of is
+  // the same as the as self's variable and the current function is a
+  // dynamic replacement directly call the implementation.
+  if (isContextRead && isOnSelfParameter && strategy.hasAccessor() &&
+      strategy.getAccessor() == AccessorKind::Get &&
+      decl->getAccessor(AccessorKind::Read)) {
+    bool isObjC = false;
+    auto readAccessor =
+        SGF.SGM.getAccessorDeclRef(decl->getAccessor(AccessorKind::Read));
+    if (isCallToReplacedInDynamicReplacement(
+            SGF, readAccessor.getAbstractFunctionDecl(), isObjC)) {
+      accessSemantics = AccessSemantics::DirectToImplementation;
+      strategy = decl->getAccessStrategy(
+          accessSemantics, getFormalAccessKind(accessKind), SGF.FunctionDC);
+    }
+  }
+
   LValue lv = visitRec(e->getBase(),
                        getBaseAccessKind(SGF.SGM, decl, accessKind, strategy,
                                          getBaseFormalType(e->getBase())),
@@ -2973,51 +3058,94 @@
   lv.addMemberSubscriptComponent(SGF, e, decl, subs,
                                  options, e->isSuper(), accessKind, strategy,
                                  formalRValueType, std::move(indices),
-                                 indexExpr);
+                                 indexExpr, isOnSelfParameter);
   return lv;
 }
 
 LValue SILGenLValue::visitKeyPathApplicationExpr(KeyPathApplicationExpr *e,
                                                  SGFAccessKind accessKind,
                                                  LValueOptions options) {
+  auto keyPathExpr = e->getKeyPath();
+  auto keyPathKind =
+    *keyPathExpr->getType()->getAnyNominal()->getKeyPathTypeKind();
+
   // Determine the base access strategy based on the strategy of this access.
-  auto keyPathTy = e->getKeyPath()->getType()->castTo<BoundGenericType>();
   SGFAccessKind subAccess;
-  if (keyPathTy->getDecl() == SGF.getASTContext().getWritableKeyPathDecl()) {
-    // Assume the keypath only partially projects the root value.
-    subAccess = (isReadAccess(accessKind)
+  if (!isReadAccess(accessKind)) {
+    // The only read-write accesses we allow are with WritableKeyPath and
+    // ReferenceWritableKeyPath.
+    assert(keyPathKind == KPTK_WritableKeyPath ||
+           keyPathKind == KPTK_ReferenceWritableKeyPath);
+    subAccess = (keyPathKind == KPTK_ReferenceWritableKeyPath
                     ? SGFAccessKind::BorrowedAddressRead
                     : SGFAccessKind::ReadWrite);
   } else {
-    // The base is only ever read from a read-only or reference-writable
-    // keypath.
+    // For all the other kinds, we want the emit the base as an address
+    // r-value; we don't support key paths for storage with mutating read
+    // operations.
     subAccess = SGFAccessKind::BorrowedAddressRead;
   }
 
   // For now, just ignore any options we were given.
   LValueOptions subOptions = LValueOptions();
-  
+
+  // Do formal evaluation of the base l-value.
   // The base should be reabstracted to the maximal abstraction pattern.
   LValue lv = visitRec(e->getBase(), subAccess, subOptions,
                        AbstractionPattern::getOpaque());
-  
+
+  // Emit the key path r-value.
+  auto keyPath = SGF.emitRValueAsSingleValue(keyPathExpr);
+
   // The result will end up projected at the maximal abstraction level too.
-  auto resultTy = e->getType()->getRValueType()->getCanonicalType();
-  auto resultSILTy = SGF.getLoweredType(AbstractionPattern::getOpaque(),
-                                        resultTy);
-  
-  
-  lv.add<KeyPathApplicationComponent>(
-    LValueTypeData(accessKind, AbstractionPattern::getOpaque(), resultTy,
-                   resultSILTy.getObjectType()),
-    ArgumentSource(e->getKeyPath()));
-  
-  // Reabstract to the substituted abstraction level if necessary.
-  auto substResultSILTy = SGF.getLoweredType(resultTy);
-  if (resultSILTy.getObjectType() != substResultSILTy.getObjectType()) {
-    lv.addOrigToSubstComponent(substResultSILTy);
+  auto substFormalType = e->getType()->getRValueType()->getCanonicalType();
+
+  bool useLogical = [&] {
+    switch (accessKind) {
+    // Use the physical 'read' pattern for these unless we're working with
+    // AnyKeyPath or PartialKeyPath, which only have getters.
+    case SGFAccessKind::BorrowedAddressRead:
+    case SGFAccessKind::BorrowedObjectRead:
+      return (keyPathKind == KPTK_AnyKeyPath ||
+              keyPathKind == KPTK_PartialKeyPath);
+
+    case SGFAccessKind::OwnedObjectRead:
+    case SGFAccessKind::OwnedAddressRead:
+    case SGFAccessKind::IgnoredRead: // should we use physical for this?
+    case SGFAccessKind::Write:
+      return true;
+
+    case SGFAccessKind::ReadWrite:
+      return false;
+    }
+    llvm_unreachable("bad access kind");
+  }();
+
+  if (useLogical) {
+    auto typeData = getLogicalStorageTypeData(SGF.SGM, accessKind,
+                                              substFormalType);
+
+    Type baseFormalType = e->getBase()->getType()->getRValueType();
+    lv.add<LogicalKeyPathApplicationComponent>(typeData, keyPathKind, keyPath,
+                                               baseFormalType);
+
+    // TODO: make LogicalKeyPathApplicationComponent expect/produce values
+    // in the opaque AbstractionPattern and push an OrigToSubstComponent here
+    // so it can be peepholed.
+  } else {
+    auto typeData = getAbstractedTypeData(SGF.SGM, accessKind,
+                                          AbstractionPattern::getOpaque(),
+                                          substFormalType);
+
+    lv.add<PhysicalKeyPathApplicationComponent>(typeData, keyPathKind, keyPath);
+
+    // Reabstract to the substituted abstraction level if necessary.
+    auto substResultSILTy = SGF.getLoweredType(substFormalType);
+    if (typeData.TypeOfRValue != substResultSILTy.getObjectType()) {
+      lv.addOrigToSubstComponent(substResultSILTy);
+    }
   }
-  
+
   return lv;
 }
 
@@ -3030,7 +3158,8 @@
                                          AccessStrategy strategy,
                                          CanType formalRValueType,
                                          PreparedArguments &&indices,
-                                         Expr *indexExprForDiagnostics) {
+                                         Expr *indexExprForDiagnostics,
+                                         bool isOnSelfParameter) {
   struct MemberSubscriptAccessEmitter
       : MemberStorageAccessEmitter<MemberSubscriptAccessEmitter,
                                    SubscriptDecl> {
@@ -3043,9 +3172,9 @@
     void emitUsingBehaviorStorage() {
       llvm_unreachable("subscripts never have behaviors");
     }
-  } emitter(SGF, loc, decl, subs, isSuper,
-            accessKind, formalRValueType, options, *this,
-            indexExprForDiagnostics, std::move(indices));
+  } emitter(SGF, loc, decl, subs, isSuper, accessKind, formalRValueType,
+            options, *this, indexExprForDiagnostics, std::move(indices),
+            isOnSelfParameter);
 
   emitter.emitUsingStrategy(strategy);
 }
@@ -3757,6 +3886,154 @@
   return std::move(component.asLogical()).get(*this, loc, addr, C);
 }
 
+static AbstractionPattern
+getFormalStorageAbstractionPattern(SILGenFunction &SGF, AbstractStorageDecl *field) {
+  if (auto var = dyn_cast<VarDecl>(field)) {
+    auto origType = SGF.SGM.Types.getAbstractionPattern(var);
+    return origType.getReferenceStorageReferentType();
+  }
+  auto sub = cast<SubscriptDecl>(field);
+  return SGF.SGM.Types.getAbstractionPattern(sub);
+}
+
+/// Produce a singular RValue for a load from the specified property.  This is
+/// designed to work with RValue ManagedValue bases that are either +0 or +1.
+RValue SILGenFunction::emitRValueForStorageLoad(
+    SILLocation loc, ManagedValue base, CanType baseFormalType,
+    bool isSuper, AbstractStorageDecl *storage,
+    PreparedArguments &&subscriptIndices,
+    SubstitutionMap substitutions,
+    AccessSemantics semantics, Type propTy, SGFContext C,
+    bool isBaseGuaranteed) {
+  AccessStrategy strategy =
+    storage->getAccessStrategy(semantics, AccessKind::Read, FunctionDC);
+
+  // If we should call an accessor of some kind, do so.
+  if (strategy.getKind() != AccessStrategy::Storage) {
+    auto accessKind = SGFAccessKind::OwnedObjectRead;
+
+    LValue lv = [&] {
+      if (!base) return LValue();
+
+      auto baseAccess = getBaseAccessKind(SGM, storage, accessKind,
+                                          strategy, baseFormalType);
+      return LValue::forValue(baseAccess, base, baseFormalType);
+    }();
+
+    lv.addMemberComponent(*this, loc, storage, substitutions, LValueOptions(),
+                          isSuper, accessKind, strategy,
+                          propTy->getCanonicalType(),
+                          std::move(subscriptIndices),
+                          /*index for diagnostics*/ nullptr);
+
+    return emitLoadOfLValue(loc, std::move(lv), C, isBaseGuaranteed);
+  }
+
+  assert(isa<VarDecl>(storage) && "only properties should have storage");
+  auto field = cast<VarDecl>(storage);
+  assert(field->hasStorage() &&
+         "Cannot directly access value without storage");
+
+  // For static variables, emit a reference to the global variable backing
+  // them.
+  // FIXME: This has to be dynamically looked up for classes, and
+  // dynamically instantiated for generics.
+  if (field->isStatic()) {
+    auto baseMeta = base.getType().castTo<MetatypeType>().getInstanceType();
+    (void)baseMeta;
+    assert(!baseMeta->is<BoundGenericType>() &&
+           "generic static stored properties not implemented");
+    if (field->getDeclContext()->getSelfClassDecl() &&
+        field->hasStorage())
+      // FIXME: don't need to check hasStorage, already done above
+      assert(field->isFinal() && "non-final class stored properties not implemented");
+
+    return emitRValueForDecl(loc, field, propTy, semantics, C);
+  }
+
+
+  // rvalue MemberRefExprs are produced in two cases: when accessing a 'let'
+  // decl member, and when the base is a (non-lvalue) struct.
+  assert(baseFormalType->getAnyNominal() &&
+         base.getType().getASTType()->getAnyNominal() &&
+         "The base of an rvalue MemberRefExpr should be an rvalue value");
+
+  // If the accessed field is stored, emit a StructExtract on the base.
+
+  auto substFormalType = propTy->getCanonicalType();
+  auto &lowering = getTypeLowering(substFormalType);
+
+  // Check for an abstraction difference.
+  AbstractionPattern origFormalType =
+    getFormalStorageAbstractionPattern(*this, field);
+  bool hasAbstractionChange = false;
+  auto &abstractedTL = getTypeLowering(origFormalType, substFormalType);
+  if (!origFormalType.isExactType(substFormalType)) {
+    hasAbstractionChange =
+        (abstractedTL.getLoweredType() != lowering.getLoweredType());
+  }
+
+  // If the base is a reference type, just handle this as loading the lvalue.
+  ManagedValue result;
+  if (baseFormalType->hasReferenceSemantics()) {
+    LValue LV = emitPropertyLValue(loc, base, baseFormalType, field,
+                                   LValueOptions(),
+                                   SGFAccessKind::OwnedObjectRead,
+                                   AccessSemantics::DirectToStorage);
+    auto loaded = emitLoadOfLValue(loc, std::move(LV), C, isBaseGuaranteed);
+    // If we don't have to reabstract, the load is sufficient.
+    if (!hasAbstractionChange)
+      return loaded;
+
+    // Otherwise, bring the component up to +1 so we can reabstract it.
+    result = std::move(loaded).getAsSingleValue(*this, loc)
+                              .copyUnmanaged(*this, loc);
+  } else if (!base.getType().isAddress()) {
+    // For non-address-only structs, we emit a struct_extract sequence.
+    result = B.createStructExtract(loc, base, field);
+
+    if (result.getType().is<ReferenceStorageType>()) {
+      // For weak and unowned types, convert the reference to the right
+      // pointer, producing a +1.
+      result = emitConversionToSemanticRValue(loc, result, lowering);
+
+    } else if (hasAbstractionChange ||
+               (!C.isImmediatePlusZeroOk() &&
+                !(C.isGuaranteedPlusZeroOk() && isBaseGuaranteed))) {
+      // If we have an abstraction change or if we have to produce a result at
+      // +1, then copy the value. If we know that our base will stay alive for
+      // the entire usage of this value, we can borrow the value at +0 for a
+      // guaranteed consumer. Otherwise, since we do not have enough information
+      // to know if the base's lifetime last's as long as our use of the access,
+      // we can only emit at +0 for immediate clients.
+      result = result.copyUnmanaged(*this, loc);
+    }
+  } else {
+    // Create a tiny unenforced access scope around a load from local memory. No
+    // cleanup is necessary since we directly emit the load here. This will
+    // probably go away with opaque values.
+    UnenforcedAccess access;
+    SILValue accessAddress =
+      access.beginAccess(*this, loc, base.getValue(), SILAccessKind::Read);
+
+    // For address-only sequences, the base is in memory.  Emit a
+    // struct_element_addr to get to the field, and then load the element as an
+    // rvalue.
+    SILValue ElementPtr = B.createStructElementAddr(loc, accessAddress, field);
+
+    result = emitLoad(loc, ElementPtr, abstractedTL,
+                      hasAbstractionChange ? SGFContext() : C, IsNotTake);
+    access.endAccess(*this);
+  }
+
+  // If we're accessing this member with an abstraction change, perform that
+  // now.
+  if (hasAbstractionChange)
+    result =
+        emitOrigToSubstValue(loc, result, origFormalType, substFormalType, C);
+  return RValue(*this, loc, substFormalType, result);
+}
+
 ManagedValue SILGenFunction::emitAddressOfLValue(SILLocation loc,
                                                  LValue &&src,
                                                  TSanKind tsanKind) {
@@ -3784,13 +4061,19 @@
   assert(src.getAccessKind() == SGFAccessKind::IgnoredRead ||
          src.getAccessKind() == SGFAccessKind::BorrowedAddressRead ||
          src.getAccessKind() == SGFAccessKind::BorrowedObjectRead);
+  bool isIgnored = src.getAccessKind() == SGFAccessKind::IgnoredRead;
 
   ManagedValue base;
   PathComponent &&component =
     drillToLastComponent(*this, loc, std::move(src), base, tsanKind);
 
-  base = drillIntoComponent(*this, loc, std::move(component), base, tsanKind);
-  return ManagedValue::forBorrowedRValue(base.getValue());
+  auto value =
+    drillIntoComponent(*this, loc, std::move(component), base, tsanKind);
+
+  // If project() returned an owned value, and the caller cares, borrow it.
+  if (value.hasCleanup() && !isIgnored)
+    value = value.formalAccessBorrow(*this, loc);
+  return value;
 }
 
 LValue
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index fa7a8de..40956d4 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -3167,7 +3167,7 @@
   }
 
   // Create it in our current function.
-  auto thunkValue = SGF.B.createFunctionRef(loc, thunk);
+  auto thunkValue = SGF.B.createFunctionRefFor(loc, thunk);
   ManagedValue thunkedFn =
     SGF.B.createPartialApply(loc, thunkValue,
                              SILType::getPrimitiveObjectType(substFnType),
@@ -3275,7 +3275,7 @@
   }
 
   // Create it in our current function.
-  auto thunkValue = B.createFunctionRef(loc, thunk);
+  auto thunkValue = B.createFunctionRefFor(loc, thunk);
   SILValue noEscapeValue =
       noEscapingFunctionValue.ensurePlusOne(*this, loc).forward(*this);
   SingleValueInstruction *thunkedFn = B.createPartialApply(
@@ -3552,7 +3552,7 @@
   forwardFunctionArguments(*this, loc, fTy, substArgs, args);
 
   // Create the call.
-  auto implRef = B.createFunctionRef(loc, implFn);
+  auto implRef = B.createFunctionRefFor(loc, implFn);
   SILValue implResult = emitApplyWithRethrow(loc, implRef,
                                 SILType::getPrimitiveObjectType(fTy),
                                 subs, args);
@@ -3586,7 +3586,7 @@
     return WitnessDispatchKind::Static;
 
   // If the witness is dynamic, go through dynamic dispatch.
-  if (decl->isDynamic()) {
+  if (decl->isObjCDynamic()) {
     // For initializers we still emit a static allocating thunk around
     // the dynamic initializing entry point.
     if (witness.kind == SILDeclRef::Kind::Allocator)
@@ -3659,25 +3659,6 @@
   llvm_unreachable("Unhandled WitnessDispatchKind in switch.");
 }
 
-namespace {
-  class EmitAbortApply : public Cleanup {
-    SILValue Token;
-  public:
-    EmitAbortApply(SILValue token) : Token(token) {}
-    void emit(SILGenFunction &SGF, CleanupLocation loc,
-              ForUnwind_t forUnwind) override {
-      SGF.B.createAbortApply(loc, Token);
-    }
-    void dump(SILGenFunction &SGF) const override {
-#ifndef NDEBUG
-      llvm::errs() << "EmitAbortApply\n"
-                   << "State:" << getState() << "\n"
-                   << "Token:" << Token << "\n";
-#endif
-    }
-  };
-}
-
 void SILGenFunction::emitProtocolWitness(AbstractionPattern reqtOrigTy,
                                          CanAnyFunctionType reqtSubstTy,
                                          SILDeclRef requirement,
@@ -3793,14 +3774,10 @@
 
   case SILCoroutineKind::YieldOnce: {
     SmallVector<SILValue, 4> witnessYields;
-    auto token =
+    auto tokenAndCleanup =
       emitBeginApplyWithRethrow(loc, witnessFnRef, witnessSILTy, witnessSubs,
                                 args, witnessYields);
 
-    // Push a cleanup to abort the inner coroutine.
-    Cleanups.pushCleanup<EmitAbortApply>(token);
-    auto abortCleanup = Cleanups.getTopCleanup();
-
     YieldInfo witnessYieldInfo(SGM, witness, witnessFTy, witnessSubs);
     YieldInfo reqtYieldInfo(SGM, requirement, thunkTy,
                             reqtSubs.subst(getForwardingSubstitutionMap()));
@@ -3808,10 +3785,10 @@
     translateYields(*this, loc, witnessYields, witnessYieldInfo, reqtYieldInfo);
 
     // Kill the abort cleanup without emitting it.
-    Cleanups.setCleanupState(abortCleanup, CleanupState::Dead);
+    Cleanups.setCleanupState(tokenAndCleanup.second, CleanupState::Dead);
 
     // End the inner coroutine normally.
-    emitEndApplyWithRethrow(loc, token);
+    emitEndApplyWithRethrow(loc, tokenAndCleanup.first);
 
     reqtResultValue = B.createTuple(loc, {});
     break;
@@ -3958,7 +3935,7 @@
   }
 
   // Create it in the current function.
-  auto thunkValue = B.createFunctionRef(loc, thunk);
+  auto thunkValue = B.createFunctionRefFor(loc, thunk);
   ManagedValue thunkedFn = B.createPartialApply(
       loc, thunkValue, SILType::getPrimitiveObjectType(substFnTy),
       interfaceSubs, {fn},
diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp
index 5eb7e95..c3f6b99 100644
--- a/lib/SILGen/SILGenStmt.cpp
+++ b/lib/SILGen/SILGenStmt.cpp
@@ -507,6 +507,26 @@
   SGF.emitYield(S, sources, origTypes, SGF.CoroutineUnwindDest);
 }
 
+void StmtEmitter::visitPoundAssertStmt(PoundAssertStmt *stmt) {
+  SILValue condition;
+  {
+    FullExpr scope(SGF.Cleanups, CleanupLocation(stmt));
+    condition =
+        SGF.emitRValueAsSingleValue(stmt->getCondition()).getUnmanagedValue();
+  }
+
+  // Sema forces conditions to have Builtin.i1 type.
+  assert(condition->getType().castTo<BuiltinIntegerType>()->isFixedWidth(1));
+
+  SILValue message = SGF.B.createStringLiteral(
+      stmt, stmt->getMessage(), StringLiteralInst::Encoding::UTF8);
+
+  auto resultType = SGF.getASTContext().TheEmptyTupleType;
+  SGF.B.createBuiltin(
+      stmt, SGF.getASTContext().getIdentifier("poundAssert"),
+      SGF.getLoweredType(resultType), {}, {condition, message});
+}
+
 namespace {
   // This is a little cleanup that ensures that there are no jumps out of a
   // defer body.  The cleanup is only active and installed when emitting the
diff --git a/lib/SILGen/SILGenThunk.cpp b/lib/SILGen/SILGenThunk.cpp
index 7a143bf..baaa856 100644
--- a/lib/SILGen/SILGenThunk.cpp
+++ b/lib/SILGen/SILGenThunk.cpp
@@ -54,7 +54,7 @@
   SILGenFunctionBuilder builder(*this);
   auto F = builder.getOrCreateFunction(
       constant.getDecl(), name, SILLinkage::Shared, constantTy, IsBare,
-      IsTransparent, IsSerializable, ProfileCounter(), IsThunk);
+      IsTransparent, IsSerializable, IsNotDynamic, ProfileCounter(), IsThunk);
 
   if (F->empty()) {
     // Emit the thunk if we haven't yet.
@@ -76,14 +76,14 @@
   if (constant.isForeignToNativeThunk()) {
     if (!SGM.hasFunction(constant))
       SGM.emitForeignToNativeThunk(constant);
-    return ManagedValue::forUnmanaged(
-        B.createFunctionRef(loc, SGM.getFunction(constant, NotForDefinition)));
+    return ManagedValue::forUnmanaged(B.createFunctionRefFor(
+        loc, SGM.getFunction(constant, NotForDefinition)));
   }
 
   // Otherwise, we need a dynamic dispatch thunk.
   SILFunction *F = SGM.getDynamicThunk(constant, constantTy);
 
-  return ManagedValue::forUnmanaged(B.createFunctionRef(loc, F));
+  return ManagedValue::forUnmanaged(B.createFunctionRefFor(loc, F));
 }
 
 static ManagedValue getNextUncurryLevelRef(SILGenFunction &SGF, SILLocation loc,
@@ -110,8 +110,9 @@
   if (auto *func = dyn_cast<AbstractFunctionDecl>(vd)) {
     if (getMethodDispatch(func) == MethodDispatch::Class) {
       // Use the dynamic thunk if dynamic.
-      if (vd->isDynamic())
+      if (vd->isObjCDynamic()) {
         return SGF.emitDynamicMethodRef(loc, next, constantInfo.SILFnType);
+      }
 
       auto methodTy = SGF.SGM.Types.getConstantOverrideType(next);
       SILValue result =
@@ -237,9 +238,10 @@
   postEmitFunction(thunk, f);
 }
 
-SILValue SILGenFunction::emitGlobalFunctionRef(SILLocation loc,
-                                               SILDeclRef constant,
-                                               SILConstantInfo constantInfo) {
+SILValue
+SILGenFunction::emitGlobalFunctionRef(SILLocation loc, SILDeclRef constant,
+                                      SILConstantInfo constantInfo,
+                                      bool callPreviousDynamicReplaceableImpl) {
   assert(constantInfo == getConstantInfo(constant));
 
   // Builtins must be fully applied at the point of reference.
@@ -265,7 +267,10 @@
 
   auto f = SGM.getFunction(constant, NotForDefinition);
   assert(f->getLoweredFunctionType() == constantInfo.SILFnType);
-  return B.createFunctionRef(loc, f);
+  if (callPreviousDynamicReplaceableImpl)
+    return B.createPreviousDynamicFunctionRef(loc, f);
+  else
+    return B.createFunctionRefFor(loc, f);
 }
 
 SILFunction *SILGenModule::
@@ -294,5 +299,5 @@
   SILGenFunctionBuilder builder(*this);
   return builder.getOrCreateSharedFunction(
       loc, name, thunkDeclType, IsBare, IsTransparent, IsSerializable,
-      ProfileCounter(), IsReabstractionThunk);
+      ProfileCounter(), IsReabstractionThunk, IsNotDynamic);
 }
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index 170c8cc..4be10a3 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -80,7 +80,7 @@
   // If the member is dynamic, reference its dynamic dispatch thunk so that
   // it will be redispatched, funneling the method call through the runtime
   // hook point.
-  if (derivedDecl->isDynamic()
+  if (derivedDecl->isObjCDynamic()
       && derived.kind != SILDeclRef::Kind::Allocator) {
     implFn = getDynamicThunk(derived, Types.getConstantInfo(derived).SILFnType);
     implLinkage = SILLinkage::Public;
@@ -135,7 +135,7 @@
   auto thunk = builder.createFunction(
       SILLinkage::Private, name, overrideInfo.SILFnType,
       cast<AbstractFunctionDecl>(derivedDecl)->getGenericEnvironment(), loc,
-      IsBare, IsNotTransparent, IsNotSerialized);
+      IsBare, IsNotTransparent, IsNotSerialized, IsNotDynamic);
   thunk->setDebugScope(new (M) SILDebugScope(loc, thunk));
 
   SILGenFunction(*this, *thunk, theClass)
@@ -684,7 +684,8 @@
   auto *f = builder.createFunction(
       linkage, nameBuffer, witnessSILFnType, genericEnv,
       SILLocation(witnessRef.getDecl()), IsNotBare, IsTransparent, isSerialized,
-      ProfileCounter(), IsThunk, SubclassScope::NotApplicable, InlineStrategy);
+      IsNotDynamic, ProfileCounter(), IsThunk, SubclassScope::NotApplicable,
+      InlineStrategy);
 
   f->setDebugScope(new (M)
                    SILDebugScope(RegularLocation(witnessRef.getDecl()), f));
@@ -822,11 +823,13 @@
       genVTable.emitVTable();
     }
 
-    // Build a default witness table if this is a protocol.
+    // Build a default witness table if this is a protocol that needs one.
     if (auto protocol = dyn_cast<ProtocolDecl>(theType)) {
-      if (!protocol->isObjC() &&
-          protocol->isResilient())
-        SGM.emitDefaultWitnessTable(protocol);
+      if (!protocol->isObjC() && protocol->isResilient()) {
+        auto *SF = protocol->getParentSourceFile();
+        if (!SF || SF->Kind != SourceFileKind::Interface)
+          SGM.emitDefaultWitnessTable(protocol);
+      }
       return;
     }
 
diff --git a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
index d1a34de..b63c6ed 100644
--- a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
@@ -87,11 +87,6 @@
   return true;
 }
 
-bool swift::mayCheckRefCount(SILInstruction *User) {
-  return isa<IsUniqueInst>(User) ||
-         isa<IsEscapingClosureInst>(User);
-}
-
 //===----------------------------------------------------------------------===//
 //                                Use Analysis
 //===----------------------------------------------------------------------===//
@@ -136,6 +131,8 @@
   switch (Inst->getKind()) {
   // These instructions do not use other values.
   case SILInstructionKind::FunctionRefInst:
+  case SILInstructionKind::DynamicFunctionRefInst:
+  case SILInstructionKind::PreviousDynamicFunctionRefInst:
   case SILInstructionKind::IntegerLiteralInst:
   case SILInstructionKind::FloatLiteralInst:
   case SILInstructionKind::StringLiteralInst:
diff --git a/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp b/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
index 52ab994..66e43ec 100644
--- a/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
@@ -227,8 +227,8 @@
 
   // Make sure the partial_apply is not calling the result of another
   // partial_apply.
-  assert(isa<FunctionRefInst>(apply->getCallee()) &&
-         "Noescape partial apply of non-functionref?");
+  assert(isa<FunctionRefBaseInst>(apply->getCallee())
+         && "Noescape partial apply of non-functionref?");
 
   assert(llvm::all_of(apply->getUses(),
                       hasExpectedUsesOfNoEscapePartialApply) &&
diff --git a/lib/SILOptimizer/Analysis/ArraySemantic.cpp b/lib/SILOptimizer/Analysis/ArraySemantic.cpp
index bde7e34..85aaa12 100644
--- a/lib/SILOptimizer/Analysis/ArraySemantic.cpp
+++ b/lib/SILOptimizer/Analysis/ArraySemantic.cpp
@@ -731,12 +731,13 @@
   SILValue ArrRef = SemanticsCall->getArgument(1);
   SILBuilderWithScope Builder(SemanticsCall);
   auto Loc = SemanticsCall->getLoc();
-  auto *FnRef = Builder.createFunctionRef(Loc, AppendFn);
+  auto *FnRef = Builder.createFunctionRefFor(Loc, AppendFn);
 
   if (Vals.size() > 1) {
     // Create a call to reserveCapacityForAppend() to reserve space for multiple
     // elements.
-    FunctionRefInst *ReserveFnRef = Builder.createFunctionRef(Loc, ReserveFn);
+    FunctionRefBaseInst *ReserveFnRef =
+        Builder.createFunctionRefFor(Loc, ReserveFn);
     SILFunctionType *ReserveFnTy =
       ReserveFnRef->getType().castTo<SILFunctionType>();
     assert(ReserveFnTy->getNumParameters() == 2);
diff --git a/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp
index 78402fb..5d7af6e 100644
--- a/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp
@@ -241,6 +241,10 @@
   case ValueKind::FunctionRefInst:
     return CalleeList(cast<FunctionRefInst>(Callee)->getReferencedFunction());
 
+  case ValueKind::DynamicFunctionRefInst:
+  case ValueKind::PreviousDynamicFunctionRefInst:
+    return CalleeList(); // Don't know the dynamic target.
+
   case ValueKind::PartialApplyInst:
     return getCalleeListForCalleeKind(
         cast<PartialApplyInst>(Callee)->getCallee());
diff --git a/lib/SILOptimizer/Analysis/CallerAnalysis.cpp b/lib/SILOptimizer/Analysis/CallerAnalysis.cpp
index be7a51a..950d97d 100644
--- a/lib/SILOptimizer/Analysis/CallerAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/CallerAnalysis.cpp
@@ -55,7 +55,17 @@
   ~ApplySiteFinderVisitor();
 
   bool visitSILInstruction(SILInstruction *) { return false; }
-  bool visitFunctionRefInst(FunctionRefInst *fri);
+  bool visitFunctionRefInst(FunctionRefInst *fri) {
+    return visitFunctionRefBaseInst(fri);
+  }
+  bool visitDynamicFunctionRefInst(DynamicFunctionRefInst *fri) {
+    return visitFunctionRefBaseInst(fri);
+  }
+  bool
+  visitPreviousDynamicFunctionRefInst(PreviousDynamicFunctionRefInst *fri) {
+    return visitFunctionRefBaseInst(fri);
+  }
+  bool visitFunctionRefBaseInst(FunctionRefBaseInst *fri);
 
   void process();
   void processApplySites(ArrayRef<ApplySite> applySites);
@@ -100,8 +110,8 @@
 #endif
 }
 
-bool CallerAnalysis::ApplySiteFinderVisitor::visitFunctionRefInst(
-    FunctionRefInst *fri) {
+bool CallerAnalysis::ApplySiteFinderVisitor::visitFunctionRefBaseInst(
+    FunctionRefBaseInst *fri) {
   auto optResult = findLocalApplySites(fri);
   auto *calleeFn = fri->getReferencedFunction();
   FunctionInfo &calleeInfo = analysis->unsafeGetFunctionInfo(calleeFn);
diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
index b9fe0d8..82b3fd0 100644
--- a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
@@ -65,6 +65,8 @@
 static bool isNonWritableMemoryAddress(SILNode *V) {
   switch (V->getKind()) {
   case SILNodeKind::FunctionRefInst:
+  case SILNodeKind::DynamicFunctionRefInst:
+  case SILNodeKind::PreviousDynamicFunctionRefInst:
   case SILNodeKind::WitnessMethodInst:
   case SILNodeKind::ClassMethodInst:
   case SILNodeKind::SuperMethodInst:
@@ -105,7 +107,8 @@
 
 EscapeAnalysis::CGNode *EscapeAnalysis::ConnectionGraph::
 getNode(ValueBase *V, EscapeAnalysis *EA, bool createIfNeeded) {
-  if (isa<FunctionRefInst>(V))
+  if (isa<FunctionRefInst>(V) || isa<DynamicFunctionRefInst>(V) ||
+      isa<PreviousDynamicFunctionRefInst>(V))
     return nullptr;
   
   if (!EA->isPointer(V))
@@ -1612,7 +1615,8 @@
     if (V->getType().is<SILBoxType>())
       return true;
 
-    if (isa<FunctionRefInst>(V))
+    if (isa<FunctionRefInst>(V) || isa<DynamicFunctionRefInst>(V) ||
+        isa<PreviousDynamicFunctionRefInst>(V))
       return true;
 
     // Check all operands of a partial_apply
diff --git a/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
index f823b43..db30ddf 100644
--- a/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
@@ -353,6 +353,14 @@
 // FunctionSideEffects object without visiting its body.
 bool FunctionSideEffects::summarizeFunction(SILFunction *F) {
   assert(ParamEffects.empty() && "Expect uninitialized effects.");
+
+  if (F->isDynamicallyReplaceable()) {
+    LLVM_DEBUG(llvm::dbgs()
+               << "  -- is dynamically_replaceable " << F->getName() << '\n');
+    setWorstEffects();
+    return true;
+  }
+
   if (!F->empty())
     ParamEffects.resize(F->getArguments().size());
 
diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp
index 6eebe61..54eb7f1 100644
--- a/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp
+++ b/lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp
@@ -384,7 +384,7 @@
   auto Loc = ThunkBody->getParent()->getLocation();
 
   /// Create the function_ref instruction to the NewF.
-  auto *FRI = Builder.createFunctionRef(Loc, NewF);
+  auto *FRI = Builder.createFunctionRefFor(Loc, NewF);
 
   auto GenCalleeType = NewF->getLoweredFunctionType();
   auto CalleeGenericSig = GenCalleeType->getGenericSignature();
@@ -518,9 +518,9 @@
   /// Step 1: Create the new protocol constrained generic function.
   NewF = FunctionBuilder.createFunction(
       linkage, Name, NewFTy, NewFGenericEnv, F->getLocation(), F->isBare(),
-      F->isTransparent(), F->isSerialized(), F->getEntryCount(), F->isThunk(),
-      F->getClassSubclassScope(), F->getInlineStrategy(), F->getEffectsKind(),
-      nullptr, F->getDebugScope());
+      F->isTransparent(), F->isSerialized(), IsNotDynamic, F->getEntryCount(),
+      F->isThunk(), F->getClassSubclassScope(), F->getInlineStrategy(),
+      F->getEffectsKind(), nullptr, F->getDebugScope());
   /// Set the semantics attributes for the new function.
   for (auto &Attr : F->getSemanticsAttrs())
     NewF->addSemanticsAttr(Attr);
diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp
index 6471a48..a8e27f2 100644
--- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp
+++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp
@@ -501,7 +501,8 @@
   // classSubclassScope.
   TransformDescriptor.OptimizedFunction = FunctionBuilder.createFunction(
       linkage, Name, NewFTy, NewFGenericEnv, F->getLocation(), F->isBare(),
-      F->isTransparent(), F->isSerialized(), F->getEntryCount(), F->isThunk(),
+      F->isTransparent(), F->isSerialized(), IsNotDynamic, F->getEntryCount(),
+      F->isThunk(),
       /*classSubclassScope=*/SubclassScope::NotApplicable,
       F->getInlineStrategy(), F->getEffectsKind(), nullptr, F->getDebugScope());
   SILFunction *NewF = TransformDescriptor.OptimizedFunction.get();
@@ -742,6 +743,9 @@
     if (!F->shouldOptimize())
       return;
 
+    if (F->isDynamicallyReplaceable())
+      return;
+
     // This is the function to optimize.
     LLVM_DEBUG(llvm::dbgs() << "*** FSO on function: " << F->getName()
                             << " ***\n");
diff --git a/lib/SILOptimizer/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp
index 0105794..3f01e15 100644
--- a/lib/SILOptimizer/IPO/CapturePromotion.cpp
+++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp
@@ -435,9 +435,9 @@
   auto *Fn = FunctionBuilder.createFunction(
       Orig->getLinkage(), ClonedName, ClonedTy, Orig->getGenericEnvironment(),
       Orig->getLocation(), Orig->isBare(), IsNotTransparent, Serialized,
-      Orig->getEntryCount(), Orig->isThunk(), Orig->getClassSubclassScope(),
-      Orig->getInlineStrategy(), Orig->getEffectsKind(), Orig,
-      Orig->getDebugScope());
+      IsNotDynamic, Orig->getEntryCount(), Orig->isThunk(),
+      Orig->getClassSubclassScope(), Orig->getInlineStrategy(),
+      Orig->getEffectsKind(), Orig, Orig->getDebugScope());
   for (auto &Attr : Orig->getSemanticsAttrs())
     Fn->addSemanticsAttr(Attr);
   if (!Orig->hasQualifiedOwnership()) {
diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp
index 6c2d13d..0536192 100644
--- a/lib/SILOptimizer/IPO/CapturePropagation.cpp
+++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp
@@ -261,7 +261,7 @@
   SILOptFunctionBuilder FuncBuilder(*this);
   SILFunction *NewF = FuncBuilder.createFunction(
       SILLinkage::Shared, Name, NewFTy, GenericEnv, OrigF->getLocation(),
-      OrigF->isBare(), OrigF->isTransparent(), Serialized,
+      OrigF->isBare(), OrigF->isTransparent(), Serialized, IsNotDynamic,
       OrigF->getEntryCount(), OrigF->isThunk(), OrigF->getClassSubclassScope(),
       OrigF->getInlineStrategy(), OrigF->getEffectsKind(),
       /*InsertBefore*/ OrigF, OrigF->getDebugScope());
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index f102ee7..56c0195 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -659,7 +659,7 @@
       getSpecializedLinkage(ClosureUser, ClosureUser->getLinkage()), ClonedName,
       ClonedTy, ClosureUser->getGenericEnvironment(),
       ClosureUser->getLocation(), IsBare, ClosureUser->isTransparent(),
-      CallSiteDesc.isSerialized(), ClosureUser->getEntryCount(),
+      CallSiteDesc.isSerialized(), IsNotDynamic, ClosureUser->getEntryCount(),
       ClosureUser->isThunk(),
       /*classSubclassScope=*/SubclassScope::NotApplicable,
       ClosureUser->getInlineStrategy(), ClosureUser->getEffectsKind(),
@@ -1035,7 +1035,8 @@
         // so continue...
         auto AI = FullApplySite::isa(Use->getUser());
         if (!AI || AI.hasSubstitutions() ||
-            !canSpecializeFullApplySite(AI.getKind()))
+            !canSpecializeFullApplySite(AI.getKind()) ||
+            !AI.canOptimize())
           continue;
 
         // Check if we have already associated this apply inst with a closure to
diff --git a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
index f9ecb53..ad715e7 100644
--- a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
+++ b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
@@ -362,6 +362,10 @@
           ensureAliveClassMethod(mi, dyn_cast<FuncDecl>(funcDecl), MethodCl);
         } else if (auto *FRI = dyn_cast<FunctionRefInst>(&I)) {
           ensureAlive(FRI->getReferencedFunction());
+        } else if (auto *FRI = dyn_cast<DynamicFunctionRefInst>(&I)) {
+          ensureAlive(FRI->getReferencedFunction());
+        } else if (auto *FRI = dyn_cast<PreviousDynamicFunctionRefInst>(&I)) {
+          ensureAlive(FRI->getReferencedFunction());
         } else if (auto *KPI = dyn_cast<KeyPathInst>(&I)) {
           for (auto &component : KPI->getPattern()->getComponents())
             ensureKeyPathComponentIsAlive(component);
diff --git a/lib/SILOptimizer/IPO/EagerSpecializer.cpp b/lib/SILOptimizer/IPO/EagerSpecializer.cpp
index 0cdf70d..49cad1d 100644
--- a/lib/SILOptimizer/IPO/EagerSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/EagerSpecializer.cpp
@@ -755,6 +755,9 @@
     if (F.isExternalDeclaration() || F.isAvailableExternally())
       continue;
 
+    if (F.isDynamicallyReplaceable())
+      continue;
+
     if (!F.getLoweredFunctionType()->getGenericSignature())
       continue;
 
diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp
index 9ee51ec..6eb97d0 100644
--- a/lib/SILOptimizer/IPO/GlobalOpt.cpp
+++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp
@@ -274,9 +274,9 @@
                          /*params*/ {}, /*yields*/ {}, Results, None,
                          M.getASTContext());
   auto getterName = M.allocateCopy(getterNameTmp);
-  return FunctionBuilder.getOrCreateFunction(loc, getterName, Linkage,
-                                             LoweredType, IsBare,
-                                             IsNotTransparent, Serialized);
+  return FunctionBuilder.getOrCreateFunction(
+      loc, getterName, Linkage, LoweredType, IsBare, IsNotTransparent,
+      Serialized, IsNotDynamic);
 }
 
 /// Generate getter from the initialization code whose result is stored by a
diff --git a/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp b/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp
index bdbf2ba..8a0f4a4 100644
--- a/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp
+++ b/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp
@@ -72,6 +72,13 @@
     else if (isa<FunctionRefInst>(Inst)) {
       Move.push_back(Inst);
       Invariant.insert(Inst);
+    } else if (isa<DynamicFunctionRefInst>(Inst)) {
+      Move.push_back(Inst);
+      Invariant.insert(Inst);
+    }
+    else if (isa<PreviousDynamicFunctionRefInst>(Inst)) {
+      Move.push_back(Inst);
+      Invariant.insert(Inst);
     } else if (isa<IntegerLiteralInst>(Inst)) {
       Move.push_back(Inst);
       Invariant.insert(Inst);
diff --git a/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp b/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp
index 091925a..091a8d4 100644
--- a/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp
+++ b/lib/SILOptimizer/Mandatory/GuaranteedARCOpts.cpp
@@ -129,7 +129,8 @@
 bool GuaranteedARCOptsVisitor::visitStrongReleaseInst(StrongReleaseInst *SRI) {
   SILValue Operand = SRI->getOperand();
   // Release on a functionref is a noop.
-  if (isa<FunctionRefInst>(Operand)) {
+  if (isa<FunctionRefInst>(Operand) || isa<DynamicFunctionRefInst>(Operand) ||
+      isa<PreviousDynamicFunctionRefInst>(Operand)) {
     SRI->eraseFromParent();
     ++NumInstsEliminated;
     return true;
diff --git a/lib/SILOptimizer/Mandatory/IRGenPrepare.cpp b/lib/SILOptimizer/Mandatory/IRGenPrepare.cpp
index da15951..c87b541 100644
--- a/lib/SILOptimizer/Mandatory/IRGenPrepare.cpp
+++ b/lib/SILOptimizer/Mandatory/IRGenPrepare.cpp
@@ -16,7 +16,8 @@
 ///
 /// We perform the following canonicalizations:
 ///
-/// 1. We remove calls to Builtin.staticReport(), which are not needed post SIL.
+/// 1. We remove calls to Builtin.poundAssert() and Builtin.staticReport(),
+///    which are not needed post SIL.
 ///
 //===----------------------------------------------------------------------===//
 
@@ -41,14 +42,15 @@
       SILInstruction *inst = &*i;
       ++i;
 
-      // Remove calls to Builtin.staticReport().
+      // Remove calls to Builtin.poundAssert() and Builtin.staticReport().
       auto *bi = dyn_cast<BuiltinInst>(inst);
       if (!bi) {
         continue;
       }
 
       const BuiltinInfo &bInfo = bi->getBuiltinInfo();
-      if (bInfo.ID != BuiltinValueKind::StaticReport) {
+      if (bInfo.ID != BuiltinValueKind::PoundAssert &&
+          bInfo.ID != BuiltinValueKind::StaticReport) {
         continue;
       }
 
diff --git a/lib/SILOptimizer/Mandatory/SemanticARCOpts.cpp b/lib/SILOptimizer/Mandatory/SemanticARCOpts.cpp
index 77d86c8..269bbc1 100644
--- a/lib/SILOptimizer/Mandatory/SemanticARCOpts.cpp
+++ b/lib/SILOptimizer/Mandatory/SemanticARCOpts.cpp
@@ -11,10 +11,12 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "sil-semantic-arc-opts"
+#include "swift/Basic/STLExtras.h"
 #include "swift/SIL/BasicBlockUtils.h"
 #include "swift/SIL/OwnershipUtils.h"
 #include "swift/SIL/SILArgument.h"
 #include "swift/SIL/SILInstruction.h"
+#include "swift/SIL/SILVisitor.h"
 #include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
 #include "swift/SILOptimizer/PassManager/Passes.h"
 #include "swift/SILOptimizer/PassManager/Transforms.h"
@@ -26,123 +28,144 @@
 
 STATISTIC(NumEliminatedInsts, "number of removed instructions");
 
-static bool optimizeGuaranteedArgument(SILArgument *Arg,
-                                       OwnershipChecker &Checker) {
-  bool MadeChange = false;
+namespace {
 
-  // Gather all copy_value users of Arg.
-  llvm::SmallVector<CopyValueInst *, 4> Worklist;
-  for (auto *Op : Arg->getUses()) {
-    if (auto *CVI = dyn_cast<CopyValueInst>(Op->getUser())) {
-      Worklist.push_back(CVI);
+struct SemanticARCOptVisitor
+    : SILInstructionVisitor<SemanticARCOptVisitor, bool> {
+  bool visitSILInstruction(SILInstruction *i) { return false; }
+  bool visitCopyValueInst(CopyValueInst *cvi);
+  bool visitBeginBorrowInst(BeginBorrowInst *bbi);
+};
+
+} // end anonymous namespace
+
+bool SemanticARCOptVisitor::visitBeginBorrowInst(BeginBorrowInst *bbi) {
+  auto kind = bbi->getOperand().getOwnershipKind();
+  SmallVector<EndBorrowInst *, 16> endBorrows;
+  for (auto *op : bbi->getUses()) {
+    auto *user = op->getUser();
+    switch (user->getKind()) {
+    case SILInstructionKind::EndBorrowInst:
+      endBorrows.push_back(cast<EndBorrowInst>(user));
+      break;
+    default:
+      // Make sure that this operand can accept our arguments kind.
+      auto map = op->getOwnershipKindMap();
+      if (map.canAcceptKind(kind))
+        continue;
+      return false;
     }
   }
 
-  // Then until we run out of copies...
-  while (!Worklist.empty()) {
-    auto *CVI = Worklist.pop_back_val();
-
-    // Quickly see if copy has only one use and that use is a destroy_value. In
-    // such a case, we can always eliminate both the copy and the destroy.
-    if (auto *Op = CVI->getSingleUse()) {
-      if (auto *DVI = dyn_cast<DestroyValueInst>(Op->getUser())) {
-        DVI->eraseFromParent();
-        CVI->eraseFromParent();
-        NumEliminatedInsts += 2;
-        continue;
-      }
-    }
-
-    // Ok, now run the checker on the copy value. If it fails, then we just
-    // continue.
-    if (!Checker.checkValue(CVI))
-      continue;
-
-    // Otherwise, lets do a quick check on what the checker thinks the lifetime
-    // ending and non-lifetime ending users. To be conservative, we bail unless
-    // each lifetime ending use is a destroy_value and if each non-lifetime
-    // ending use is one of the following instructions:
-    //
-    // 1. copy_value.
-    // 2. begin_borrow.
-    // 3. end_borrow.
-    if (!all_of(Checker.lifetimeEndingUsers, [](SILInstruction *I) -> bool {
-          return isa<DestroyValueInst>(I);
-        }))
-      continue;
-
-    // Extra copy values that we should visit recursively.
-    llvm::SmallVector<CopyValueInst *, 8> NewCopyInsts;
-    llvm::SmallVector<SILInstruction *, 8> NewBorrowInsts;
-    if (!all_of(Checker.regularUsers, [&](SILInstruction *I) -> bool {
-          if (auto *CVI = dyn_cast<CopyValueInst>(I)) {
-            NewCopyInsts.push_back(CVI);
-            return true;
-          }
-
-          if (!isa<BeginBorrowInst>(I) && !isa<EndBorrowInst>(I))
-            return false;
-
-          NewBorrowInsts.push_back(I);
-          return true;
-        }))
-      continue;
-
-    // Ok! we can remove the copy_value, destroy_values!
-    MadeChange = true;
-    CVI->replaceAllUsesWith(CVI->getOperand());
-    CVI->eraseFromParent();
+  // 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();
+    ebi->eraseFromParent();
     ++NumEliminatedInsts;
+  }
+  bbi->replaceAllUsesWith(bbi->getOperand());
+  bbi->eraseFromParent();
+  ++NumEliminatedInsts;
+  return true;
+}
 
-    while (!Checker.lifetimeEndingUsers.empty()) {
-      Checker.lifetimeEndingUsers.pop_back_val()->eraseFromParent();
-      ++NumEliminatedInsts;
-    }
+static bool canHandleOperand(SILValue operand, SmallVectorImpl<SILValue> &out) {
+  if (!getUnderlyingBorrowIntroducers(operand, out))
+    return false;
 
-    // Then add the copy_values that were users of our original copy value to
-    // the worklist.
-    while (!NewCopyInsts.empty()) {
-      Worklist.push_back(NewCopyInsts.pop_back_val());
-    }
+  /// TODO: Add support for begin_borrow, load_borrow.
+  return all_of(out, [](SILValue v) { return isa<SILFunctionArgument>(v); });
+}
 
-    // Then remove any begin/end borrow that we found. These are unneeded since
-    // the lifetime guarantee from the argument exists above and beyond said
-    // scope.
-    while (!NewBorrowInsts.empty()) {
-      SILInstruction *I = NewBorrowInsts.pop_back_val();
-      if (auto *BBI = dyn_cast<BeginBorrowInst>(I)) {
-        // Any copy_value that is used by the begin borrow is added to the
-        // worklist.
-        for (auto *BBIUse : BBI->getUses()) {
-          if (auto *BBIUseCopyValue =
-                  dyn_cast<CopyValueInst>(BBIUse->getUser())) {
-            Worklist.push_back(BBIUseCopyValue);
-          }
-        }
+static bool performGuaranteedCopyValueOptimization(CopyValueInst *cvi) {
+  SmallVector<SILValue, 16> borrowIntroducers;
 
-        // First go through and eliminate all end borrows.
-        SmallVector<EndBorrowInst *, 4> endBorrows;
-        copy(BBI->getEndBorrows(), std::back_inserter(endBorrows));
-        while (!endBorrows.empty()) {
-          endBorrows.pop_back_val()->eraseFromParent();
-          ++NumEliminatedInsts;
-        }
+  // Whitelist the operands that we know how to support and make sure
+  // our operand is actually guaranteed.
+  if (!canHandleOperand(cvi->getOperand(), borrowIntroducers))
+    return false;
 
-        // Then eliminate BBI itself.
-        BBI->replaceAllUsesWith(BBI->getOperand());
-        BBI->eraseFromParent();
-        ++NumEliminatedInsts;
+  // Then go over all of our uses. Find our destroying instructions
+  // and make sure all of them are destroy_value. For our
+  // non-destroying instructions, make sure that they accept a
+  // guaranteed value. After that, make sure that our destroys are
+  // within the lifetime of our borrowed values.
+  SmallVector<DestroyValueInst *, 16> destroys;
+  for (auto *op : cvi->getUses()) {
+    // We know that a copy_value produces an @owned value. Look
+    // through all of our uses and classify them as either
+    // invalidating or not invalidating. Make sure that all of the
+    // invalidating ones are destroy_value since otherwise the
+    // live_range is not complete.
+    auto map = op->getOwnershipKindMap();
+    auto constraint = map.getLifetimeConstraint(ValueOwnershipKind::Owned);
+    switch (constraint) {
+    case UseLifetimeConstraint::MustBeInvalidated:
+      // And we have a destroy_value, track it and continue.
+      if (auto *dvi = dyn_cast<DestroyValueInst>(op->getUser())) {
+        destroys.push_back(dvi);
         continue;
       }
+      // Otherwise, we found a non-destroy value invalidating owned
+      // user... This is not an unnecessary live range.
+      return false;
+    case UseLifetimeConstraint::MustBeLive:
+      // Ok, this constraint can take something owned as live. Lets
+      // see if it can also take something that is guaranteed. If it
+      // can not, then we bail.
+      if (!map.canAcceptKind(ValueOwnershipKind::Guaranteed)) {
+        return false;
+      }
 
-      // This is not necessary, but it does add a check.
-      auto *EBI = cast<EndBorrowInst>(I);
-      EBI->eraseFromParent();
-      ++NumEliminatedInsts;
+      // Otherwise, continue.
+      continue;
     }
   }
 
-  return MadeChange;
+  // 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 destroy_value. Check if all of our destroys are joint
+  // post-dominated by the end_borrow set. If they do not, then the
+  // copy_value is lifetime extending the guaranteed value, we can not
+  // eliminate it.
+  //
+  // TODO: When we support begin_borrow/load_borrow a linear linfetime
+  // check will be needed here.
+  assert(all_of(borrowIntroducers,
+                [](SILValue v) { return isa<SILFunctionArgument>(v); }));
+
+  // Otherwise, we know that our copy_value/destroy_values are all
+  // completely within the guaranteed value scope.
+  while (!destroys.empty()) {
+    auto *dvi = destroys.pop_back_val();
+    dvi->eraseFromParent();
+    ++NumEliminatedInsts;
+  }
+  cvi->replaceAllUsesWith(cvi->getOperand());
+  cvi->eraseFromParent();
+  ++NumEliminatedInsts;
+  return true;
+}
+
+bool SemanticARCOptVisitor::visitCopyValueInst(CopyValueInst *cvi) {
+  // If our copy value inst has a single destroy value user, eliminate
+  // it.
+  if (auto *op = cvi->getSingleUse()) {
+    if (auto *dvi = dyn_cast<DestroyValueInst>(op->getUser())) {
+      dvi->eraseFromParent();
+      cvi->eraseFromParent();
+      NumEliminatedInsts += 2;
+      return true;
+    }
+  }
+
+  // Then try to perform the guaranteed copy value optimization.
+  if (performGuaranteedCopyValueOptimization(cvi))
+    return true;
+
+  return false;
 }
 
 //===----------------------------------------------------------------------===//
@@ -156,31 +179,56 @@
 // configuration.
 struct SemanticARCOpts : SILFunctionTransform {
   void run() override {
-    bool MadeChange = false;
-    SILFunction *F = getFunction();
-    if (!F->getModule().isStdlibModule()) {
-      return;
-    }
+    SILFunction &f = *getFunction();
 
-    DeadEndBlocks DEBlocks(F);
-    OwnershipChecker Checker{{}, {}, {}, {}, F->getModule(), DEBlocks};
+    // Make sure we are running with ownership verification enabled.
+    assert(f.getModule().getOptions().EnableSILOwnership &&
+           "Can not perform semantic arc optimization unless ownership "
+           "verification is enabled");
 
-    // First as a special case, handle guaranteed SIL function arguments.
+    // Iterate over all of the arguments, performing small peephole
+    // ARC optimizations.
     //
-    // The reason that this is special is that we do not need to consider the
-    // end of the borrow scope since the end of the function is the end of the
-    // borrow scope.
-    for (auto *Arg : F->getArguments()) {
-      if (Arg->getOwnershipKind() != ValueOwnershipKind::Guaranteed)
+    // FIXME: Should we iterate or use a RPOT order here?
+    bool madeChange = false;
+    for (auto &bb : f) {
+      auto ii = bb.rend();
+      auto start = bb.rbegin();
+
+      // If the bb is empty, continue.
+      if (start == ii)
         continue;
-      MadeChange |= optimizeGuaranteedArgument(Arg, Checker);
+
+      // Go to the first instruction to process.
+      --ii;
+
+      // Then until we process the first instruction of the block...
+      while (ii != start) {
+        // Move the iterator before ii.
+        auto tmp = std::next(ii);
+
+        // Then try to optimize. If we succeeded, then we deleted
+        // ii. Move ii from the next value back onto the instruction
+        // after ii's old value in the block instruction list and then
+        // process that.
+        if (SemanticARCOptVisitor().visit(&*ii)) {
+          madeChange = true;
+          ii = std::prev(tmp);
+          continue;
+        }
+
+        // Otherwise, we didn't delete ii. Just visit the next instruction.
+        --ii;
+      }
+
+      // Finally visit the first instruction of the block.
+      madeChange |= SemanticARCOptVisitor().visit(&*ii);
     }
 
-    if (MadeChange) {
+    if (madeChange) {
       invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
     }
   }
-
 };
 
 } // end anonymous namespace
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 684cd14..51dc183 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -747,9 +747,13 @@
       if (!DT->properlyDominates(AI, user))
         return false;
     } else {
+      // The caller has to guarantee that there are no other instructions which
+      // use the address. This is done in findInitExistential called from
+      // the constructor of ConcreteExistentialInfo.
       assert(isa<CopyAddrInst>(user) || isa<InitExistentialAddrInst>(user) ||
              isa<OpenExistentialAddrInst>(user) ||
              isa<DeallocStackInst>(user) ||
+             isa<ApplyInst>(user) || isa<TryApplyInst>(user) ||
              user->isDebugInstruction() && "Unexpected instruction");
     }
   }
diff --git a/lib/SILOptimizer/Transforms/ARCCodeMotion.cpp b/lib/SILOptimizer/Transforms/ARCCodeMotion.cpp
index d6e5f1f..390c005 100644
--- a/lib/SILOptimizer/Transforms/ARCCodeMotion.cpp
+++ b/lib/SILOptimizer/Transforms/ARCCodeMotion.cpp
@@ -70,13 +70,14 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "sil-rr-code-motion"
+#include "swift/SIL/InstructionUtils.h"
 #include "swift/SIL/SILBuilder.h"
 #include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
 #include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
 #include "swift/SILOptimizer/Analysis/EscapeAnalysis.h"
 #include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
-#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
 #include "swift/SILOptimizer/Analysis/ProgramTerminationAnalysis.h"
+#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
 #include "swift/SILOptimizer/PassManager/Passes.h"
 #include "swift/SILOptimizer/PassManager/Transforms.h"
 #include "swift/SILOptimizer/Utils/CFG.h"
diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
index 8cb4540..6c8c761 100644
--- a/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
+++ b/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
@@ -241,6 +241,13 @@
     /// Map each begin access to its AccessInfo with index, data, and flags.
     /// Iterating over this map is nondeterministic. If it is necessary to order
     /// the accesses, then AccessInfo::getAccessIndex() can be used.
+    /// This maps contains every dynamic begin_access instruction,
+    /// even those with invalid storage:
+    /// We would like to keep track of unrecognized or invalid storage locations
+    /// Because they affect our decisions for recognized locations,
+    /// be it nested conflict or merging out of scope accesses.
+    /// The access map is just a “cache” of accesses.
+    /// Keeping those invalid ones just makes the lookup faster
     AccessMap accessMap;
 
     /// Instruction pairs we can merge the scope of
@@ -536,8 +543,6 @@
       // here as an invalid `storage` value.
       const AccessedStorage &storage =
           findAccessedStorageNonNested(beginAccess->getSource());
-      if (!storage)
-        continue;
 
       auto iterAndSuccess = result.accessMap.try_emplace(
           beginAccess, static_cast<const AccessInfo &>(storage));
@@ -637,7 +642,7 @@
 
       auto &outerAccessInfo = result.getAccessInfo(outerBeginAccess);
       // If there is no potential conflict, leave the outer access mapped.
-      if (!outerAccessInfo.isDistinctFrom(beginAccessInfo))
+      if (outerAccessInfo.isDistinctFrom(beginAccessInfo))
         continue;
 
       LLVM_DEBUG(beginAccessInfo.dump();
diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp
index e0d3405..d73f09b 100644
--- a/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp
+++ b/lib/SILOptimizer/Transforms/AccessEnforcementReleaseSinking.cpp
@@ -27,6 +27,7 @@
 
 #include "swift/SIL/ApplySite.h"
 #include "swift/SIL/DebugUtils.h"
+#include "swift/SIL/InstructionUtils.h"
 #include "swift/SIL/SILFunction.h"
 #include "swift/SILOptimizer/PassManager/Transforms.h"
 
@@ -47,15 +48,124 @@
 }
 
 // Returns a bool: If this is a "barrier" instruction for this opt
-static bool isBarrier(SILInstruction &inst) {
-  switch (inst.getKind()) {
-  default:
-    return FullApplySite::isa(&inst) != FullApplySite();
-  case SILInstructionKind::BeginAccessInst:
-  case SILInstructionKind::BeginUnpairedAccessInst:
-  case SILInstructionKind::IsUniqueInst:
+static bool isBarrier(SILInstruction *inst) {
+  // Calls hide many dangers, from checking reference counts, to beginning
+  // keypath access, to forcing memory to be live. Checking for these and other
+  // possible barries at ever call is certainly not worth it.
+  if (FullApplySite::isa(inst) != FullApplySite())
     return true;
+
+  // Don't extend lifetime past any sort of uniqueness check.
+  if (mayCheckRefCount(inst))
+    return true;
+
+  // Don't extend object lifetime past deallocation.
+  if (isa<DeallocationInst>(inst))
+    return true;
+
+  // Avoid introducing access conflicts.
+  if (isa<BeginAccessInst>(inst) || isa<BeginUnpairedAccessInst>(inst))
+    return true;
+
+  if (auto *BI = dyn_cast<BuiltinInst>(inst)) {
+    auto kind = BI->getBuiltinKind();
+    if (!kind)
+      return false; // LLVM intrinsics are not barriers.
+
+    // Whitelist the safe builtin categories. Builtins should generally be
+    // treated conservatively, because introducing a new builtin does not
+    // require updating all passes to be aware of it.
+    switch (kind.getValue()) {
+    case BuiltinValueKind::None:
+      llvm_unreachable("Builtin must has a non-empty kind.");
+
+      // Unhandled categories don't generate a case. Instead, they result
+      // in a build error: enumeration values not handled in switch.
+#define BUILTIN(Id, Name, Attrs)
+
+#define BUILTIN_NO_BARRIER(Id)                                                 \
+  case BuiltinValueKind::Id:                                                   \
+    return false;
+#define BUILTIN_CAST_OPERATION(Id, Name, Attrs) BUILTIN_NO_BARRIER(Id)
+#define BUILTIN_CAST_OR_BITCAST_OPERATION(Id, Name, Attrs)                     \
+  BUILTIN_NO_BARRIER(Id)
+#define BUILTIN_BINARY_OPERATION(Id, Name, Attrs, Overload)                    \
+  BUILTIN_NO_BARRIER(Id)
+#define BUILTIN_BINARY_OPERATION_WITH_OVERFLOW(Id, Name, UncheckedID, Attrs,   \
+                                               Overload)                       \
+  BUILTIN_NO_BARRIER(Id)
+#define BUILTIN_UNARY_OPERATION(Id, Name, Attrs, Overload)                     \
+  BUILTIN_NO_BARRIER(Id)
+#define BUILTIN_BINARY_PREDICATE(Id, Name, Attrs, Overload)                    \
+  BUILTIN_NO_BARRIER(Id)
+#define BUILTIN_SIL_OPERATION(Id, Name, Overload)                              \
+  case BuiltinValueKind::Id:                                                   \
+    llvm_unreachable("SIL operation must be lowered to instructions.");
+#define BUILTIN_RUNTIME_CALL(Id, Name, Attrs)                                  \
+  case BuiltinValueKind::Id:                                                   \
+    return true; // A runtime call could be anything.
+
+    // Handle BUILTIN_MISC_OPERATIONs individually.
+    case BuiltinValueKind::Sizeof:
+    case BuiltinValueKind::Strideof:
+    case BuiltinValueKind::IsPOD:
+    case BuiltinValueKind::IsBitwiseTakable:
+    case BuiltinValueKind::IsSameMetatype:
+    case BuiltinValueKind::Alignof:
+    case BuiltinValueKind::OnFastPath:
+    case BuiltinValueKind::ExtractElement:
+    case BuiltinValueKind::InsertElement:
+    case BuiltinValueKind::StaticReport:
+    case BuiltinValueKind::AssertConf:
+    case BuiltinValueKind::StringObjectOr:
+    case BuiltinValueKind::UToSCheckedTrunc:
+    case BuiltinValueKind::SToUCheckedTrunc:
+    case BuiltinValueKind::SToSCheckedTrunc:
+    case BuiltinValueKind::UToUCheckedTrunc:
+    case BuiltinValueKind::SUCheckedConversion:
+    case BuiltinValueKind::USCheckedConversion:
+    case BuiltinValueKind::IntToFPWithOverflow:
+    case BuiltinValueKind::ZeroInitializer:
+    case BuiltinValueKind::Once:
+    case BuiltinValueKind::OnceWithContext:
+    case BuiltinValueKind::GetObjCTypeEncoding:
+    case BuiltinValueKind::Swift3ImplicitObjCEntrypoint:
+    case BuiltinValueKind::WillThrow:
+    case BuiltinValueKind::PoundAssert:
+      return false;
+
+    // Handle some rare builtins that may be sensitive to object lifetime
+    // or deinit side effects conservatively.
+    case BuiltinValueKind::AllocRaw:
+    case BuiltinValueKind::DeallocRaw:
+    case BuiltinValueKind::Fence:
+    case BuiltinValueKind::AtomicLoad:
+    case BuiltinValueKind::AtomicStore:
+    case BuiltinValueKind::AtomicRMW:
+    case BuiltinValueKind::Unreachable:
+    case BuiltinValueKind::CmpXChg:
+    case BuiltinValueKind::CondUnreachable:
+    case BuiltinValueKind::DestroyArray:
+    case BuiltinValueKind::CopyArray:
+    case BuiltinValueKind::TakeArrayNoAlias:
+    case BuiltinValueKind::TakeArrayFrontToBack:
+    case BuiltinValueKind::TakeArrayBackToFront:
+    case BuiltinValueKind::AssignCopyArrayNoAlias:
+    case BuiltinValueKind::AssignCopyArrayFrontToBack:
+    case BuiltinValueKind::AssignCopyArrayBackToFront:
+    case BuiltinValueKind::AssignTakeArray:
+    case BuiltinValueKind::UnsafeGuaranteed:
+    case BuiltinValueKind::UnsafeGuaranteedEnd:
+      return true;
+
+#define BUILTIN_SANITIZER_OPERATION(Id, Name, Attrs) BUILTIN_NO_BARRIER(Id)
+#define BUILTIN_TYPE_CHECKER_OPERATION(Id, Name) BUILTIN_NO_BARRIER(Id)
+#define BUILTIN_TYPE_TRAIT_OPERATION(Id, Name) BUILTIN_NO_BARRIER(Id)
+
+#include "swift/AST/Builtins.def"
+    }
   }
+  return false;
 }
 
 // Processes a block bottom-up, keeping a lookout for end_access instructions
@@ -70,7 +180,7 @@
       if (!bottomEndAccessInst) {
         bottomEndAccessInst = currEAI;
       }
-    } else if (isBarrier(currIns)) {
+    } else if (isBarrier(&currIns)) {
       LLVM_DEBUG(llvm::dbgs() << "Found a barrier " << currIns
                               << ", clearing last seen end_access\n");
       bottomEndAccessInst = nullptr;
diff --git a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
index c0496e8..a44182f 100644
--- a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
+++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp
@@ -609,9 +609,9 @@
   auto *Fn = FuncBuilder.createFunction(
       SILLinkage::Shared, ClonedName, ClonedTy, Orig->getGenericEnvironment(),
       Orig->getLocation(), Orig->isBare(), IsNotTransparent, Serialized,
-      Orig->getEntryCount(), Orig->isThunk(), Orig->getClassSubclassScope(),
-      Orig->getInlineStrategy(), Orig->getEffectsKind(), Orig,
-      Orig->getDebugScope());
+      IsNotDynamic, Orig->getEntryCount(), Orig->isThunk(),
+      Orig->getClassSubclassScope(), Orig->getInlineStrategy(),
+      Orig->getEffectsKind(), Orig, Orig->getDebugScope());
   for (auto &Attr : Orig->getSemanticsAttrs()) {
     Fn->addSemanticsAttr(Attr);
   }
diff --git a/lib/SILOptimizer/Transforms/GenericSpecializer.cpp b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp
index ace4f64..9037c6a 100644
--- a/lib/SILOptimizer/Transforms/GenericSpecializer.cpp
+++ b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp
@@ -97,7 +97,7 @@
       SILFunction *Callee = Apply.getReferencedFunction();
       assert(Callee && "Expected to have a known callee");
 
-      if (!Callee->shouldOptimize())
+      if (!Apply.canOptimize() || !Callee->shouldOptimize())
         continue;
 
       // We have a call that can potentially be specialized, so
diff --git a/lib/SILOptimizer/Transforms/Outliner.cpp b/lib/SILOptimizer/Transforms/Outliner.cpp
index 410aae8..3c8c439 100644
--- a/lib/SILOptimizer/Transforms/Outliner.cpp
+++ b/lib/SILOptimizer/Transforms/Outliner.cpp
@@ -322,7 +322,7 @@
 
   auto *Fun = FuncBuilder.getOrCreateFunction(
       ObjCMethod->getLoc(), name, SILLinkage::Shared, FunctionType, IsNotBare,
-      IsNotTransparent, IsSerializable);
+      IsNotTransparent, IsSerializable, IsNotDynamic);
   bool NeedsDefinition = Fun->empty();
 
   if (Release) {
@@ -933,7 +933,7 @@
 
   auto *Fun = FuncBuilder.getOrCreateFunction(
       ObjCMethod->getLoc(), name, SILLinkage::Shared, FunctionType, IsNotBare,
-      IsNotTransparent, IsSerializable);
+      IsNotTransparent, IsSerializable, IsNotDynamic);
   bool NeedsDefinition = Fun->empty();
 
   // Call the outlined function.
diff --git a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp
index 89f6137..73a6fd3 100644
--- a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp
+++ b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp
@@ -94,7 +94,7 @@
     SILFunction *F = FunctionBuilder.getOrCreateSharedFunction(
         RegularLocation::getAutoGeneratedLocation(), RuntimeCrasherFunctionName,
         FuncType, IsBare, IsNotTransparent, IsSerialized, ProfileCounter(),
-        IsNotThunk);
+        IsNotThunk, IsNotDynamic);
     if (F->isDefinition())
       return F;
 
diff --git a/lib/SILOptimizer/Utils/Devirtualize.cpp b/lib/SILOptimizer/Utils/Devirtualize.cpp
index e80b935..87abeec 100644
--- a/lib/SILOptimizer/Utils/Devirtualize.cpp
+++ b/lib/SILOptimizer/Utils/Devirtualize.cpp
@@ -712,7 +712,7 @@
 
   SILBuilderWithScope B(AI.getInstruction());
   SILLocation Loc = AI.getLoc();
-  FunctionRefInst *FRI = B.createFunctionRef(Loc, F);
+  auto *FRI = B.createFunctionRefFor(Loc, F);
 
   // Create the argument list for the new apply, casting when needed
   // in order to handle covariant indirect return types and
@@ -949,7 +949,7 @@
   // the witness thunk.
   SILBuilderWithScope Builder(AI.getInstruction());
   SILLocation Loc = AI.getLoc();
-  FunctionRefInst *FRI = Builder.createFunctionRef(Loc, F);
+  auto *FRI = Builder.createFunctionRefFor(Loc, F);
 
   ApplySite SAI = replaceApplySite(Builder, Loc, AI, FRI, SubMap, Arguments,
                                    substConv);
diff --git a/lib/SILOptimizer/Utils/GenericCloner.cpp b/lib/SILOptimizer/Utils/GenericCloner.cpp
index a9cc17a..51b6765 100644
--- a/lib/SILOptimizer/Utils/GenericCloner.cpp
+++ b/lib/SILOptimizer/Utils/GenericCloner.cpp
@@ -44,9 +44,9 @@
       getSpecializedLinkage(Orig, Orig->getLinkage()), NewName,
       ReInfo.getSpecializedType(), ReInfo.getSpecializedGenericEnvironment(),
       Orig->getLocation(), Orig->isBare(), Orig->isTransparent(), Serialized,
-      Orig->getEntryCount(), Orig->isThunk(), Orig->getClassSubclassScope(),
-      Orig->getInlineStrategy(), Orig->getEffectsKind(), Orig,
-      Orig->getDebugScope());
+      IsNotDynamic, Orig->getEntryCount(), Orig->isThunk(),
+      Orig->getClassSubclassScope(), Orig->getInlineStrategy(),
+      Orig->getEffectsKind(), Orig, Orig->getDebugScope());
   for (auto &Attr : Orig->getSemanticsAttrs()) {
     NewF->addSemanticsAttr(Attr);
   }
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index 794304f..3c89a75 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -2097,7 +2097,7 @@
 SILFunction *ReabstractionThunkGenerator::createThunk() {
   SILFunction *Thunk = FunctionBuilder.getOrCreateSharedFunction(
       Loc, ThunkName, ReInfo.getSubstitutedType(), IsBare, IsTransparent,
-      Serialized, ProfileCounter(), IsThunk);
+      Serialized, ProfileCounter(), IsThunk, IsNotDynamic);
   // Re-use an existing thunk.
   if (!Thunk->empty())
     return Thunk;
diff --git a/lib/SILOptimizer/Utils/Local.cpp b/lib/SILOptimizer/Utils/Local.cpp
index 02e23dd..4f71557 100644
--- a/lib/SILOptimizer/Utils/Local.cpp
+++ b/lib/SILOptimizer/Utils/Local.cpp
@@ -220,6 +220,14 @@
       auto *FRI = dyn_cast<FunctionRefInst>(I);
       if (FRI && FRI->getReferencedFunction())
         FRI->dropReferencedFunction();
+
+      auto *DFRI = dyn_cast<DynamicFunctionRefInst>(I);
+      if (DFRI && DFRI->getReferencedFunction())
+        DFRI->dropReferencedFunction();
+
+      auto *PFRI = dyn_cast<PreviousDynamicFunctionRefInst>(I);
+      if (PFRI && PFRI->getReferencedFunction())
+        PFRI->dropReferencedFunction();
     }
 
     for (auto I : DeadInsts) {
@@ -1561,8 +1569,9 @@
   if (!AFD->isChildContextOf(AssocDC))
     return false;
 
-  if (AFD->isDynamic())
+  if (AFD->isDynamic()) {
     return false;
+  }
 
   if (!AFD->hasAccess())
     return false;
@@ -1634,7 +1643,7 @@
 }
 
 Optional<FindLocalApplySitesResult>
-swift::findLocalApplySites(FunctionRefInst *FRI) {
+swift::findLocalApplySites(FunctionRefBaseInst *FRI) {
   SmallVector<Operand *, 32> worklist(FRI->use_begin(), FRI->use_end());
 
   Optional<FindLocalApplySitesResult> f;
diff --git a/lib/SILOptimizer/Utils/SILInliner.cpp b/lib/SILOptimizer/Utils/SILInliner.cpp
index f50d5c0..418188a 100644
--- a/lib/SILOptimizer/Utils/SILInliner.cpp
+++ b/lib/SILOptimizer/Utils/SILInliner.cpp
@@ -17,10 +17,54 @@
 #include "swift/SIL/TypeSubstCloner.h"
 #include "swift/SILOptimizer/Utils/CFG.h"
 #include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
+#include "swift/SILOptimizer/Utils/StackNesting.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Debug.h"
 using namespace swift;
 
+/// Does the given coroutine make any stack allocations that are live across
+/// its yields?
+static bool allocatesStackAcrossYields(SILFunction *F) {
+  assert(F->getLoweredFunctionType()->isCoroutine());
+
+  return hasStackDifferencesAt(&F->getEntryBlock()->front(),
+                               [](SILInstruction *i) -> InstructionMatchResult {
+    if (isa<YieldInst>(i)) {
+      return {
+        /*matches*/ true,
+        /*halt*/ i->getFunction()->getLoweredFunctionType()->getCoroutineKind()
+                       == SILCoroutineKind::YieldOnce
+      };
+    }
+
+    // Otherwise, search until the end of the function.
+    return { false, false };
+  });
+}
+
+static bool isEndOfApply(SILInstruction *i, BeginApplyInst *beginApply) {
+  if (auto endApply = dyn_cast<EndApplyInst>(i)) {
+    return endApply->getBeginApply() == beginApply;
+  } else if (auto abortApply = dyn_cast<AbortApplyInst>(i)) {
+    return abortApply->getBeginApply() == beginApply;
+  } else {
+    return false;
+  }
+}
+
+/// Are there any stack differences from the given begin_apply to any
+/// corresponding end_apply/abort_apply?
+static bool hasStackDifferencesAtEnds(BeginApplyInst *apply) {
+  return hasStackDifferencesAt(apply, [apply](SILInstruction *i)
+                                                     -> InstructionMatchResult {
+    // Search for ends of the original apply.  We can stop searching
+    // at these points.
+    if (isEndOfApply(i, apply))
+      return { true, true };
+    return { false, false };
+  });
+}
+
 static bool canInlineBeginApply(BeginApplyInst *BA) {
   // Don't inline if we have multiple resumption sites (i.e. end_apply or
   // abort_apply instructions).  The current implementation clones a single
@@ -62,6 +106,9 @@
 }
 
 bool SILInliner::canInlineApplySite(FullApplySite apply) {
+  if (!apply.canOptimize())
+    return false;
+
   if (auto BA = dyn_cast<BeginApplyInst>(apply))
     return canInlineBeginApply(BA);
 
@@ -75,6 +122,7 @@
   SILBuilder *Builder;
   BeginApplyInst *BeginApply;
   bool HasYield = false;
+  bool NeedsStackCorrection;
 
   EndApplyInst *EndApply = nullptr;
   SILBasicBlock *EndApplyBB = nullptr;
@@ -86,15 +134,31 @@
 
 public:
   BeginApplySite(BeginApplyInst *BeginApply, SILLocation Loc,
-                 SILBuilder *Builder)
-      : Loc(Loc), Builder(Builder), BeginApply(BeginApply) {}
+                 SILBuilder *Builder, bool NeedsStackCorrection)
+      : Loc(Loc), Builder(Builder), BeginApply(BeginApply),
+        NeedsStackCorrection(NeedsStackCorrection) {}
 
   static Optional<BeginApplySite> get(FullApplySite AI, SILLocation Loc,
                                       SILBuilder *Builder) {
     auto *BeginApply = dyn_cast<BeginApplyInst>(AI);
     if (!BeginApply)
       return None;
-    return BeginApplySite(BeginApply, Loc, Builder);
+
+    // We need stack correction if there are both:
+    //   - stack allocations in the callee that are live across the yield and
+    //   - stack differences in the caller from the begin_apply to any
+    //     end_apply or abort_apply.
+    // In these cases, naive cloning will cause the allocations to become
+    // improperly nested.
+    //
+    // We need to compute this here before we do any splitting in the parent
+    // function.
+    bool NeedsStackCorrection = false;
+    if (allocatesStackAcrossYields(BeginApply->getReferencedFunction()) &&
+        hasStackDifferencesAtEnds(BeginApply))
+      NeedsStackCorrection = true;
+
+    return BeginApplySite(BeginApply, Loc, Builder, NeedsStackCorrection);
   }
 
   void preprocess(SILBasicBlock *returnToBB) {
@@ -222,6 +286,11 @@
       AbortApply->eraseFromParent();
 
     assert(!BeginApply->hasUsesOfAnyResult());
+
+    // Correct the stack if necessary.
+    if (NeedsStackCorrection) {
+      StackNesting().correctStackNesting(BeginApply->getFunction());
+    }
   }
 };
 } // namespace swift
@@ -620,6 +689,8 @@
   case SILInstructionKind::EndBorrowInst:
   case SILInstructionKind::BeginBorrowInst:
   case SILInstructionKind::MarkDependenceInst:
+  case SILInstructionKind::PreviousDynamicFunctionRefInst:
+  case SILInstructionKind::DynamicFunctionRefInst:
   case SILInstructionKind::FunctionRefInst:
   case SILInstructionKind::AllocGlobalInst:
   case SILInstructionKind::GlobalAddrInst:
diff --git a/lib/SILOptimizer/Utils/SILSSAUpdater.cpp b/lib/SILOptimizer/Utils/SILSSAUpdater.cpp
index 3c8d3df..ba98d7b 100644
--- a/lib/SILOptimizer/Utils/SILSSAUpdater.cpp
+++ b/lib/SILOptimizer/Utils/SILSSAUpdater.cpp
@@ -109,6 +109,20 @@
     auto *NewFR = cast<FunctionRefInst>(FR->clone(User));
     Op.set(NewFR);
     return;
+  } else if (auto *FR = dyn_cast<PreviousDynamicFunctionRefInst>(Op.get())) {
+    assert(areIdentical(*AV) &&
+           "The function_refs need to have the same value");
+    SILInstruction *User = Op.getUser();
+    auto *NewFR = cast<PreviousDynamicFunctionRefInst>(FR->clone(User));
+    Op.set(NewFR);
+    return;
+  } else if (auto *FR = dyn_cast<DynamicFunctionRefInst>(Op.get())) {
+    assert(areIdentical(*AV) &&
+           "The function_refs need to have the same value");
+    SILInstruction *User = Op.getUser();
+    auto *NewFR = cast<DynamicFunctionRefInst>(FR->clone(User));
+    Op.set(NewFR);
+    return;
   } else if (auto *IL = dyn_cast<IntegerLiteralInst>(Op.get()))
     if (areIdentical(*AV)) {
       // Some llvm intrinsics don't like phi nodes as their constant inputs (e.g
diff --git a/lib/SILOptimizer/Utils/SpecializationMangler.cpp b/lib/SILOptimizer/Utils/SpecializationMangler.cpp
index 03f5746..129dbe5 100644
--- a/lib/SILOptimizer/Utils/SpecializationMangler.cpp
+++ b/lib/SILOptimizer/Utils/SpecializationMangler.cpp
@@ -202,6 +202,12 @@
   switch (LI->getKind()) {
   default:
     llvm_unreachable("unknown literal");
+  case SILInstructionKind::DynamicFunctionRefInst: {
+    SILFunction *F = cast<DynamicFunctionRefInst>(LI)->getReferencedFunction();
+    ArgOpBuffer << 'f';
+    appendIdentifier(F->getName());
+    break;
+  }
   case SILInstructionKind::FunctionRefInst: {
     SILFunction *F = cast<FunctionRefInst>(LI)->getReferencedFunction();
     ArgOpBuffer << 'f';
diff --git a/lib/SILOptimizer/Utils/StackNesting.cpp b/lib/SILOptimizer/Utils/StackNesting.cpp
index 98c53ad..ceb0ea1 100644
--- a/lib/SILOptimizer/Utils/StackNesting.cpp
+++ b/lib/SILOptimizer/Utils/StackNesting.cpp
@@ -18,6 +18,75 @@
 
 using namespace swift;
 
+bool swift::hasStackDifferencesAt(SILInstruction *start,
+                                  InstructionMatcher matcher) {
+  struct StackStatus {
+    /// The number of currently-active stack allocations on this path.
+    /// Because of the stack discipline, we only have to maintain a count.
+    unsigned depth;
+
+    /// Whether we've popped anything off of the stack that was active
+    /// at the start of the search.
+    bool hasPops;
+
+    bool hasDifferences() const { return hasPops || depth != 0; }
+  };
+
+  SmallPtrSet<SILBasicBlock*, 8> visited;
+  SmallVector<std::pair<SILInstruction *, StackStatus>, 8> worklist;
+  worklist.push_back({start, {0, false}});
+
+  while (!worklist.empty()) {
+    // Pull a block and depth off the worklist.
+    // Visitation order doesn't matter.
+    auto pair = worklist.pop_back_val();
+    auto status = pair.second;
+    auto firstInst = pair.first;
+    auto block = firstInst->getParent();
+
+    for (SILBasicBlock::iterator i(firstInst), e = block->end(); i != e; ++i) {
+      auto match = matcher(&*i);
+
+      // If this is an interesting instruction, check for stack
+      // differences here.
+      if (match.matches && status.hasDifferences())
+        return true;
+
+      // If we should halt, just go to the next work-list item, bypassing
+      // visiting the successors.
+      if (match.halt)
+        goto nextWorkListItem; // a labelled continue would be nice
+
+      // Otherwise, do stack-depth bookkeeping.
+      if (i->isAllocatingStack()) {
+        status.depth++;
+      } else if (i->isDeallocatingStack()) {
+        // If the stack depth is already zero, we're deallocating a stack
+        // allocation that was live into the search.
+        if (status.depth > 0) {
+          status.depth--;
+        } else {
+          status.hasPops = true;
+        }
+      }
+    }
+
+    // Add the successors to the worklist.
+    for (auto &succ : block->getSuccessors()) {
+      auto succBlock = succ.getBB();
+      auto insertResult = visited.insert(succBlock);
+      if (insertResult.second) {
+        worklist.push_back({&succBlock->front(), status});
+      }
+    }
+
+  nextWorkListItem: ;
+  }
+
+  return false;
+}
+
+
 void StackNesting::setup(SILFunction *F) {
   SmallVector<BlockInfo *, 8> WorkList;
   llvm::DenseMap<SILBasicBlock *, BlockInfo *> BlockMapping;
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index eb1af0a..1553902 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -393,20 +393,20 @@
 }
 
 /// Form a type checked expression for the index of a @dynamicMemberLookup
-/// subscript index expression.  This will have tuple type of (dynamicMember:T).
-static Expr *getDMLIndexExpr(StringRef name, Type ty, SourceLoc loc,
-                             DeclContext *dc, ConstraintSystem &cs) {
+/// subscript index parameter.
+/// The index expression will have a tuple type of `(dynamicMember: T)`.
+static Expr *buildDynamicMemberLookupIndexExpr(StringRef name, Type ty,
+                                               SourceLoc loc, DeclContext *dc,
+                                               ConstraintSystem &cs) {
   auto &ctx = cs.TC.Context;
   
   // Build and type check the string literal index value to the specific
   // string type expected by the subscript.
-  Expr *nameExpr = new (ctx)
-    StringLiteralExpr(name, loc, /*implicit*/true);
-  
-  
-  // Build a tuple so that argument has a label.
-  Expr *tuple = TupleExpr::create(ctx, loc, nameExpr, ctx.Id_dynamicMember, loc,
-                                  loc, /*hasTrailingClosure*/false,
+  Expr *nameExpr = new (ctx) StringLiteralExpr(name, loc, /*implicit*/true);
+
+  // Build a tuple so that the argument has a label.
+  Expr *tuple = TupleExpr::create(ctx, loc, nameExpr, ctx.Id_dynamicMember,
+                                  loc, loc, /*hasTrailingClosure*/false,
                                   /*implicit*/true);
   (void)cs.TC.typeCheckExpression(tuple, dc, TypeLoc::withoutLoc(ty),
                                   CTP_CallArgument);
@@ -1524,8 +1524,7 @@
       // Check whether the base is 'super'.
       bool isSuper = base->isSuperExpr();
 
-      // Use the correct kind of locator depending on how this subscript came
-      // to be.
+      // Use the correct locator kind based on the subscript kind.
       auto locatorKind = ConstraintLocator::SubscriptMember;
       if (choice.getKind() == OverloadChoiceKind::DynamicMemberLookup)
         locatorKind = ConstraintLocator::Member;
@@ -1631,6 +1630,8 @@
 
       auto ref = ConcreteDeclRef(ctor, substitutions);
 
+      tc.requestMemberLayout(ctor);
+
       // The constructor was opened with the allocating type, not the
       // initializer type. Map the former into the latter.
       auto resultTy = solution.simplifyType(openedFullType);
@@ -2769,7 +2770,8 @@
         // Build and type check the string literal index value to the specific
         // string type expected by the subscript.
         auto fieldName = selected.choice.getName().getBaseIdentifier().str();
-        auto index = getDMLIndexExpr(fieldName, tupleTy, loc, dc, cs);
+        auto index =
+          buildDynamicMemberLookupIndexExpr(fieldName, tupleTy, loc, dc, cs);
 
         // Build and return a subscript that uses this string as the index.
         return buildSubscript(base, index, ctx.Id_dynamicMember,
@@ -4370,11 +4372,6 @@
 
           auto dc = subscript->getInnermostDeclContext();
 
-          // FIXME: It's not correct to turn the subscript's parameter list
-          // into a single type here. Further down we pass it to coerceToType(),
-          // but the rules for argument list conversions are different than
-          // tuple conversions, and coerceToType() doesn't handle varargs or
-          // default arguments.
           auto indexType = AnyFunctionType::composeInput(
             cs.TC.Context,
             subscript->getInterfaceType()
@@ -4393,35 +4390,35 @@
           // through the subscript(dynamicMember:) member, restore the
           // openedType and origComponent to its full reference as if the user
           // wrote out the subscript manually.
-          if (foundDecl->choice.getKind()
-                                  == OverloadChoiceKind::DynamicMemberLookup) {
+          if (foundDecl->choice.getKind() ==
+              OverloadChoiceKind::DynamicMemberLookup) {
             foundDecl->openedType = foundDecl->openedFullType
-                  ->castTo<AnyFunctionType>()->getResult();
+                ->castTo<AnyFunctionType>()->getResult();
 
             auto &ctx = cs.TC.Context;
             auto loc = origComponent.getLoc();
             auto fieldName =
                 foundDecl->choice.getName().getBaseIdentifier().str();
-            auto index = getDMLIndexExpr(fieldName, indexType, loc, dc, cs);
+            auto index = buildDynamicMemberLookupIndexExpr(fieldName, indexType,
+                                                           loc, dc, cs);
             
             origComponent = KeyPathExpr::Component::
               forUnresolvedSubscript(ctx, loc, index, {}, loc, loc,
                                      /*trailingClosure*/nullptr);
             cs.setType(origComponent.getIndexExpr(), index->getType());
           }
-          
-          auto resolvedTy = foundDecl->openedType->castTo<AnyFunctionType>()
-            ->getResult();
-          
-          resolvedTy = simplifyType(resolvedTy);
-          
+
+          auto subscriptType =
+              simplifyType(foundDecl->openedType)->castTo<AnyFunctionType>();
+          auto resolvedTy = subscriptType->getResult();
           auto ref = ConcreteDeclRef(subscript, subs);
-          
+
           // Coerce the indices to the type the subscript expects.
-          auto indexExpr = coerceToType(origComponent.getIndexExpr(),
-                                        indexType,
-                                        locator);
-          
+          auto indexExpr = coerceCallArguments(
+              origComponent.getIndexExpr(), subscriptType,
+              /*applyExpr*/ nullptr, origComponent.getSubscriptLabels(),
+              /* hasTrailingClosure */ false, locator);
+
           component = KeyPathExpr::Component
             ::forSubscriptWithPrebuiltIndexExpr(ref, indexExpr,
                                             origComponent.getSubscriptLabels(),
@@ -4927,14 +4924,14 @@
                     unsigned index) {
   auto &tc = cs.getTypeChecker();
 
-  auto defArg = getDefaultArgumentInfo(cast<ValueDecl>(owner.getDecl()), index);
+  const auto *param = getParameterAt(cast<ValueDecl>(owner.getDecl()), index);
   Expr *init = nullptr;
-  switch (defArg.first) {
+  switch (param->getDefaultArgumentKind()) {
   case DefaultArgumentKind::None:
     llvm_unreachable("No default argument here?");
 
   case DefaultArgumentKind::Normal:
-    return {nullptr, defArg.first};
+    return {nullptr, param->getDefaultArgumentKind()};
 
   case DefaultArgumentKind::Inherited:
     // Update the owner to reflect inheritance here.
@@ -4987,16 +4984,18 @@
   }
 
   // Convert the literal to the appropriate type.
-  auto defArgType = owner.getDecl()->getDeclContext()
-                       ->mapTypeIntoContext(defArg.second);
-  auto resultTy = tc.typeCheckExpression(
-      init, dc, TypeLoc::withoutLoc(defArgType), CTP_CannotFail);
+  auto defArgType = owner.getDecl()->getDeclContext()->mapTypeIntoContext(
+      param->getInterfaceType());
+  auto resultTy =
+      tc.typeCheckParameterDefault(init, dc, defArgType,
+                                   /*isAutoClosure=*/param->isAutoClosure(),
+                                   /*canFail=*/false);
   assert(resultTy && "Conversion cannot fail");
   (void)resultTy;
 
   cs.cacheExprTypes(init);
 
-  return {init, defArg.first};
+  return {init, param->getDefaultArgumentKind()};
 }
 
 static Expr *lookThroughIdentityExprs(Expr *expr) {
@@ -5643,9 +5642,37 @@
       continue;
     }
 
-    // Convert the argument.
-    auto convertedArg = coerceToType(arg, paramType,
-                                     getArgLocator(argIdx, paramIdx));
+    auto isAutoClosureArg = [](Expr *arg) -> bool {
+      if (auto *DRE = dyn_cast<DeclRefExpr>(arg)) {
+        if (auto *PD = dyn_cast<ParamDecl>(DRE->getDecl()))
+          return PD->isAutoClosure();
+      }
+      return false;
+    };
+
+    Expr *convertedArg = nullptr;
+    // Since it was allowed to pass function types to @autoclosure
+    // parameters in Swift versions < 5, it has to be handled as
+    // a regular function coversion by `coerceToType`.
+    if (param.isAutoClosure() && (!argType->is<FunctionType>() ||
+                                  !isAutoClosureArg(arg))) {
+      // If parameter is an autoclosure, we need to make sure that:
+      //   - argument type is coerced to parameter result type
+      //   - impilict autoclosure is created to wrap argument expression
+      //   - new types are propagated to constraint system
+      auto *closureType = param.getPlainType()->castTo<FunctionType>();
+
+      arg = coerceToType(
+          arg, closureType->getResult(),
+          locator.withPathElement(ConstraintLocator::AutoclosureResult));
+
+      convertedArg = cs.TC.buildAutoClosureExpr(dc, arg, closureType);
+      cs.cacheExprTypes(convertedArg);
+    } else {
+      convertedArg =
+          coerceToType(arg, paramType, getArgLocator(argIdx, paramIdx));
+    }
+
     if (!convertedArg)
       return nullptr;
 
@@ -6534,59 +6561,10 @@
       isInDefaultArgumentContext = (initalizerCtx->getInitializerKind() ==
                                     InitializerKind::DefaultArgument);
     auto toEI = toFunc->getExtInfo();
-
-    auto fromFunc = fromType->getAs<FunctionType>();
-
-    // Coercion to an autoclosure type produces an implicit closure.
-    // The constraint solver only performs this conversion when the source
-    // type is not an autoclosure function type.  That's a weird rule in
-    // some rules, but it's easy to follow here.  Really we just shouldn't
-    // represent autoclosures as a bit on function types.
-    // FIXME: The type checker is more lenient, and allows @autoclosures to
-    // be subtypes of non-@autoclosures, which is bogus.
-    if (toFunc->isAutoClosure() &&
-        (!fromFunc || !fromFunc->isAutoClosure())) {
-      // The function type without @noescape if we are in the default argument
-      // context.
-      auto newToFuncType = toFunc;
-
-      // Remove the noescape attribute so that we can apply a separate function
-      // conversion instruction if we are in a default argument context.
-      if (isInDefaultArgumentContext && toEI.isNoEscape())
-        newToFuncType = toFunc->withExtInfo(toEI.withNoEscape(false))
-                            ->castTo<FunctionType>();
-
-      // Convert the value to the expected result type of the function.
-      expr = coerceToType(
-          expr, toFunc->getResult(),
-          locator.withPathElement(ConstraintLocator::AutoclosureResult));
-
-      // We'll set discriminator values on all the autoclosures in a
-      // later pass.
-      auto discriminator = AutoClosureExpr::InvalidDiscriminator;
-      auto closure = cs.cacheType(new (tc.Context) AutoClosureExpr(
-          expr, newToFuncType, discriminator, dc));
-      closure->setParameterList(ParameterList::createEmpty(tc.Context));
-
-      // Compute the capture list, now that we have analyzed the expression.
-      tc.ClosuresWithUncomputedCaptures.push_back(closure);
-
-      // Apply the noescape conversion.
-      if (!newToFuncType->isEqual(toFunc)) {
-        assert(isInDefaultArgumentContext);
-        assert(newToFuncType
-                   ->withExtInfo(newToFuncType->getExtInfo().withNoEscape(true))
-                   ->isEqual(toFunc));
-        return cs.cacheType(new (tc.Context)
-                                FunctionConversionExpr(closure, toFunc));
-      }
-
-      return closure;
-    }
-
     // Coercion from one function type to another, this produces a
     // FunctionConversionExpr in its full generality.
-    if (fromFunc) {
+    if (auto fromFunc = fromType->getAs<FunctionType>()) {
+      assert(toType->is<FunctionType>());
       // If we have a ClosureExpr, then we can safely propagate the 'no escape'
       // bit to the closure without invalidating prior analysis.
       auto fromEI = fromFunc->getExtInfo();
@@ -7046,6 +7024,74 @@
   return literal;
 }
 
+// Resolve @dynamicCallable applications.
+static Expr *finishApplyDynamicCallable(ConstraintSystem &cs,
+                                        const Solution &solution,
+                                        ApplyExpr *apply,
+                                        ConstraintLocatorBuilder locator) {
+  auto &ctx = cs.getASTContext();
+  auto *fn = apply->getFn();
+
+  TupleExpr *arg = dyn_cast<TupleExpr>(apply->getArg());
+  if (auto parenExpr = dyn_cast<ParenExpr>(apply->getArg()))
+    arg = TupleExpr::createImplicit(ctx, parenExpr->getSubExpr(), {});
+
+  // Get resolved `dynamicallyCall` method and verify it.
+  auto loc = locator.withPathElement(ConstraintLocator::ApplyFunction);
+  auto selected = solution.getOverloadChoice(cs.getConstraintLocator(loc));
+  auto *method = dyn_cast<FuncDecl>(selected.choice.getDecl());
+  auto methodType = selected.openedType->castTo<AnyFunctionType>();
+  assert(method->getName() == ctx.Id_dynamicallyCall &&
+         "Expected 'dynamicallyCall' method");
+  assert(methodType->getParams().size() == 1 &&
+         "Expected 'dynamicallyCall' method with one parameter");
+  auto argumentLabel = methodType->getParams()[0].getLabel();
+  assert((argumentLabel == ctx.Id_withArguments ||
+          argumentLabel == ctx.Id_withKeywordArguments) &&
+         "Expected 'dynamicallyCall' method argument label 'withArguments' or "
+         "'withKeywordArguments'");
+
+  // Determine which method was resolved: a `withArguments` method or a
+  // `withKeywordArguments` method.
+  bool useKwargsMethod = argumentLabel == ctx.Id_withKeywordArguments;
+
+  // Construct expression referencing the `dynamicallyCall` method.
+  Expr *member =
+    new (ctx) MemberRefExpr(fn, fn->getEndLoc(), ConcreteDeclRef(method),
+                            DeclNameLoc(method->getNameLoc()),
+                            /*Implicit*/ true);
+
+  // Construct argument to the method (either an array or dictionary
+  // expression).
+  Expr *argument = nullptr;
+  if (!useKwargsMethod) {
+    argument = ArrayExpr::create(ctx, SourceLoc(), arg->getElements(),
+                                 {}, SourceLoc());
+  } else {
+    SmallVector<Identifier, 4> names;
+    SmallVector<Expr *, 4> dictElements;
+    for (unsigned i = 0, n = arg->getNumElements(); i < n; i++) {
+      Expr *labelExpr =
+        new (ctx) StringLiteralExpr(arg->getElementName(i).get(),
+                                    arg->getElementNameLoc(i),
+                                    /*Implicit*/ true);
+      Expr *pair =
+        TupleExpr::createImplicit(ctx, { labelExpr, arg->getElement(i) }, {});
+      dictElements.push_back(pair);
+    }
+    argument = DictionaryExpr::create(ctx, SourceLoc(), dictElements, {},
+                                      SourceLoc());
+  }
+  argument->setImplicit();
+
+  // Construct call to the `dynamicallyCall` method.
+  Expr *result = CallExpr::createImplicit(ctx, member, argument,
+                                          { argumentLabel });
+  cs.TC.typeCheckExpression(result, cs.DC);
+  cs.cacheExprTypes(result);
+  return result;
+}
+
 Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
                                 ConstraintLocatorBuilder locator) {
   TypeChecker &tc = cs.getTypeChecker();
@@ -7340,67 +7386,73 @@
   }
 
   // We have a type constructor.
-  auto metaTy = cs.getType(fn)->castTo<AnyMetatypeType>();
-  auto ty = metaTy->getInstanceType();
+  if (auto metaTy = cs.getType(fn)->getAs<AnyMetatypeType>()) {
+    auto ty = metaTy->getInstanceType();
 
-  if (!cs.isTypeReference(fn)) {
-    bool isExistentialType = false;
-    // If this is an attempt to initialize existential type.
-    if (auto metaType = cs.getType(fn)->getAs<MetatypeType>()) {
-      auto instanceType = metaType->getInstanceType();
-      isExistentialType = instanceType->isExistentialType();
+    if (!cs.isTypeReference(fn)) {
+      bool isExistentialType = false;
+      // If this is an attempt to initialize existential type.
+      if (auto metaType = cs.getType(fn)->getAs<MetatypeType>()) {
+        auto instanceType = metaType->getInstanceType();
+        isExistentialType = instanceType->isExistentialType();
+      }
+
+      if (!isExistentialType) {
+        // If the metatype value isn't a type expression,
+        // the user should reference '.init' explicitly, for clarity.
+        cs.TC
+            .diagnose(apply->getArg()->getStartLoc(),
+                      diag::missing_init_on_metatype_initialization)
+            .fixItInsert(apply->getArg()->getStartLoc(), ".init");
+      }
     }
 
-    if (!isExistentialType) {
-      // If the metatype value isn't a type expression,
-      // the user should reference '.init' explicitly, for clarity.
-      cs.TC
-          .diagnose(apply->getArg()->getStartLoc(),
-                    diag::missing_init_on_metatype_initialization)
-          .fixItInsert(apply->getArg()->getStartLoc(), ".init");
+    // If we're "constructing" a tuple type, it's simply a conversion.
+    if (auto tupleTy = ty->getAs<TupleType>()) {
+      // FIXME: Need an AST to represent this properly.
+      return coerceToType(apply->getArg(), tupleTy, locator);
     }
+
+    // We're constructing a value of nominal type. Look for the constructor or
+    // enum element to use.
+    auto ctorLocator = cs.getConstraintLocator(
+        locator.withPathElement(ConstraintLocator::ApplyFunction)
+               .withPathElement(ConstraintLocator::ConstructorMember));
+    auto selected = solution.getOverloadChoiceIfAvailable(ctorLocator);
+    if (!selected) {
+      assert(ty->hasError() || ty->hasUnresolvedType());
+      cs.setType(apply, ty);
+      return apply;
+    }
+
+    assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>() ||
+           ty->isExistentialType() || ty->is<ArchetypeType>());
+
+    // We have the constructor.
+    auto choice = selected->choice;
+
+    // Consider the constructor decl reference expr 'implicit', but the
+    // constructor call expr itself has the apply's 'implicitness'.
+    bool isDynamic = choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
+    Expr *declRef = buildMemberRef(fn, selected->openedFullType,
+                                   /*dotLoc=*/SourceLoc(), choice,
+                                   DeclNameLoc(fn->getEndLoc()),
+                                   selected->openedType, locator, ctorLocator,
+                                   /*Implicit=*/true,
+                                   choice.getFunctionRefKind(),
+                                   AccessSemantics::Ordinary, isDynamic);
+    if (!declRef)
+      return nullptr;
+    declRef->setImplicit(apply->isImplicit());
+    apply->setFn(declRef);
+
+    // Tail-recur to actually call the constructor.
+    return finishApply(apply, openedType, locator);
   }
 
-  // If we're "constructing" a tuple type, it's simply a conversion.
-  if (auto tupleTy = ty->getAs<TupleType>()) {
-    // FIXME: Need an AST to represent this properly.
-    return coerceToType(apply->getArg(), tupleTy, locator);
-  }
-
-  // We're constructing a value of nominal type. Look for the constructor or
-  // enum element to use.
-  auto ctorLocator = cs.getConstraintLocator(
-                 locator.withPathElement(ConstraintLocator::ApplyFunction)
-                        .withPathElement(ConstraintLocator::ConstructorMember));
-  auto selected = solution.getOverloadChoiceIfAvailable(ctorLocator);
-  if (!selected) {
-    assert(ty->hasError() || ty->hasUnresolvedType());
-    cs.setType(apply, ty);
-    return apply;
-  }
-
-  assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>() ||
-         ty->isExistentialType() || ty->is<ArchetypeType>());
-
-  // We have the constructor.
-  auto choice = selected->choice;
-  
-  // Consider the constructor decl reference expr 'implicit', but the
-  // constructor call expr itself has the apply's 'implicitness'.
-  bool isDynamic = choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
-  Expr *declRef = buildMemberRef(fn, selected->openedFullType,
-                                 /*dotLoc=*/SourceLoc(), choice,
-                                 DeclNameLoc(fn->getEndLoc()),
-                                 selected->openedType, locator, ctorLocator,
-                                 /*Implicit=*/true, choice.getFunctionRefKind(),
-                                 AccessSemantics::Ordinary, isDynamic);
-  if (!declRef)
-    return nullptr;
-  declRef->setImplicit(apply->isImplicit());
-  apply->setFn(declRef);
-
-  // Tail-recur to actually call the constructor.
-  return finishApply(apply, openedType, locator);
+  // Handle @dynamicCallable applications.
+  // At this point, all other ApplyExpr cases have been handled.
+  return finishApplyDynamicCallable(cs, solution, apply, locator);
 }
 
 
diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp
index 2f63999..20814e6 100644
--- a/lib/Sema/CSBindings.cpp
+++ b/lib/Sema/CSBindings.cpp
@@ -132,48 +132,6 @@
   type.walk(Walker(typeVars));
 }
 
-/// \brief Return whether a relational constraint between a type variable and a
-/// trivial wrapper type (autoclosure, unary tuple) should result in the type
-/// variable being potentially bound to the value type, as opposed to the
-/// wrapper type.
-static bool shouldBindToValueType(Constraint *constraint) {
-  switch (constraint->getKind()) {
-  case ConstraintKind::OperatorArgumentConversion:
-  case ConstraintKind::ArgumentConversion:
-  case ConstraintKind::Conversion:
-  case ConstraintKind::BridgingConversion:
-  case ConstraintKind::Subtype:
-    return true;
-  case ConstraintKind::Bind:
-  case ConstraintKind::Equal:
-  case ConstraintKind::BindParam:
-  case ConstraintKind::BindToPointerType:
-  case ConstraintKind::ConformsTo:
-  case ConstraintKind::LiteralConformsTo:
-  case ConstraintKind::CheckedCast:
-  case ConstraintKind::SelfObjectOfProtocol:
-  case ConstraintKind::ApplicableFunction:
-  case ConstraintKind::BindOverload:
-  case ConstraintKind::OptionalObject:
-    return false;
-  case ConstraintKind::DynamicTypeOf:
-  case ConstraintKind::EscapableFunctionOf:
-  case ConstraintKind::OpenedExistentialOf:
-  case ConstraintKind::KeyPath:
-  case ConstraintKind::KeyPathApplication:
-  case ConstraintKind::ValueMember:
-  case ConstraintKind::UnresolvedValueMember:
-  case ConstraintKind::Defaultable:
-  case ConstraintKind::Disjunction:
-  case ConstraintKind::FunctionInput:
-  case ConstraintKind::FunctionResult:
-    llvm_unreachable("shouldBindToValueType() may only be called on "
-                     "relational constraints");
-  }
-
-  llvm_unreachable("Unhandled ConstraintKind in switch.");
-}
-
 void ConstraintSystem::PotentialBindings::addPotentialBinding(
     PotentialBinding binding, bool allowJoinMeet) {
   assert(!binding.BindingType->is<ErrorType>());
@@ -296,14 +254,6 @@
   if (type->hasError())
     return None;
 
-  // Don't deduce autoclosure types.
-  if (shouldBindToValueType(constraint)) {
-    if (auto funcTy = type->getAs<FunctionType>()) {
-      if (funcTy->isAutoClosure())
-        type = funcTy->getResult();
-    }
-  }
-
   // If the source of the binding is 'OptionalObject' constraint
   // and type variable is on the left-hand side, that means
   // that it _has_ to be of optional type, since the right-hand
@@ -429,7 +379,12 @@
       // this constraint is resolved, because we currently don't
       // look-through constraints expect to `subtype` to try and
       // find related bindings.
-      if (constraint->getKind() == ConstraintKind::BindParam)
+      // This only affects type variable that appears one the
+      // right-hand side of the `bind param` constraint and
+      // represents result type of the closure body, because
+      // left-hand side gets types from overload choices.
+      if (constraint->getKind() == ConstraintKind::BindParam &&
+          constraint->getSecondType()->isEqual(typeVar))
         result.PotentiallyIncomplete = true;
 
       auto binding = getPotentialBindingForRelationalConstraint(
@@ -575,6 +530,7 @@
     }
 
     case ConstraintKind::ApplicableFunction:
+    case ConstraintKind::DynamicCallableApplicableFunction:
     case ConstraintKind::BindOverload: {
       if (result.FullyBound && result.InvolvesTypeVariables)
         continue;
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 3b21bd6..5627fd9 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -2228,48 +2228,6 @@
   return false;
 }
 
-/// Try to add a fix-it when converting between a collection and its slice type,
-/// such as String <-> Substring or (eventually) Array <-> ArraySlice
-static bool trySequenceSubsequenceConversionFixIts(InFlightDiagnostic &diag,
-                                                   ConstraintSystem &CS,
-                                                   Type fromType, Type toType,
-                                                   Expr *expr) {
-  if (CS.TC.Context.getStdlibModule() == nullptr)
-    return false;
-
-  auto String = CS.TC.getStringType(CS.DC);
-  auto Substring = CS.TC.getSubstringType(CS.DC);
-
-  if (!String || !Substring)
-    return false;
-
-  /// FIXME: Remove this flag when void subscripts are implemented.
-  /// Make this unconditional and remove the if statement.
-  if (CS.TC.getLangOpts().FixStringToSubstringConversions) {
-    // String -> Substring conversion
-    // Add '[]' void subscript call to turn the whole String into a Substring
-    if (fromType->isEqual(String)) {
-      if (toType->isEqual(Substring)) {
-        diag.fixItInsertAfter(expr->getEndLoc (), "[]");
-        return true;
-      }
-    }
-  }
-
-  // Substring -> String conversion
-  // Wrap in String.init
-  if (fromType->isEqual(Substring)) {
-    if (toType->isEqual(String)) {
-      auto range = expr->getSourceRange();
-      diag.fixItInsert(range.Start, "String(");
-      diag.fixItInsertAfter(range.End, ")");
-      return true;
-    }
-  }
-
-  return false;
-}
-
 /// Attempts to add fix-its for these two mistakes:
 ///
 /// - Passing an integer with the right type but which is getting wrapped with a
@@ -2396,7 +2354,7 @@
   InFlightDiagnostic note = CS.TC.diagnose(
       paramDecl->getLoc(), diag::noescape_parameter, paramDecl->getName());
 
-  if (!srcFT->isAutoClosure()) {
+  if (!paramDecl->isAutoClosure()) {
     note.fixItInsert(paramDecl->getTypeLoc().getSourceRange().Start,
                      "@escaping ");
   } // TODO: add in a fixit for autoclosure
@@ -2738,10 +2696,9 @@
 
   // Try to convert between a sequence and its subsequence, notably
   // String <-> Substring.
-  if (trySequenceSubsequenceConversionFixIts(diag, CS, exprType, contextualType,
-                                             expr)) {
+  if (ContextualFailure::trySequenceSubsequenceFixIts(diag, CS, exprType,
+                                                      contextualType, expr))
     return true;
-  }
 
   // Attempt to add a fixit for the error.
   switch (CTP) {
@@ -3014,7 +2971,13 @@
     // punt on passing down the type information, since type checking the
     // subexpression won't be able to find the default argument provider.
     if (argType) {
-      if (auto argTT = argType->getAs<TupleType>()) {
+      if (auto *PT = dyn_cast<ParenType>(argType.getPointer())) {
+        const auto &flags = PT->getParameterFlags();
+        if (flags.isAutoClosure()) {
+          auto resultTy = PT->castTo<FunctionType>()->getResult();
+          argType = ParenType::get(PT->getASTContext(), resultTy);
+        }
+      } else if (auto argTT = argType->getAs<TupleType>()) {
         if (auto scalarElt = getElementForScalarInitOfArg(argTT, candidates)) {
           // If we found the single argument being initialized, use it.
           auto &arg = argTT->getElement(*scalarElt);
@@ -3024,6 +2987,8 @@
           // the individual varargs argument, not the overall array type.
           if (arg.isVararg())
             argType = arg.getVarargBaseTy();
+          else if (arg.isAutoClosure())
+            argType = arg.getType()->castTo<FunctionType>()->getResult();
           else
             argType = arg.getType();
         } else if (candidatesHaveAnyDefaultValues(candidates)) {
@@ -3090,6 +3055,11 @@
 
         // Look at each of the arguments assigned to this parameter.
         auto currentParamType = param.getOldType();
+
+        if (param.isAutoClosure())
+          currentParamType =
+              currentParamType->castTo<FunctionType>()->getResult();
+
         for (auto inArgNo : paramBindings[paramIdx]) {
           // Determine the argument type.
           auto currentArgType = TE->getElement(inArgNo);
@@ -3756,9 +3726,8 @@
       Ty = param.getPlainType();
     }
     // @autoclosure; the type should be the result type.
-    if (auto FT = param.getOldType()->getAs<AnyFunctionType>())
-      if (FT->isAutoClosure())
-        Ty = FT->getResult();
+    if (param.isAutoClosure())
+      Ty = param.getPlainType()->castTo<FunctionType>()->getResult();
     insertText << "<#" << Ty << "#>";
     if (argIdx == 0 && insertableEndIdx != 0)
       insertText << ", ";
@@ -5357,9 +5326,28 @@
   // non-function/non-metatype type, then we cannot call it!
   if (!isUnresolvedOrTypeVarType(fnType) &&
       !fnType->is<AnyFunctionType>() && !fnType->is<MetatypeType>()) {
-    
+
     auto arg = callExpr->getArg();
 
+    // Diagnose @dynamicCallable errors.
+    if (CS.DynamicCallableCache[fnType->getCanonicalType()].isValid()) {
+      auto dynamicCallableMethods =
+        CS.DynamicCallableCache[fnType->getCanonicalType()];
+
+      // Diagnose dynamic calls with keywords on @dynamicCallable types that
+      // don't define the `withKeywordArguments` method.
+      if (auto tuple = dyn_cast<TupleExpr>(arg)) {
+        bool hasArgLabel = llvm::any_of(
+          tuple->getElementNames(), [](Identifier i) { return !i.empty(); });
+        if (hasArgLabel &&
+            dynamicCallableMethods.keywordArgumentsMethods.empty()) {
+          diagnose(callExpr->getFn()->getStartLoc(),
+                   diag::missing_dynamic_callable_kwargs_method, fnType);
+          return true;
+        }
+      }
+    }
+
     if (fnType->is<ExistentialMetatypeType>()) {
       auto diag = diagnose(arg->getStartLoc(),
                            diag::missing_init_on_metatype_initialization);
@@ -6709,10 +6697,16 @@
                                            : defaultUnqualifiedLookupOptions),
                                corrections);
 
-      if (currentType)
-        TC.diagnose(componentNameLoc, diag::could_not_find_type_member,
-                    currentType, componentName);
-      else
+      if (currentType) {
+        if (currentType->is<TupleType>()) {
+          TC.diagnose(KPE->getLoc(), diag::expr_keypath_unimplemented_tuple);
+          isInvalid = true;
+          break;
+        }
+        else
+          TC.diagnose(componentNameLoc, diag::could_not_find_type_member,
+                      currentType, componentName);
+      } else
         TC.diagnose(componentNameLoc, diag::use_unresolved_identifier,
                     componentName, false);
 
@@ -7905,12 +7899,6 @@
   if (!contextualType)
     return {contextualType, CTP};
 
-  // If we're asked to convert to an autoclosure, then we really want to
-  // convert to the result of it.
-  if (auto *FT = contextualType->getAs<AnyFunctionType>())
-    if (FT->isAutoClosure())
-      contextualType = FT->getResult();
-
   // Since some of the contextual types might be tuples e.g. subscript argument
   // is a tuple or paren wrapping a tuple, it's required to recursively check
   // its elements to determine nullability of the contextual type, because it
diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp
index be248a9..3124eaf 100644
--- a/lib/Sema/CSDiagnostics.cpp
+++ b/lib/Sema/CSDiagnostics.cpp
@@ -664,7 +664,8 @@
     }
 
     if (auto resolvedOverload = getResolvedOverload(getLocator()))
-      if (resolvedOverload->Choice.getKind() == OverloadChoiceKind::DynamicMemberLookup)
+      if (resolvedOverload->Choice.getKind() ==
+          OverloadChoiceKind::DynamicMemberLookup)
         subElementDiagID = diag::assignment_dynamic_property_has_immutable_base;
   } else if (auto sub = dyn_cast<SubscriptExpr>(diagExpr)) {
       subElementDiagID = diag::assignment_subscript_has_immutable_base;
@@ -1106,3 +1107,90 @@
 
   return diag::assignment_lhs_is_immutable_variable;
 }
+
+bool ContextualFailure::diagnoseAsError() {
+  auto *anchor = getAnchor();
+  auto path = getLocator()->getPath();
+
+  assert(!path.empty());
+
+  if (diagnoseMissingFunctionCall())
+    return true;
+
+  Diag<Type, Type> diagnostic;
+  switch (path.back().getKind()) {
+  case ConstraintLocator::ClosureResult: {
+    diagnostic = diag::cannot_convert_closure_result;
+    break;
+  }
+
+  default:
+    return false;
+  }
+
+  auto diag = emitDiagnostic(anchor->getLoc(), diagnostic, FromType, ToType);
+  diag.highlight(anchor->getSourceRange());
+
+  (void)trySequenceSubsequenceFixIts(diag, getConstraintSystem(), FromType,
+                                     ToType, anchor);
+  return true;
+}
+
+bool ContextualFailure::diagnoseMissingFunctionCall() const {
+  auto &TC = getTypeChecker();
+
+  auto *srcFT = FromType->getAs<FunctionType>();
+  if (!srcFT || !srcFT->getParams().empty())
+    return false;
+
+  if (ToType->is<AnyFunctionType>() ||
+      !TC.isConvertibleTo(srcFT->getResult(), ToType, getDC()))
+    return false;
+
+  auto *anchor = getAnchor();
+  emitDiagnostic(anchor->getLoc(), diag::missing_nullary_call,
+                 srcFT->getResult())
+      .highlight(anchor->getSourceRange())
+      .fixItInsertAfter(anchor->getEndLoc(), "()");
+  return true;
+}
+
+bool ContextualFailure::trySequenceSubsequenceFixIts(InFlightDiagnostic &diag,
+                                                     ConstraintSystem &CS,
+                                                     Type fromType, Type toType,
+                                                     Expr *expr) {
+  if (!CS.TC.Context.getStdlibModule())
+    return false;
+
+  auto String = CS.TC.getStringType(CS.DC);
+  auto Substring = CS.TC.getSubstringType(CS.DC);
+
+  if (!String || !Substring)
+    return false;
+
+  /// FIXME: Remove this flag when void subscripts are implemented.
+  /// Make this unconditional and remove the if statement.
+  if (CS.TC.getLangOpts().FixStringToSubstringConversions) {
+    // String -> Substring conversion
+    // Add '[]' void subscript call to turn the whole String into a Substring
+    if (fromType->isEqual(String)) {
+      if (toType->isEqual(Substring)) {
+        diag.fixItInsertAfter(expr->getEndLoc(), "[]");
+        return true;
+      }
+    }
+  }
+
+  // Substring -> String conversion
+  // Wrap in String.init
+  if (fromType->isEqual(Substring)) {
+    if (toType->isEqual(String)) {
+      auto range = expr->getSourceRange();
+      diag.fixItInsert(range.Start, "String(");
+      diag.fixItInsertAfter(range.End, ")");
+      return true;
+    }
+  }
+
+  return false;
+}
diff --git a/lib/Sema/CSDiagnostics.h b/lib/Sema/CSDiagnostics.h
index eb8e751..b14b31e 100644
--- a/lib/Sema/CSDiagnostics.h
+++ b/lib/Sema/CSDiagnostics.h
@@ -558,6 +558,40 @@
   }
 };
 
+/// Intended to diagnose any possible contextual failure
+/// e.g. argument/parameter, closure result, conversions etc.
+class ContextualFailure final : public FailureDiagnostic {
+  Type FromType, ToType;
+
+public:
+  ContextualFailure(Expr *root, ConstraintSystem &cs, Type lhs, Type rhs,
+                    ConstraintLocator *locator)
+      : FailureDiagnostic(root, cs, locator), FromType(resolve(lhs)),
+        ToType(resolve(rhs)) {}
+
+  bool diagnoseAsError() override;
+
+  // If we're trying to convert something of type "() -> T" to T,
+  // then we probably meant to call the value.
+  bool diagnoseMissingFunctionCall() const;
+
+  /// Try to add a fix-it when converting between a collection and its slice
+  /// type, such as String <-> Substring or (eventually) Array <-> ArraySlice
+  static bool trySequenceSubsequenceFixIts(InFlightDiagnostic &diag,
+                                           ConstraintSystem &CS, Type fromType,
+                                           Type toType, Expr *expr);
+
+private:
+  Type resolve(Type rawType) {
+    auto type = resolveType(rawType)->getWithoutSpecifierType();
+    if (auto *BGT = type->getAs<BoundGenericType>()) {
+      if (BGT->hasUnresolvedType())
+        return BGT->getDecl()->getDeclaredInterfaceType();
+    }
+    return type;
+  }
+};
+
 } // end namespace constraints
 } // end namespace swift
 
diff --git a/lib/Sema/CSFix.cpp b/lib/Sema/CSFix.cpp
index 311265e..3772beb 100644
--- a/lib/Sema/CSFix.cpp
+++ b/lib/Sema/CSFix.cpp
@@ -190,3 +190,15 @@
   return new (cs.getAllocator())
       SkipSuperclassRequirement(cs, lhs, rhs, locator);
 }
+
+bool ContextualMismatch::diagnose(Expr *root, bool asNote) const {
+  auto failure = ContextualFailure(root, getConstraintSystem(), getFromType(),
+                                   getToType(), getLocator());
+  return failure.diagnose(asNote);
+}
+
+ContextualMismatch *ContextualMismatch::create(ConstraintSystem &cs, Type lhs,
+                                               Type rhs,
+                                               ConstraintLocator *locator) {
+  return new (cs.getAllocator()) ContextualMismatch(cs, lhs, rhs, locator);
+}
diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h
index d90feb5..3033e54 100644
--- a/lib/Sema/CSFix.h
+++ b/lib/Sema/CSFix.h
@@ -80,6 +80,9 @@
   /// and assume that types are related.
   SkipSuperclassRequirement,
 
+  /// Fix up one of the sides of conversion to make it seem
+  /// like the types are aligned.
+  ContextualMismatch,
 };
 
 class ConstraintFix {
@@ -347,6 +350,35 @@
   create(ConstraintSystem &cs, Type lhs, Type rhs, ConstraintLocator *locator);
 };
 
+/// For example: Sometimes type returned from the body of the
+/// closure doesn't match expected contextual type:
+///
+/// func foo(_: () -> Int) {}
+/// foo { "ultimate question" }
+///
+/// Body of the closure produces `String` type when `Int` is expected
+/// by the context.
+class ContextualMismatch : public ConstraintFix {
+  Type LHS, RHS;
+
+protected:
+  ContextualMismatch(ConstraintSystem &cs, Type lhs, Type rhs,
+                     ConstraintLocator *locator)
+      : ConstraintFix(cs, FixKind::ContextualMismatch, locator), LHS(lhs),
+        RHS(rhs) {}
+
+public:
+  std::string getName() const override { return "fix contextual mismatch"; }
+
+  Type getFromType() const { return LHS; }
+  Type getToType() const { return RHS; }
+
+  bool diagnose(Expr *root, bool asNote = false) const override;
+
+  static ContextualMismatch *create(ConstraintSystem &cs, Type lhs, Type rhs,
+                                    ConstraintLocator *locator);
+};
+
 } // end namespace constraints
 } // end namespace swift
 
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 01b9d8f..d1bdfd2 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -3086,6 +3086,11 @@
     }
 
     Type visitTapExpr(TapExpr *expr) {
+      DeclContext *varDC = expr->getVar()->getDeclContext();
+      assert(varDC == CS.DC || (varDC && isa<AbstractClosureExpr>(varDC) &&
+              cast<AbstractClosureExpr>(varDC)->hasSingleExpressionBody()) &&
+             "TapExpr var should be in the same DeclContext we're checking it in!");
+      
       auto locator = CS.getConstraintLocator(expr);
       auto tv = CS.createTypeVariable(locator);
 
diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp
index 47a033f..628a967 100644
--- a/lib/Sema/CSRanking.cpp
+++ b/lib/Sema/CSRanking.cpp
@@ -357,13 +357,10 @@
 
 /// Retrieve the adjusted parameter type for overloading purposes.
 static Type getAdjustedParamType(const AnyFunctionType::Param &param) {
-  if (auto funcTy = param.getOldType()->getAs<FunctionType>()) {
-    if (funcTy->isAutoClosure()) {
-      return funcTy->getResult();
-    }
-  }
-
-  return param.getOldType();
+  auto type = param.getOldType();
+  if (param.isAutoClosure())
+    return type->castTo<FunctionType>()->getResult();
+  return type;
 }
 
 // Is a particular parameter of a function or subscript declaration
@@ -1066,7 +1063,7 @@
         auto param2 = params[1].getOldType()->castTo<AnyFunctionType>();
 
         assert(param1->getOptionalObjectType());
-        assert(param2->isAutoClosure());
+        assert(params[1].isAutoClosure());
         assert(param2->getResult()->getOptionalObjectType());
 
         (void) param1;
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 0f1eb56..03e66cb 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -835,7 +835,42 @@
   ConstraintKind subKind = (isOperator
                             ? ConstraintKind::OperatorArgumentConversion
                             : ConstraintKind::ArgumentConversion);
-  
+
+  // Check whether argument of the call at given position refers to
+  // parameter marked as `@autoclosure`. This function is used to
+  // maintain source compatibility with Swift versions < 5,
+  // previously examples like following used to type-check:
+  //
+  // func foo(_ x: @autoclosure () -> Int) {}
+  // func bar(_ y: @autoclosure () -> Int) {
+  //   foo(y)
+  // }
+  auto isAutoClosureArg = [&](Expr *anchor, unsigned argIdx) -> bool {
+    assert(anchor);
+
+    auto *call = dyn_cast<ApplyExpr>(anchor);
+    if (!call)
+      return false;
+
+    Expr *argExpr = nullptr;
+    if (auto *PE = dyn_cast<ParenExpr>(call->getArg())) {
+      assert(argsWithLabels.size() == 1);
+      argExpr = PE->getSubExpr();
+    } else if (auto *TE = dyn_cast<TupleExpr>(call->getArg())) {
+      argExpr = TE->getElement(argIdx);
+    }
+
+    if (!argExpr)
+      return false;
+
+    if (auto *DRE = dyn_cast<DeclRefExpr>(argExpr)) {
+      if (auto *param = dyn_cast<ParamDecl>(DRE->getDecl()))
+        return param->isAutoClosure();
+    }
+
+    return false;
+  };
+
   for (unsigned paramIdx = 0, numParams = parameterBindings.size();
        paramIdx != numParams; ++paramIdx){
     // Skip unfulfilled parameters. There's nothing to do for them.
@@ -846,13 +881,39 @@
     const auto &param = params[paramIdx];
     auto paramTy = param.getOldType();
 
+    if (param.isAutoClosure())
+      paramTy = paramTy->castTo<FunctionType>()->getResult();
+
     // Compare each of the bound arguments for this parameter.
     for (auto argIdx : parameterBindings[paramIdx]) {
       auto loc = locator.withPathElement(LocatorPathElt::
                                             getApplyArgToParam(argIdx,
                                                                paramIdx));
       auto argTy = argsWithLabels[argIdx].getOldType();
-      cs.addConstraint(subKind, argTy, paramTy, loc, /*isFavored=*/false);
+
+      // If parameter was marked as `@autoclosure` and argument
+      // is itself `@autoclosure` function type in Swift < 5,
+      // let's fix that up by making it look like argument is
+      // called implicitly.
+      if (!cs.getASTContext().isSwiftVersionAtLeast(5)) {
+        if (param.isAutoClosure() &&
+            isAutoClosureArg(locator.getAnchor(), argIdx)) {
+          argTy = argTy->castTo<FunctionType>()->getResult();
+          cs.increaseScore(SK_FunctionConversion);
+        }
+      }
+
+      // If argument comes for declaration it should loose
+      // `@autoclosure` flag, because in context it's used
+      // as a function type represented by autoclosure.
+      assert(!argsWithLabels[argIdx].isAutoClosure());
+
+      cs.addConstraint(
+          subKind, argTy, paramTy,
+          param.isAutoClosure()
+              ? loc.withPathElement(ConstraintLocator::AutoclosureResult)
+              : loc,
+          /*isFavored=*/false);
     }
   }
 
@@ -920,6 +981,7 @@
   case ConstraintKind::Equal:
   case ConstraintKind::Subtype:
   case ConstraintKind::ApplicableFunction:
+  case ConstraintKind::DynamicCallableApplicableFunction:
   case ConstraintKind::BindOverload:
   case ConstraintKind::CheckedCast:
   case ConstraintKind::ConformsTo:
@@ -1013,6 +1075,7 @@
   case ConstraintKind::ArgumentConversion:
   case ConstraintKind::OperatorArgumentConversion:
   case ConstraintKind::ApplicableFunction:
+  case ConstraintKind::DynamicCallableApplicableFunction:
   case ConstraintKind::BindOverload:
   case ConstraintKind::CheckedCast:
   case ConstraintKind::ConformsTo:
@@ -1040,19 +1103,6 @@
 ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
                                      ConstraintKind kind, TypeMatchOptions flags,
                                      ConstraintLocatorBuilder locator) {
-  // An @autoclosure function type can be a subtype of a
-  // non-@autoclosure function type.
-  if (func1->isAutoClosure() != func2->isAutoClosure()) {
-    // If the 2nd type is an autoclosure, then the first type needs wrapping in a
-    // closure despite already being a function type.
-    if (func2->isAutoClosure())
-      return getTypeMatchFailure(locator);
-    if (kind < ConstraintKind::Subtype)
-      return getTypeMatchFailure(locator);
-
-    increaseScore(SK_FunctionConversion);
-  }
-  
   // A non-throwing function can be a subtype of a throwing function.
   if (func1->throws() != func2->throws()) {
     // Cannot drop 'throws'.
@@ -1090,6 +1140,7 @@
     break;
 
   case ConstraintKind::ApplicableFunction:
+  case ConstraintKind::DynamicCallableApplicableFunction:
   case ConstraintKind::BindOverload:
   case ConstraintKind::CheckedCast:
   case ConstraintKind::ConformsTo:
@@ -1573,21 +1624,42 @@
   return getTypeMatchSuccess();
 }
 
-static void attemptToFixRequirementFailure(
-    ConstraintSystem &cs, Type type1, Type type2,
-    SmallVectorImpl<RestrictionOrFix> &conversionsOrFixes,
-    ConstraintLocatorBuilder locator) {
-  using LocatorPathEltKind = ConstraintLocator::PathElementKind;
-
+static ConstraintFix *fixRequirementFailure(ConstraintSystem &cs, Type type1,
+                                            Type type2, Expr *anchor,
+                                            LocatorPathElt &req) {
   // Can't fix not yet properly resolved types.
   if (type1->hasTypeVariable() || type2->hasTypeVariable())
-    return;
+    return nullptr;
 
   // If dependent members are present here it's because
   // base doesn't conform to associated type's protocol.
   if (type1->hasDependentMember() || type2->hasDependentMember())
-    return;
+    return nullptr;
 
+  // Build simplified locator which only contains anchor and requirement info.
+  ConstraintLocatorBuilder requirement(cs.getConstraintLocator(anchor));
+  auto *reqLoc = cs.getConstraintLocator(requirement.withPathElement(req));
+
+  auto reqKind = static_cast<RequirementKind>(req.getValue2());
+  switch (reqKind) {
+  case RequirementKind::SameType: {
+    return SkipSameTypeRequirement::create(cs, type1, type2, reqLoc);
+  }
+
+  case RequirementKind::Superclass: {
+    return SkipSuperclassRequirement::create(cs, type1, type2, reqLoc);
+  }
+
+  case RequirementKind::Conformance:
+  case RequirementKind::Layout:
+    llvm_unreachable("conformance requirements are handled elsewhere");
+  }
+}
+
+static void
+repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
+               SmallVectorImpl<RestrictionOrFix> &conversionsOrFixes,
+               ConstraintLocatorBuilder locator) {
   SmallVector<LocatorPathElt, 4> path;
   auto *anchor = locator.getLocatorParts(path);
 
@@ -1595,30 +1667,22 @@
     return;
 
   auto &elt = path.back();
-  if (elt.getKind() != LocatorPathEltKind::TypeParameterRequirement)
-    return;
-
-  // Build simplified locator which only contains anchor and requirement info.
-  ConstraintLocatorBuilder requirement(cs.getConstraintLocator(anchor));
-  auto *reqLoc = cs.getConstraintLocator(requirement.withPathElement(elt));
-
-  auto reqKind = static_cast<RequirementKind>(elt.getValue2());
-  switch (reqKind) {
-  case RequirementKind::SameType: {
-    auto *fix = SkipSameTypeRequirement::create(cs, type1, type2, reqLoc);
-    conversionsOrFixes.push_back(fix);
-    return;
+  switch (elt.getKind()) {
+  case ConstraintLocator::TypeParameterRequirement: {
+    if (auto *fix = fixRequirementFailure(cs, lhs, rhs, anchor, elt))
+      conversionsOrFixes.push_back(fix);
+    break;
   }
 
-  case RequirementKind::Superclass: {
-    auto *fix = SkipSuperclassRequirement::create(cs, type1, type2, reqLoc);
+  case ConstraintLocator::ClosureResult: {
+    auto *fix = ContextualMismatch::create(cs, lhs, rhs,
+                                           cs.getConstraintLocator(locator));
     conversionsOrFixes.push_back(fix);
-    return;
+    break;
   }
 
-  case RequirementKind::Conformance:
-  case RequirementKind::Layout:
-    llvm_unreachable("conformance requirements are handled elsewhere");
+  default:
+    return;
   }
 }
 
@@ -1774,6 +1838,7 @@
       break;
 
     case ConstraintKind::ApplicableFunction:
+    case ConstraintKind::DynamicCallableApplicableFunction:
     case ConstraintKind::BindOverload:
     case ConstraintKind::BridgingConversion:
     case ConstraintKind::CheckedCast:
@@ -1924,14 +1989,6 @@
     case TypeKind::Function: {
       auto func1 = cast<FunctionType>(desugar1);
       auto func2 = cast<FunctionType>(desugar2);
-
-      // If the 2nd type is an autoclosure, then we don't actually want to
-      // treat these as parallel. The first type needs wrapping in a closure
-      // despite already being a function type.
-      if (!func1->isAutoClosure() && func2->isAutoClosure()) {
-        increaseScore(SK_FunctionConversion);
-        break;
-      }
       return matchFunctionTypes(func1, func2, kind, flags, locator);
     }
 
@@ -2144,15 +2201,6 @@
       conversionsOrFixes.push_back(
         ConversionRestrictionKind::LValueToRValue);
 
-    // An expression can be converted to an auto-closure function type, creating
-    // an implicit closure.
-    if (auto function2 = type2->getAs<FunctionType>()) {
-      if (function2->isAutoClosure())
-        return matchTypes(
-            type1, function2->getResult(), kind, subflags,
-            locator.withPathElement(ConstraintLocator::AutoclosureResult));
-    }
-
     // It is never legal to form an autoclosure that results in these
     // implicit conversions to pointer types.
     bool isAutoClosureArgument = false;
@@ -2407,9 +2455,9 @@
           TreatRValueAsLValue::create(*this, getConstraintLocator(locator)));
   }
 
+  // Attempt to repair any failures identifiable at this point.
   if (attemptFixes)
-    attemptToFixRequirementFailure(*this, type1, type2, conversionsOrFixes,
-                                   locator);
+    repairFailures(*this, type1, type2, conversionsOrFixes, locator);
 
   if (conversionsOrFixes.empty()) {
     // If one of the types is a type variable or member thereof, we leave this
@@ -3030,34 +3078,51 @@
   return known->second;
 }
 
-
 /// Return true if the specified type or a super-class/super-protocol has the
 /// @dynamicMemberLookup attribute on it.  This implementation is not
 /// particularly fast in the face of deep class hierarchies or lots of protocol
 /// conformances, but this is fine because it doesn't get invoked in the normal
 /// name lookup path (only when lookup is about to fail).
-static bool hasDynamicMemberLookupAttribute(CanType ty,
-                    llvm::DenseMap<CanType, bool> &IsDynamicMemberLookupCache) {
-  auto it = IsDynamicMemberLookupCache.find(ty);
-  if (it != IsDynamicMemberLookupCache.end()) return it->second;
-  
-  auto calculate = [&]()-> bool {
-    // If this is a protocol composition, check to see if any of the protocols
-    // have the attribute on them.
-    if (auto protocolComp = ty->getAs<ProtocolCompositionType>()) {
-      for (auto p : protocolComp->getMembers())
-        if (hasDynamicMemberLookupAttribute(p->getCanonicalType(),
-                                            IsDynamicMemberLookupCache))
-          return true;
-      return false;
+static bool hasDynamicMemberLookupAttribute(Type type,
+                    llvm::DenseMap<CanType, bool> &DynamicMemberLookupCache) {
+  auto canType = type->getCanonicalType();
+  auto it = DynamicMemberLookupCache.find(canType);
+  if (it != DynamicMemberLookupCache.end()) return it->second;
+
+  // Calculate @dynamicMemberLookup attribute for composite types with multiple
+  // components (protocol composition types and archetypes).
+  auto calculateForComponentTypes =
+      [&](ArrayRef<Type> componentTypes) -> bool {
+    for (auto componentType : componentTypes)
+      if (hasDynamicMemberLookupAttribute(componentType,
+                                          DynamicMemberLookupCache))
+        return true;
+    return false;
+  };
+
+  auto calculate = [&]() -> bool {
+    // If this is an archetype type, check if any types it conforms to
+    // (superclass or protocols) have the attribute.
+    if (auto archetype = dyn_cast<ArchetypeType>(canType)) {
+      SmallVector<Type, 2> componentTypes;
+      for (auto protocolDecl : archetype->getConformsTo())
+        componentTypes.push_back(protocolDecl->getDeclaredType());
+      if (auto superclass = archetype->getSuperclass())
+        componentTypes.push_back(superclass);
+      return calculateForComponentTypes(componentTypes);
     }
-    
-    // Otherwise this has to be a nominal type.
-    auto nominal = ty->getAnyNominal();
-    if (!nominal) return false;  // Dynamic lookups don't exist on tuples, etc.
-    
-    // If any of the protocols this type conforms to has the attribute, then
-    // yes.
+
+    // If this is a protocol composition, check if any of its members have the
+    // attribute.
+    if (auto protocolComp = dyn_cast<ProtocolCompositionType>(canType))
+      return calculateForComponentTypes(protocolComp->getMembers());
+
+    // Otherwise, this must be a nominal type.
+    // Dynamic member lookup doesn't work for tuples, etc.
+    auto nominal = canType->getAnyNominal();
+    if (!nominal) return false;
+
+    // If this type conforms to a protocol with the attribute, then return true.
     for (auto p : nominal->getAllProtocols())
       if (p->getAttrs().hasAttribute<DynamicMemberLookupAttr>())
         return true;
@@ -3086,11 +3151,9 @@
   };
   
   auto result = calculate();
-  
-  // Cache this if we can.
-  if (!ty->hasTypeVariable())
-    IsDynamicMemberLookupCache[ty] = result;
-  
+  // Cache the result if the type does not contain type variables.
+  if (!type->hasTypeVariable())
+    DynamicMemberLookupCache[canType] = result;
   return result;
 }
 
@@ -3499,32 +3562,32 @@
   }
   
   // If we're about to fail lookup, but we are looking for members in a type
-  // that has the @dynamicMemberLookup attribute, then we resolve the reference
-  // to the subscript(dynamicMember:) member, and pass the member name as a
-  // string.
+  // with the @dynamicMemberLookup attribute, then we resolve a reference
+  // to a `subscript(dynamicMember:)` method and pass the member name as a
+  // string parameter.
   if (result.ViableCandidates.empty() &&
       constraintKind == ConstraintKind::ValueMember &&
       memberName.isSimpleName() && !memberName.isSpecial()) {
     auto name = memberName.getBaseIdentifier();
-    if (hasDynamicMemberLookupAttribute(instanceTy->getCanonicalType(),
-                                        IsDynamicMemberLookupCache)) {
+    // TC.extract
+    if (hasDynamicMemberLookupAttribute(instanceTy, DynamicMemberLookupCache)) {
       auto &ctx = getASTContext();
-      // Recursively look up the subscript(dynamicMember:)'s in this type.
+
+      // Recursively look up `subscript(dynamicMember:)` methods in this type.
       auto subscriptName =
         DeclName(ctx, DeclBaseName::createSubscript(), ctx.Id_dynamicMember);
-
       auto subscripts = performMemberLookup(constraintKind,
                                             subscriptName,
                                             baseTy, functionRefKind,
                                             memberLocator,
                                             includeInaccessibleMembers);
         
-      // Reflect the candidates found as DynamicMemberLookup results.
+      // Reflect the candidates found as `DynamicMemberLookup` results.
       for (auto candidate : subscripts.ViableCandidates) {
         auto decl = cast<SubscriptDecl>(candidate.getDecl());
-        if (isAcceptableDynamicMemberLookupSubscript(decl, DC, TC))
-          result.addViable(OverloadChoice::getDynamicMemberLookup(baseTy,
-                                                                  decl, name));
+        if (isValidDynamicMemberLookupSubscript(decl, DC, TC))
+          result.addViable(
+            OverloadChoice::getDynamicMemberLookup(baseTy, decl, name));
       }
       for (auto candidate : subscripts.UnviableCandidates) {
         auto decl = candidate.first.getDecl();
@@ -4429,6 +4492,10 @@
   ConstraintLocatorBuilder outerLocator =
     getConstraintLocator(anchor, parts, locator.getSummaryFlags());
 
+  // Before stripping optional types, save original type for handling
+  // @dynamicCallable applications. This supports the fringe case where
+  // `Optional` itself is extended with @dynamicCallable functionality.
+  auto origType2 = desugar2;
   unsigned unwrapCount = 0;
   if (shouldAttemptFixes()) {
     // If we have an optional type, try forcing it to see if that
@@ -4497,7 +4564,287 @@
     return simplified;
   }
 
-  return SolutionKind::Error;
+  // Handle applications of @dynamicCallable types.
+  return simplifyDynamicCallableApplicableFnConstraint(type1, origType2,
+                                                       subflags, locator);
+}
+
+/// Looks up and returns the @dynamicCallable required methods (if they exist)
+/// implemented by a type.
+static llvm::DenseSet<FuncDecl *>
+lookupDynamicCallableMethods(Type type, ConstraintSystem &CS,
+                             const ConstraintLocatorBuilder &locator,
+                             Identifier argumentName, bool hasKeywordArgs) {
+  auto &ctx = CS.getASTContext();
+  auto decl = type->getAnyNominal();
+  auto methodName = DeclName(ctx, ctx.Id_dynamicallyCall, { argumentName });
+  auto matches = CS.performMemberLookup(ConstraintKind::ValueMember,
+                                        methodName, type,
+                                        FunctionRefKind::SingleApply,
+                                        CS.getConstraintLocator(locator),
+                                        /*includeInaccessibleMembers*/ false);
+  // Filter valid candidates.
+  auto candidates = matches.ViableCandidates;
+  auto filter = [&](OverloadChoice choice) {
+    auto cand = cast<FuncDecl>(choice.getDecl());
+    return !isValidDynamicCallableMethod(cand, decl, CS.TC, hasKeywordArgs);
+  };
+  candidates.erase(
+      std::remove_if(candidates.begin(), candidates.end(), filter),
+      candidates.end());
+
+  llvm::DenseSet<FuncDecl *> methods;
+  for (auto candidate : candidates)
+    methods.insert(cast<FuncDecl>(candidate.getDecl()));
+  return methods;
+}
+
+/// Looks up and returns the @dynamicCallable required methods (if they exist)
+/// implemented by a type. This function should not be called directly:
+/// instead, call `getDynamicCallableMethods` which performs caching.
+static DynamicCallableMethods
+lookupDynamicCallableMethods(Type type, ConstraintSystem &CS,
+                             const ConstraintLocatorBuilder &locator) {
+  auto &ctx = CS.getASTContext();
+  DynamicCallableMethods methods;
+  methods.argumentsMethods =
+    lookupDynamicCallableMethods(type, CS, locator, ctx.Id_withArguments,
+                                 /*hasKeywordArgs*/ false);
+  methods.keywordArgumentsMethods =
+    lookupDynamicCallableMethods(type, CS, locator,
+                                 ctx.Id_withKeywordArguments,
+                                 /*hasKeywordArgs*/ true);
+  return methods;
+}
+
+/// Returns the @dynamicCallable required methods (if they exist) implemented
+/// by a type.
+/// This function may be slow for deep class hierarchies and multiple protocol
+/// conformances, but it is invoked only after other constraint simplification
+/// rules fail.
+static DynamicCallableMethods
+getDynamicCallableMethods(Type type, ConstraintSystem &CS,
+                          const ConstraintLocatorBuilder &locator) {
+  auto canType = type->getCanonicalType();
+  auto it = CS.DynamicCallableCache.find(canType);
+  if (it != CS.DynamicCallableCache.end()) return it->second;
+
+  // Calculate @dynamicCallable methods for composite types with multiple
+  // components (protocol composition types and archetypes).
+  auto calculateForComponentTypes =
+      [&](ArrayRef<Type> componentTypes) -> DynamicCallableMethods {
+    DynamicCallableMethods methods;
+    for (auto componentType : componentTypes) {
+      auto tmp = getDynamicCallableMethods(componentType, CS, locator);
+      methods.argumentsMethods.insert(tmp.argumentsMethods.begin(),
+                                      tmp.argumentsMethods.end());
+      methods.keywordArgumentsMethods.insert(
+          tmp.keywordArgumentsMethods.begin(),
+          tmp.keywordArgumentsMethods.end());
+    }
+    return methods;
+  };
+
+  // Calculate @dynamicCallable methods.
+  auto calculate = [&]() -> DynamicCallableMethods {
+    // If this is an archetype type, check if any types it conforms to
+    // (superclass or protocols) have the attribute.
+    if (auto archetype = dyn_cast<ArchetypeType>(canType)) {
+      SmallVector<Type, 2> componentTypes;
+      for (auto protocolDecl : archetype->getConformsTo())
+        componentTypes.push_back(protocolDecl->getDeclaredType());
+      if (auto superclass = archetype->getSuperclass())
+        componentTypes.push_back(superclass);
+      return calculateForComponentTypes(componentTypes);
+    }
+
+    // If this is a protocol composition, check if any of its members have the
+    // attribute.
+    if (auto protocolComp = dyn_cast<ProtocolCompositionType>(canType))
+      return calculateForComponentTypes(protocolComp->getMembers());
+
+    // Otherwise, this must be a nominal type.
+    // Dynamic calling doesn't work for tuples, etc.
+    auto nominal = canType->getAnyNominal();
+    if (!nominal) return DynamicCallableMethods();
+
+    // If this type conforms to a protocol which has the attribute, then
+    // look up the methods.
+    for (auto p : nominal->getAllProtocols())
+      if (p->getAttrs().hasAttribute<DynamicCallableAttr>())
+        return lookupDynamicCallableMethods(type, CS, locator);
+
+    // Walk superclasses, if present.
+    llvm::SmallPtrSet<const NominalTypeDecl*, 8> visitedDecls;
+    while (1) {
+      // If we found a circular parent class chain, reject this.
+      if (!visitedDecls.insert(nominal).second)
+        return DynamicCallableMethods();
+
+      // If this type has the attribute on it, then look up the methods.
+      if (nominal->getAttrs().hasAttribute<DynamicCallableAttr>())
+        return lookupDynamicCallableMethods(type, CS, locator);
+
+      // If this type is a class with a superclass, check superclasses.
+      if (auto *cd = dyn_cast<ClassDecl>(nominal)) {
+        if (auto superClass = cd->getSuperclassDecl()) {
+          nominal = superClass;
+          continue;
+        }
+      }
+
+      return DynamicCallableMethods();
+    }
+  };
+
+  auto result = calculate();
+  // Cache the result if the type does not contain type variables.
+  if (!type->hasTypeVariable())
+    CS.DynamicCallableCache[canType] = result;
+  return result;
+}
+
+ConstraintSystem::SolutionKind
+ConstraintSystem::simplifyDynamicCallableApplicableFnConstraint(
+                                            Type type1,
+                                            Type type2,
+                                            TypeMatchOptions flags,
+                                            ConstraintLocatorBuilder locator) {
+  auto &ctx = getASTContext();
+
+  // By construction, the left hand side is a function type: $T1 -> $T2.
+  assert(type1->is<FunctionType>());
+
+  // Drill down to the concrete type on the right hand side.
+  type2 = getFixedTypeRecursive(type2, flags, /*wantRValue=*/true);
+  auto desugar2 = type2->getDesugaredType();
+
+  TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);
+
+  // If the types are obviously equivalent, we're done.
+  if (type1.getPointer() == desugar2)
+    return SolutionKind::Solved;
+
+  // Local function to form an unsolved result.
+  auto formUnsolved = [&] {
+    if (flags.contains(TMF_GenerateConstraints)) {
+      addUnsolvedConstraint(
+        Constraint::create(*this,
+          ConstraintKind::DynamicCallableApplicableFunction, type1, type2,
+          getConstraintLocator(locator)));
+      return SolutionKind::Solved;
+    }
+    return SolutionKind::Unsolved;
+  };
+
+  // If right-hand side is a type variable, the constraint is unsolved.
+  if (desugar2->isTypeVariableOrMember())
+    return formUnsolved();
+
+  // If right-hand side is a function type, it must be a valid
+  // `dynamicallyCall` method type. Bind the output and convert the argument
+  // to the input.
+  auto func1 = type1->castTo<FunctionType>();
+  if (auto func2 = dyn_cast<FunctionType>(desugar2)) {
+    // The argument type must be convertible to the input type.
+    assert(func1->getParams().size() == 1 && func2->getParams().size() == 1 &&
+           "Expected `dynamicallyCall` method with one parameter");
+    assert((func2->getParams()[0].getLabel() == ctx.Id_withArguments ||
+            func2->getParams()[0].getLabel() == ctx.Id_withKeywordArguments) &&
+           "Expected 'dynamicallyCall' method argument label 'withArguments' "
+           "or 'withKeywordArguments'");
+    if (matchTypes(func1->getParams()[0].getPlainType(),
+                   func2->getParams()[0].getPlainType(),
+                   ConstraintKind::ArgumentConversion,
+                   subflags,
+                   locator.withPathElement(
+                     ConstraintLocator::ApplyArgument)).isFailure())
+      return SolutionKind::Error;
+
+    // The result types are equivalent.
+    if (matchTypes(func1->getResult(),
+                   func2->getResult(),
+                   ConstraintKind::Bind,
+                   subflags,
+                   locator.withPathElement(
+                     ConstraintLocator::FunctionResult)).isFailure())
+      return SolutionKind::Error;
+
+    return SolutionKind::Solved;
+  }
+
+  // If the right-hand side is not a function type, it must be a valid
+  // @dynamicCallable type. Attempt to get valid `dynamicallyCall` methods.
+  auto methods = getDynamicCallableMethods(desugar2, *this, locator);
+  if (!methods.isValid()) return SolutionKind::Error;
+
+  // Determine whether to call a `withArguments` method or a
+  // `withKeywordArguments` method.
+  bool useKwargsMethod = methods.argumentsMethods.empty();
+  useKwargsMethod |= llvm::any_of(
+    func1->getParams(), [](AnyFunctionType::Param p) { return p.hasLabel(); });
+
+  auto candidates = useKwargsMethod ?
+    methods.keywordArgumentsMethods :
+    methods.argumentsMethods;
+
+  // Create a type variable for the `dynamicallyCall` method.
+  auto loc = getConstraintLocator(locator);
+  auto tv = createTypeVariable(loc, TVO_CanBindToLValue);
+
+  // Record the 'dynamicallyCall` method overload set.
+  SmallVector<OverloadChoice, 4> choices;
+  for (auto candidate : candidates) {
+    TC.validateDecl(candidate);
+    if (candidate->isInvalid()) continue;
+    choices.push_back(
+      OverloadChoice(type2, candidate, FunctionRefKind::SingleApply));
+  }
+  if (choices.empty()) return SolutionKind::Error;
+  addOverloadSet(tv, choices, DC, loc);
+
+  // Create a type variable for the argument to the `dynamicallyCall` method.
+  auto tvParam = createTypeVariable(loc);
+  AnyFunctionType *funcType =
+    FunctionType::get({ AnyFunctionType::Param(tvParam) }, func1->getResult());
+  addConstraint(ConstraintKind::DynamicCallableApplicableFunction,
+                funcType, tv, locator);
+
+  // Get argument type for the `dynamicallyCall` method.
+  Type argumentType;
+  if (!useKwargsMethod) {
+    auto arrayLitProto =
+      ctx.getProtocol(KnownProtocolKind::ExpressibleByArrayLiteral);
+    addConstraint(ConstraintKind::ConformsTo, tvParam,
+                  arrayLitProto->getDeclaredType(), locator);
+    auto elementAssocType = cast<AssociatedTypeDecl>(
+      arrayLitProto->lookupDirect(ctx.Id_ArrayLiteralElement).front());
+    argumentType = DependentMemberType::get(tvParam, elementAssocType);
+  } else {
+    auto dictLitProto =
+      ctx.getProtocol(KnownProtocolKind::ExpressibleByDictionaryLiteral);
+    addConstraint(ConstraintKind::ConformsTo, tvParam,
+                  dictLitProto->getDeclaredType(), locator);
+    auto valueAssocType = cast<AssociatedTypeDecl>(
+      dictLitProto->lookupDirect(ctx.Id_Value).front());
+    argumentType = DependentMemberType::get(tvParam, valueAssocType);
+  }
+
+  // Argument type can default to `Any`.
+  addConstraint(ConstraintKind::Defaultable, argumentType,
+                ctx.TheAnyType, locator);
+
+  // All dynamic call parameter types must be convertible to the argument type.
+  for (auto i : indices(func1->getParams())) {
+    auto param = func1->getParams()[i];
+    auto paramType = param.getPlainType();
+    auto locatorBuilder =
+    locator.withPathElement(LocatorPathElt::getTupleElement(i));
+    addConstraint(ConstraintKind::ArgumentConversion, paramType,
+                  argumentType, locatorBuilder);
+  }
+
+  return SolutionKind::Solved;
 }
 
 static Type getBaseTypeForPointer(ConstraintSystem &cs, TypeBase *type) {
@@ -5047,7 +5394,8 @@
   }
 
   case FixKind::SkipSameTypeRequirement:
-  case FixKind::SkipSuperclassRequirement: {
+  case FixKind::SkipSuperclassRequirement:
+  case FixKind::ContextualMismatch: {
     return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
   }
 
@@ -5087,6 +5435,10 @@
   case ConstraintKind::ApplicableFunction:
     return simplifyApplicableFnConstraint(first, second, subflags, locator);
 
+  case ConstraintKind::DynamicCallableApplicableFunction:
+    return simplifyDynamicCallableApplicableFnConstraint(first, second,
+                                                         subflags, locator);
+
   case ConstraintKind::DynamicTypeOf:
     return simplifyDynamicTypeOfConstraint(first, second, subflags, locator);
 
@@ -5364,6 +5716,11 @@
                                           constraint.getSecondType(),
                                           None, constraint.getLocator());
 
+  case ConstraintKind::DynamicCallableApplicableFunction:
+    return simplifyDynamicCallableApplicableFnConstraint(
+      constraint.getFirstType(), constraint.getSecondType(), None,
+      constraint.getLocator());
+
   case ConstraintKind::DynamicTypeOf:
     return simplifyDynamicTypeOfConstraint(constraint.getFirstType(),
                                            constraint.getSecondType(),
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 64d2f54..93885ec 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1550,6 +1550,7 @@
       case ConstraintKind::CheckedCast:
       case ConstraintKind::OpenedExistentialOf:
       case ConstraintKind::ApplicableFunction:
+      case ConstraintKind::DynamicCallableApplicableFunction:
       case ConstraintKind::BindOverload:
       case ConstraintKind::FunctionInput:
       case ConstraintKind::FunctionResult:
@@ -1750,6 +1751,9 @@
 
   for (auto *protocol : argInfo.getLiteralProtocols()) {
     auto defaultType = TC.getDefaultType(protocol, DC);
+    // ExpressibleByNilLiteral does not have a default type.
+    if (!defaultType)
+      continue;
     auto *nominal = defaultType->getAnyNominal();
     for (size_t i = nextType + 1; i < nominalTypes.size(); ++i) {
       if (nominal == nominalTypes[i]) {
@@ -1784,10 +1788,7 @@
     auto *funcDecl = cast<FuncDecl>(decl);
 
     auto *parentDC = funcDecl->getParent();
-    auto *parentDecl = parentDC->getAsDecl();
-
-    if (parentDC->isExtensionContext())
-      parentDecl = cast<ExtensionDecl>(parentDecl)->getExtendedNominal();
+    auto *parentDecl = parentDC->getSelfNominalTypeDecl();
 
     for (auto designatedTypeIndex : indices(designatedNominalTypes)) {
       auto *designatedNominal =
@@ -1797,7 +1798,7 @@
         continue;
 
       auto &constraints =
-          parentDC->isExtensionContext()
+          isa<ExtensionDecl>(parentDC)
               ? definedInExtensionOfDesignatedType[designatedTypeIndex]
               : definedInDesignatedType[designatedTypeIndex];
 
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 900c52a..2b05607 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -222,7 +222,7 @@
 
   auto getter = AccessorDecl::create(
       TC.Context, loc, /*AccessorKeywordLoc*/ loc,
-      AccessorKind::Get, AddressorKind::NotAddressor, storage,
+      AccessorKind::Get, storage,
       staticLoc, StaticSpellingKind::None,
       /*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
       genericParams,
@@ -255,6 +255,9 @@
   if (storage->isStatic())
     getter->setStatic();
 
+  if (!storage->requiresOpaqueAccessor(AccessorKind::Get))
+    getter->setForcedStaticDispatch(true);
+
   // Always add the getter to the context immediately after the storage.
   addMemberToContextIfNeeded(getter, storage->getDeclContext(), storage);
 
@@ -284,7 +287,7 @@
   Type setterRetTy = TupleType::getEmpty(TC.Context);
   auto setter = AccessorDecl::create(
       TC.Context, loc, /*AccessorKeywordLoc*/ SourceLoc(),
-      AccessorKind::Set, AddressorKind::NotAddressor, storage,
+      AccessorKind::Set, storage,
       /*StaticLoc=*/SourceLoc(), StaticSpellingKind::None,
       /*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
       genericParams, params,
@@ -298,22 +301,18 @@
   if (isStatic)
     setter->setStatic();
 
+  // All mutable storage requires a setter.
+  assert(storage->requiresOpaqueAccessor(AccessorKind::Set));
+
   // Always add the setter to the context immediately after the getter.
   if (!getter) getter = storage->getGetter();
-  assert(getter && "always synthesize setter prototype after getter");
+  if (!getter) getter = storage->getReadCoroutine();
+  assert(getter && "always synthesize setter prototype after get/read");
   addMemberToContextIfNeeded(setter, storage->getDeclContext(), getter);
 
   return setter;
 }
 
-// True if the storage is dynamic or imported from Objective-C. In these cases,
-// we need to emit static coroutine accessors that dynamically dispatch
-// to 'get' and 'set', rather than the normal dynamically dispatched
-// opaque accessors that peer dispatch to 'get' and 'set'.
-static bool needsDynamicCoroutineAccessors(AbstractStorageDecl *storage) {
-  return storage->isDynamic() || storage->hasClangNode();
-}
-
 /// Mark the accessor as transparent if we can.
 ///
 /// If the storage is inside a fixed-layout nominal type, we can mark the
@@ -401,7 +400,7 @@
 
   auto *accessor = AccessorDecl::create(
       ctx, loc, /*AccessorKeywordLoc=*/SourceLoc(),
-      kind, AddressorKind::NotAddressor, storage,
+      kind, storage,
       /*StaticLoc=*/SourceLoc(), StaticSpellingKind::None,
       /*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
       genericParams, params, TypeLoc::withoutLoc(retTy), dc);
@@ -417,11 +416,11 @@
   if (storage->isFinal())
     makeFinal(ctx, accessor);
 
-  // If the storage is dynamic or ObjC-native, we can't add a dynamically-
-  // dispatched method entry for the accessor, so force it to be
-  // statically dispatched. ("final" would be inappropriate because the
-  // property can still be overridden.)
-  if (needsDynamicCoroutineAccessors(storage))
+  // If the storage does not provide this accessor as an opaque accessor,
+  // we can't add a dynamically-dispatched method entry for the accessor,
+  // so force it to be statically dispatched. ("final" would be inappropriate
+  // because the property can still be overridden.)
+  if (!storage->requiresOpaqueAccessor(kind))
     accessor->setForcedStaticDispatch(true);
 
   // Make sure the coroutine is available enough to access
@@ -486,6 +485,16 @@
       ref = new (ctx) InOutExpr(SourceLoc(), ref, Type(), /*isImplicit=*/true);
     else if (param->isVariadic())
       ref = new (ctx) VarargExpansionExpr(ref, /*implicit*/ true);
+    else if (param->isAutoClosure()) {
+      // If parameter is marked as `@autoclosure` it means
+      // that it has to be called.
+      auto arg = TupleExpr::createEmpty(ctx, SourceLoc(), SourceLoc(),
+                                        /*implicit=*/true);
+      ref = CallExpr::create(ctx, ref, arg, {}, {},
+                             /*hasTrailingClosure=*/false,
+                             /*implicit=*/true);
+    }
+
     args.push_back(ref);
     
     labels.push_back(param->getArgumentName());
@@ -2092,6 +2101,11 @@
 }
 
 static void synthesizeGetterBody(TypeChecker &TC, AccessorDecl *getter) {
+  if (getter->hasForcedStaticDispatch()) {
+    synthesizeTrivialGetterBody(TC, getter, TargetImpl::Ordinary);
+    return;
+  }
+
   switch (getter->getStorage()->getReadImpl()) {
   case ReadImplKind::Stored:
     synthesizeTrivialGetterBody(TC, getter);
@@ -2459,11 +2473,12 @@
   }
 
   // Wire up the overrides.
-  ctor->getAttrs().add(new (ctx) OverrideAttr(/*IsImplicit=*/true));
   ctor->setOverriddenDecl(superclassCtor);
 
   if (superclassCtor->isRequired())
-    ctor->getAttrs().add(new (ctx) RequiredAttr(/*IsImplicit=*/true));
+    ctor->getAttrs().add(new (ctx) RequiredAttr(/*IsImplicit=*/false));
+  else
+    ctor->getAttrs().add(new (ctx) OverrideAttr(/*IsImplicit=*/false));
 
   // If the superclass constructor is @objc but the subclass constructor is
   // not representable in Objective-C, add @nonobjc implicitly.
diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp
index 22bc83d..5098973 100644
--- a/lib/Sema/Constraint.cpp
+++ b/lib/Sema/Constraint.cpp
@@ -69,6 +69,7 @@
     assert(!Second.isNull());
     break;
   case ConstraintKind::ApplicableFunction:
+  case ConstraintKind::DynamicCallableApplicableFunction:
     assert(First->is<FunctionType>()
            && "The left-hand side type should be a function type");
     break;
@@ -123,6 +124,7 @@
   case ConstraintKind::OpenedExistentialOf:
   case ConstraintKind::OptionalObject:
   case ConstraintKind::ApplicableFunction:
+  case ConstraintKind::DynamicCallableApplicableFunction:
   case ConstraintKind::ValueMember:
   case ConstraintKind::UnresolvedValueMember:
   case ConstraintKind::Defaultable:
@@ -227,6 +229,7 @@
   case ConstraintKind::OpenedExistentialOf:
   case ConstraintKind::SelfObjectOfProtocol:
   case ConstraintKind::ApplicableFunction:
+  case ConstraintKind::DynamicCallableApplicableFunction:
   case ConstraintKind::OptionalObject:
   case ConstraintKind::Defaultable:
   case ConstraintKind::FunctionInput:
@@ -297,6 +300,8 @@
   case ConstraintKind::CheckedCast: Out << " checked cast to "; break;
   case ConstraintKind::SelfObjectOfProtocol: Out << " Self type of "; break;
   case ConstraintKind::ApplicableFunction: Out << " applicable fn "; break;
+  case ConstraintKind::DynamicCallableApplicableFunction:
+      Out << " dynamic callable applicable fn "; break;
   case ConstraintKind::DynamicTypeOf: Out << " dynamicType type of "; break;
   case ConstraintKind::EscapableFunctionOf: Out << " @escaping type of "; break;
   case ConstraintKind::OpenedExistentialOf: Out << " opened archetype of "; break;
@@ -487,6 +492,7 @@
     LLVM_FALLTHROUGH;
 
   case ConstraintKind::ApplicableFunction:
+  case ConstraintKind::DynamicCallableApplicableFunction:
   case ConstraintKind::Bind:
   case ConstraintKind::BindParam:
   case ConstraintKind::BindToPointerType:
diff --git a/lib/Sema/Constraint.h b/lib/Sema/Constraint.h
index f2f9cd0..9f5bd4a 100644
--- a/lib/Sema/Constraint.h
+++ b/lib/Sema/Constraint.h
@@ -97,6 +97,12 @@
   /// function type is expected to become a function type. Note, we
   /// do not require the function type attributes to match.
   ApplicableFunction,
+  /// \brief The first type is a function type whose input is the value passed
+  /// to the function and whose output is a type variable describing the output.
+  /// The second type is either a `@dynamicCallable` nominal type or the
+  /// function type of a `dynamicallyCall` method defined on a
+  /// `@dynamicCallable` nominal type.
+  DynamicCallableApplicableFunction,
   /// \brief The first type is the type of the dynamicType member of the
   /// second type.
   DynamicTypeOf,
@@ -472,6 +478,7 @@
     case ConstraintKind::CheckedCast:
     case ConstraintKind::SelfObjectOfProtocol:
     case ConstraintKind::ApplicableFunction:
+    case ConstraintKind::DynamicCallableApplicableFunction:
     case ConstraintKind::BindOverload:
     case ConstraintKind::OptionalObject:
       return ConstraintClassification::Relational;
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index 73d3f1b..51a674e 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -1560,7 +1560,6 @@
     FunctionType::Param arg(escapeClosure);
     auto bodyClosure = FunctionType::get(arg, result,
         FunctionType::ExtInfo(FunctionType::Representation::Swift,
-                              /*autoclosure*/ false,
                               /*noescape*/ true,
                               /*throws*/ true));
     FunctionType::Param args[] = {
@@ -1570,7 +1569,6 @@
     
     refType = FunctionType::get(args, result,
       FunctionType::ExtInfo(FunctionType::Representation::Swift,
-                            /*autoclosure*/ false,
                             /*noescape*/ false,
                             /*throws*/ true));
     openedFullType = refType;
@@ -1591,7 +1589,6 @@
     FunctionType::Param bodyArgs[] = {FunctionType::Param(openedTy)};
     auto bodyClosure = FunctionType::get(bodyArgs, result,
         FunctionType::ExtInfo(FunctionType::Representation::Swift,
-                              /*autoclosure*/ false,
                               /*noescape*/ true,
                               /*throws*/ true));
     FunctionType::Param args[] = {
@@ -1600,7 +1597,6 @@
     };
     refType = FunctionType::get(args, result,
       FunctionType::ExtInfo(FunctionType::Representation::Swift,
-                            /*autoclosure*/ false,
                             /*noescape*/ false,
                             /*throws*/ true));
     openedFullType = refType;
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 1e29f70..7baa8be 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -906,8 +906,28 @@
   }
   
 };
-  
-  
+
+/// \brief Stores the required methods for @dynamicCallable types.
+struct DynamicCallableMethods {
+  llvm::DenseSet<FuncDecl *> argumentsMethods;
+  llvm::DenseSet<FuncDecl *> keywordArgumentsMethods;
+
+  void addArgumentsMethod(FuncDecl *method) {
+    argumentsMethods.insert(method);
+  }
+
+  void addKeywordArgumentsMethod(FuncDecl *method) {
+    keywordArgumentsMethods.insert(method);
+  }
+
+  /// \brief Returns true if type defines either of the @dynamicCallable
+  /// required methods. Returns false iff type does not satisfy @dynamicCallable
+  /// requirements.
+  bool isValid() const {
+    return !argumentsMethods.empty() || !keywordArgumentsMethods.empty();
+  }
+};
+
 /// \brief Describes a system of constraints on type variables, the
 /// solution of which assigns concrete types to each of the type variables.
 /// Constraint systems are typically generated given an (untyped) expression.
@@ -1061,10 +1081,13 @@
   /// The locators of \c Defaultable constraints whose defaults were used.
   SmallVector<ConstraintLocator *, 8> DefaultedConstraints;
 
-  /// This is a cache that keeps track of whether a given type is known (or not)
-  /// to be a @dynamicMemberLookup type.
-  ///
-  llvm::DenseMap<CanType, bool> IsDynamicMemberLookupCache;
+  /// A cache that stores the @dynamicCallable required methods implemented by
+  /// types.
+  llvm::DenseMap<CanType, DynamicCallableMethods> DynamicCallableCache;
+
+  /// A cache that stores whether types are valid @dynamicMemberLookup types.
+  llvm::DenseMap<CanType, bool> DynamicMemberLookupCache;
+
 private:
   /// \brief Describe the candidate expression for partial solving.
   /// This class used by shrink & solve methods which apply
@@ -2649,6 +2672,13 @@
                                       TypeMatchOptions flags,
                                       ConstraintLocatorBuilder locator);
 
+  /// \brief Attempt to simplify the DynamicCallableApplicableFunction constraint.
+  SolutionKind simplifyDynamicCallableApplicableFnConstraint(
+                                      Type type1,
+                                      Type type2,
+                                      TypeMatchOptions flags,
+                                      ConstraintLocatorBuilder locator);
+
   /// \brief Attempt to simplify the given DynamicTypeOf constraint.
   SolutionKind simplifyDynamicTypeOfConstraint(
                                          Type type1, Type type2,
diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp
index 1ab14a8..682cf20 100644
--- a/lib/Sema/DerivedConformanceEquatableHashable.cpp
+++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp
@@ -1077,7 +1077,7 @@
 
   AccessorDecl *getterDecl = AccessorDecl::create(C,
       /*FuncLoc=*/SourceLoc(), /*AccessorKeywordLoc=*/SourceLoc(),
-      AccessorKind::Get, AddressorKind::NotAddressor, hashValueDecl,
+      AccessorKind::Get, hashValueDecl,
       /*StaticLoc=*/SourceLoc(), StaticSpellingKind::None,
       /*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
       /*GenericParams=*/nullptr, params,
diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp
index 7b1cda9..ac9f044 100644
--- a/lib/Sema/DerivedConformances.cpp
+++ b/lib/Sema/DerivedConformances.cpp
@@ -290,7 +290,7 @@
   
   auto getterDecl = AccessorDecl::create(C,
     /*FuncLoc=*/SourceLoc(), /*AccessorKeywordLoc=*/SourceLoc(),
-    AccessorKind::Get, AddressorKind::NotAddressor, property,
+    AccessorKind::Get, property,
     /*StaticLoc=*/SourceLoc(), StaticSpellingKind::None,
     /*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
     /*GenericParams=*/nullptr, params,
diff --git a/lib/Sema/NameBinding.cpp b/lib/Sema/NameBinding.cpp
index 6f05d47..057f915 100644
--- a/lib/Sema/NameBinding.cpp
+++ b/lib/Sema/NameBinding.cpp
@@ -52,10 +52,9 @@
     InFlightDiagnostic diagnose(ArgTypes &&...Args) {
       return Context.Diags.diagnose(std::forward<ArgTypes>(Args)...);
     }
-    
-    void addImport(
-        SmallVectorImpl<std::pair<ImportedModule, ImportOptions>> &imports,
-        ImportDecl *ID);
+
+    void addImport(SmallVectorImpl<SourceFile::ImportedModuleDesc> &imports,
+                   ImportDecl *ID);
 
     /// Load a module referenced by an import statement.
     ///
@@ -168,8 +167,7 @@
 }
 
 void NameBinder::addImport(
-    SmallVectorImpl<std::pair<ImportedModule, ImportOptions>> &imports,
-    ImportDecl *ID) {
+    SmallVectorImpl<SourceFile::ImportedModuleDesc> &imports, ImportDecl *ID) {
   if (ID->getModulePath().front().first == SF.getParentModule()->getName() &&
       ID->getModulePath().size() == 1 && !shouldImportSelfImportClang(ID, SF)) {
     // If the imported module name is the same as the current module,
@@ -233,15 +231,33 @@
     testableAttr->setInvalid();
   }
 
+  auto *privateImportAttr = ID->getAttrs().getAttribute<PrivateImportAttr>();
+  StringRef privateImportFileName;
+  if (privateImportAttr) {
+    if (!topLevelModule->arePrivateImportsEnabled()) {
+      diagnose(ID->getModulePath().front().second,
+               diag::module_not_compiled_for_private_import,
+               topLevelModule->getName());
+      privateImportAttr->setInvalid();
+    } else {
+      privateImportFileName = privateImportAttr->getSourceFile();
+    }
+  }
+
   ImportOptions options;
   if (ID->isExported())
     options |= SourceFile::ImportFlags::Exported;
   if (testableAttr)
     options |= SourceFile::ImportFlags::Testable;
-  imports.push_back({ { ID->getDeclPath(), M }, options });
+  if (privateImportAttr)
+    options |= SourceFile::ImportFlags::PrivateImport;
+
+  imports.push_back(SourceFile::ImportedModuleDesc(
+      {ID->getDeclPath(), M}, options, privateImportFileName));
 
   if (topLevelModule != M)
-    imports.push_back({ { ID->getDeclPath(), topLevelModule }, options });
+    imports.push_back(SourceFile::ImportedModuleDesc(
+        {ID->getDeclPath(), topLevelModule}, options, privateImportFileName));
 
   if (ID->getImportKind() != ImportKind::Module) {
     // If we're importing a specific decl, validate the import kind.
@@ -367,7 +383,7 @@
 
   NameBinder Binder(SF);
 
-  SmallVector<std::pair<ImportedModule, ImportOptions>, 8> ImportedModules;
+  SmallVector<SourceFile::ImportedModuleDesc, 8> ImportedModules;
 
   // Do a prepass over the declarations to find and load the imported modules
   // and map operator decls.
diff --git a/lib/Sema/OverloadChoice.h b/lib/Sema/OverloadChoice.h
index 9cca7bf..101249b 100644
--- a/lib/Sema/OverloadChoice.h
+++ b/lib/Sema/OverloadChoice.h
@@ -183,7 +183,8 @@
   }
   
   /// Retrieve an overload choice for a declaration that was found via
-  /// dynamic lookup.  The ValueDecl is the subscript(dynamicMember:)
+  /// dynamic member lookup. The `ValueDecl` is a `subscript(dynamicMember:)`
+  /// method.
   static OverloadChoice getDynamicMemberLookup(Type base, ValueDecl *value,
                                                Identifier name) {
     OverloadChoice result;
diff --git a/lib/Sema/ResilienceDiagnostics.cpp b/lib/Sema/ResilienceDiagnostics.cpp
index 5cf0f3d..c25c233 100644
--- a/lib/Sema/ResilienceDiagnostics.cpp
+++ b/lib/Sema/ResilienceDiagnostics.cpp
@@ -58,11 +58,6 @@
         return std::make_pair(FragileFunctionKind::Inlinable,
                               /*treatUsableFromInlineAsPublic=*/true);
 
-      if (auto attr = AFD->getAttrs().getAttribute<InlineAttr>())
-        if (attr->getKind() == InlineKind::Always)
-          return std::make_pair(FragileFunctionKind::InlineAlways,
-                                /*treatUsableFromInlineAsPublic=*/true);
-
       // If a property or subscript is @inlinable, the accessors are
       // @inlinable also.
       if (auto accessor = dyn_cast<AccessorDecl>(AFD))
@@ -114,7 +109,7 @@
   // Dynamic declarations were mistakenly not checked in Swift 4.2.
   // Do enforce the restriction even in pre-Swift-5 modes if the module we're
   // building is resilient, though.
-  if (D->isDynamic() && !Context.isSwiftVersionAtLeast(5) &&
+  if (D->isObjCDynamic() && !Context.isSwiftVersionAtLeast(5) &&
       DC->getParentModule()->getResilienceStrategy() !=
         ResilienceStrategy::Resilient) {
     return false;
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index ff73e73..3eacaab 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -78,6 +78,7 @@
   IGNORED_ATTR(ClangImporterSynthesizedType)
   IGNORED_ATTR(Convenience)
   IGNORED_ATTR(DiscardableResult)
+  IGNORED_ATTR(DynamicCallable)
   IGNORED_ATTR(DynamicMemberLookup)
   IGNORED_ATTR(Effects)
   IGNORED_ATTR(Exported)
@@ -117,6 +118,8 @@
   IGNORED_ATTR(UnsafeNoObjCTaggedPointer)
   IGNORED_ATTR(UsableFromInline)
   IGNORED_ATTR(WeakLinked)
+  IGNORED_ATTR(DynamicReplacement)
+  IGNORED_ATTR(PrivateImport)
 #undef IGNORED_ATTR
 
   // @noreturn has been replaced with a 'Never' return type.
@@ -186,6 +189,32 @@
       TC.diagnose(attr->getLocation(), diag::alignment_not_power_of_two);
   }
 
+  void visitBorrowedAttr(BorrowedAttr *attr) {
+    // These criteria are the same preconditions laid out by
+    // AbstractStorageDecl::requiresOpaqueModifyCoroutine().
+
+    assert(!D->hasClangNode() && "@_borrowed on imported declaration?");
+
+    if (D->getAttrs().hasAttribute<DynamicAttr>()) {
+      TC.diagnose(attr->getLocation(), diag::borrowed_with_objc_dynamic,
+                  D->getDescriptiveKind())
+        .fixItRemove(attr->getRange());
+      D->getAttrs().removeAttribute(attr);
+      return;
+    }
+
+    auto dc = D->getDeclContext();
+    auto protoDecl = dyn_cast<ProtocolDecl>(dc);
+    if (protoDecl && protoDecl->isObjC()) {
+      TC.diagnose(attr->getLocation(),
+                  diag::borrowed_on_objc_protocol_requirement,
+                  D->getDescriptiveKind())
+        .fixItRemove(attr->getRange());
+      D->getAttrs().removeAttribute(attr);
+      return;
+    }
+  }
+
   void visitTransparentAttr(TransparentAttr *attr);
   void visitMutationAttr(DeclAttribute *attr);
   void visitMutatingAttr(MutatingAttr *attr) { visitMutationAttr(attr); }
@@ -256,7 +285,7 @@
   void visitAccessControlAttr(AccessControlAttr *attr);
   void visitSetterAccessAttr(SetterAccessAttr *attr);
   bool visitAbstractAccessControlAttr(AbstractAccessControlAttr *attr);
-  void visitSILStoredAttr(SILStoredAttr *attr);
+  void visitHasStorageAttr(HasStorageAttr *attr);
   void visitObjCMembersAttr(ObjCMembersAttr *attr);
 };
 } // end anonymous namespace
@@ -359,6 +388,11 @@
   // Members cannot be both dynamic and @nonobjc.
   if (D->getAttrs().hasAttribute<NonObjCAttr>())
     diagnoseAndRemoveAttr(attr, diag::dynamic_with_nonobjc);
+
+  // Members cannot be both dynamic and @_transparent.
+  if (D->getASTContext().LangOpts.isSwiftVersionAtLeast(5) &&
+      D->getAttrs().hasAttribute<TransparentAttr>())
+    diagnoseAndRemoveAttr(attr, diag::dynamic_with_transparent);
 }
 
 
@@ -394,7 +428,7 @@
                                  attr->getAttrName());
 }
 
-void AttributeEarlyChecker::visitSILStoredAttr(SILStoredAttr *attr) {
+void AttributeEarlyChecker::visitHasStorageAttr(HasStorageAttr *attr) {
   auto *VD = cast<VarDecl>(D);
   if (VD->getDeclContext()->getSelfClassDecl())
     return;
@@ -775,6 +809,7 @@
     void visit##CLASS##Attr(CLASS##Attr *) {}
 
     IGNORED_ATTR(Alignment)
+    IGNORED_ATTR(Borrowed)
     IGNORED_ATTR(HasInitialValue)
     IGNORED_ATTR(ClangImporterSynthesizedType)
     IGNORED_ATTR(Consuming)
@@ -784,6 +819,7 @@
     IGNORED_ATTR(Exported)
     IGNORED_ATTR(ForbidSerializingReference)
     IGNORED_ATTR(GKInspectable)
+    IGNORED_ATTR(HasStorage)
     IGNORED_ATTR(IBDesignable)
     IGNORED_ATTR(IBInspectable)
     IGNORED_ATTR(IBOutlet) // checked early.
@@ -811,19 +847,22 @@
     IGNORED_ATTR(Semantics)
     IGNORED_ATTR(ShowInInterface)
     IGNORED_ATTR(SILGenName)
-    IGNORED_ATTR(SILStored)
     IGNORED_ATTR(StaticInitializeObjCMetadata)
     IGNORED_ATTR(SynthesizedProtocol)
     IGNORED_ATTR(Testable)
     IGNORED_ATTR(Transparent)
     IGNORED_ATTR(WarnUnqualifiedAccess)
     IGNORED_ATTR(WeakLinked)
+    IGNORED_ATTR(DynamicReplacement)
+    IGNORED_ATTR(PrivateImport)
 #undef IGNORED_ATTR
 
   void visitAvailableAttr(AvailableAttr *attr);
   
   void visitCDeclAttr(CDeclAttr *attr);
 
+  void visitDynamicCallableAttr(DynamicCallableAttr *attr);
+
   void visitDynamicMemberLookupAttr(DynamicMemberLookupAttr *attr);
   
   void visitFinalAttr(FinalAttr *attr);
@@ -910,23 +949,115 @@
   return isiOS(TC) || iswatchOS(TC);
 }
 
-/// Given a subscript defined as "subscript(dynamicMember:)->T", return true if
-/// it is an acceptable implementation of the @dynamicMemberLookup attribute's
-/// requirement.
-bool swift::isAcceptableDynamicMemberLookupSubscript(SubscriptDecl *decl,
-                                                     DeclContext *DC,
-                                                     TypeChecker &TC) {
-  // The only thing that we care about is that the index list has exactly one
-  // non-variadic entry.  The type must conform to ExpressibleByStringLiteral.
+/// Returns true if the given method is an valid implementation of a
+/// @dynamicCallable attribute requirement. The method is given to be defined
+/// as one of the following: `dynamicallyCall(withArguments:)` or
+/// `dynamicallyCall(withKeywordArguments:)`.
+bool swift::isValidDynamicCallableMethod(FuncDecl *decl, DeclContext *DC,
+                                         TypeChecker &TC,
+                                         bool hasKeywordArguments) {
+  // There are two cases to check.
+  // 1. `dynamicallyCall(withArguments:)`.
+  //    In this case, the method is valid if the argument has type `A` where
+  //    `A` conforms to `ExpressibleByArrayLiteral`.
+  //    `A.ArrayLiteralElement` and the return type can be arbitrary.
+  // 2. `dynamicallyCall(withKeywordArguments:)`
+  //    In this case, the method is valid if the argument has type `D` where
+  //    `D` conforms to `ExpressibleByDictionaryLiteral` and `D.Key` conforms to
+  //    `ExpressibleByStringLiteral`.
+  //    `D.Value` and the return type can be arbitrary.
+
+  TC.validateDeclForNameLookup(decl);
+  auto paramList = decl->getParameters();
+  if (paramList->size() != 1 || paramList->get(0)->isVariadic()) return false;
+  auto argType = paramList->get(0)->getType();
+
+  // If non-keyword (positional) arguments, check that argument type conforms to
+  // `ExpressibleByArrayLiteral`.
+  if (!hasKeywordArguments) {
+    auto arrayLitProto =
+      TC.Context.getProtocol(KnownProtocolKind::ExpressibleByArrayLiteral);
+    return TC.conformsToProtocol(argType, arrayLitProto, DC,
+                                 ConformanceCheckOptions()).hasValue();
+  }
+  // If keyword arguments, check that argument type conforms to
+  // `ExpressibleByDictionaryLiteral` and that the `Key` associated type
+  // conforms to `ExpressibleByStringLiteral`.
+  auto stringLitProtocol =
+    TC.Context.getProtocol(KnownProtocolKind::ExpressibleByStringLiteral);
+  auto dictLitProto =
+    TC.Context.getProtocol(KnownProtocolKind::ExpressibleByDictionaryLiteral);
+  auto dictConf = TC.conformsToProtocol(argType, dictLitProto, DC,
+                                        ConformanceCheckOptions());
+  if (!dictConf) return false;
+  auto lookup = dictLitProto->lookupDirect(TC.Context.Id_Key);
+  auto keyAssocType =
+    cast<AssociatedTypeDecl>(lookup[0])->getDeclaredInterfaceType();
+  auto keyType = dictConf.getValue().getAssociatedType(argType, keyAssocType);
+  return TC.conformsToProtocol(keyType, stringLitProtocol, DC,
+                               ConformanceCheckOptions()).hasValue();
+}
+
+/// Returns true if the given nominal type has a valid implementation of a
+/// @dynamicCallable attribute requirement with the given argument name.
+static bool hasValidDynamicCallableMethod(TypeChecker &TC,
+                                          NominalTypeDecl *decl,
+                                          Identifier argumentName,
+                                          bool hasKeywordArgs) {
+  auto declType = decl->getDeclaredType();
+  auto methodName = DeclName(TC.Context,
+                             DeclBaseName(TC.Context.Id_dynamicallyCall),
+                             { argumentName });
+  auto candidates = TC.lookupMember(decl, declType, methodName);
+  if (candidates.empty()) return false;
+
+  // Filter valid candidates.
+  candidates.filter([&](LookupResultEntry entry, bool isOuter) {
+    auto candidate = cast<FuncDecl>(entry.getValueDecl());
+    return isValidDynamicCallableMethod(candidate, decl, TC, hasKeywordArgs);
+  });
+
+  // If there are no valid candidates, return false.
+  if (candidates.size() == 0) return false;
+  return true;
+}
+
+void AttributeChecker::
+visitDynamicCallableAttr(DynamicCallableAttr *attr) {
+  // This attribute is only allowed on nominal types.
+  auto decl = cast<NominalTypeDecl>(D);
+  auto type = decl->getDeclaredType();
+
+  bool hasValidMethod = false;
+  hasValidMethod |=
+    hasValidDynamicCallableMethod(TC, decl, TC.Context.Id_withArguments,
+                                  /*hasKeywordArgs*/ false);
+  hasValidMethod |=
+    hasValidDynamicCallableMethod(TC, decl, TC.Context.Id_withKeywordArguments,
+                                  /*hasKeywordArgs*/ true);
+  if (!hasValidMethod) {
+    TC.diagnose(attr->getLocation(), diag::invalid_dynamic_callable_type, type);
+    attr->setInvalid();
+  }
+}
+
+/// Returns true if the given subscript method is an valid implementation of
+/// the `subscript(dynamicMember:)` requirement for @dynamicMemberLookup.
+/// The method is given to be defined as `subscript(dynamicMember:)`.
+bool swift::isValidDynamicMemberLookupSubscript(SubscriptDecl *decl,
+                                                DeclContext *DC,
+                                                TypeChecker &TC) {
+  // There are two requirements:
+  // - The subscript method has exactly one, non-variadic parameter.
+  // - The parameter type conforms to `ExpressibleByStringLiteral`.
   auto indices = decl->getIndices();
-  
-  auto EBSL =
+
+  auto stringLitProto =
     TC.Context.getProtocol(KnownProtocolKind::ExpressibleByStringLiteral);
   
-  return indices->size() == 1 &&
-    !indices->get(0)->isVariadic() &&
+  return indices->size() == 1 && !indices->get(0)->isVariadic() &&
     TC.conformsToProtocol(indices->get(0)->getType(),
-                          EBSL, DC, ConformanceCheckOptions());
+                          stringLitProto, DC, ConformanceCheckOptions());
 }
 
 /// The @dynamicMemberLookup attribute is only allowed on types that have at
@@ -935,45 +1066,38 @@
 /// subscript<KeywordType: ExpressibleByStringLiteral, LookupValue>
 ///   (dynamicMember name: KeywordType) -> LookupValue { get }
 ///
-/// ... but doesn't care about the mutating'ness of the getter/setter.  We just
-/// manually check the requirements here.
-///
+/// ... but doesn't care about the mutating'ness of the getter/setter.
+/// We just manually check the requirements here.
 void AttributeChecker::
 visitDynamicMemberLookupAttr(DynamicMemberLookupAttr *attr) {
   // This attribute is only allowed on nominal types.
   auto decl = cast<NominalTypeDecl>(D);
   auto type = decl->getDeclaredType();
   
-  // Lookup our subscript.
-  auto subscriptName =
-    DeclName(TC.Context, DeclBaseName::createSubscript(),
-             TC.Context.Id_dynamicMember);
+  // Look up `subscript(dynamicMember:)` candidates.
+  auto subscriptName = DeclName(TC.Context, DeclBaseName::createSubscript(),
+                                TC.Context.Id_dynamicMember);
+  auto candidates = TC.lookupMember(decl, type, subscriptName);
   
-  auto lookupOptions = defaultMemberTypeLookupOptions;
-  lookupOptions -= NameLookupFlags::PerformConformanceCheck;
-  
-  // Lookup the implementations of our subscript.
-  auto candidates = TC.lookupMember(decl, type, subscriptName, lookupOptions);
-  
-  // If we have none, then there is no attribute.
+  // If there are no candidates, then the attribute is invalid.
   if (candidates.empty()) {
-    TC.diagnose(attr->getLocation(), diag::type_invalid_dml, type);
+    TC.diagnose(attr->getLocation(), diag::invalid_dynamic_member_lookup_type,
+                type);
     attr->setInvalid();
     return;
   }
 
-  
-  // If none of the ones we find are acceptable, then reject one.
+  // If no candidates are valid, then reject one.
   auto oneCandidate = candidates.front();
   candidates.filter([&](LookupResultEntry entry, bool isOuter) -> bool {
     auto cand = cast<SubscriptDecl>(entry.getValueDecl());
     TC.validateDeclForNameLookup(cand);
-    return isAcceptableDynamicMemberLookupSubscript(cand, decl, TC);
+    return isValidDynamicMemberLookupSubscript(cand, decl, TC);
   });
 
   if (candidates.empty()) {
     TC.diagnose(oneCandidate.getValueDecl()->getLoc(),
-                diag::type_invalid_dml, type);
+                diag::invalid_dynamic_member_lookup_type, type);
     attr->setInvalid();
   }
 }
@@ -1904,6 +2028,215 @@
   }
 }
 
+/// Lookup the replaced decl in the replacments scope.
+void lookupReplacedDecl(DeclName replacedDeclName,
+                        DynamicReplacementAttr *attr,
+                        AbstractFunctionDecl *replacement,
+                        SmallVectorImpl<ValueDecl *> &results) {
+  auto *declCtxt = replacement->getDeclContext();
+
+  // Look at the accessors' storage's context.
+  if (auto *accessor = dyn_cast<AccessorDecl>(replacement)) {
+    auto *storage = accessor->getStorage();
+    declCtxt = storage->getDeclContext();
+  }
+
+  if (isa<FileUnit>(declCtxt)) {
+    UnqualifiedLookup lookup(replacedDeclName,
+                             replacement->getModuleScopeContext(), nullptr,
+                             attr->getLocation());
+    if (lookup.isSuccess()) {
+      for (auto entry : lookup.Results)
+        results.push_back(entry.getValueDecl());
+    }
+    return;
+  }
+
+  assert(declCtxt->isTypeContext());
+  auto typeCtx = dyn_cast<NominalTypeDecl>(declCtxt->getAsDecl());
+  if (!typeCtx)
+    typeCtx = cast<ExtensionDecl>(declCtxt->getAsDecl())->getExtendedNominal();
+
+  replacement->getModuleScopeContext()->lookupQualified(
+      {typeCtx}, replacedDeclName, NL_QualifiedDefault, results);
+}
+
+static FuncDecl *findReplacedAccessor(DeclName replacedVarName,
+                                      AccessorDecl *replacement,
+                                      DynamicReplacementAttr *attr,
+                                      TypeChecker &TC) {
+
+  // Retrieve the replaced abstract storage decl.
+  SmallVector<ValueDecl *, 4> results;
+  lookupReplacedDecl(replacedVarName, attr, replacement, results);
+
+  if (results.empty()) {
+    TC.diagnose(attr->getLocation(),
+                diag::dynamic_replacement_accessor_not_found, replacedVarName);
+    attr->setInvalid();
+    return nullptr;
+  }
+  assert(results.size() == 1 && "Should only have on var or fun");
+
+  assert(!isa<FuncDecl>(results[0]));
+  TC.validateDecl(results[0]);
+  auto *origStorage = cast<AbstractStorageDecl>(results[0]);
+  if (!origStorage->isDynamic()) {
+    TC.diagnose(attr->getLocation(),
+                diag::dynamic_replacement_accessor_not_dynamic,
+                replacedVarName);
+    attr->setInvalid();
+    return nullptr;
+  }
+
+  // Find the accessor in the replaced storage decl.
+  for (auto *origAccessor : origStorage->getAllAccessors()) {
+    TC.validateDecl(origAccessor);
+    if (origAccessor->getAccessorKind() != replacement->getAccessorKind())
+      continue;
+
+    if (!replacement->getInterfaceType()->getCanonicalType()->matches(
+            origAccessor->getInterfaceType()->getCanonicalType(),
+            TypeMatchFlags::AllowABICompatible)) {
+      TC.diagnose(attr->getLocation(),
+                  diag::dynamic_replacement_accessor_type_mismatch,
+                  replacedVarName);
+      attr->setInvalid();
+      return nullptr;
+    }
+    if (origAccessor->isImplicit() &&
+        !(origStorage->getReadImpl() == ReadImplKind::Stored &&
+          origStorage->getWriteImpl() == WriteImplKind::Stored)) {
+      TC.diagnose(attr->getLocation(),
+                  diag::dynamic_replacement_accessor_not_explicit,
+                  (unsigned)origAccessor->getAccessorKind(), replacedVarName);
+      attr->setInvalid();
+      return nullptr;
+    }
+    return origAccessor;
+  }
+  return nullptr;
+}
+
+static AbstractFunctionDecl *
+findReplacedFunction(DeclName replacedFunctionName,
+                     AbstractFunctionDecl *replacement,
+                     DynamicReplacementAttr *attr, TypeChecker &TC) {
+
+  SmallVector<ValueDecl *, 4> results;
+  lookupReplacedDecl(replacedFunctionName, attr, replacement, results);
+
+  for (auto *result : results) {
+    TC.validateDecl(result);
+    if (result->getInterfaceType()->getCanonicalType()->matches(
+            replacement->getInterfaceType()->getCanonicalType(),
+            TypeMatchFlags::AllowABICompatible)) {
+      if (!result->isDynamic()) {
+        TC.diagnose(attr->getLocation(),
+                    diag::dynamic_replacement_function_not_dynamic,
+                    replacedFunctionName);
+        attr->setInvalid();
+        return nullptr;
+      }
+      return cast<AbstractFunctionDecl>(result);
+    }
+  }
+  if (results.empty())
+    TC.diagnose(attr->getLocation(),
+                diag::dynamic_replacement_function_not_found,
+                attr->getReplacedFunctionName());
+  else {
+    TC.diagnose(attr->getLocation(),
+                diag::dynamic_replacement_function_of_type_not_found,
+                attr->getReplacedFunctionName(),
+                replacement->getInterfaceType()->getCanonicalType());
+
+    for (auto *result : results) {
+      TC.diagnose(SourceLoc(), diag::dynamic_replacement_found_function_of_type,
+                  attr->getReplacedFunctionName(),
+                  result->getInterfaceType()->getCanonicalType());
+    }
+  }
+  attr->setInvalid();
+  return nullptr;
+}
+
+void TypeChecker::checkDynamicReplacementAttribute(ValueDecl *D) {
+  assert(isa<AbstractFunctionDecl>(D) || isa<AbstractStorageDecl>(D));
+
+  auto *attr = D->getAttrs().getAttribute<DynamicReplacementAttr>();
+  assert(attr);
+
+  if (!isa<ExtensionDecl>(D->getDeclContext()) &&
+      !D->getDeclContext()->isModuleScopeContext()) {
+    diagnose(attr->getLocation(), diag::dynamic_replacement_not_in_extension,
+             D->getBaseName());
+    attr->setInvalid();
+    return;
+  }
+
+  if (D->isDynamic() && !D->isObjC()) {
+    diagnose(attr->getLocation(), diag::dynamic_replacement_must_not_be_dynamic,
+             D->getBaseName());
+    attr->setInvalid();
+    return;
+  }
+
+  // Don't process a declaration twice. This will happen to accessor decls after
+  // we have processed their var decls.
+  if (attr->getReplacedFunction())
+    return;
+
+  SmallVector<AbstractFunctionDecl *, 4> replacements;
+  SmallVector<AbstractFunctionDecl *, 4> origs;
+
+  // Collect the accessor replacement mapping if this is an abstract storage.
+  if (auto *var = dyn_cast<AbstractStorageDecl>(D)) {
+     for (auto *accessor : var->getAllAccessors()) {
+       validateDecl(accessor);
+       if (accessor->isImplicit())
+         continue;
+       auto *orig = findReplacedAccessor(attr->getReplacedFunctionName(),
+                                         accessor, attr, *this);
+       if (attr->isInvalid())
+         return;
+       if (!orig)
+         continue;
+       origs.push_back(orig);
+       replacements.push_back(accessor);
+     }
+  } else {
+    // Otherwise, find the matching function.
+    auto *fun = cast<AbstractFunctionDecl>(D);
+    if (auto *orig = findReplacedFunction(attr->getReplacedFunctionName(), fun,
+                                          attr, *this)) {
+      origs.push_back(orig);
+      replacements.push_back(fun);
+    } else
+      return;
+  }
+
+  // Annotate the replacement with the original func decl.
+  for (auto index : indices(replacements)) {
+    if (auto *attr = replacements[index]
+                         ->getAttrs()
+                         .getAttribute<DynamicReplacementAttr>()) {
+      attr->setReplacedFunction(origs[index]);
+      continue;
+    }
+    auto *newAttr = DynamicReplacementAttr::create(
+        D->getASTContext(), attr->getReplacedFunctionName(), origs[index]);
+    DeclAttributes &attrs = replacements[index]->getAttrs();
+    attrs.add(newAttr);
+  }
+
+  // Remove the attribute on the abstract storage (we have moved it to the
+  // accessor decl).
+  if (!isa<AbstractStorageDecl>(D))
+    return;
+  D->getAttrs().removeAttribute(attr);
+}
+
 void AttributeChecker::visitImplementsAttr(ImplementsAttr *attr) {
   TypeLoc &ProtoTypeLoc = attr->getProtocolType();
   TypeResolutionOptions options = None;
@@ -2116,3 +2449,20 @@
 
   return None;
 }
+
+void TypeChecker::addImplicitDynamicAttribute(Decl *D) {
+  if (!getLangOpts().EnableImplicitDynamic)
+    return;
+
+  // Add the attribute if the decl kind allows it and it is not an accessor
+  // decl. Accessor decls should always infer the var/subscript's attribute.
+  if (!DeclAttribute::canAttributeAppearOnDecl(DAK_Dynamic, D) ||
+      isa<AccessorDecl>(D))
+    return;
+
+  if (!D->getAttrs().hasAttribute<DynamicAttr>() &&
+      !D->getAttrs().hasAttribute<DynamicReplacementAttr>()) {
+    auto attr = new (D->getASTContext()) DynamicAttr(/*implicit=*/true);
+    D->getAttrs().add(attr);
+  }
+}
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 1cc8f8c..1410e8e 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -1055,10 +1055,17 @@
 
           if (isa<TupleExpr>(parent) || isa<ParenExpr>(parent)) {
             auto call = parents.find(parent);
-            if (call != parents.end() &&
-                (isa<ApplyExpr>(call->getSecond()) ||
-                 isa<UnresolvedMemberExpr>(call->getSecond())))
-              return finish(true, expr);
+            if (call != parents.end()) {
+              if (isa<ApplyExpr>(call->getSecond()) ||
+                  isa<UnresolvedMemberExpr>(call->getSecond()))
+                return finish(true, expr);
+
+              if (isa<SubscriptExpr>(call->getSecond())) {
+                TC.diagnose(expr->getStartLoc(),
+                            diag::cannot_pass_inout_arg_to_subscript);
+                return finish(false, nullptr);
+              }
+            }
           }
         }
 
@@ -1967,12 +1974,11 @@
          "Purpose for conversion type was not specified");
 
   // Take a look at the conversion type to check to make sure it is sensible.
-  if (convertType.getType()) {
+  if (auto type = convertType.getType()) {
     // If we're asked to convert to an UnresolvedType, then ignore the request.
     // This happens when CSDiags nukes a type.
-    if (convertType.getType()->is<UnresolvedType>() ||
-        (convertType.getType()->is<MetatypeType>() &&
-         convertType.getType()->hasUnresolvedType())) {
+    if (type->is<UnresolvedType>() ||
+        (type->is<MetatypeType>() && type->hasUnresolvedType())) {
       convertType = TypeLoc();
       convertTypePurpose = CTP_Unused;
     }
@@ -2065,6 +2071,41 @@
   return cs.getType(expr);
 }
 
+Type TypeChecker::typeCheckParameterDefault(Expr *&defaultValue,
+                                            DeclContext *DC, Type paramType,
+                                            bool isAutoClosure, bool canFail) {
+  assert(paramType && !paramType->hasError());
+
+  if (isAutoClosure) {
+    class AutoClosureListener : public ExprTypeCheckListener {
+      DeclContext *DC;
+      FunctionType *ParamType;
+
+    public:
+      AutoClosureListener(DeclContext *DC, FunctionType *paramType)
+          : DC(DC), ParamType(paramType) {}
+
+      Expr *appliedSolution(constraints::Solution &solution,
+                            Expr *expr) override {
+        auto &cs = solution.getConstraintSystem();
+        auto *closure = cs.TC.buildAutoClosureExpr(DC, expr, ParamType);
+        cs.cacheExprTypes(closure);
+        return closure;
+      }
+    };
+
+    auto *fnType = paramType->castTo<FunctionType>();
+    AutoClosureListener listener(DC, fnType);
+    return typeCheckExpression(defaultValue, DC,
+                               TypeLoc::withoutLoc(fnType->getResult()),
+                               canFail ? CTP_DefaultParameter : CTP_CannotFail,
+                               TypeCheckExprOptions(), &listener);
+  }
+
+  return typeCheckExpression(defaultValue, DC, TypeLoc::withoutLoc(paramType),
+                             canFail ? CTP_DefaultParameter : CTP_CannotFail);
+}
+
 Type TypeChecker::
 getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc,
                                    ConcreteDeclRef &referencedDecl,
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index ab2946a..8dcfa67 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -972,7 +972,7 @@
   // Validate 'static'/'class' on properties in nominal type decls.
   auto StaticSpelling = binding->getStaticSpelling();
   if (StaticSpelling != StaticSpellingKind::None &&
-      binding->getDeclContext()->isExtensionContext()) {
+      isa<ExtensionDecl>(binding->getDeclContext())) {
     if (auto *NTD = binding->getDeclContext()->getSelfNominalTypeDecl()) {
       if (!isa<ClassDecl>(NTD)) {
         if (StaticSpelling == StaticSpellingKind::KeywordClass) {
@@ -1117,7 +1117,7 @@
 /// constraints before doing so.
 ///
 /// \returns true if it can be made dynamic, false otherwise.
-static bool makeDynamic(ValueDecl *decl) {
+static bool makeObjCDynamic(ValueDecl *decl) {
   // Only  members of classes can be dynamic.
   auto classDecl = decl->getDeclContext()->getSelfClassDecl();
   if (!classDecl) {
@@ -1127,7 +1127,7 @@
     return false;
   }
 
-  // 'dynamic' is only supported through the Objective-C runtime.
+  // '@objc dynamic' is only supported through the Objective-C runtime.
   if (!decl->isObjC()) {
     decl->diagnose(diag::dynamic_requires_objc,
                    decl->getDescriptiveKind(), decl->getFullName())
@@ -1145,6 +1145,69 @@
   return true;
 }
 
+static llvm::Expected<bool> isStorageDynamic(Evaluator &evaluator,
+                                             AccessorDecl *accessor) {
+  auto isDynamicResult = evaluator(IsDynamicRequest{accessor->getStorage()});
+
+  if (!isDynamicResult)
+    return isDynamicResult;
+
+  return *isDynamicResult;
+}
+
+/// Runtime-replacable accessors are dynamic when their storage declaration
+/// is dynamic and they were explicitly defined or they are implicitly defined
+/// getter/setter because no accessor was defined.
+static llvm::Expected<bool>
+doesAccessorNeedDynamicAttribute(AccessorDecl *accessor, Evaluator &evaluator) {
+  auto kind = accessor->getAccessorKind();
+  auto storage = accessor->getStorage();
+  bool isObjC = storage->isObjC();
+
+  switch (kind) {
+  case AccessorKind::Get: {
+    auto readImpl = storage->getReadImpl();
+    if (!isObjC &&
+        (readImpl == ReadImplKind::Read || readImpl == ReadImplKind::Address))
+      return false;
+    return isStorageDynamic(evaluator, accessor);
+  }
+  case AccessorKind::Set: {
+    auto writeImpl = storage->getWriteImpl();
+    if (!isObjC && (writeImpl == WriteImplKind::Modify ||
+                    writeImpl == WriteImplKind::MutableAddress ||
+                    writeImpl == WriteImplKind::StoredWithObservers))
+      return false;
+    return isStorageDynamic(evaluator, accessor);
+  }
+  case AccessorKind::Read:
+    if (!isObjC && storage->getReadImpl() == ReadImplKind::Read)
+      return isStorageDynamic(evaluator, accessor);
+    return false;
+  case AccessorKind::Modify: {
+    if (!isObjC && storage->getWriteImpl() == WriteImplKind::Modify)
+      return isStorageDynamic(evaluator, accessor);
+    return false;
+  }
+  case AccessorKind::MutableAddress: {
+    if (!isObjC && storage->getWriteImpl() == WriteImplKind::MutableAddress)
+      return isStorageDynamic(evaluator, accessor);
+    return false;
+  }
+  case AccessorKind::Address: {
+    if (!isObjC && storage->getReadImpl() == ReadImplKind::Address)
+      return isStorageDynamic(evaluator, accessor);
+    return false;
+  }
+  case AccessorKind::DidSet:
+  case AccessorKind::WillSet:
+    if (!isObjC &&
+        storage->getWriteImpl() == WriteImplKind::StoredWithObservers)
+      return isStorageDynamic(evaluator, accessor);
+    return false;
+  }
+}
+
 llvm::Expected<bool>
 IsDynamicRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
   // If we can't infer dynamic here, don't.
@@ -1153,12 +1216,20 @@
 
   // If 'dynamic' was explicitly specified, check it.
   if (decl->getAttrs().hasAttribute<DynamicAttr>()) {
-    return makeDynamic(decl);
+    if (decl->getASTContext().LangOpts.isSwiftVersionAtLeast(5))
+      return true;
+    return makeObjCDynamic(decl);
   }
 
-  // Runtime-replacable accessors are dynamic when their storage declaration
-  // is dynamic. Other accessors are never dynamic.
   if (auto accessor = dyn_cast<AccessorDecl>(decl)) {
+    // Swift 5: Runtime-replacable accessors are dynamic when their storage declaration
+    // is dynamic and they were explicitly defined or they are implicitly defined
+    // getter/setter because no accessor was defined.
+    if (decl->getASTContext().LangOpts.isSwiftVersionAtLeast(5))
+      return doesAccessorNeedDynamicAttribute(accessor, evaluator);
+
+    // Pre Swift 5: Runtime-replacable accessors are dynamic when their storage declaration
+    // is dynamic. Other accessors are never dynamic.
     switch (accessor->getAccessorKind()) {
     case AccessorKind::Get:
     case AccessorKind::Set: {
@@ -1169,7 +1240,7 @@
         return isDynamicResult;
 
       if (*isDynamicResult)
-        return makeDynamic(decl);
+        return makeObjCDynamic(decl);
 
       return false;
     }
@@ -1186,7 +1257,7 @@
   // FIXME: Use a semantic check for NSManaged rather than looking for the
   // attribute (which could be ill-formed).
   if (decl->getAttrs().hasAttribute<NSManagedAttr>()) {
-    return makeDynamic(decl);
+    return makeObjCDynamic(decl);
   }
 
   // The presence of 'final' blocks the inference of 'dynamic'.
@@ -1205,7 +1276,7 @@
   // This is intended to enable overriding the declarations.
   auto dc = decl->getDeclContext();
   if (isa<ExtensionDecl>(dc) && dc->getSelfClassDecl()) {
-    return makeDynamic(decl);
+    return makeObjCDynamic(decl);
   }
 
   // If any of the declarations overridden by this declaration are dynamic
@@ -1216,11 +1287,13 @@
   auto overriddenDecls = evaluateOrDefault(evaluator,
     OverriddenDeclsRequest{decl}, {});
   for (auto overridden : overriddenDecls) {
-    if (overridden->isDynamic())
-      return makeDynamic(decl);
+    if (overridden->isDynamic() &&
+        (!decl->getASTContext().LangOpts.isSwiftVersionAtLeast(5) ||
+         overridden->isObjC()))
+      return makeObjCDynamic(decl);
 
     if (overridden->hasClangNode())
-      return makeDynamic(decl);
+      return makeObjCDynamic(decl);
   }
 
   return false;
@@ -2268,8 +2341,16 @@
   llvm_unreachable("bad storage kind");
 }
 
+static bool shouldUseOpaqueReadAccessor(TypeChecker &TC,
+                                        AbstractStorageDecl *storage) {
+  return storage->getAttrs().hasAttribute<BorrowedAttr>();
+}
+
 static void validateAbstractStorageDecl(TypeChecker &TC,
                                         AbstractStorageDecl *storage) {
+  if (shouldUseOpaqueReadAccessor(TC, storage))
+    storage->setOpaqueReadOwnership(OpaqueReadOwnership::Borrowed);
+
   // isGetterMutating and isSetterMutating are part of the signature
   // of a storage declaration and need to be validated immediately.
   storage->setIsGetterMutating(computeIsGetterMutating(TC, storage));
@@ -2460,25 +2541,6 @@
       }
     }
 
-    // Reject variable if it is a stored property with an uninhabited type
-    if (VD->hasStorage() && 
-        VD->getInterfaceType()->isStructurallyUninhabited()) {
-      auto uninhabitedTypeDiag = diag::pattern_no_uninhabited_type;
-      
-      if (VD->getInterfaceType()->is<TupleType>()) {
-        uninhabitedTypeDiag = diag::pattern_no_uninhabited_tuple_type;
-      } else {
-        assert((VD->getInterfaceType()->is<EnumType>() || 
-                VD->getInterfaceType()->is<BoundGenericEnumType>()) && 
-          "unknown structurally uninhabited type");
-      }
-          
-      TC.diagnose(VD->getLoc(), uninhabitedTypeDiag, VD->isLet(),
-                  VD->isInstanceMember(), VD->getName(),
-                  VD->getInterfaceType());
-      VD->markInvalid();
-    }
-
     if (!checkOverrides(VD)) {
       // If a property has an override attribute but does not override
       // anything, complain.
@@ -2664,6 +2726,8 @@
   }
 
   void visitSubscriptDecl(SubscriptDecl *SD) {
+    TC.addImplicitDynamicAttribute(SD);
+
     TC.validateDecl(SD);
 
     if (!SD->isInvalid()) {
@@ -2689,6 +2753,9 @@
     }
 
     triggerAccessorSynthesis(TC, SD);
+    if (SD->getAttrs().hasAttribute<DynamicReplacementAttr>()) {
+      TC.checkDynamicReplacementAttribute(SD);
+    }
   }
 
   void visitTypeAliasDecl(TypeAliasDecl *TAD) {
@@ -3069,6 +3136,7 @@
     if (!PD->hasValidSignature())
       return;
 
+    auto *SF = PD->getParentSourceFile();
     {
       // Check for circular inheritance within the protocol.
       SmallVector<ProtocolDecl *, 8> path;
@@ -3076,7 +3144,7 @@
       checkCircularity(TC, PD, diag::circular_protocol_def,
                        DescriptiveDeclKind::Protocol, path);
 
-      if (auto *SF = PD->getParentSourceFile()) {
+      if (SF) {
         if (auto *tracker = SF->getReferencedNameTracker()) {
           bool isNonPrivate =
               (PD->getFormalAccess() > AccessLevel::FilePrivate);
@@ -3098,7 +3166,8 @@
 
     TC.checkDeclCircularity(PD);
     if (PD->isResilient())
-      TC.inferDefaultWitnesses(PD);
+      if (!SF || SF->Kind != SourceFileKind::Interface)
+        TC.inferDefaultWitnesses(PD);
 
     if (TC.Context.LangOpts.DebugGenericSignatures) {
       auto requirementsSig =
@@ -3128,8 +3197,16 @@
   }
 
   void visitVarDecl(VarDecl *VD) {
+    TC.addImplicitDynamicAttribute(VD);
+
     // Delay type-checking on VarDecls until we see the corresponding
     // PatternBindingDecl.
+
+    // Except if there is a dynamic replacement attribute.
+    if (VD->getAttrs().hasAttribute<DynamicReplacementAttr>()) {
+      TC.validateDecl(VD);
+      TC.checkDynamicReplacementAttribute(VD);
+    }
   }
 
   /// Determine whether the given declaration requires a definition.
@@ -3173,6 +3250,8 @@
   }
 
   void visitFuncDecl(FuncDecl *FD) {
+    TC.addImplicitDynamicAttribute(FD);
+
     TC.validateDecl(FD);
 
     if (!FD->isInvalid()) {
@@ -3202,6 +3281,10 @@
       // Record the body.
       TC.definedFunctions.push_back(FD);
     }
+
+    if (FD->getAttrs().hasAttribute<DynamicReplacementAttr>()) {
+      TC.checkDynamicReplacementAttribute(FD);
+    }
   }
 
   void visitModuleDecl(ModuleDecl *) { }
@@ -3285,6 +3368,7 @@
   }
 
   void visitConstructorDecl(ConstructorDecl *CD) {
+    TC.addImplicitDynamicAttribute(CD);
     TC.validateDecl(CD);
 
     if (!CD->isInvalid()) {
@@ -3398,6 +3482,10 @@
     } else {
       TC.definedFunctions.push_back(CD);
     }
+
+    if (CD->getAttrs().hasAttribute<DynamicReplacementAttr>()) {
+      TC.checkDynamicReplacementAttribute(CD);
+    }
   }
 
   void visitDestructorDecl(DestructorDecl *DD) {
@@ -3714,37 +3802,7 @@
     (addressor->getAccessorKind() == AccessorKind::Address)
       ? TC.getUnsafePointerType(addressor->getLoc(), valueType)
       : TC.getUnsafeMutablePointerType(addressor->getLoc(), valueType);
-  if (!pointerType) return Type();
-
-  switch (addressor->getAddressorKind()) {
-  case AddressorKind::NotAddressor:
-    llvm_unreachable("addressor without addressor kind");
-
-  // For unsafe addressors, it's just the pointer type.
-  case AddressorKind::Unsafe:
-    return pointerType;
-
-  // For non-native owning addressors, the return type is actually
-  //   (Unsafe{,Mutable}Pointer<T>, AnyObject)
-  case AddressorKind::Owning: {
-    TupleTypeElt elts[] = {
-      pointerType,
-      TC.Context.getAnyObjectType()
-    };
-    return TupleType::get(elts, TC.Context);
-  }
-
-  // For native owning addressors, the return type is actually
-  //   (Unsafe{,Mutable}Pointer<T>, Builtin.NativeObject)
-  case AddressorKind::NativeOwning: {
-    TupleTypeElt elts[] = {
-      pointerType,
-      TC.Context.TheNativeObjectType
-    };
-    return TupleType::get(elts, TC.Context);
-  }
-  }
-  llvm_unreachable("bad addressor kind");
+  return pointerType;
 }
 
 static TypeLoc getTypeLocForFunctionResult(FuncDecl *FD) {
@@ -4089,7 +4147,7 @@
     // Validate 'static'/'class' on functions in extensions.
     auto StaticSpelling = FD->getStaticSpelling();
     if (StaticSpelling != StaticSpellingKind::None &&
-        FD->getDeclContext()->isExtensionContext()) {
+        isa<ExtensionDecl>(FD->getDeclContext())) {
       if (auto *NTD = FD->getDeclContext()->getSelfNominalTypeDecl()) {
         if (!isa<ClassDecl>(NTD)) {
           if (StaticSpelling == StaticSpellingKind::KeywordClass) {
diff --git a/lib/Sema/TypeCheckDeclObjC.cpp b/lib/Sema/TypeCheckDeclObjC.cpp
index d7fba1f..2ee3db6 100644
--- a/lib/Sema/TypeCheckDeclObjC.cpp
+++ b/lib/Sema/TypeCheckDeclObjC.cpp
@@ -1142,14 +1142,15 @@
 
       return ObjCReason(ObjCReason::ExplicitlyDynamic);
     }
-
-    // Complain that 'dynamic' requires '@objc', but (quietly) infer @objc
-    // anyway for better recovery.
-    VD->diagnose(diag::dynamic_requires_objc,
-                 VD->getDescriptiveKind(), VD->getFullName())
-      .fixItInsert(VD->getAttributeInsertionLoc(/*forModifier=*/false),
-                 "@objc ");
-    return ObjCReason(ObjCReason::ImplicitlyObjC);
+    if (!ctx.isSwiftVersionAtLeast(5)) {
+      // Complain that 'dynamic' requires '@objc', but (quietly) infer @objc
+      // anyway for better recovery.
+      VD->diagnose(diag::dynamic_requires_objc, VD->getDescriptiveKind(),
+                   VD->getFullName())
+          .fixItInsert(VD->getAttributeInsertionLoc(/*forModifier=*/false),
+                       "@objc ");
+      return ObjCReason(ObjCReason::ImplicitlyObjC);
+    }
   }
 
   // If we aren't provided Swift 3's @objc inference rules, we're done.
diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp
index 85622b7..5878682 100644
--- a/lib/Sema/TypeCheckDeclOverride.cpp
+++ b/lib/Sema/TypeCheckDeclOverride.cpp
@@ -1166,9 +1166,11 @@
 
     UNINTERESTING_ATTR(AccessControl)
     UNINTERESTING_ATTR(Alignment)
+    UNINTERESTING_ATTR(Borrowed)
     UNINTERESTING_ATTR(CDecl)
     UNINTERESTING_ATTR(Consuming)
     UNINTERESTING_ATTR(Dynamic)
+    UNINTERESTING_ATTR(DynamicCallable)
     UNINTERESTING_ATTR(DynamicMemberLookup)
     UNINTERESTING_ATTR(SILGenName)
     UNINTERESTING_ATTR(Exported)
@@ -1210,6 +1212,8 @@
     UNINTERESTING_ATTR(SwiftNativeObjCRuntimeBase)
     UNINTERESTING_ATTR(ShowInInterface)
     UNINTERESTING_ATTR(Specialize)
+    UNINTERESTING_ATTR(DynamicReplacement)
+    UNINTERESTING_ATTR(PrivateImport)
 
     // These can't appear on overridable declarations.
     UNINTERESTING_ATTR(Prefix)
@@ -1220,7 +1224,7 @@
     UNINTERESTING_ATTR(SynthesizedProtocol)
     UNINTERESTING_ATTR(RequiresStoredPropertyInits)
     UNINTERESTING_ATTR(Transparent)
-    UNINTERESTING_ATTR(SILStored)
+    UNINTERESTING_ATTR(HasStorage)
     UNINTERESTING_ATTR(Testable)
 
     UNINTERESTING_ATTR(WarnUnqualifiedAccess)
@@ -1509,12 +1513,12 @@
   // Non-Objective-C declarations in extensions cannot override or
   // be overridden.
   if (!isAccessor &&
-      (base->getDeclContext()->isExtensionContext() ||
-       override->getDeclContext()->isExtensionContext()) &&
+      (isa<ExtensionDecl>(base->getDeclContext()) ||
+       isa<ExtensionDecl>(override->getDeclContext())) &&
       !base->isObjC()) {
     bool baseCanBeObjC = canBeRepresentedInObjC(base);
     diags.diagnose(override, diag::override_decl_extension, baseCanBeObjC,
-                   !base->getDeclContext()->isExtensionContext());
+                   !isa<ExtensionDecl>(base->getDeclContext()));
     if (baseCanBeObjC) {
       SourceLoc insertionLoc =
         override->getAttributeInsertionLoc(/*forModifier=*/false);
@@ -1557,9 +1561,8 @@
   if (auto *baseDecl = dyn_cast<ClassDecl>(base->getDeclContext())) {
     if (!isAccessor &&
         baseDecl->hasKnownSwiftImplementation() &&
-        !base->isDynamic() &&
-        override->getDeclContext()->isExtensionContext()) {
-      // For compatibility, only generate a warning in Swift 3
+        !base->isObjCDynamic() &&
+        isa<ExtensionDecl>(override->getDeclContext())) {
       diags.diagnose(override, diag::override_class_declaration_in_extension);
       diags.diagnose(base, diag::overridden_here);
     }
@@ -1775,21 +1778,15 @@
       auto baseAccessor = baseASD->getAccessor(kind);
       if (!baseAccessor) continue;
 
-      switch (kind) {
-      case AccessorKind::Read:
-        if (baseASD->getReadCoroutine()->hasForcedStaticDispatch())
-          continue;
-        LLVM_FALLTHROUGH;
+      if (baseAccessor->hasForcedStaticDispatch())
+        continue;
 
+      switch (kind) {
       case AccessorKind::Get:
+      case AccessorKind::Read:
         break;
 
       case AccessorKind::Modify:
-        if (baseASD->getModifyCoroutine()->hasForcedStaticDispatch())
-          continue;
-
-        LLVM_FALLTHROUGH;
-
       case AccessorKind::Set:
         // For setter accessors, we need the base's setter to be
         // accessible from the overriding context, or it's not an override.
diff --git a/lib/Sema/TypeCheckExpr.cpp b/lib/Sema/TypeCheckExpr.cpp
index c85c184..15786b8 100644
--- a/lib/Sema/TypeCheckExpr.cpp
+++ b/lib/Sema/TypeCheckExpr.cpp
@@ -19,6 +19,7 @@
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/Decl.h"
 #include "swift/AST/Initializer.h"
+#include "swift/AST/ParameterList.h"
 #include "swift/Parse/Lexer.h"
 using namespace swift;
 
@@ -539,6 +540,38 @@
   return result;
 }
 
+Expr *TypeChecker::buildAutoClosureExpr(DeclContext *DC, Expr *expr,
+                                        FunctionType *closureType) {
+  bool isInDefaultArgumentContext = false;
+  if (auto *init = dyn_cast<Initializer>(DC))
+    isInDefaultArgumentContext =
+        init->getInitializerKind() == InitializerKind::DefaultArgument;
+
+  auto info = closureType->getExtInfo();
+  auto newClosureType = closureType;
+
+  if (isInDefaultArgumentContext && info.isNoEscape())
+    newClosureType = closureType->withExtInfo(info.withNoEscape(false))
+                         ->castTo<FunctionType>();
+
+  auto *closure = new (Context) AutoClosureExpr(
+      expr, newClosureType, AutoClosureExpr::InvalidDiscriminator, DC);
+
+  closure->setParameterList(ParameterList::createEmpty(Context));
+
+  ClosuresWithUncomputedCaptures.push_back(closure);
+
+  if (!newClosureType->isEqual(closureType)) {
+    assert(isInDefaultArgumentContext);
+    assert(newClosureType
+               ->withExtInfo(newClosureType->getExtInfo().withNoEscape(true))
+               ->isEqual(closureType));
+    return new (Context) FunctionConversionExpr(closure, closureType);
+  }
+
+  return closure;
+}
+
 static Type lookupDefaultLiteralType(TypeChecker &TC, DeclContext *dc,
                                      StringRef name) {
   auto lookupOptions = defaultUnqualifiedLookupOptions;
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index e3a2d0a..c526965 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -602,6 +602,12 @@
   StringRef writtenBase = writtenName.getBaseName().userFacingName();
   StringRef correctedBase = correctedName.getBaseName().userFacingName();
 
+  // Don't typo-correct to a name with a leading underscore unless the typed
+  // name also begins with an underscore.
+  if (correctedBase.startswith("_") && !writtenBase.startswith("_")) {
+    return UnreasonableCallEditDistance;
+  }
+
   unsigned distance = writtenBase.edit_distance(correctedBase, maxEditDistance);
 
   // Bound the distance to UnreasonableCallEditDistance.
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index c76ad25..cfddd4d 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -1091,14 +1091,16 @@
     var->getTypeLoc().setType(var->getType());
 
     // If we are inferring a variable to have type AnyObject.Type,
-    // "()", or optional thereof, emit a diagnostic.  In the first 2 cases, the
-    // coder probably forgot a cast and expected a concrete type.  In the later
-    // case, they probably didn't mean to bind to a variable, or there is some
-    // other bug.  We always tell them that they can silence the warning with an
-    // explicit type annotation (and provide a fixit) as a note.
+    // "()", an uninhabited type, or optional thereof, emit a diagnostic.
+    // In the first 2 cases, the coder probably forgot a cast and expected a
+    // concrete type.  In the later case, they probably didn't mean to bind to
+    // a variable, or there is some other bug.  We always tell them that they
+    // can silence the warning with an explicit type annotation
+    // (and provide a fixit) as a note.
     Type diagTy = type->getOptionalObjectType();
     if (!diagTy) diagTy = type;
     
+    auto diag = diag::type_inferred_to_undesirable_type;
     bool shouldRequireType = false;
     if (NP->isImplicit()) {
       // If the whole pattern is implicit, the user didn't write it.
@@ -1108,14 +1110,24 @@
     } else if (auto MTT = diagTy->getAs<AnyMetatypeType>()) {
       if (MTT->getInstanceType()->isAnyObject())
         shouldRequireType = true;
+    } else if (diagTy->isStructurallyUninhabited()) {
+      shouldRequireType = true;
+      diag = diag::type_inferred_to_uninhabited_type;
+      
+      if (diagTy->is<TupleType>()) {
+        diag = diag::type_inferred_to_uninhabited_tuple_type;
+      } else {
+        assert((diagTy->is<EnumType>() || diagTy->is<BoundGenericEnumType>()) &&
+          "unknown structurally uninhabited type");
+      }
     }
     
     if (shouldRequireType &&
         !options.is(TypeResolverContext::ForEachStmt) &&
         !options.is(TypeResolverContext::EditorPlaceholderExpr) &&
         !(options & TypeResolutionFlags::FromNonInferredPattern)) {
-      diagnose(NP->getLoc(), diag::type_inferred_to_undesirable_type,
-               NP->getDecl()->getName(), type, NP->getDecl()->isLet());
+      diagnose(NP->getLoc(), diag, NP->getDecl()->getName(), type,
+               NP->getDecl()->isLet());
       diagnose(NP->getLoc(), diag::add_explicit_type_annotation_to_silence);
     }
 
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index a9e837e..6577a9e 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -18,7 +18,6 @@
 #include "ConstraintSystem.h"
 #include "DerivedConformances.h"
 #include "MiscDiagnostics.h"
-#include "TypeChecker.h"
 #include "TypeCheckAvailability.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/Basic/StringExtras.h"
@@ -1174,23 +1173,6 @@
   }
 
   if (numViable == 0) {
-    // Assume any missing value witnesses for a conformance in a parseable
-    // interface can be treated as opaque.
-    // FIXME: ...but we should do something better about types.
-    if (conformance && !conformance->isInvalid()) {
-      if (auto *SF = DC->getParentSourceFile()) {
-        if (SF->Kind == SourceFileKind::Interface) {
-          auto match = matchWitness(TC, ReqEnvironmentCache, Proto,
-                                    conformance, DC, requirement, requirement);
-          assert(match.isViable());
-          numViable = 1;
-          bestIdx = matches.size();
-          matches.push_back(std::move(match));
-          return true;
-        }
-      }
-    }
-
     if (anyFromUnconstrainedExtension &&
         conformance != nullptr &&
         conformance->isInvalid()) {
@@ -1233,23 +1215,51 @@
   return isReallyBest;
 }
 
-bool WitnessChecker::checkWitnessAccess(AccessScope &requiredAccessScope,
-                                        ValueDecl *requirement,
+AccessScope WitnessChecker::getRequiredAccessScope() {
+  if (RequiredAccessScopeAndUsableFromInline.hasValue())
+    return RequiredAccessScopeAndUsableFromInline.getValue().first;
+
+  AccessScope result = Proto->getFormalAccessScope(DC);
+
+  bool witnessesMustBeUsableFromInline = false;
+  if (Adoptee) {
+    const NominalTypeDecl *adoptingNominal = Adoptee->getAnyNominal();
+
+    // Compute the intersection of the conforming type's access scope
+    // and the protocol's access scope.
+    auto scopeIntersection =
+        result.intersectWith(adoptingNominal->getFormalAccessScope(DC));
+    assert(scopeIntersection.hasValue());
+    result = scopeIntersection.getValue();
+
+    if (!result.isPublic()) {
+      witnessesMustBeUsableFromInline =
+          Proto->getFormalAccessScope(
+            DC, /*usableFromInlineAsPublic*/true).isPublic() &&
+          adoptingNominal->getFormalAccessScope(
+            DC, /*usableFromInlineAsPublic*/true).isPublic();
+    }
+  } else {
+    if (!result.isPublic()) {
+      witnessesMustBeUsableFromInline =
+          Proto->getFormalAccessScope(
+            DC, /*usableFromInlineAsPublic*/true).isPublic();
+    }
+  }
+
+  RequiredAccessScopeAndUsableFromInline =
+      std::make_pair(result, witnessesMustBeUsableFromInline);
+  return result;
+}
+
+bool WitnessChecker::checkWitnessAccess(ValueDecl *requirement,
                                         ValueDecl *witness,
                                         bool *isSetter) {
   *isSetter = false;
   if (!TC.getLangOpts().EnableAccessControl)
     return false;
 
-  // Compute the intersection of the conforming type's access scope
-  // and the protocol's access scope.
-  auto scopeIntersection =
-    requiredAccessScope.intersectWith(Proto->getFormalAccessScope(DC));
-  assert(scopeIntersection.hasValue());
-
-  requiredAccessScope = *scopeIntersection;
-
-  AccessScope actualScopeToCheck = requiredAccessScope;
+  AccessScope actualScopeToCheck = getRequiredAccessScope();
 
   // Setting the 'forConformance' flag means that we admit witnesses in
   // protocol extensions that we can see, but are not necessarily as
@@ -1261,16 +1271,18 @@
     // That is, if '@testable' allows us to see the witness here, it should
     // allow us to see it anywhere, because any other client could also add
     // their own `@testable import`.
+    // Same with @_private(sourceFile:) import.
     if (auto parentFile = dyn_cast<SourceFile>(DC->getModuleScopeContext())) {
       const ModuleDecl *witnessModule = witness->getModuleContext();
       if (parentFile->getParentModule() != witnessModule &&
-          parentFile->hasTestableImport(witnessModule) &&
+          parentFile->hasTestableOrPrivateImport(witness->getFormalAccess(),
+                                                 witness) &&
           witness->isAccessibleFrom(parentFile)) {
         actualScopeToCheck = parentFile;
       }
     }
 
-    if (actualScopeToCheck.hasEqualDeclContextWith(requiredAccessScope))
+    if (actualScopeToCheck.hasEqualDeclContextWith(getRequiredAccessScope()))
       return true;
   }
 
@@ -1297,20 +1309,17 @@
                                                DC, *requiredAvailability));
 }
 
-RequirementCheck WitnessChecker::
-checkWitness(AccessScope requiredAccessScope,
-             ValueDecl *requirement,
-             const RequirementMatch &match) {
+RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
+                                              const RequirementMatch &match) {
   if (!match.OptionalAdjustments.empty())
     return CheckKind::OptionalityConflict;
 
   bool isSetter = false;
-  if (checkWitnessAccess(requiredAccessScope, requirement, match.Witness,
-                         &isSetter)) {
+  if (checkWitnessAccess(requirement, match.Witness, &isSetter)) {
     CheckKind kind = (isSetter
                       ? CheckKind::AccessOfSetter
                       : CheckKind::Access);
-    return RequirementCheck(kind, requiredAccessScope);
+    return RequirementCheck(kind, getRequiredAccessScope());
   }
 
   auto requiredAvailability = AvailabilityContext::alwaysAvailable();
@@ -2340,6 +2349,36 @@
   return true;
 }
 
+namespace {
+/// Helper class for use with ConformanceChecker::diagnoseOrDefer when a witness
+/// needs to be marked as '\@usableFromInline'.
+class DiagnoseUsableFromInline {
+  const ValueDecl *witness;
+
+public:
+  explicit DiagnoseUsableFromInline(const ValueDecl *witness)
+      : witness(witness) {
+    assert(witness);
+  }
+
+  void operator()(const NormalProtocolConformance *conformance) {
+    auto proto = conformance->getProtocol();
+    ASTContext &ctx = proto->getASTContext();
+
+    auto diagID = diag::witness_not_usable_from_inline;
+    if (!ctx.isSwiftVersionAtLeast(5))
+      diagID = diag::witness_not_usable_from_inline_warn;
+
+    SourceLoc diagLoc = getLocForDiagnosingWitness(conformance, witness);
+    ctx.Diags.diagnose(diagLoc, diagID,
+                       witness->getDescriptiveKind(),
+                       witness->getFullName(),
+                       proto->getName());
+    emitDeclaredHereIfNeeded(ctx.Diags, diagLoc, witness);
+  }
+};
+}
+
 void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
                                            Type type,
                                            TypeDecl *typeDecl) {
@@ -2357,24 +2396,20 @@
 
   if (typeDecl) {
     // Check access.
-    AccessScope requiredAccessScope =
-        Adoptee->getAnyNominal()->getFormalAccessScope(DC);
     bool isSetter = false;
-    if (checkWitnessAccess(requiredAccessScope, assocType, typeDecl,
-                           &isSetter)) {
+    if (checkWitnessAccess(assocType, typeDecl, &isSetter)) {
       assert(!isSetter);
 
       // Avoid relying on the lifetime of 'this'.
       const DeclContext *DC = this->DC;
       diagnoseOrDefer(assocType, false,
-        [DC, typeDecl, requiredAccessScope](
-          NormalProtocolConformance *conformance) {
+          [this, DC, typeDecl](NormalProtocolConformance *conformance) {
         AccessLevel requiredAccess =
-          requiredAccessScope.requiredAccessForDiagnostics();
+            getRequiredAccessScope().requiredAccessForDiagnostics();
         auto proto = conformance->getProtocol();
         auto protoAccessScope = proto->getFormalAccessScope(DC);
         bool protoForcesAccess =
-          requiredAccessScope.hasEqualDeclContextWith(protoAccessScope);
+            getRequiredAccessScope().hasEqualDeclContextWith(protoAccessScope);
         auto diagKind = protoForcesAccess
                           ? diag::type_witness_not_accessible_proto
                           : diag::type_witness_not_accessible_type;
@@ -2391,6 +2426,13 @@
         fixItAccess(fixItDiag, typeDecl, requiredAccess);
       });
     }
+
+    if (isUsableFromInlineRequired()) {
+      bool witnessIsUsableFromInline = typeDecl->getFormalAccessScope(
+          DC, /*usableFromInlineAsPublic*/true).isPublic();
+      if (!witnessIsUsableFromInline)
+        diagnoseOrDefer(assocType, false, DiagnoseUsableFromInline(typeDecl));
+    }
   } else {
     // If there was no type declaration, synthesize one.
     auto aliasDecl = new (TC.Context) TypeAliasDecl(SourceLoc(),
@@ -2466,10 +2508,10 @@
                      Type AdopterTy, SourceLoc TypeLoc, raw_ostream &OS) {
   if (isa<ConstructorDecl>(Requirement)) {
     if (auto CD = Adopter->getSelfClassDecl()) {
-      if (!CD->isFinal() && Adopter->isExtensionContext()) {
-          // In this case, user should mark class as 'final' or define
-          // 'required' initializer directly in the class definition.
-          return false;
+      if (!CD->isFinal() && isa<ExtensionDecl>(Adopter)) {
+        // In this case, user should mark class as 'final' or define
+        // 'required' initializer directly in the class definition.
+        return false;
       }
     }
   }
@@ -2508,7 +2550,7 @@
       if (auto CD = Adopter->getSelfClassDecl()) {
         if (!CD->isFinal()) {
           Printer << "required ";
-        } else if (Adopter->isExtensionContext()) {
+        } else if (isa<ExtensionDecl>(Adopter)) {
           Printer << "convenience ";
         }
       }
@@ -2530,7 +2572,7 @@
     };
     Options.setBaseType(AdopterTy);
     Options.CurrentModule = Adopter->getParentModule();
-    if (!Adopter->isExtensionContext()) {
+    if (!isa<ExtensionDecl>(Adopter)) {
       // Create a variable declaration instead of a computed property in
       // nominal types
       Options.PrintPropertyAccessors = false;
@@ -2851,6 +2893,23 @@
 }
 
 ResolveWitnessResult
+ConformanceChecker::resolveWitnessAsOpaque(ValueDecl *requirement) {
+  assert(!isa<AssociatedTypeDecl>(requirement) && "Use resolveTypeWitnessVia*");
+  auto match = matchWitness(TC, ReqEnvironmentCache, Proto,
+                            Conformance, DC, requirement, requirement);
+  recordWitness(requirement, match);
+  return ResolveWitnessResult::Success;
+}
+
+static bool isConformanceFromParseableInterface(
+    const NormalProtocolConformance *conformance) {
+  auto *containingSF = conformance->getDeclContext()->getParentSourceFile();
+  if (!containingSF)
+    return false;
+  return containingSF->Kind == SourceFileKind::Interface;
+}
+
+ResolveWitnessResult
 ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
   assert(!isa<AssociatedTypeDecl>(requirement) && "Use resolveTypeWitnessVia*");
 
@@ -2867,25 +2926,33 @@
     }
   }
 
-  // Determine whether we can derive a witness for this requirement.
-  bool canDerive = false;
+  // Determine whether we can get a witness for this requirement some other way.
+  bool hasFallbacks = false;
+  if (!hasFallbacks)
+    hasFallbacks = requirement->getAttrs().hasAttribute<OptionalAttr>();
+  if (!hasFallbacks)
+    hasFallbacks = requirement->getAttrs().isUnavailable(TC.Context);
+  if (!hasFallbacks)
+    hasFallbacks = isConformanceFromParseableInterface(Conformance);
 
-  // Can a witness for this requirement be derived for this nominal type?
-  if (auto derivable = DerivedConformance::getDerivableRequirement(
-                         TC,
-                         nominal,
-                         requirement)) {
-    if (derivable == requirement) {
-      // If it's the same requirement, we can derive it here.
-      canDerive = true;
-    } else {
-      // Otherwise, go satisfy the derivable requirement, which can introduce
-      // a member that could in turn satisfy *this* requirement.
-      auto derivableProto = cast<ProtocolDecl>(derivable->getDeclContext());
-      if (auto conformance =
-            TC.conformsToProtocol(Adoptee, derivableProto, DC, None)) {
-        if (conformance->isConcrete())
-          (void)conformance->getConcrete()->getWitnessDecl(derivable, &TC);
+  if (!hasFallbacks) {
+    // Can a witness for this requirement be derived for this nominal type?
+    if (auto derivable = DerivedConformance::getDerivableRequirement(
+                           TC,
+                           nominal,
+                           requirement)) {
+      if (derivable == requirement) {
+        // If it's the same requirement, we can derive it here.
+        hasFallbacks = true;
+      } else {
+        // Otherwise, go satisfy the derivable requirement, which can introduce
+        // a member that could in turn satisfy *this* requirement.
+        auto derivableProto = cast<ProtocolDecl>(derivable->getDeclContext());
+        if (auto conformance =
+              TC.conformsToProtocol(Adoptee, derivableProto, DC, None)) {
+          if (conformance->isConcrete())
+            (void)conformance->getConcrete()->getWitnessDecl(derivable, &TC);
+        }
       }
     }
   }
@@ -2896,11 +2963,7 @@
   unsigned bestIdx = 0;
   bool doNotDiagnoseMatches = false;
   bool ignoringNames = false;
-  bool considerRenames =
-    !canDerive && !requirement->getAttrs().hasAttribute<OptionalAttr>() &&
-    !requirement->getAttrs().isUnavailable(TC.Context);
-  if (findBestWitness(requirement,
-                      considerRenames ? &ignoringNames : nullptr,
+  if (findBestWitness(requirement, hasFallbacks ? nullptr : &ignoringNames,
                       Conformance,
                       /* out parameters: */
                       matches, numViable, bestIdx, doNotDiagnoseMatches)) {
@@ -2939,8 +3002,7 @@
         });
     }
 
-    auto nominalAccessScope = nominal->getFormalAccessScope(DC);
-    auto check = checkWitness(nominalAccessScope, requirement, best);
+    auto check = checkWitness(requirement, best);
 
     switch (check.Kind) {
     case CheckKind::Success:
@@ -3119,19 +3181,7 @@
   // We have either no matches or an ambiguous match.
 
   // If we can derive a definition for this requirement, just call it missing.
-  if (canDerive) {
-    return ResolveWitnessResult::Missing;
-  }
-
-  // If the requirement is optional, it's okay. We'll satisfy this via
-  // our handling of default definitions.
-  //
-  // FIXME: revisit this once we get default definitions in protocol bodies.
-  //
-  // Treat 'unavailable' implicitly as if it were 'optional'.
-  // The compiler will reject actual uses.
-  auto Attrs = requirement->getAttrs();
-  if (Attrs.hasAttribute<OptionalAttr>() || Attrs.isUnavailable(TC.Context)) {
+  if (hasFallbacks) {
     return ResolveWitnessResult::Missing;
   }
 
@@ -3292,6 +3342,47 @@
   return CheckTypeWitnessResult();
 }
 
+ResolveWitnessResult
+ConformanceChecker::resolveWitnessTryingAllStrategies(ValueDecl *requirement) {
+  using ResolveWitnessStrategy =
+      decltype(&ConformanceChecker::resolveWitnessViaLookup);
+  static const constexpr ResolveWitnessStrategy defaultStrategies[] = {
+      &ConformanceChecker::resolveWitnessViaLookup,
+      &ConformanceChecker::resolveWitnessViaDerivation,
+      &ConformanceChecker::resolveWitnessViaDefault};
+  ArrayRef<ResolveWitnessStrategy> strategies = defaultStrategies;
+
+  // Don't try any sort of derivation when processing a parseable interface.
+  if (isConformanceFromParseableInterface(Conformance)) {
+    if (Conformance->isResilient()) {
+      // Resilient conformances don't allow any sort of devirtualization, so
+      // don't bother looking up witnesses at all.
+      static const constexpr ResolveWitnessStrategy resilientStrategies[] = {
+          &ConformanceChecker::resolveWitnessAsOpaque};
+      strategies = resilientStrategies;
+    } else {
+      static const constexpr ResolveWitnessStrategy interfaceStrategies[] = {
+          &ConformanceChecker::resolveWitnessViaLookup,
+          &ConformanceChecker::resolveWitnessAsOpaque};
+      strategies = interfaceStrategies;
+    }
+  }
+
+  for (auto strategy : strategies) {
+    ResolveWitnessResult result = (this->*strategy)(requirement);
+    switch (result) {
+    case ResolveWitnessResult::Success:
+    case ResolveWitnessResult::ExplicitFailed:
+      return result;
+    case ResolveWitnessResult::Missing:
+      // Continue trying.
+      break;
+    }
+  }
+
+  return ResolveWitnessResult::Missing;
+}
+
 /// Attempt to resolve a type witness via member name lookup.
 ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
                        AssociatedTypeDecl *assocType) {
@@ -3562,60 +3653,14 @@
 }
 
 #pragma mark Protocol conformance checking
-void ConformanceChecker::checkConformance(MissingWitnessDiagnosisKind Kind) {
-  assert(!Conformance->isComplete() && "Conformance is already complete");
 
-  FrontendStatsTracer statsTracer(TC.Context.Stats, "check-conformance",
-                                  Conformance);
-
-  llvm::SaveAndRestore<bool> restoreSuppressDiagnostics(SuppressDiagnostics);
-  SuppressDiagnostics = false;
-
-  // FIXME: Caller checks that this type conforms to all of the
-  // inherited protocols.
-
-  // Emit known diags for this conformance.
-  emitDelayedDiags();
-
-  // If delayed diags have already complained, return.
-  if (AlreadyComplained) {
-    Conformance->setInvalid();
-    return;
-  }
-
-  // Resolve all of the type witnesses.
-  resolveTypeWitnesses();
-
-  // Diagnose missing type witnesses for now.
-  diagnoseMissingWitnesses(Kind);
-
-  // Ensure the conforming type is used.
-  //
-  // FIXME: This feels like the wrong place for this, but if we don't put
-  // it here, extensions don't end up depending on the extended type.
-  recordConformanceDependency(DC, Adoptee->getAnyNominal(), Conformance, false);
-
-  // If we complain about any associated types, there is no point in continuing.
-  // FIXME: Not really true. We could check witnesses that don't involve the
-  // failed associated types.
-  if (AlreadyComplained) {
-    Conformance->setInvalid();
-    return;
-  }
-
-  // Diagnose missing value witnesses later.
-  SWIFT_DEFER { diagnoseMissingWitnesses(Kind); };
-
-  // Ensure the associated type conformances are used.
-  addUsedConformances(Conformance);
-
-  // Check non-type requirements.
+void ConformanceChecker::resolveValueWitnesses() {
   for (auto member : Proto->getMembers()) {
     auto requirement = dyn_cast<ValueDecl>(member);
     if (!requirement)
       continue;
 
-    // Associated type requirements handled above.
+    // Associated type requirements handled elsewhere.
     if (isa<TypeDecl>(requirement))
       continue;
 
@@ -3766,9 +3811,9 @@
     // If this is an accessor for a storage decl, ignore it.
     if (isa<AccessorDecl>(requirement))
       continue;
-    
-    // Try to resolve the witness via explicit definitions.
-    switch (resolveWitnessViaLookup(requirement)) {
+
+    // Try to resolve the witness.
+    switch (resolveWitnessTryingAllStrategies(requirement)) {
     case ResolveWitnessResult::Success:
       finalizeWitness();
       continue;
@@ -3778,40 +3823,61 @@
       continue;
 
     case ResolveWitnessResult::Missing:
-      // Continue trying below.
-      break;
-    }
-
-    // Try to resolve the witness via derivation.
-    switch (resolveWitnessViaDerivation(requirement)) {
-    case ResolveWitnessResult::Success:
-      finalizeWitness();
-      continue;
-
-    case ResolveWitnessResult::ExplicitFailed:
-      Conformance->setInvalid();
-      continue;
-
-    case ResolveWitnessResult::Missing:
-      // Continue trying below.
-      break;
-    }
-
-    // Try to resolve the witness via defaults.
-    switch (resolveWitnessViaDefault(requirement)) {
-    case ResolveWitnessResult::Success:
-      finalizeWitness();
-      continue;
-
-    case ResolveWitnessResult::ExplicitFailed:
-      Conformance->setInvalid();
-      continue;
-
-    case ResolveWitnessResult::Missing:
-      // Continue trying below.
+      // Let it get diagnosed later.
       break;
     }
   }
+}
+
+void ConformanceChecker::checkConformance(MissingWitnessDiagnosisKind Kind) {
+  assert(!Conformance->isComplete() && "Conformance is already complete");
+
+  FrontendStatsTracer statsTracer(TC.Context.Stats, "check-conformance",
+                                  Conformance);
+
+  llvm::SaveAndRestore<bool> restoreSuppressDiagnostics(SuppressDiagnostics);
+  SuppressDiagnostics = false;
+
+  // FIXME: Caller checks that this type conforms to all of the
+  // inherited protocols.
+
+  // Emit known diags for this conformance.
+  emitDelayedDiags();
+
+  // If delayed diags have already complained, return.
+  if (AlreadyComplained) {
+    Conformance->setInvalid();
+    return;
+  }
+
+  // Resolve all of the type witnesses.
+  resolveTypeWitnesses();
+
+  // Diagnose missing type witnesses for now.
+  diagnoseMissingWitnesses(Kind);
+
+  // Ensure the conforming type is used.
+  //
+  // FIXME: This feels like the wrong place for this, but if we don't put
+  // it here, extensions don't end up depending on the extended type.
+  recordConformanceDependency(DC, Adoptee->getAnyNominal(), Conformance, false);
+
+  // If we complain about any associated types, there is no point in continuing.
+  // FIXME: Not really true. We could check witnesses that don't involve the
+  // failed associated types.
+  if (AlreadyComplained) {
+    Conformance->setInvalid();
+    return;
+  }
+
+  // Diagnose missing value witnesses later.
+  SWIFT_DEFER { diagnoseMissingWitnesses(Kind); };
+
+  // Ensure the associated type conformances are used.
+  addUsedConformances(Conformance);
+
+  // Check non-type requirements.
+  resolveValueWitnesses();
 
   emitDelayedDiags();
 
@@ -3956,9 +4022,8 @@
 
     // First, if we have a superclass constraint, the class may conform
     // concretely.
-    if (layout.explicitSuperclass) {
-      if (auto result = conformsToProtocol(layout.explicitSuperclass, Proto,
-                                           DC, options)) {
+    if (auto superclass = layout.getSuperclass()) {
+      if (auto result = conformsToProtocol(superclass, Proto, DC, options)) {
         return result;
       }
     }
@@ -3972,15 +4037,6 @@
       if (PD == Proto)
         return ProtocolConformanceRef(Proto);
 
-      // If the protocol has a superclass constraint, we might conform
-      // concretely.
-      if (auto superclass = PD->getSuperclass()) {
-        if (auto result = conformsToProtocol(superclass, Proto,
-                                             DC, options)) {
-          return result;
-        }
-      }
-
       // Now check refined protocols.
       if (PD->inheritsFrom(Proto))
         return ProtocolConformanceRef(Proto);
@@ -5432,7 +5488,7 @@
 
     // Perform the same checks as conformance witness matching, but silently
     // ignore the candidate instead of diagnosing anything.
-    auto check = checkWitness(AccessScope::getPublic(), requirement, best);
+    auto check = checkWitness(requirement, best);
     if (check.Kind != CheckKind::Success)
       return ResolveWitnessResult::ExplicitFailed;
 
diff --git a/lib/Sema/TypeCheckProtocol.h b/lib/Sema/TypeCheckProtocol.h
index 77a41fe..7105faa 100644
--- a/lib/Sema/TypeCheckProtocol.h
+++ b/lib/Sema/TypeCheckProtocol.h
@@ -18,6 +18,8 @@
 #ifndef SWIFT_SEMA_PROTOCOL_H
 #define SWIFT_SEMA_PROTOCOL_H
 
+#include "TypeChecker.h"
+#include "swift/AST/AccessScope.h"
 #include "swift/AST/RequirementEnvironment.h"
 #include "swift/AST/Type.h"
 #include "swift/AST/Types.h"
@@ -475,11 +477,24 @@
 
   RequirementEnvironmentCache ReqEnvironmentCache;
 
+  Optional<std::pair<AccessScope, bool>> RequiredAccessScopeAndUsableFromInline;
+
   WitnessChecker(TypeChecker &tc, ProtocolDecl *proto,
                  Type adoptee, DeclContext *dc);
 
   bool isMemberOperator(FuncDecl *decl, Type type);
 
+  AccessScope getRequiredAccessScope();
+
+  bool isUsableFromInlineRequired() {
+    if (!TC.getLangOpts().EnableAccessControl)
+      return false;
+
+    assert(RequiredAccessScopeAndUsableFromInline.hasValue() &&
+           "must check access first using getRequiredAccessScope");
+    return RequiredAccessScopeAndUsableFromInline.getValue().second;
+  }
+
   /// Gather the value witnesses for the given requirement.
   ///
   /// \param ignoringNames If non-null and there are no value
@@ -501,8 +516,7 @@
                        unsigned &bestIdx,
                        bool &doNotDiagnoseMatches);
 
-  bool checkWitnessAccess(AccessScope &requiredAccessScope,
-                          ValueDecl *requirement,
+  bool checkWitnessAccess(ValueDecl *requirement,
                           ValueDecl *witness,
                           bool *isSetter);
 
@@ -510,8 +524,7 @@
                                 ValueDecl *witness,
                                 AvailabilityContext *requirementInfo);
 
-  RequirementCheck checkWitness(AccessScope requiredAccessScope,
-                                ValueDecl *requirement,
+  RequirementCheck checkWitness(ValueDecl *requirement,
                                 const RequirementMatch &match);
 };
 
@@ -607,6 +620,9 @@
   void checkNonFinalClassWitness(ValueDecl *requirement,
                                  ValueDecl *witness);
 
+  /// Resolve the (non-type) witness as requiring dynamic dispatch.
+  ResolveWitnessResult resolveWitnessAsOpaque(ValueDecl *requirement);
+
   /// Resolve a (non-type) witness via name lookup.
   ResolveWitnessResult resolveWitnessViaLookup(ValueDecl *requirement);
 
@@ -616,6 +632,11 @@
   /// Resolve a (non-type) witness via default definition or optional.
   ResolveWitnessResult resolveWitnessViaDefault(ValueDecl *requirement);
 
+  /// Resolve a (non-type) witness by trying each standard strategy until one
+  /// of them produces a result.
+  ResolveWitnessResult
+  resolveWitnessTryingAllStrategies(ValueDecl *requirement);
+
   /// Attempt to resolve a type witness via member name lookup.
   ResolveWitnessResult resolveTypeWitnessViaLookup(
                          AssociatedTypeDecl *assocType);
@@ -662,6 +683,9 @@
   /// Resolve all of the type witnesses.
   void resolveTypeWitnesses();
 
+  /// Resolve all of the non-type witnesses.
+  void resolveValueWitnesses();
+
   /// Resolve the witness for the given non-type requirement as
   /// directly as possible, only resolving other witnesses if
   /// needed, e.g., to determine type witnesses used within the
diff --git a/lib/Sema/TypeCheckProtocolInference.cpp b/lib/Sema/TypeCheckProtocolInference.cpp
index dd84209..8cfaa0a 100644
--- a/lib/Sema/TypeCheckProtocolInference.cpp
+++ b/lib/Sema/TypeCheckProtocolInference.cpp
@@ -2083,38 +2083,8 @@
     }
   }
 
-  // Try to resolve the witness via explicit definitions.
-  switch (resolveWitnessViaLookup(requirement)) {
-  case ResolveWitnessResult::Success:
-    return;
-
-  case ResolveWitnessResult::ExplicitFailed:
-    Conformance->setInvalid();
-    recordInvalidWitness(requirement);
-    return;
-
-  case ResolveWitnessResult::Missing:
-    // Continue trying below.
-    break;
-  }
-
-  // Try to resolve the witness via derivation.
-  switch (resolveWitnessViaDerivation(requirement)) {
-  case ResolveWitnessResult::Success:
-    return;
-
-  case ResolveWitnessResult::ExplicitFailed:
-    Conformance->setInvalid();
-    recordInvalidWitness(requirement);
-    return;
-
-  case ResolveWitnessResult::Missing:
-    // Continue trying below.
-    break;
-  }
-
-  // Try to resolve the witness via defaults.
-  switch (resolveWitnessViaDefault(requirement)) {
+  // Try to resolve the witness.
+  switch (resolveWitnessTryingAllStrategies(requirement)) {
   case ResolveWitnessResult::Success:
     return;
 
@@ -2125,6 +2095,5 @@
 
   case ResolveWitnessResult::Missing:
     llvm_unreachable("Should have failed");
-    break;
   }
 }
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index fd15d1a..d4a97bd 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -553,6 +553,13 @@
     
     return TS;
   }
+
+  Stmt *visitPoundAssertStmt(PoundAssertStmt *PA) {
+    Expr *C = PA->getCondition();
+    TC.typeCheckCondition(C, DC);
+    PA->setCondition(C);
+    return PA;
+  }
     
   Stmt *visitDeferStmt(DeferStmt *DS) {
     TC.typeCheckDecl(DS->getTempDecl());
@@ -1515,12 +1522,12 @@
       continue;
 
     Expr *e = param->getDefaultValue();
-    auto initContext = param->getDefaultArgumentInitContext();
+    auto *initContext = param->getDefaultArgumentInitContext();
 
-    // Type-check the initializer, then flag that we did so.
-    auto resultTy = typeCheckExpression(
-        e, initContext, TypeLoc::withoutLoc(param->getType()),
-        CTP_DefaultParameter);
+    auto resultTy =
+        typeCheckParameterDefault(e, initContext, param->getType(),
+                                  /*isAutoClosure=*/param->isAutoClosure());
+
     if (resultTy) {
       param->setDefaultValue(e);
     } else {
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 285b410..151f7a6 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -2093,7 +2093,6 @@
 
     // Resolve the function type directly with these attributes.
     FunctionType::ExtInfo extInfo(rep,
-                                  attrs.has(TAK_autoclosure),
                                   attrs.has(TAK_noescape),
                                   fnRepr->throws());
 
@@ -2242,6 +2241,10 @@
       variadic = true;
     }
 
+    bool autoclosure = false;
+    if (auto *ATR = dyn_cast<AttributedTypeRepr>(eltTypeRepr))
+      autoclosure = ATR->getAttrs().has(TAK_autoclosure);
+
     Type ty = resolveType(eltTypeRepr, thisElementOptions);
     if (!ty) return true;
 
@@ -2281,8 +2284,8 @@
       ownership = ValueOwnership::Default;
       break;
     }
-    ParameterTypeFlags paramFlags =
-        ParameterTypeFlags::fromParameterType(ty, variadic, ownership);
+    auto paramFlags = ParameterTypeFlags::fromParameterType(
+        ty, variadic, autoclosure, ownership);
     elements.emplace_back(ty, Identifier(), paramFlags);
   }
 
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index 2fbcf33..504766f 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -300,6 +300,28 @@
     prepareGenericParamList(outerGenericParams);
 }
 
+/// Ensure that the outer generic parameters of the given generic
+/// context have been configured.
+static void configureOuterGenericParams(const GenericContext *dc) {
+  auto genericParams = dc->getGenericParams();
+  if (!genericParams) return;
+
+  if (genericParams->getOuterParameters()) return;
+
+  DeclContext *outerDC = dc->getParent();
+  while (!outerDC->isModuleScopeContext()) {
+    if (auto outerDecl = outerDC->getAsDecl()) {
+      if (auto outerGenericDC = outerDecl->getAsGenericContext()) {
+        genericParams->setOuterParameters(outerGenericDC->getGenericParams());
+        configureOuterGenericParams(outerGenericDC);
+        return;
+      }
+    }
+
+    outerDC = outerDC->getParent();
+  }
+}
+
 /// Bind the given extension to the given nominal type.
 static void bindExtensionToNominal(ExtensionDecl *ext,
                                    NominalTypeDecl *nominal) {
@@ -313,10 +335,7 @@
     ext->setGenericParams(genericParams);
   } else if (auto genericParams = nominal->getGenericParamsOfContext()) {
     // Make sure the generic parameters are set up.
-    if (auto nominalGenericParams = nominal->getGenericParams()) {
-      nominalGenericParams->setOuterParameters(
-        nominal->getDeclContext()->getGenericParamsOfContext());
-    }
+    configureOuterGenericParams(nominal);
 
     // Clone the generic parameter list of a generic type.
     prepareGenericParamList(genericParams);
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index d7cbccd..be8c1a6 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -1082,6 +1082,10 @@
 
   bool typeCheckTapBody(TapExpr *expr, DeclContext *DC);
 
+  Type typeCheckParameterDefault(Expr *&defaultValue, DeclContext *DC,
+                                 Type paramType, bool isAutoClosure = false,
+                                 bool canFail = true);
+
   void typeCheckTopLevelCodeDecl(TopLevelCodeDecl *TLCD);
 
   void processREPLTopLevel(SourceFile &SF, TopLevelContext &TLC,
@@ -1091,7 +1095,9 @@
   void typeCheckDecl(Decl *D);
 
   void checkDeclAttributesEarly(Decl *D);
+  void addImplicitDynamicAttribute(Decl *D);
   void checkDeclAttributes(Decl *D);
+  void checkDynamicReplacementAttribute(ValueDecl *D);
   void checkTypeModifyingDeclAttributes(VarDecl *var);
 
   void checkReferenceOwnershipAttr(VarDecl *D, ReferenceOwnershipAttr *attr);
@@ -1749,7 +1755,8 @@
   void checkConformance(NormalProtocolConformance *conformance);
 
   /// Check the requirement signature of the given conformance.
-  void checkConformanceRequirements(NormalProtocolConformance *conformance);
+  void checkConformanceRequirements(NormalProtocolConformance *conformance)
+         override ;
 
   /// Check all of the conformances in the given context.
   void checkConformancesInContext(DeclContext *dc,
@@ -1900,6 +1907,11 @@
   Expr *buildRefExpr(ArrayRef<ValueDecl *> Decls, DeclContext *UseDC,
                      DeclNameLoc NameLoc, bool Implicit,
                      FunctionRefKind functionRefKind);
+
+  /// Build implicit autoclosure expression wrapping a given expression.
+  /// Given expression represents computed result of the closure.
+  Expr *buildAutoClosureExpr(DeclContext *DC, Expr *expr,
+                             FunctionType *closureType);
   /// @}
 
   /// \brief Retrieve a specific, known protocol.
@@ -1944,7 +1956,6 @@
   /// Used in diagnostic %selects.
   enum class FragileFunctionKind : unsigned {
     Transparent,
-    InlineAlways,
     Inlinable,
     DefaultArgument,
     PropertyInitializer
@@ -2156,12 +2167,18 @@
   const StringRef Message;
 };
 
-/// Given a subscript defined as "subscript(dynamicMember:)->T", return true if
-/// it is an acceptable implementation of the @dynamicMemberLookup attribute's
-/// requirement.
-bool isAcceptableDynamicMemberLookupSubscript(SubscriptDecl *decl,
-                                              DeclContext *DC,
-                                              TypeChecker &TC);
+/// Returns true if the given method is an valid implementation of a
+/// @dynamicCallable attribute requirement. The method is given to be defined
+/// as one of the following: `dynamicallyCall(withArguments:)` or
+/// `dynamicallyCall(withKeywordArguments:)`.
+bool isValidDynamicCallableMethod(FuncDecl *decl, DeclContext *DC,
+                                  TypeChecker &TC, bool hasKeywordArguments);
+
+/// Returns true if the given subscript method is an valid implementation of
+/// the `subscript(dynamicMember:)` requirement for @dynamicMemberLookup.
+/// The method is given to be defined as `subscript(dynamicMember:)`.
+bool isValidDynamicMemberLookupSubscript(SubscriptDecl *decl, DeclContext *DC,
+                                         TypeChecker &TC);
 
 /// Whether an overriding declaration requires the 'override' keyword.
 enum class OverrideRequiresKeyword {
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index b201980..00d8f83 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -652,39 +652,19 @@
   unsigned kind = DeclTypeCursor.readRecord(next.ID, scratch, &blobData);
   if (kind != GENERIC_PARAM_LIST)
     return nullptr;
+  lastRecordOffset.reset();
 
   SmallVector<GenericTypeParamDecl *, 8> params;
 
-  while (true) {
-    lastRecordOffset.reset();
-    bool shouldContinue = true;
-
-    auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
-    if (entry.Kind != llvm::BitstreamEntry::Record)
-      break;
-
-    scratch.clear();
-    unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch,
-                                                  &blobData);
-    switch (recordID) {
-    case GENERIC_PARAM: {
-      DeclID paramDeclID;
-      GenericParamLayout::readRecord(scratch, paramDeclID);
-      auto genericParam = cast<GenericTypeParamDecl>(getDecl(paramDeclID));
-      params.push_back(genericParam);
-      break;
-    }
-    default:
-      // This record is not part of the GenericParamList.
-      shouldContinue = false;
-      break;
-    }
-
-    if (!shouldContinue)
-      break;
+  ArrayRef<uint64_t> paramIDs;
+  GenericParamListLayout::readRecord(scratch, paramIDs);
+  for (DeclID nextParamID : paramIDs) {
+    auto genericParam = cast<GenericTypeParamDecl>(getDecl(nextParamID));
+    params.push_back(genericParam);
   }
 
-  // Don't create empty generic parameter lists.
+  // Don't create empty generic parameter lists. (This should never happen in
+  // practice, but it doesn't hurt to be defensive.)
   if (params.empty())
     return nullptr;
 
@@ -2047,22 +2027,6 @@
   return None;
 }
 
-static Optional<swift::AddressorKind>
-getActualAddressorKind(uint8_t raw) {
-  switch (serialization::AddressorKind(raw)) {
-  case serialization::AddressorKind::NotAddressor:
-    return swift::AddressorKind::NotAddressor;
-  case serialization::AddressorKind::Unsafe:
-    return swift::AddressorKind::Unsafe;
-  case serialization::AddressorKind::Owning:
-    return swift::AddressorKind::Owning;
-  case serialization::AddressorKind::NativeOwning:
-    return swift::AddressorKind::NativeOwning;
-  }
-
-  return None;
-}
-
 static Optional<swift::SelfAccessKind>
 getActualSelfAccessKind(uint8_t raw) {
   switch (serialization::SelfAccessKind(raw)) {
@@ -2258,6 +2222,15 @@
   return deserialized;
 }
 
+template <typename DERIVED>
+static bool attributeChainContains(DeclAttribute *attr) {
+  DeclAttributes tempAttrs;
+  tempAttrs.setRawAttributeChain(attr);
+  static_assert(std::is_trivially_destructible<DeclAttributes>::value,
+                "must not try to destroy the attribute chain");
+  return tempAttrs.hasAttribute<DERIVED>();
+}
+
 Expected<Decl *>
 ModuleFile::getDeclCheckedImpl(DeclID DID) {
   if (DID == 0)
@@ -2334,9 +2307,33 @@
     }
   };
 
+  class FilenameForPrivateRAII {
+    Serialized<Decl *> &declOrOffset;
+
+  public:
+    Identifier filename;
+
+    FilenameForPrivateRAII(Serialized<Decl *> &decl) : declOrOffset(decl) {}
+    ~FilenameForPrivateRAII() {
+      if (filename.empty())
+        return;
+      if (!declOrOffset.isComplete())
+        return;
+      auto *valueDecl = dyn_cast<ValueDecl>(declOrOffset.get());
+      if (!valueDecl)
+        return;
+      auto *loadedFile = dyn_cast<LoadedFile>(
+          valueDecl->getDeclContext()->getModuleScopeContext());
+      if (!loadedFile)
+        return;
+      loadedFile->addFilenameForPrivateDecl(valueDecl, filename);
+    }
+  };
+
   PrivateDiscriminatorRAII privateDiscriminatorRAII{*this, declOrOffset};
   LocalDiscriminatorRAII localDiscriminatorRAII(declOrOffset);
   DeserializingEntityRAII deserializingEntity(*this);
+  FilenameForPrivateRAII filenameForPrivate(declOrOffset);
 
   // Local function that handles the "inherited" list for a type.
   auto handleInherited
@@ -2541,6 +2538,30 @@
         break;
       }
 
+      case decls_block::DynamicReplacement_DECL_ATTR: {
+        bool isImplicit;
+        uint64_t numArgs;
+        ArrayRef<uint64_t> rawPieceIDs;
+        DeclID replacedFunID;
+        serialization::decls_block::DynamicReplacementDeclAttrLayout::
+            readRecord(scratch, isImplicit, replacedFunID, numArgs, rawPieceIDs);
+
+        auto replacedFunDecl = getDeclChecked(replacedFunID);
+        if (!replacedFunDecl)
+          return replacedFunDecl.takeError();
+        auto baseName = getDeclBaseName(rawPieceIDs[0]);
+        SmallVector<Identifier, 4> pieces;
+        for (auto pieceID : rawPieceIDs.slice(1))
+          pieces.push_back(getIdentifier(pieceID));
+
+        assert(numArgs != 0);
+        assert(!isImplicit && "Need to update for implicit");
+        Attr = DynamicReplacementAttr::create(
+            ctx, DeclName(ctx, baseName, ArrayRef<Identifier>(pieces)),
+            cast<AbstractFunctionDecl>(*replacedFunDecl));
+        break;
+      }
+
 #define SIMPLE_DECL_ATTR(NAME, CLASS, ...) \
       case decls_block::CLASS##_DECL_ATTR: { \
         bool isImplicit; \
@@ -2572,6 +2593,10 @@
       unsigned discriminator;
       decls_block::LocalDiscriminatorLayout::readRecord(scratch, discriminator);
       localDiscriminatorRAII.discriminator = discriminator;
+    } else if (recordID == decls_block::FILENAME_FOR_PRIVATE) {
+      IdentifierID filenameID;
+      decls_block::FilenameForPrivateLayout::readRecord(scratch, filenameID);
+      filenameForPrivate.filename = getIdentifier(filenameID);
     } else {
       break;
     }
@@ -2650,7 +2675,7 @@
                                                         index);
 
     // Always create GenericTypeParamDecls in the associated module;
-    // maybeReadGenericParams() will reparent them.
+    // the real context will reparent them.
     auto DC = getAssociatedModule();
     auto genericParam = createDecl<GenericTypeParamDecl>(DC,
                                                          getIdentifier(nameID),
@@ -2876,9 +2901,16 @@
       ctor->setStubImplementation(true);
     if (initKind.hasValue())
       ctor->setInitKind(initKind.getValue());
-    ctor->setOverriddenDecl(cast_or_null<ConstructorDecl>(overridden.get()));
     ctor->setNeedsNewVTableEntry(needsNewVTableEntry);
 
+    ctor->setOverriddenDecl(cast_or_null<ConstructorDecl>(overridden.get()));
+    if (auto *overridden = ctor->getOverriddenDecl()) {
+      if (!attributeChainContains<RequiredAttr>(DAttrs) ||
+          !overridden->isRequired()) {
+        AddAttribute(new (ctx) OverrideAttr(SourceLoc()));
+      }
+    }
+
     if (auto defaultArgumentResilienceExpansion = getActualResilienceExpansion(
             rawDefaultArgumentResilienceExpansion)) {
       ctor->setDefaultArgumentResilienceExpansion(
@@ -3013,12 +3045,13 @@
     unsigned rawSpecifier;
     TypeID interfaceTypeID;
     bool isVariadic;
+    bool isAutoClosure;
     uint8_t rawDefaultArg;
 
     decls_block::ParamLayout::readRecord(scratch, argNameID, paramNameID,
                                          contextID, rawSpecifier,
                                          interfaceTypeID, isVariadic,
-                                         rawDefaultArg);
+                                         isAutoClosure, rawDefaultArg);
 
     auto DC = getDeclContext(contextID);
     if (declOrOffset.isComplete())
@@ -3049,6 +3082,7 @@
 
     param->setInterfaceType(paramTy);
     param->setVariadic(isVariadic);
+    param->setAutoClosure(isAutoClosure);
 
     // Decode the default argument kind.
     // FIXME: Default argument expression, if available.
@@ -3068,7 +3102,7 @@
     bool isImplicit;
     bool isStatic;
     uint8_t rawStaticSpelling, rawAccessLevel, rawMutModifier;
-    uint8_t rawAccessorKind, rawAddressorKind;
+    uint8_t rawAccessorKind;
     bool isObjC, hasDynamicSelf, hasForcedStaticDispatch, throws;
     unsigned numNameComponentsBiased;
     GenericEnvironmentID genericEnvID;
@@ -3102,7 +3136,7 @@
                                           resultInterfaceTypeID,
                                           overriddenID,
                                           accessorStorageDeclID,
-                                          rawAccessorKind, rawAddressorKind,
+                                          rawAccessorKind,
                                           rawAccessLevel,
                                           needsNewVTableEntry,
                                           rawDefaultArgumentResilienceExpansion,
@@ -3116,7 +3150,6 @@
     // Parse the accessor-specific fields.
     AbstractStorageDecl *storage = nullptr;
     AccessorKind accessorKind;
-    AddressorKind addressorKind;
     if (isAccessor) {
       auto storageResult = getDeclChecked(accessorStorageDeclID);
       if (!storageResult ||
@@ -3134,13 +3167,6 @@
         return nullptr;
       }
 
-      if (auto addressorKindResult = getActualAddressorKind(rawAddressorKind)) {
-        addressorKind = *addressorKindResult;
-      } else {
-        error();
-        return nullptr;
-      }
-
       // Deserializing the storage declaration will cause a recurrence
       // into this code.  When we come out, don't create the accessor twice.
       // TODO: find some better way of breaking this cycle, like lazily
@@ -3212,7 +3238,7 @@
     } else {
       fn = AccessorDecl::createDeserialized(
         ctx, /*FuncLoc=*/SourceLoc(), /*AccessorKeywordLoc=*/SourceLoc(),
-        accessorKind, addressorKind, storage,
+        accessorKind, storage,
         /*StaticLoc=*/SourceLoc(), staticSpelling.getValue(),
         /*Throws=*/throws, /*ThrowsLoc=*/SourceLoc(),
         genericParams, DC);
@@ -3912,9 +3938,12 @@
     // Generic parameter lists are written from outermost to innermost.
     // Keep reading until we run out of generic parameter lists.
     GenericParamList *outerParams = nullptr;
-    while (auto *genericParams = maybeReadGenericParams(DC, outerParams))
+    while (auto *genericParams = maybeReadGenericParams(DC, outerParams)) {
+      // We do this repeatedly to set up the correct DeclContexts for the
+      // GenericTypeParamDecls in the list.
+      extension->setGenericParams(genericParams);
       outerParams = genericParams;
-    extension->setGenericParams(outerParams);
+    }
 
     configureGenericEnvironment(extension, genericEnvID);
 
@@ -4394,13 +4423,12 @@
   case decls_block::GENERIC_FUNCTION_TYPE: {
     TypeID resultID;
     uint8_t rawRepresentation;
-    bool autoClosure = false, noescape = false, throws;
+    bool noescape = false, throws;
     GenericSignature *genericSig = nullptr;
 
     if (recordID == decls_block::FUNCTION_TYPE) {
       decls_block::FunctionTypeLayout::readRecord(scratch, resultID,
                                                   rawRepresentation,
-                                                  autoClosure,
                                                   noescape,
                                                   throws);
     } else {
@@ -4419,8 +4447,7 @@
       return nullptr;
     }
     
-    auto info = FunctionType::ExtInfo(*representation, autoClosure, noescape,
-                                      throws);
+    auto info = FunctionType::ExtInfo(*representation, noescape, throws);
 
     auto resultTy = getTypeChecked(resultID);
     if (!resultTy)
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 45fcbf8..72fde0d 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -463,17 +463,19 @@
 
   DeclID clangNodeOwnerID;
   TypeID funcTyID;
+  IdentifierID replacedFunctionID;
   GenericEnvironmentID genericEnvID;
   unsigned rawLinkage, isTransparent, isSerialized, isThunk,
       isWithoutactuallyEscapingThunk, isGlobal, inlineStrategy,
       optimizationMode, effect, numSpecAttrs, hasQualifiedOwnership,
-      isWeakLinked;
+      isWeakLinked, isDynamic;
   ArrayRef<uint64_t> SemanticsIDs;
   SILFunctionLayout::readRecord(
       scratch, rawLinkage, isTransparent, isSerialized, isThunk,
       isWithoutactuallyEscapingThunk, isGlobal, inlineStrategy,
       optimizationMode, effect, numSpecAttrs, hasQualifiedOwnership,
-      isWeakLinked, funcTyID, genericEnvID, clangNodeOwnerID, SemanticsIDs);
+      isWeakLinked, isDynamic, funcTyID, replacedFunctionID, genericEnvID,
+      clangNodeOwnerID, SemanticsIDs);
 
   if (funcTyID == 0) {
     LLVM_DEBUG(llvm::dbgs() << "SILFunction typeID is 0.\n");
@@ -496,6 +498,17 @@
     return nullptr;
   }
 
+  SILFunction *replacedFunction = nullptr;
+  Identifier replacedObjectiveCFunc;
+  if (replacedFunctionID &&
+      ty.getAs<SILFunctionType>()->getExtInfo().getRepresentation() !=
+          SILFunctionTypeRepresentation::ObjCMethod) {
+    replacedFunction =
+        getFuncForReference(MF->getIdentifier(replacedFunctionID).str());
+  } else if (replacedFunctionID) {
+    replacedObjectiveCFunc = MF->getIdentifier(replacedFunctionID);
+  }
+
   auto linkage = fromStableSILLinkage(rawLinkage);
   if (!linkage) {
     LLVM_DEBUG(llvm::dbgs() << "invalid linkage code " << rawLinkage
@@ -550,6 +563,11 @@
         linkage == SILLinkage::PublicNonABI) {
       fn->setLinkage(SILLinkage::SharedExternal);
     }
+    if (fn->isDynamicallyReplaceable() != isDynamic) {
+      LLVM_DEBUG(llvm::dbgs() << "SILFunction type mismatch.\n");
+      MF->error();
+      return nullptr;
+    }
   } else {
     // Otherwise, create a new function.
     SILSerializationFunctionBuilder builder(SILMod);
@@ -564,6 +582,11 @@
     fn->setEffectsKind(EffectsKind(effect));
     fn->setOptimizationMode(OptimizationMode(optimizationMode));
     fn->setWeakLinked(isWeakLinked);
+    fn->setIsDynamic(IsDynamicallyReplaceable_t(isDynamic));
+    if (replacedFunction)
+      fn->setDynamicallyReplacedFunction(replacedFunction);
+    if (!replacedObjectiveCFunc.empty())
+      fn->setObjCReplacement(replacedObjectiveCFunc);
     if (clangNodeOwner)
       fn->setClangNodeOwner(clangNodeOwner);
     for (auto ID : SemanticsIDs) {
@@ -1480,9 +1503,25 @@
   case SILInstructionKind::FunctionRefInst: {
     auto Ty = MF->getType(TyID);
     StringRef FuncName = MF->getIdentifierText(ValID);
-    ResultVal = Builder.createFunctionRef(Loc,
-        getFuncForReference(FuncName,
-                            getSILType(Ty, (SILValueCategory)TyCategory)));
+    ResultVal = Builder.createFunctionRef(
+        Loc, getFuncForReference(FuncName,
+                                 getSILType(Ty, (SILValueCategory)TyCategory)));
+    break;
+  }
+  case SILInstructionKind::DynamicFunctionRefInst: {
+    auto Ty = MF->getType(TyID);
+    StringRef FuncName = MF->getIdentifierText(ValID);
+    ResultVal = Builder.createDynamicFunctionRef(
+        Loc, getFuncForReference(FuncName,
+                                 getSILType(Ty, (SILValueCategory)TyCategory)));
+    break;
+  }
+  case SILInstructionKind::PreviousDynamicFunctionRefInst: {
+    auto Ty = MF->getType(TyID);
+    StringRef FuncName = MF->getIdentifierText(ValID);
+    ResultVal = Builder.createPreviousDynamicFunctionRef(
+        Loc, getFuncForReference(FuncName,
+                                 getSILType(Ty, (SILValueCategory)TyCategory)));
     break;
   }
   case SILInstructionKind::MarkDependenceInst: {
@@ -2475,17 +2514,19 @@
   // linkage to avoid re-reading it from the bitcode each time?
   DeclID clangOwnerID;
   TypeID funcTyID;
+  IdentifierID replacedFunctionID;
   GenericEnvironmentID genericEnvID;
   unsigned rawLinkage, isTransparent, isSerialized, isThunk,
       isWithoutactuallyEscapingThunk, isGlobal, inlineStrategy,
       optimizationMode, effect, numSpecAttrs, hasQualifiedOwnership,
-      isWeakLinked;
+      isWeakLinked, isDynamic;
   ArrayRef<uint64_t> SemanticsIDs;
   SILFunctionLayout::readRecord(
       scratch, rawLinkage, isTransparent, isSerialized, isThunk,
       isWithoutactuallyEscapingThunk, isGlobal, inlineStrategy,
       optimizationMode, effect, numSpecAttrs, hasQualifiedOwnership,
-      isWeakLinked, funcTyID, genericEnvID, clangOwnerID, SemanticsIDs);
+      isWeakLinked, isDynamic, funcTyID, replacedFunctionID, genericEnvID,
+      clangOwnerID, SemanticsIDs);
   auto linkage = fromStableSILLinkage(rawLinkage);
   if (!linkage) {
     LLVM_DEBUG(llvm::dbgs() << "invalid linkage code " << rawLinkage
diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp
index d81edfd..da59964 100644
--- a/lib/Serialization/ModuleFile.cpp
+++ b/lib/Serialization/ModuleFile.cpp
@@ -14,6 +14,7 @@
 #include "DeserializationErrors.h"
 #include "DocFormat.h"
 #include "swift/Serialization/ModuleFormat.h"
+#include "swift/Serialization/SerializationOptions.h"
 #include "swift/Subsystems.h"
 #include "swift/AST/ASTContext.h"
 #include "swift/AST/ASTMangler.h"
@@ -28,6 +29,7 @@
 #include "swift/Serialization/BCReadingExtras.h"
 #include "swift/Serialization/SerializedModuleLoader.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Chrono.h"
 #include "llvm/Support/DJB.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/OnDiskHashTable.h"
@@ -111,6 +113,9 @@
     case options_block::IS_TESTABLE:
       extendedInfo.setIsTestable(true);
       break;
+    case options_block::ARE_PRIVATE_IMPORTS_ENABLED:
+      extendedInfo.setPrivateImportsEnabled(true);
+      break;
     case options_block::RESILIENCE_STRATEGY:
       unsigned Strategy;
       options_block::ResilienceStrategyLayout::readRecord(scratch, Strategy);
@@ -232,6 +237,35 @@
   return result;
 }
 
+static bool validateInputBlock(
+    llvm::BitstreamCursor &cursor, SmallVectorImpl<uint64_t> &scratch,
+    SmallVectorImpl<SerializationOptions::FileDependency> &dependencies) {
+  while (!cursor.AtEndOfStream()) {
+    auto entry = cursor.advance();
+    if (entry.Kind == llvm::BitstreamEntry::EndBlock)
+      break;
+
+    if (entry.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(entry.ID, scratch, &blobData);
+    switch (kind) {
+    case input_block::FILE_DEPENDENCY:
+      dependencies.push_back(SerializationOptions::FileDependency{
+          scratch[0], llvm::sys::toTimePoint(scratch[1]), blobData});
+      break;
+    default:
+      // Unknown metadata record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+  }
+  return false;
+}
+
+
 bool serialization::isSerializedAST(StringRef data) {
   StringRef signatureStr(reinterpret_cast<const char *>(SWIFTMODULE_SIGNATURE),
                          llvm::array_lengthof(SWIFTMODULE_SIGNATURE));
@@ -240,7 +274,8 @@
 
 ValidationInfo serialization::validateSerializedAST(
     StringRef data,
-    ExtendedValidationInfo *extendedInfo) {
+    ExtendedValidationInfo *extendedInfo,
+    SmallVectorImpl<SerializationOptions::FileDependency> *dependencies) {
   ValidationInfo result;
 
   // Check 32-bit alignment.
@@ -270,6 +305,14 @@
                                     extendedInfo);
       if (result.status == Status::Malformed)
         return result;
+    } else if (dependencies &&
+               result.status == Status::Valid &&
+               topLevelEntry.ID == INPUT_BLOCK_ID) {
+      cursor.EnterSubBlock(INPUT_BLOCK_ID);
+      if (validateInputBlock(cursor, scratch, *dependencies)) {
+        result.status = Status::Malformed;
+        return result;
+      }
     } else {
       if (cursor.SkipBlock()) {
         result.status = Status::Malformed;
diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h
index a07aeeb..2cf0f79 100644
--- a/lib/Serialization/SILFormat.h
+++ b/lib/Serialization/SILFormat.h
@@ -181,7 +181,6 @@
     INHERITED_PROTOCOL_CONFORMANCE
       = decls_block::INHERITED_PROTOCOL_CONFORMANCE,
     INVALID_PROTOCOL_CONFORMANCE = decls_block::INVALID_PROTOCOL_CONFORMANCE,
-    GENERIC_PARAM = decls_block::GENERIC_PARAM,
     GENERIC_REQUIREMENT = decls_block::GENERIC_REQUIREMENT,
     LAYOUT_REQUIREMENT = decls_block::LAYOUT_REQUIREMENT,
   };
@@ -290,7 +289,9 @@
                      BCVBR<8>,    // number of specialize attributes
                      BCFixed<1>,  // has qualified ownership
                      BCFixed<1>,  // must be weakly referenced
+                     BCFixed<1>,  // is dynamically replacable
                      TypeIDField, // SILFunctionType
+                     DeclIDField,  // SILFunction name or 0 (replaced function)
                      GenericEnvironmentIDField,
                      DeclIDField, // ClangNode owner
                      BCArray<IdentifierIDField> // Semantics Attribute
diff --git a/lib/Serialization/SILSerializationFunctionBuilder.h b/lib/Serialization/SILSerializationFunctionBuilder.h
index ae937ed..0caa058 100644
--- a/lib/Serialization/SILSerializationFunctionBuilder.h
+++ b/lib/Serialization/SILSerializationFunctionBuilder.h
@@ -30,7 +30,7 @@
     return builder.createFunction(
         SILLinkage::Private, name, type.getAs<SILFunctionType>(), nullptr,
         loc, IsNotBare, IsNotTransparent,
-        IsNotSerialized, ProfileCounter(), IsNotThunk,
+        IsNotSerialized, IsNotDynamic, ProfileCounter(), IsNotThunk,
         SubclassScope::NotApplicable);
   }
 };
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index adda8dd..fadb8f0 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -41,12 +41,14 @@
 #include "llvm/Bitcode/RecordLayout.h"
 #include "llvm/Config/config.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/Support/Chrono.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/DJB.h"
 #include "llvm/Support/EndianStream.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/OnDiskHashTable.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include <vector>
@@ -720,6 +722,12 @@
   return {iter->getKey(), LastUniquedStringID};
 }
 
+IdentifierID Serializer::addFilename(StringRef filename) {
+  assert(!filename.empty() && "Attemping to add an empty filename");
+
+  return addUniquedString(filename).second;
+}
+
 IdentifierID Serializer::addModuleRef(const ModuleDecl *M) {
   if (M == this->M)
     return CURRENT_MODULE_ID;
@@ -813,6 +821,7 @@
   BLOCK_RECORD(options_block, XCC);
   BLOCK_RECORD(options_block, IS_SIB);
   BLOCK_RECORD(options_block, IS_TESTABLE);
+  BLOCK_RECORD(options_block, ARE_PRIVATE_IMPORTS_ENABLED);
   BLOCK_RECORD(options_block, RESILIENCE_STRATEGY);
 
   BLOCK(INPUT_BLOCK);
@@ -822,6 +831,7 @@
   BLOCK_RECORD(input_block, IMPORTED_HEADER_CONTENTS);
   BLOCK_RECORD(input_block, MODULE_FLAGS);
   BLOCK_RECORD(input_block, SEARCH_PATH);
+  BLOCK_RECORD(input_block, FILE_DEPENDENCY);
 
   BLOCK(DECLS_AND_TYPES_BLOCK);
 #define RECORD(X) BLOCK_RECORD(decls_block, X);
@@ -906,8 +916,6 @@
   BLOCK_RECORD_WITH_NAMESPACE(sil_block,
                               decls_block::GENERIC_PARAM_LIST);
   BLOCK_RECORD_WITH_NAMESPACE(sil_block,
-                              decls_block::GENERIC_PARAM);
-  BLOCK_RECORD_WITH_NAMESPACE(sil_block,
                               decls_block::GENERIC_REQUIREMENT);
   BLOCK_RECORD_WITH_NAMESPACE(sil_block,
                               decls_block::LAYOUT_REQUIREMENT);
@@ -966,6 +974,11 @@
         IsTestable.emit(ScratchRecord);
       }
 
+      if (M->arePrivateImportsEnabled()) {
+        options_block::ArePrivateImportsEnabledLayout PrivateImports(Out);
+        PrivateImports.emit(ScratchRecord);
+      }
+
       if (M->getResilienceStrategy() != ResilienceStrategy::Default) {
         options_block::ResilienceStrategyLayout Strategy(Out);
         Strategy.emit(ScratchRecord, unsigned(M->getResilienceStrategy()));
@@ -1026,6 +1039,7 @@
   input_block::ImportedHeaderLayout ImportedHeader(Out);
   input_block::ImportedHeaderContentsLayout ImportedHeaderContents(Out);
   input_block::SearchPathLayout SearchPath(Out);
+  input_block::FileDependencyLayout FileDependency(Out);
 
   if (options.SerializeOptionsForDebugging) {
     const SearchPathOptions &searchPathOpts = M->getASTContext().SearchPathOpts;
@@ -1038,6 +1052,12 @@
       SearchPath.emit(ScratchRecord, /*framework=*/false, /*system=*/false, path);
   }
 
+  for (auto const &dep : options.Dependencies) {
+    FileDependency.emit(ScratchRecord, dep.Size,
+                        llvm::sys::toTimeT(dep.LastModTime),
+                        dep.Path);
+  }
+
   SmallVector<ModuleDecl::ImportedModule, 8> allImports;
   M->getImportedModules(allImports, ModuleDecl::ImportFilter::All);
   ModuleDecl::removeDuplicateImports(allImports);
@@ -1136,20 +1156,6 @@
   llvm_unreachable("bad representation");
 }
 
-static uint8_t getRawStableAddressorKind(swift::AddressorKind kind) {
-  switch (kind) {
-  case swift::AddressorKind::NotAddressor:
-    return uint8_t(serialization::AddressorKind::NotAddressor);
-  case swift::AddressorKind::Unsafe:
-    return uint8_t(serialization::AddressorKind::Unsafe);
-  case swift::AddressorKind::Owning:
-    return uint8_t(serialization::AddressorKind::Owning);
-  case swift::AddressorKind::NativeOwning:
-    return uint8_t(serialization::AddressorKind::NativeOwning);
-  }
-  llvm_unreachable("bad addressor kind");
-}
-
 static uint8_t getRawStableResilienceExpansion(swift::ResilienceExpansion e) {
   switch (e) {
   case swift::ResilienceExpansion::Minimal:
@@ -1350,23 +1356,19 @@
   InlinableBodyTextLayout::emitRecord(Out, ScratchRecord, abbrCode, body);
 }
 
-bool Serializer::writeGenericParams(const GenericParamList *genericParams) {
+void Serializer::writeGenericParams(const GenericParamList *genericParams) {
   using namespace decls_block;
 
   // Don't write anything if there are no generic params.
   if (!genericParams)
-    return true;
+    return;
+
+  SmallVector<DeclID, 4> paramIDs;
+  for (auto next : genericParams->getParams())
+    paramIDs.push_back(addDeclRef(next));
 
   unsigned abbrCode = DeclTypeAbbrCodes[GenericParamListLayout::Code];
-  GenericParamListLayout::emitRecord(Out, ScratchRecord, abbrCode);
-
-  abbrCode = DeclTypeAbbrCodes[GenericParamLayout::Code];
-  for (auto next : genericParams->getParams()) {
-    GenericParamLayout::emitRecord(Out, ScratchRecord, abbrCode,
-                                   addDeclRef(next));
-  }
-
-  return true;
+  GenericParamListLayout::emitRecord(Out, ScratchRecord, abbrCode, paramIDs);
 }
 
 void Serializer::writeGenericSignature(const GenericSignature *sig) {
@@ -2176,6 +2178,7 @@
   case DAK_ObjCRuntimeName:
   case DAK_RestatedObjCConformance:
   case DAK_ClangImporterSynthesizedType:
+  case DAK_PrivateImport:
     llvm_unreachable("cannot serialize attribute");
 
   case DAK_Count:
@@ -2333,6 +2336,21 @@
     writeGenericRequirements(SA->getRequirements(), DeclTypeAbbrCodes);
     return;
   }
+
+  case DAK_DynamicReplacement: {
+    auto abbrCode = DeclTypeAbbrCodes[DynamicReplacementDeclAttrLayout::Code];
+    auto theAttr = cast<DynamicReplacementAttr>(DA);
+    auto replacedFun = theAttr->getReplacedFunctionName();
+    SmallVector<IdentifierID, 4> pieces;
+    pieces.push_back(addDeclBaseNameRef(replacedFun.getBaseName()));
+    for (auto argName : replacedFun.getArgumentNames())
+      pieces.push_back(addDeclBaseNameRef(argName));
+    assert(theAttr->getReplacedFunction());
+    DynamicReplacementDeclAttrLayout::emitRecord(
+        Out, ScratchRecord, abbrCode, false, /*implicit flag*/
+        addDeclRef(theAttr->getReplacedFunction()), pieces.size(), pieces);
+    return;
+  }
   }
 }
 
@@ -2643,17 +2661,36 @@
   if (auto *value = dyn_cast<ValueDecl>(D)) {
     if (value->getFormalAccess() <= swift::AccessLevel::FilePrivate &&
         !value->getDeclContext()->isLocalContext()) {
-      // FIXME: We shouldn't need to encode this for /all/ private decls.
-      // In theory we can follow the same rules as mangling and only include
-      // the outermost private context.
       auto topLevelContext = value->getDeclContext()->getModuleScopeContext();
       if (auto *enclosingFile = dyn_cast<FileUnit>(topLevelContext)) {
+        // FIXME: We shouldn't need to encode this for /all/ private decls.
+        // In theory we can follow the same rules as mangling and only include
+        // the outermost private context.
         Identifier discriminator =
           enclosingFile->getDiscriminatorForPrivateValue(value);
         unsigned abbrCode =
           DeclTypeAbbrCodes[PrivateDiscriminatorLayout::Code];
         PrivateDiscriminatorLayout::emitRecord(Out, ScratchRecord, abbrCode,
                                         addDeclBaseNameRef(discriminator));
+        auto getFilename = [](FileUnit *enclosingFile,
+                              const ValueDecl *decl) -> StringRef {
+          if (auto *SF = dyn_cast<SourceFile>(enclosingFile)) {
+            return llvm::sys::path::filename(SF->getFilename());
+          } else if (auto *LF = dyn_cast<LoadedFile>(enclosingFile)) {
+            return LF->getFilenameForPrivateDecl(decl);
+          }
+          return StringRef();
+        };
+        // Only if compiled with -enable-private-imports.
+        if (M->arePrivateImportsEnabled()) {
+          auto filename = getFilename(enclosingFile, value);
+          if (!filename.empty()) {
+            auto filenameID = addFilename(filename);
+            FilenameForPrivateLayout::emitRecord(
+                Out, ScratchRecord,
+                DeclTypeAbbrCodes[FilenameForPrivateLayout::Code], filenameID);
+          }
+        }
       }
     }
 
@@ -3191,6 +3228,7 @@
         getRawStableVarDeclSpecifier(param->getSpecifier()),
         addTypeRef(interfaceType),
         param->isVariadic(),
+        param->isAutoClosure(),
         getRawStableDefaultArgumentKind(param->getDefaultArgumentKind()),
         defaultArgumentText);
 
@@ -3272,8 +3310,6 @@
     uint8_t rawAccessLevel = getRawStableAccessLevel(fn->getFormalAccess());
     uint8_t rawAccessorKind =
       uint8_t(getStableAccessorKind(fn->getAccessorKind()));
-    uint8_t rawAddressorKind =
-      getRawStableAddressorKind(fn->getAddressorKind());
     uint8_t rawDefaultArgumentResilienceExpansion =
       getRawStableResilienceExpansion(
           fn->getDefaultArgumentResilienceExpansion());
@@ -3301,7 +3337,6 @@
                                addDeclRef(fn->getOverriddenDecl()),
                                addDeclRef(fn->getStorage()),
                                rawAccessorKind,
-                               rawAddressorKind,
                                rawAccessLevel,
                                fn->needsNewVTableEntry(),
                                rawDefaultArgumentResilienceExpansion,
@@ -3808,11 +3843,9 @@
       FunctionTypeLayout::emitRecord(Out, ScratchRecord, abbrCode,
              addTypeRef(fnTy->getResult()),
              getRawStableFunctionTypeRepresentation(fnTy->getRepresentation()),
-             fnTy->isAutoClosure(),
              fnTy->isNoEscape(),
              fnTy->throws());
     } else {
-      assert(!fnTy->isAutoClosure());
       assert(!fnTy->isNoEscape());
 
       auto *genericSig = cast<GenericFunctionType>(fnTy)->getGenericSignature();
@@ -4073,10 +4106,9 @@
   registerDeclTypeAbbr<TypedPatternLayout>();
   registerDeclTypeAbbr<InlinableBodyTextLayout>();
   registerDeclTypeAbbr<GenericParamListLayout>();
-  registerDeclTypeAbbr<GenericParamLayout>();
+  registerDeclTypeAbbr<GenericSignatureLayout>();
   registerDeclTypeAbbr<GenericRequirementLayout>();
   registerDeclTypeAbbr<LayoutRequirementLayout>();
-  registerDeclTypeAbbr<GenericSignatureLayout>();
   registerDeclTypeAbbr<SILGenericEnvironmentLayout>();
   registerDeclTypeAbbr<SubstitutionMapLayout>();
 
@@ -4106,6 +4138,7 @@
 
   registerDeclTypeAbbr<LocalDiscriminatorLayout>();
   registerDeclTypeAbbr<PrivateDiscriminatorLayout>();
+  registerDeclTypeAbbr<FilenameForPrivateLayout>();
   registerDeclTypeAbbr<MembersLayout>();
   registerDeclTypeAbbr<XRefLayout>();
 
diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h
index 12dee9c..3a9a4f5 100644
--- a/lib/Serialization/Serialization.h
+++ b/lib/Serialization/Serialization.h
@@ -342,8 +342,8 @@
   /// Writes the given pattern, recursively.
   void writePattern(const Pattern *pattern, DeclContext *owningDC);
 
-  /// Writes a generic parameter list.
-  bool writeGenericParams(const GenericParamList *genericParams);
+  /// Writes a generic parameter list, if non-null.
+  void writeGenericParams(const GenericParamList *genericParams);
 
   /// Writes the body text of the provided funciton, if the function is
   /// inlinable and has body text.
@@ -489,6 +489,13 @@
     return addUniquedString(str).second;
   }
 
+  /// Records the use of the given file name.
+  ///
+  /// The Identifier will be scheduled for serialization if necessary.
+  ///
+  /// \returns The ID for the given file name in this module.
+  IdentifierID addFilename(StringRef filename);
+
   /// Records the use of the given Decl.
   ///
   /// The Decl will be scheduled for serialization if necessary.
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index 65f1bf3..16e363e 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -385,6 +385,15 @@
   if (F.hasClangNode())
     clangNodeOwnerID = S.addDeclRef(F.getClangNodeOwner());
 
+  IdentifierID replacedFunctionID = 0;
+  if (auto *fun = F.getDynamicallyReplacedFunction()) {
+    addReferencedSILFunction(fun, true);
+    replacedFunctionID = S.addUniquedStringRef(fun->getName());
+  }
+  else if (F.hasObjCReplacement()) {
+    replacedFunctionID =
+        S.addUniquedStringRef(F.getObjCReplacement().str());
+  }
   unsigned numSpecAttrs = NoBody ? 0 : F.getSpecializeAttrs().size();
   SILFunctionLayout::emitRecord(
       Out, ScratchRecord, abbrCode, toStableSILLinkage(Linkage),
@@ -393,7 +402,8 @@
       (unsigned)F.isGlobalInit(), (unsigned)F.getInlineStrategy(),
       (unsigned)F.getOptimizationMode(), (unsigned)F.getEffectsKind(),
       (unsigned)numSpecAttrs, (unsigned)F.hasQualifiedOwnership(),
-      F.isWeakLinked(), FnID, genericEnvID, clangNodeOwnerID, SemanticsIDs);
+      F.isWeakLinked(), (unsigned)F.isDynamicallyReplaceable(), FnID,
+      replacedFunctionID, genericEnvID, clangNodeOwnerID, SemanticsIDs);
 
   if (NoBody)
     return;
@@ -1291,6 +1301,34 @@
 
     break;
   }
+  case SILInstructionKind::DynamicFunctionRefInst: {
+    // Use SILOneOperandLayout to specify the function type and the function
+    // name (IdentifierID).
+    const auto *FRI = cast<DynamicFunctionRefInst>(&SI);
+    SILFunction *ReferencedFunction = FRI->getReferencedFunction();
+    unsigned abbrCode = SILAbbrCodes[SILOneOperandLayout::Code];
+    SILOneOperandLayout::emitRecord(Out, ScratchRecord, abbrCode,
+        (unsigned)SI.getKind(), 0,
+        S.addTypeRef(FRI->getType().getASTType()),
+        (unsigned)FRI->getType().getCategory(),
+        addSILFunctionRef(ReferencedFunction));
+
+    break;
+  }
+  case SILInstructionKind::PreviousDynamicFunctionRefInst: {
+    // Use SILOneOperandLayout to specify the function type and the function
+    // name (IdentifierID).
+    const auto *FRI = cast<PreviousDynamicFunctionRefInst>(&SI);
+    SILFunction *ReferencedFunction = FRI->getReferencedFunction();
+    unsigned abbrCode = SILAbbrCodes[SILOneOperandLayout::Code];
+    SILOneOperandLayout::emitRecord(Out, ScratchRecord, abbrCode,
+        (unsigned)SI.getKind(), 0,
+        S.addTypeRef(FRI->getType().getASTType()),
+        (unsigned)FRI->getType().getCategory(),
+        addSILFunctionRef(ReferencedFunction));
+
+    break;
+  }
   case SILInstructionKind::CopyBlockWithoutEscapingInst:
   case SILInstructionKind::DeallocPartialRefInst:
   case SILInstructionKind::MarkDependenceInst:
diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp
index 5105e5f..f0ac31e 100644
--- a/lib/Serialization/SerializedModuleLoader.cpp
+++ b/lib/Serialization/SerializedModuleLoader.cpp
@@ -117,6 +117,13 @@
     }
   }
 
+  if (foundArchs.empty()) {
+    // Maybe this swiftmodule directory only contains swiftinterfaces, or
+    // maybe something else is going on. Regardless, we shouldn't emit a
+    // possibly incorrect diagnostic.
+    return;
+  }
+
   ctx.Diags.diagnose(sourceLocation, diag::sema_no_import_arch, moduleName,
                      archName, foundArchs);
 }
@@ -304,6 +311,8 @@
     M.addFile(*fileUnit);
     if (extendedInfo.isTestable())
       M.setTestingEnabled();
+    if (extendedInfo.arePrivateImportsEnabled())
+      M.setPrivateImportsEnabled();
 
     auto diagLocOrInvalid = diagLoc.getValueOr(SourceLoc());
     loadInfo.status =
diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp
index 455fb43..2e9be82 100644
--- a/lib/TBDGen/TBDGen.cpp
+++ b/lib/TBDGen/TBDGen.cpp
@@ -164,6 +164,17 @@
 
   addSymbol(SILDeclRef(AFD));
 
+  // Add the global function pointer for a dynamically replaceable function.
+  if (AFD->isDynamic() && ! AFD->isObjC()) {
+    addSymbol(LinkEntity::forDynamicallyReplaceableFunctionVariable(AFD));
+    addSymbol(LinkEntity::forDynamicallyReplaceableFunctionImpl(AFD));
+    addSymbol(LinkEntity::forDynamicallyReplaceableFunctionKey(AFD));
+  }
+  if (AFD->getAttrs().hasAttribute<DynamicReplacementAttr>()) {
+    addSymbol(LinkEntity::forDynamicallyReplaceableFunctionVariable(AFD));
+    addSymbol(LinkEntity::forDynamicallyReplaceableFunctionImpl(AFD));
+  }
+
   if (AFD->getAttrs().hasAttribute<CDeclAttr>()) {
     // A @_cdecl("...") function has an extra symbol, with the name from the
     // attribute.
diff --git a/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb b/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb
new file mode 100644
index 0000000..bcc138a
--- /dev/null
+++ b/stdlib/private/SwiftPrivate/AtomicInt.swift.gyb
@@ -0,0 +1,129 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 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 Swift
+
+public final class _stdlib_AtomicInt {
+  internal var _value: Int
+
+  internal var _valuePtr: UnsafeMutablePointer<Int> {
+    return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
+      to: Int.self)
+  }
+
+  public init(_ value: Int = 0) {
+    _value = value
+  }
+
+  public func store(_ desired: Int) {
+    return _swift_stdlib_atomicStoreInt(object: _valuePtr, desired: desired)
+  }
+
+  public func load() -> Int {
+    return _swift_stdlib_atomicLoadInt(object: _valuePtr)
+  }
+
+% for operation_name, operation in [ ('Add', '+'), ('And', '&'), ('Or', '|'), ('Xor', '^') ]:
+  @discardableResult
+  public func fetchAnd${operation_name}(_ operand: Int) -> Int {
+    return _swift_stdlib_atomicFetch${operation_name}Int(
+      object: _valuePtr,
+      operand: operand)
+  }
+
+  public func ${operation_name.lower()}AndFetch(_ operand: Int) -> Int {
+    return fetchAnd${operation_name}(operand) ${operation} operand
+  }
+% end
+
+  public func compareExchange(expected: inout Int, desired: Int) -> Bool {
+    var expectedVar = expected
+    let result = _stdlib_atomicCompareExchangeStrongInt(
+      object: _valuePtr,
+      expected: &expectedVar,
+      desired: desired)
+    expected = expectedVar
+    return result
+  }
+}
+
+public func _swift_stdlib_atomicLoadInt(
+  object target: UnsafeMutablePointer<Int>) -> Int {
+#if arch(i386) || arch(arm)
+  let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
+  return Int(value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+  let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
+  return Int(value)
+#endif
+}
+
+public func _swift_stdlib_atomicStoreInt(
+  object target: UnsafeMutablePointer<Int>,
+  desired: Int) {
+#if arch(i386) || arch(arm)
+  Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+  Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
+#endif
+}
+
+public func _stdlib_atomicCompareExchangeStrongInt(
+  object target: UnsafeMutablePointer<Int>,
+  expected: UnsafeMutablePointer<Int>,
+  desired: Int) -> Bool {
+#if arch(i386) || arch(arm)
+  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
+    target._rawValue, expected.pointee._value, desired._value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
+    target._rawValue, expected.pointee._value, desired._value)
+#endif
+  expected.pointee._value = oldValue
+  return Bool(won)
+}
+
+% for operation in ['Add', 'And', 'Or', 'Xor']:
+// Warning: no overflow checking.
+public func _swift_stdlib_atomicFetch${operation}Int(
+  object target: UnsafeMutablePointer<Int>,
+  operand: Int) -> Int {
+  let rawTarget = UnsafeMutableRawPointer(target)
+#if arch(i386) || arch(arm)
+  let value = _swift_stdlib_atomicFetch${operation}Int32(
+    object: rawTarget.assumingMemoryBound(to: Int32.self),
+    operand: Int32(operand))
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+  let value = _swift_stdlib_atomicFetch${operation}Int64(
+    object: rawTarget.assumingMemoryBound(to: Int64.self),
+    operand: Int64(operand))
+#endif
+  return Int(value)
+}
+
+%   for bits in [ 32, 64 ]:
+
+// Warning: no overflow checking.
+public func _swift_stdlib_atomicFetch${operation}Int${bits}(
+  object target: UnsafeMutablePointer<Int${bits}>,
+  operand: Int${bits}) -> Int${bits} {
+
+  let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
+    target._rawValue, operand._value)
+
+  return Int${bits}(value)
+}
+
+%   end
+
+% end
+
diff --git a/stdlib/private/SwiftPrivate/CMakeLists.txt b/stdlib/private/SwiftPrivate/CMakeLists.txt
index 2e13567..566f0db 100644
--- a/stdlib/private/SwiftPrivate/CMakeLists.txt
+++ b/stdlib/private/SwiftPrivate/CMakeLists.txt
@@ -1,18 +1,16 @@
+set(swift_swiftprivate_compile_flags
+    "-parse-stdlib"
+    "-Xfrontend" "-disable-access-control")
+
 add_swift_target_library(swiftSwiftPrivate ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
   # This file should be listed the first.  Module name is inferred from the
   # filename.
   SwiftPrivate.swift
+
+  AtomicInt.swift.gyb
   IO.swift
   ShardedAtomicCounter.swift
 
-  SWIFT_MODULE_DEPENDS_IOS Darwin
-  SWIFT_MODULE_DEPENDS_OSX Darwin
-  SWIFT_MODULE_DEPENDS_TVOS Darwin
-  SWIFT_MODULE_DEPENDS_WATCHOS Darwin
-  SWIFT_MODULE_DEPENDS_LINUX Glibc
-  SWIFT_MODULE_DEPENDS_FREEBSD Glibc
-  SWIFT_MODULE_DEPENDS_CYGWIN Glibc
-  SWIFT_MODULE_DEPENDS_HAIKU Glibc
-  SWIFT_COMPILE_FLAGS
+  SWIFT_COMPILE_FLAGS ${swift_swiftprivate_compile_flags}
   INSTALL_IN_COMPONENT stdlib-experimental)
 
diff --git a/stdlib/private/SwiftPrivate/IO.swift b/stdlib/private/SwiftPrivate/IO.swift
index 1d648c2..baaf6e8 100644
--- a/stdlib/private/SwiftPrivate/IO.swift
+++ b/stdlib/private/SwiftPrivate/IO.swift
@@ -10,8 +10,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+import Swift
 import SwiftShims
-import SwiftOverlayShims
 
 public struct _FDInputStream {
   public let fd: CInt
diff --git a/stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift b/stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift
index f56c396..be5eb6b 100644
--- a/stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift
+++ b/stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+import Swift
 import SwiftShims
 
 public func _stdlib_getHardwareConcurrency() -> Int {
diff --git a/stdlib/private/SwiftPrivate/SwiftPrivate.swift b/stdlib/private/SwiftPrivate/SwiftPrivate.swift
index d2f21cb..c92c007 100644
--- a/stdlib/private/SwiftPrivate/SwiftPrivate.swift
+++ b/stdlib/private/SwiftPrivate/SwiftPrivate.swift
@@ -2,7 +2,7 @@
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Copyright (c) 2014 - 2018 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
@@ -10,21 +10,22 @@
 //
 //===----------------------------------------------------------------------===//
 
+import Swift
 import SwiftShims
 
 /// Convert the given numeric value to a hexadecimal string.
-  // FIXME(integers): support a more general BinaryInteger protocol
+// FIXME(integers): support a more general BinaryInteger protocol
 public func asHex<T : FixedWidthInteger>(_ x: T) -> String {
-  return "0x" + String(x, radix: 16)
+  return "0x\(String(x, radix: 16))"
 }
 
 /// Convert the given sequence of numeric values to a string representing
 /// their hexadecimal values.
-  // FIXME(integers): support a more general BinaryInteger protocol
+// FIXME(integers): support a more general BinaryInteger protocol
 public func asHex<S : Sequence>(_ x: S) -> String
   where
   S.Element : FixedWidthInteger {
-  return "[ " + x.lazy.map { asHex($0) }.joined(separator: ", ") + " ]"
+  return "[ \(x.lazy.map { asHex($0) }.joined(separator: ", ")) ]"
 }
 
 /// Compute the prefix sum of `seq`.
@@ -62,14 +63,12 @@
   let argsCounts = Array(args.map { $0.utf8.count + 1 })
   let argsOffsets = [ 0 ] + scan(argsCounts, 0, +)
   let argsBufferSize = argsOffsets.last!
-
   var argsBuffer: [UInt8] = []
   argsBuffer.reserveCapacity(argsBufferSize)
   for arg in args {
     argsBuffer.append(contentsOf: arg.utf8)
     argsBuffer.append(0)
   }
-
   return argsBuffer.withUnsafeMutableBufferPointer {
     (argsBuffer) in
     let ptr = UnsafeMutableRawPointer(argsBuffer.baseAddress!).bindMemory(
diff --git a/stdlib/public/CMakeLists.txt b/stdlib/public/CMakeLists.txt
index 731051a..a3fddfa 100644
--- a/stdlib/public/CMakeLists.txt
+++ b/stdlib/public/CMakeLists.txt
@@ -13,7 +13,7 @@
   endif()
 endif()
 
-list(APPEND SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS "-Xfrontend" "-verify-syntax-tree" "-Xfrontend" "-enable-operator-designated-types")
+list(APPEND SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS "-Xfrontend" "-verify-syntax-tree")
 
 # Build the runtime with -Wall to catch, e.g., uninitialized variables
 # warnings.
diff --git a/stdlib/public/Platform/glibc.modulemap.gyb b/stdlib/public/Platform/glibc.modulemap.gyb
index 60e466a..b024b92 100644
--- a/stdlib/public/Platform/glibc.modulemap.gyb
+++ b/stdlib/public/Platform/glibc.modulemap.gyb
@@ -120,6 +120,9 @@
       export *
     }
     module math {
+% if CMAKE_SDK == "LINUX":
+      link "m"
+% end
       header "${GLIBC_INCLUDE_PATH}/math.h"
       export *
     }
diff --git a/stdlib/public/Reflection/CMakeLists.txt b/stdlib/public/Reflection/CMakeLists.txt
index 8a31278..f670fb2 100644
--- a/stdlib/public/Reflection/CMakeLists.txt
+++ b/stdlib/public/Reflection/CMakeLists.txt
@@ -19,24 +19,31 @@
     "${SWIFT_SOURCE_DIR}/lib/Demangling/NodeDumper.cpp")
 endif(LLVM_ENABLE_ASSERTIONS)
 
-add_swift_target_library(swiftReflection STATIC TARGET_LIBRARY
-  ${swiftReflection_SOURCES}
-  C_COMPILE_FLAGS ${SWIFT_RUNTIME_CXX_FLAGS}
-  LINK_FLAGS ${SWIFT_RUNTIME_LINK_FLAGS}
-  INSTALL_IN_COMPONENT dev)
+if(SWIFT_BUILD_STDLIB)
+  add_swift_target_library(swiftReflection STATIC TARGET_LIBRARY
+    ${swiftReflection_SOURCES}
+    C_COMPILE_FLAGS ${SWIFT_RUNTIME_CXX_FLAGS}
+    LINK_FLAGS ${SWIFT_RUNTIME_LINK_FLAGS}
+    INSTALL_IN_COMPONENT dev)
+endif()
 
 # Build a specific version for the host with the host toolchain.  This is going
 # to be used by tools (e.g. lldb)
+if(SWIFT_INCLUDE_TOOLS)
+  if(NOT SWIFT_BUILD_STDLIB)
+    add_custom_target(swiftReflection-${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR})
+  endif()
 
-if(NOT SWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER)
-  set(CMAKE_C_COMPILER ${HOST_CMAKE_C_COMPILER})
-  set(CMAKE_CXX_COMPILER ${HOST_CMAKE_CXX_COMPILER})
+  if(NOT SWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER)
+    set(CMAKE_C_COMPILER ${HOST_CMAKE_C_COMPILER})
+    set(CMAKE_CXX_COMPILER ${HOST_CMAKE_CXX_COMPILER})
+  endif()
+
+  add_swift_host_library(swiftReflection STATIC
+    ${swiftReflection_SOURCES})
+  target_compile_options(swiftReflection PRIVATE
+    ${SWIFT_RUNTIME_CXX_FLAGS})
+  set_property(TARGET swiftReflection
+    APPEND_STRING PROPERTY LINK_FLAGS ${SWIFT_RUNTIME_LINK_FLAGS})
 endif()
 
-add_swift_host_library(swiftReflection STATIC
-  ${swiftReflection_SOURCES})
-target_compile_options(swiftReflection PRIVATE
-  ${SWIFT_RUNTIME_CXX_FLAGS})
-set_property(TARGET swiftReflection
-  APPEND_STRING PROPERTY LINK_FLAGS ${SWIFT_RUNTIME_LINK_FLAGS})
-
diff --git a/stdlib/public/Reflection/TypeLowering.cpp b/stdlib/public/Reflection/TypeLowering.cpp
index c3bd877..b01397c 100644
--- a/stdlib/public/Reflection/TypeLowering.cpp
+++ b/stdlib/public/Reflection/TypeLowering.cpp
@@ -18,6 +18,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "swift/ABI/Enum.h"
 #include "swift/Reflection/TypeLowering.h"
 #include "swift/Reflection/TypeRef.h"
 #include "swift/Reflection/TypeRefBuilder.h"
@@ -77,6 +78,7 @@
     printField("alignment", TI.getAlignment());
     printField("stride", TI.getStride());
     printField("num_extra_inhabitants", TI.getNumExtraInhabitants());
+    printField("bitwise_takable", TI.isBitwiseTakable());
   }
 
   void printFields(const RecordTypeInfo &TI) {
@@ -190,8 +192,12 @@
 }
 
 BuiltinTypeInfo::BuiltinTypeInfo(const BuiltinTypeDescriptor *descriptor)
-    : TypeInfo(TypeInfoKind::Builtin, descriptor->Size, descriptor->Alignment,
-               descriptor->Stride, descriptor->NumExtraInhabitants),
+    : TypeInfo(TypeInfoKind::Builtin,
+               descriptor->Size,
+               descriptor->getAlignment(),
+               descriptor->Stride,
+               descriptor->NumExtraInhabitants,
+               descriptor->isBitwiseTakable()),
       Name(descriptor->getMangledTypeName(0)) {}
 
 /// Utility class for building values that contain witness tables.
@@ -263,6 +269,29 @@
         case FieldDescriptorKind::ClassProtocol:
           Representation = ExistentialTypeRepresentation::Class;
           WitnessTableCount++;
+
+          if (auto *Superclass = TC.getBuilder().lookupSuperclass(P)) {
+            auto *SuperclassTI = TC.getTypeInfo(Superclass);
+            if (SuperclassTI == nullptr) {
+              DEBUG_LOG(std::cerr << "No TypeInfo for superclass: ";
+                        Superclass->dump());
+              Invalid = true;
+              continue;
+            }
+
+            if (!isa<ReferenceTypeInfo>(SuperclassTI)) {
+              DEBUG_LOG(std::cerr << "Superclass not a reference type: ";
+                        SuperclassTI->dump());
+              Invalid = true;
+              continue;
+            }
+
+            if (cast<ReferenceTypeInfo>(SuperclassTI)->getReferenceCounting()
+                == ReferenceCounting::Native) {
+              Refcounting = ReferenceCounting::Native;
+            }
+          }
+
           continue;
         case FieldDescriptorKind::Protocol:
           WitnessTableCount++;
@@ -397,9 +426,12 @@
 
       // Non-class existentials consist of a three-word buffer,
       // value metadata, and finally zero or more witness tables.
+      // The buffer is always bitwise takable, since non-bitwise
+      // takable payloads are stored out of line.
       builder.addField(TI->getSize() * 3,
                        TI->getAlignment(),
-                       /*numExtraInhabitants=*/0);
+                       /*numExtraInhabitants=*/0,
+                       /*bitwiseTakable=*/true);
       builder.addField("metadata", TC.getAnyMetatypeTypeRef());
       break;
     }
@@ -441,7 +473,8 @@
 
 unsigned RecordTypeInfoBuilder::addField(unsigned fieldSize,
                                          unsigned fieldAlignment,
-                                         unsigned numExtraInhabitants) {
+                                         unsigned numExtraInhabitants,
+                                         bool bitwiseTakable) {
   assert(fieldAlignment > 0);
 
   // Align the current size appropriately
@@ -456,6 +489,9 @@
   // Update the aggregate alignment
   Alignment = std::max(Alignment, fieldAlignment);
 
+  // The aggregate is bitwise takable if all elements are.
+  BitwiseTakable &= bitwiseTakable;
+
   switch (Kind) {
   // The extra inhabitants of a struct or tuple are the same as the extra
   // inhabitants of the field that has the most.
@@ -500,7 +536,8 @@
 
   unsigned offset = addField(TI->getSize(),
                              TI->getAlignment(),
-                             TI->getNumExtraInhabitants());
+                             TI->getNumExtraInhabitants(),
+                             TI->isBitwiseTakable());
   Fields.push_back({Name, offset, TR, *TI});
 }
 
@@ -515,7 +552,8 @@
 
   return TC.makeTypeInfo<RecordTypeInfo>(
       Size, Alignment, Stride,
-      NumExtraInhabitants, Kind, Fields);
+      NumExtraInhabitants, BitwiseTakable,
+      Kind, Fields);
 }
 
 const ReferenceTypeInfo *
@@ -548,13 +586,28 @@
   }
 
   unsigned numExtraInhabitants = BuiltinTI->NumExtraInhabitants;
-  if (Kind == ReferenceKind::Weak)
+  bool bitwiseTakable = true;
+
+  switch (Kind) {
+  case ReferenceKind::Strong:
+    break;
+  case ReferenceKind::Weak:
     numExtraInhabitants = 0;
+    bitwiseTakable = false;
+    break;
+  case ReferenceKind::Unowned:
+    if (Refcounting == ReferenceCounting::Unknown)
+      bitwiseTakable = false;
+    break;
+  case ReferenceKind::Unmanaged:
+    break;
+  }
 
   auto *TI = makeTypeInfo<ReferenceTypeInfo>(BuiltinTI->Size,
-                                             BuiltinTI->Alignment,
+                                             BuiltinTI->getAlignment(),
                                              BuiltinTI->Stride,
                                              numExtraInhabitants,
+                                             bitwiseTakable,
                                              Kind, Refcounting);
   ReferenceCache[key] = TI;
   return TI;
@@ -619,7 +672,12 @@
   if (EmptyTI != nullptr)
     return EmptyTI;
 
-  EmptyTI = makeTypeInfo<TypeInfo>(TypeInfoKind::Builtin, 0, 1, 1, 0);
+  EmptyTI = makeTypeInfo<TypeInfo>(TypeInfoKind::Builtin,
+                                   /*Size=*/0,
+                                   /*Alignment=*/1,
+                                   /*Stride=*/1,
+                                   /*ExtraInhabitants=*/0,
+                                   /*BitwiseTakable=*/true);
   return EmptyTI;
 }
 
@@ -891,34 +949,10 @@
   }
 };
 
-// Copy-and-pasted from stdlib/public/runtime/Enum.cpp -- should probably go
-// in a header somewhere, since the formula is part of the ABI.
-static unsigned getNumTagBytes(size_t size, unsigned emptyCases,
-                               unsigned payloadCases) {
-  // We can use the payload area with a tag bit set somewhere outside of the
-  // payload area to represent cases. See how many bytes we need to cover
-  // all the empty cases.
-
-  unsigned numTags = payloadCases;
-  if (emptyCases > 0) {
-    if (size >= 4)
-      // Assume that one tag bit is enough if the precise calculation overflows
-      // an int32.
-      numTags += 1;
-    else {
-      unsigned bits = size * 8U;
-      unsigned casesPerTagBitValue = 1U << bits;
-      numTags += ((emptyCases + (casesPerTagBitValue-1U)) >> bits);
-    }
-  }
-  return (numTags <=    1 ? 0 :
-          numTags <   256 ? 1 :
-          numTags < 65536 ? 2 : 4);
-}
-
 class EnumTypeInfoBuilder {
   TypeConverter &TC;
   unsigned Size, Alignment, NumExtraInhabitants;
+  bool BitwiseTakable;
   RecordKind Kind;
   std::vector<FieldInfo> Cases;
   bool Invalid;
@@ -942,6 +976,7 @@
 
     Size = std::max(Size, TI->getSize());
     Alignment = std::max(Alignment, TI->getAlignment());
+    BitwiseTakable &= TI->isBitwiseTakable();
 
     Cases.push_back({Name, /*offset=*/0, TR, *TI});
   }
@@ -949,7 +984,7 @@
 public:
   EnumTypeInfoBuilder(TypeConverter &TC)
     : TC(TC), Size(0), Alignment(1), NumExtraInhabitants(0),
-      Kind(RecordKind::Invalid), Invalid(false) {}
+      BitwiseTakable(true), Kind(RecordKind::Invalid), Invalid(false) {}
 
   const TypeInfo *
   build(const TypeRef *TR,
@@ -976,9 +1011,9 @@
     // NoPayloadEnumImplStrategy
     if (PayloadCases.empty()) {
       Kind = RecordKind::NoPayloadEnum;
-      Size += getNumTagBytes(/*size=*/0,
-                             NoPayloadCases,
-                             /*payloadCases=*/0);
+      Size += getEnumTagCounts(/*size=*/0,
+                               NoPayloadCases,
+                               /*payloadCases=*/0).numTagBytes;
 
     // SinglePayloadEnumImplStrategy
     } else if (PayloadCases.size() == 1) {
@@ -1006,9 +1041,9 @@
           // Not enough extra inhabitants for all cases. We have to add an
           // extra tag field.
           NumExtraInhabitants = 0;
-          Size += getNumTagBytes(Size,
-                                 NoPayloadCases - NumExtraInhabitants,
-                                 /*payloadCases=*/1);
+          Size += getEnumTagCounts(Size,
+                                   NoPayloadCases - NumExtraInhabitants,
+                                   /*payloadCases=*/1).numTagBytes;
         }
       }
 
@@ -1028,17 +1063,24 @@
       auto *FixedDescriptor = TC.getBuilder().getBuiltinTypeInfo(TR);
       if (FixedDescriptor) {
         Size = FixedDescriptor->Size;
-        Alignment = FixedDescriptor->Alignment;
+        Alignment = FixedDescriptor->getAlignment();
         NumExtraInhabitants = FixedDescriptor->NumExtraInhabitants;
+        BitwiseTakable = FixedDescriptor->isBitwiseTakable();
       } else {
-        // Dynamic multi-payload enums do not have extra inhabitants
-        NumExtraInhabitants = 0;
-
         // Dynamic multi-payload enums always use an extra tag to differentiate
         // between cases
-        Size += getNumTagBytes(Size,
-                               NoPayloadCases,
-                               PayloadCases.size());
+        auto tagCounts = getEnumTagCounts(Size, NoPayloadCases,
+                                          PayloadCases.size());
+        
+        Size += tagCounts.numTagBytes;
+        // Dynamic multi-payload enums use the tag representations not assigned
+        // to cases for extra inhabitants.
+        if (tagCounts.numTagBytes >= 32) {
+          NumExtraInhabitants = INT_MAX;
+        } else {
+          NumExtraInhabitants =
+            (1 << (tagCounts.numTagBytes * 8)) - tagCounts.numTags;
+        }
       }
     }
 
@@ -1052,7 +1094,8 @@
 
     return TC.makeTypeInfo<RecordTypeInfo>(
         Size, Alignment, Stride,
-        NumExtraInhabitants, Kind, Cases);
+        NumExtraInhabitants, BitwiseTakable,
+        Kind, Cases);
   }
 };
 
@@ -1263,10 +1306,12 @@
       // Destructure the existential and replace the "object"
       // field with the right reference kind.
       } else if (SubKind == RecordKind::ClassExistential) {
+        bool BitwiseTakable = RecordTI->isBitwiseTakable();
         std::vector<FieldInfo> Fields;
         for (auto &Field : RecordTI->getFields()) {
           if (Field.Name == "object") {
             auto *FieldTI = rebuildStorageTypeInfo(&Field.TI, Kind);
+            BitwiseTakable &= FieldTI->isBitwiseTakable();
             Fields.push_back({Field.Name, Field.Offset, Field.TR, *FieldTI});
             continue;
           }
@@ -1278,6 +1323,7 @@
             RecordTI->getAlignment(),
             RecordTI->getStride(),
             RecordTI->getNumExtraInhabitants(),
+            BitwiseTakable,
             SubKind, Fields);
       }
     }
@@ -1354,7 +1400,10 @@
 
     // Start layout from the given instance start offset. This should
     // be the superclass instance size.
-    builder.addField(start, 1, /*numExtraInhabitants=*/0);
+    builder.addField(/*size=*/start,
+                     /*alignment=*/1,
+                     /*numExtraInhabitants=*/0,
+                     /*bitwiseTakable=*/true);
 
     for (auto Field : Fields)
       builder.addField(Field.Name, Field.TR);
diff --git a/stdlib/public/Reflection/TypeRefBuilder.cpp b/stdlib/public/Reflection/TypeRefBuilder.cpp
index 445e438..b3ff506 100644
--- a/stdlib/public/Reflection/TypeRefBuilder.cpp
+++ b/stdlib/public/Reflection/TypeRefBuilder.cpp
@@ -124,6 +124,9 @@
   if (FD.first == nullptr)
     return nullptr;
 
+  if (!FD.first->hasSuperclass())
+    return nullptr;
+
   auto TypeRefOffset = FD.second->Field.SectionOffset
                      - FD.second->TypeReference.SectionOffset;
   auto Demangled = Dem.demangleType(FD.first->getSuperclass(TypeRefOffset));
@@ -233,7 +236,7 @@
                             - Info.TypeReference.SectionOffset;
     for (auto &BuiltinTypeDescriptor : Info.Builtin.Metadata) {
       assert(BuiltinTypeDescriptor.Size > 0);
-      assert(BuiltinTypeDescriptor.Alignment > 0);
+      assert(BuiltinTypeDescriptor.getAlignment() > 0);
       assert(BuiltinTypeDescriptor.Stride > 0);
       if (!BuiltinTypeDescriptor.hasMangledTypeName())
         continue;
@@ -387,9 +390,10 @@
 
       OS << "\n- " << typeName << ":\n";
       OS << "Size: " << descriptor.Size << "\n";
-      OS << "Alignment: " << descriptor.Alignment << "\n";
+      OS << "Alignment: " << descriptor.getAlignment() << "\n";
       OS << "Stride: " << descriptor.Stride << "\n";
       OS << "NumExtraInhabitants: " << descriptor.NumExtraInhabitants << "\n";
+      OS << "BitwiseTakable: " << descriptor.isBitwiseTakable() << "\n";
     }
   }
 }
diff --git a/stdlib/public/SDK/GLKit/GLKMath.swift.gyb b/stdlib/public/SDK/GLKit/GLKMath.swift.gyb
index 6a5ca2e..d868f99 100644
--- a/stdlib/public/SDK/GLKit/GLKMath.swift.gyb
+++ b/stdlib/public/SDK/GLKit/GLKMath.swift.gyb
@@ -21,7 +21,7 @@
 // types.
 
 // Do dirty pointer manipulations to index an opaque struct like an array.
-@inline(__always)
+@inlinable @inline(__always)
 public func _indexHomogeneousValue<TTT, T>(_ aggregate: UnsafePointer<TTT>,
                                            _ index: Int) -> T {
   return UnsafeRawPointer(aggregate).load(
@@ -31,7 +31,7 @@
 %{
 def defineSubscript(Type, limit):
   return """
-  public subscript(i: Int) -> Float {{
+  @inlinable public subscript(i: Int) -> Float {{
     @inline(__always)
     get {{
       precondition(i >= 0, "Negative {0} index out of range")
diff --git a/stdlib/public/SDK/XCTest/XCTest.swift b/stdlib/public/SDK/XCTest/XCTest.swift
index b6ae6fd..b046fd5 100644
--- a/stdlib/public/SDK/XCTest/XCTest.swift
+++ b/stdlib/public/SDK/XCTest/XCTest.swift
@@ -146,17 +146,17 @@
     if !passed {
       // TODO: @auto_string expression
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr as NSString), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr as NSString), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertNil failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertNil failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
@@ -185,23 +185,23 @@
     if !passed {
       // TODO: @auto_string expression
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr as NSString), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr as NSString), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertNotNil failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertNotNil failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
 public func XCTAssert(_ expression: @autoclosure () throws -> Bool, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
   // XCTAssert is just a cover for XCTAssertTrue.
-  XCTAssertTrue(expression, message, file: file, line: line)
+  XCTAssertTrue(try expression(), message(), file: file, line: line)
 }
 
 public func XCTAssertTrue(_ expression: @autoclosure () throws -> Bool, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
@@ -221,17 +221,17 @@
     if !expressionValue {
       // TODO: @auto_string expression
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertTrue failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertTrue failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
@@ -252,17 +252,17 @@
     if expressionValue {
       // TODO: @auto_string expression
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertFalse failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertFalse failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
@@ -290,17 +290,17 @@
       let expressionValueStr1 = "\(expressionValue1)"
       let expressionValueStr2 = "\(expressionValue2)"
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertEqual failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertEqual failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
@@ -328,17 +328,17 @@
       let expressionValueStr1 = "\(expressionValue1)"
       let expressionValueStr2 = "\(expressionValue2)"
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertNotEqual failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertNotEqual failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
@@ -399,23 +399,23 @@
       let expressionValueStr2 = "\(expressionValue2)"
       let accuracyStr = "\(accuracy)"
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString, accuracyStr as NSString), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString, accuracyStr as NSString), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertEqual failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertEqual failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
 @available(*, deprecated, renamed: "XCTAssertEqual(_:_:accuracy:file:line:)")
 public func XCTAssertEqualWithAccuracy<T : FloatingPoint>(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
-  XCTAssertEqual(expression1, expression2, accuracy: accuracy, message, file: file, line: line)
+  XCTAssertEqual(try expression1(), try expression2(), accuracy: accuracy, message(), file: file, line: line)
 }
 
 func _XCTCheckNotEqualWithAccuracy_Double(_ value1: Double, _ value2: Double, _ accuracy: Double) -> Bool {
@@ -475,23 +475,23 @@
       let expressionValueStr2 = "\(expressionValue2)"
       let accuracyStr = "\(accuracy)"
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString, accuracyStr as NSString), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString, accuracyStr as NSString), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertNotEqual failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertNotEqual failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
 @available(*, deprecated, renamed: "XCTAssertNotEqual(_:_:accuracy:file:line:)")
 public func XCTAssertNotEqualWithAccuracy<T : FloatingPoint>(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, _ accuracy: T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    XCTAssertNotEqual(expression1, expression2, accuracy: accuracy, message, file: file, line: line)
+    XCTAssertNotEqual(try expression1(), try expression2(), accuracy: accuracy, message(), file: file, line: line)
 }
 
 public func XCTAssertGreaterThan<T : Comparable>(_ expression1: @autoclosure () throws -> T, _ expression2: @autoclosure () throws -> T, _ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) {
@@ -518,17 +518,17 @@
     let expressionValueStr1 = "\(expressionValue1)"
     let expressionValueStr2 = "\(expressionValue2)"
     
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message(), file, line)
   }
   
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertGreaterThan failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertGreaterThan failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
@@ -557,17 +557,17 @@
       let expressionValueStr1 = "\(expressionValue1)"
       let expressionValueStr2 = "\(expressionValue2)"
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertGreaterThanOrEqual failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertGreaterThanOrEqual failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
@@ -595,17 +595,17 @@
       let expressionValueStr1 = "\(expressionValue1)"
       let expressionValueStr2 = "\(expressionValue2)"
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertLessThan failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertLessThan failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
@@ -634,17 +634,17 @@
       let expressionValueStr1 = "\(expressionValue1)"
       let expressionValueStr2 = "\(expressionValue2)"
       
-      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message, file, line)
+      _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 0, expressionValueStr1 as NSString, expressionValueStr2 as NSString), message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertLessThanOrEqual failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertLessThanOrEqual failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(false, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
@@ -665,17 +665,17 @@
     if let caughtError = caughtErrorOptional {
       errorHandler(caughtError)
     } else {
-      _XCTRegisterFailure(true, "XCTAssertThrowsError failed: did not throw an error", message, file, line)
+      _XCTRegisterFailure(true, "XCTAssertThrowsError failed: did not throw an error", message(), file, line)
     }
     
   case .failedWithError(let error):
-    _XCTRegisterFailure(false, "XCTAssertThrowsError failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(false, "XCTAssertThrowsError failed: threw error \"\(error)\"", message(), file, line)
     
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(true, "XCTAssertThrowsError failed: throwing \(reason)", message, file, line)
+    _XCTRegisterFailure(true, "XCTAssertThrowsError failed: throwing \(reason)", message(), file, line)
     
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, "XCTAssertThrowsError failed: throwing an unknown exception", message, file, line)
+    _XCTRegisterFailure(true, "XCTAssertThrowsError failed: throwing an unknown exception", message(), file, line)
   }
 }
 
@@ -689,13 +689,13 @@
     return
 
   case .failedWithError(let error):
-    _XCTRegisterFailure(true, "XCTAssertNoThrow failed: threw error \"\(error)\"", message, file, line)
+    _XCTRegisterFailure(true, "XCTAssertNoThrow failed: threw error \"\(error)\"", message(), file, line)
 
   case .failedWithException(_, _, let reason):
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 1, reason as NSString), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 1, reason as NSString), message(), file, line)
 
   case .failedWithUnknownException:
-    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message, file, line)
+    _XCTRegisterFailure(true, _XCTFailureDescription(assertionType, 2), message(), file, line)
   }
 }
 
diff --git a/stdlib/public/SwiftShims/CoreFoundationShims.h b/stdlib/public/SwiftShims/CoreFoundationShims.h
index bf3c574..69f3d6a 100644
--- a/stdlib/public/SwiftShims/CoreFoundationShims.h
+++ b/stdlib/public/SwiftShims/CoreFoundationShims.h
@@ -104,12 +104,28 @@
 SWIFT_RUNTIME_STDLIB_API
 const char *_Nullable _swift_stdlib_CFStringGetCStringPtr(
     _swift_shims_CFStringRef _Nonnull theString,
-
     _swift_shims_CFStringEncoding encoding);
 
 SWIFT_RUNTIME_STDLIB_API
 _swift_shims_CFStringRef _Nonnull _swift_stdlib_objcDebugDescription(
     id _Nonnull nsObject);
+  
+SWIFT_RUNTIME_STDLIB_API
+_swift_shims_CFComparisonResult _swift_stdlib_CFStringCompare(
+    _swift_shims_CFStringRef _Nonnull string,
+    _swift_shims_CFStringRef _Nonnull string2);
+  
+SWIFT_RUNTIME_STDLIB_API
+__swift_uint8_t _swift_stdlib_isNSString(id _Nonnull obj);
+
+SWIFT_RUNTIME_STDLIB_API
+_swift_shims_CFHashCode _swift_stdlib_CFStringHashNSString(id _Nonnull obj);
+
+SWIFT_RUNTIME_STDLIB_API
+_swift_shims_CFHashCode
+_swift_stdlib_CFStringHashCString(const _swift_shims_UInt8 * _Nonnull bytes,
+                                  _swift_shims_CFIndex length);
+  
 #endif // __OBJC2__
 
 #ifdef __cplusplus
diff --git a/stdlib/public/SwiftShims/DispatchOverlayShims.h b/stdlib/public/SwiftShims/DispatchOverlayShims.h
index f677747..d5af2ad 100644
--- a/stdlib/public/SwiftShims/DispatchOverlayShims.h
+++ b/stdlib/public/SwiftShims/DispatchOverlayShims.h
@@ -239,7 +239,7 @@
 }
 
 #if defined(__ANDROID__)
-extern void _dispatch_install_thread_detach_callback(dispatch_function_t cb);
+extern void _dispatch_install_thread_detach_callback(void (*cb)(void));
 #endif
 
 static inline void _swift_dispatch_retain(dispatch_object_t object) {
diff --git a/stdlib/public/SwiftShims/KeyPath.h b/stdlib/public/SwiftShims/KeyPath.h
index 78cc970..fa3da06 100644
--- a/stdlib/public/SwiftShims/KeyPath.h
+++ b/stdlib/public/SwiftShims/KeyPath.h
@@ -107,9 +107,9 @@
 static const __swift_uint32_t _SwiftKeyPathComponentHeader_ComputedIDUnresolvedIndirectPointer
   = 0x00000002U;
 
-extern void *(swift_keyPathGenericWitnessTable[]);
+extern const void *_Nonnull (swift_keyPathGenericWitnessTable[]);
 
-static inline void *__swift_keyPathGenericWitnessTable_addr(void) {
+static inline const void *_Nonnull __swift_keyPathGenericWitnessTable_addr(void) {
   return swift_keyPathGenericWitnessTable;
 }
 
diff --git a/stdlib/public/SwiftShims/LibcOverlayShims.h b/stdlib/public/SwiftShims/LibcOverlayShims.h
index e875057..b11f54b 100644
--- a/stdlib/public/SwiftShims/LibcOverlayShims.h
+++ b/stdlib/public/SwiftShims/LibcOverlayShims.h
@@ -29,7 +29,6 @@
 #include <semaphore.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
-#include <unistd.h>
 #endif
 
 #include <errno.h>
@@ -114,32 +113,6 @@
 }
 #endif
 
-static inline __swift_ssize_t
-_swift_stdlib_read(int fd, void *buf, size_t nbyte) {
-#if defined(_WIN32)
-  return _read(fd, buf, nbyte);
-#else
-  return read(fd, buf, nbyte);
-#endif
-}
-
-static inline __swift_ssize_t
-_swift_stdlib_write(int fd, const void *buf, size_t nbyte) {
-#if defined(_WIN32)
-  return _write(fd, buf, nbyte);
-#else
-  return write(fd, buf, nbyte);
-#endif
-}
-
-static inline int _swift_stdlib_close(int fd) {
-#if defined(_WIN32)
-  return _close(fd);
-#else
-  return close(fd);
-#endif
-}
-
 #if __has_feature(nullability)
 #pragma clang assume_nonnull end
 #endif
diff --git a/stdlib/public/SwiftShims/LibcShims.h b/stdlib/public/SwiftShims/LibcShims.h
index f2c4749..2b3dd05 100644
--- a/stdlib/public/SwiftShims/LibcShims.h
+++ b/stdlib/public/SwiftShims/LibcShims.h
@@ -62,6 +62,14 @@
   free(ptr);
 }
 
+// <unistd.h>
+SWIFT_RUNTIME_STDLIB_SPI
+__swift_ssize_t _swift_stdlib_read(int fd, void *buf, __swift_size_t nbyte);
+SWIFT_RUNTIME_STDLIB_SPI
+__swift_ssize_t _swift_stdlib_write(int fd, const void *buf, __swift_size_t nbyte);
+SWIFT_RUNTIME_STDLIB_SPI
+int _swift_stdlib_close(int fd);
+
 // String handling <string.h>
 SWIFT_READONLY
 static inline __swift_size_t _swift_stdlib_strlen(const char *s) {
diff --git a/stdlib/public/core/AnyHashable.swift b/stdlib/public/core/AnyHashable.swift
index 28ec0b1..30ea97a 100644
--- a/stdlib/public/core/AnyHashable.swift
+++ b/stdlib/public/core/AnyHashable.swift
@@ -123,7 +123,7 @@
 ///     print(descriptions[AnyHashable(43)])       // prints "nil"
 ///     print(descriptions[AnyHashable(Int8(43))]!) // prints "an Int8"
 ///     print(descriptions[AnyHashable(Set(["a", "b"]))]!) // prints "a set of strings"
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout
 public struct AnyHashable {
   internal var _box: _AnyHashableBox
 
@@ -288,7 +288,6 @@
 }
 
 /// Provided by AnyHashable.cpp.
-@usableFromInline // FIXME(sil-serialize-all)
 @_silgen_name("_swift_makeAnyHashableUpcastingToHashableBaseType")
 internal func _makeAnyHashableUpcastingToHashableBaseType<H : Hashable>(
   _ value: H,
diff --git a/stdlib/public/core/Array.swift b/stdlib/public/core/Array.swift
index 2ea7804..c4efc52 100644
--- a/stdlib/public/core/Array.swift
+++ b/stdlib/public/core/Array.swift
@@ -384,7 +384,7 @@
   }
 
   @_semantics("array.get_element")
-  @inline(__always)
+  @inlinable @inline(__always)
   public // @testable
   func _getElement(
     _ index: Int,
@@ -440,7 +440,7 @@
   @inlinable
   public // @testable
   var _owner: AnyObject? {
-    @inline(__always)
+    @inlinable @inline(__always)
     get {
       return _buffer.owner      
     }
@@ -1447,7 +1447,7 @@
   ///   method's execution.
   /// - Returns: The return value, if any, of the `body` closure parameter.
   @_semantics("array.withUnsafeMutableBufferPointer")
-  @inline(__always) // Performance: This method should get inlined into the
+  @inlinable @inline(__always) // Performance: This method should get inlined into the
   // caller such that we can combine the partial apply with the apply in this
   // function saving on allocating a closure context. This becomes unnecessary
   // once we allocate noescape closures on the stack.
diff --git a/stdlib/public/core/ArrayBuffer.swift b/stdlib/public/core/ArrayBuffer.swift
index 3301ab0..b77c01c 100644
--- a/stdlib/public/core/ArrayBuffer.swift
+++ b/stdlib/public/core/ArrayBuffer.swift
@@ -504,6 +504,7 @@
     return count
   }
 
+  @usableFromInline
   internal typealias Indices = Range<Int>
 
   //===--- private --------------------------------------------------------===//
diff --git a/stdlib/public/core/ArrayShared.swift b/stdlib/public/core/ArrayShared.swift
index d87c1b0..afc870f 100644
--- a/stdlib/public/core/ArrayShared.swift
+++ b/stdlib/public/core/ArrayShared.swift
@@ -25,7 +25,7 @@
 /// This function is referenced by the compiler to allocate array literals.
 ///
 /// - Precondition: `storage` is `_ContiguousArrayStorage`.
-@inline(__always)
+@inlinable @inline(__always)
 public // COMPILER_INTRINSIC
 func _allocateUninitializedArray<Element>(_  builtinCount: Builtin.Word)
     -> (Array<Element>, Builtin.RawPointer) {
diff --git a/stdlib/public/core/ArraySlice.swift b/stdlib/public/core/ArraySlice.swift
index f8d7f56..40b2653 100644
--- a/stdlib/public/core/ArraySlice.swift
+++ b/stdlib/public/core/ArraySlice.swift
@@ -202,7 +202,7 @@
   }
 
   @_semantics("array.get_element")
-  @inline(__always)
+  @inlinable @inline(__always)
   public // @testable
   func _getElement(
     _ index: Int,
@@ -1192,7 +1192,7 @@
   ///   method's execution.
   /// - Returns: The return value, if any, of the `body` closure parameter.
   @_semantics("array.withUnsafeMutableBufferPointer")
-  @inline(__always) // Performance: This method should get inlined into the
+  @inlinable @inline(__always) // Performance: This method should get inlined into the
   // caller such that we can combine the partial apply with the apply in this
   // function saving on allocating a closure context. This becomes unnecessary
   // once we allocate noescape closures on the stack.
diff --git a/stdlib/public/core/AssertCommon.swift b/stdlib/public/core/AssertCommon.swift
index d8e7858..f4d401a 100644
--- a/stdlib/public/core/AssertCommon.swift
+++ b/stdlib/public/core/AssertCommon.swift
@@ -248,7 +248,6 @@
   Builtin.int_trap()
 }
 
-@inlinable // FIXME(sil-serialize-all)
 public // COMPILER_INTRINSIC
 func _undefined<T>(
   _ message: @autoclosure () -> String = String(),
diff --git a/stdlib/public/core/BridgeObjectiveC.swift b/stdlib/public/core/BridgeObjectiveC.swift
index 8ab8c0d..db0feeb 100644
--- a/stdlib/public/core/BridgeObjectiveC.swift
+++ b/stdlib/public/core/BridgeObjectiveC.swift
@@ -139,7 +139,7 @@
 
 //===--- Bridging facilities written in Objective-C -----------------------===//
 // Functions that must discover and possibly use an arbitrary type's
-// conformance to a given protocol.  See ../runtime/Metadata.cpp for
+// conformance to a given protocol.  See ../runtime/Casting.cpp for
 // implementations.
 //===----------------------------------------------------------------------===//
 
@@ -156,8 +156,8 @@
 ///   that is `id`-compatible and dynamically castable back to the type of
 ///   the boxed value, but is otherwise opaque.
 ///
-/// COMPILER_INTRINSIC
-@inlinable // FIXME(sil-serialize-all)
+// COMPILER_INTRINSIC
+@inlinable
 public func _bridgeAnythingToObjectiveC<T>(_ x: T) -> AnyObject {
   if _fastPath(_isClassOrObjCExistential(T.self)) {
     return unsafeBitCast(x, to: AnyObject.self)
@@ -166,7 +166,8 @@
 }
 
 @_silgen_name("")
-public func _bridgeAnythingNonVerbatimToObjectiveC<T>(_ x: __owned T) -> AnyObject
+public // @testable
+func _bridgeAnythingNonVerbatimToObjectiveC<T>(_ x: __owned T) -> AnyObject
 
 /// Convert a purportedly-nonnull `id` value from Objective-C into an Any.
 ///
@@ -174,8 +175,7 @@
 /// this includes a failsafe against nil `AnyObject`s, wrapping them up as
 /// a nil `AnyObject?`-inside-an-`Any`.
 ///
-/// COMPILER_INTRINSIC
-@inlinable // FIXME(sil-serialize-all)
+// COMPILER_INTRINSIC
 public func _bridgeAnyObjectToAny(_ possiblyNullObject: AnyObject?) -> Any {
   if let nonnullObject = possiblyNullObject {
     return nonnullObject // AnyObject-in-Any
@@ -194,7 +194,7 @@
 ///     or a subclass of it, trap;
 ///   + otherwise, returns the result of `T._forceBridgeFromObjectiveC(x)`;
 /// - otherwise, trap.
-@inlinable // FIXME(sil-serialize-all)
+@inlinable
 public func _forceBridgeFromObjectiveC<T>(_ x: AnyObject, _: T.Type) -> T {
   if _fastPath(_isClassOrObjCExistential(T.self)) {
     return x as! T
@@ -207,8 +207,8 @@
 
 /// Convert `x` from its Objective-C representation to its Swift
 /// representation.
-/// COMPILER_INTRINSIC
-@inlinable // FIXME(sil-serialize-all)
+// COMPILER_INTRINSIC
+@inlinable
 public func _forceBridgeFromObjectiveC_bridgeable<T:_ObjectiveCBridgeable> (
   _ x: T._ObjectiveCType,
   _: T.Type
@@ -230,7 +230,7 @@
 ///   + otherwise, returns the result of
 ///     `T._conditionallyBridgeFromObjectiveC(x)`;
 /// - otherwise, the result is empty.
-@inlinable // FIXME(sil-serialize-all)
+@inlinable
 public func _conditionallyBridgeFromObjectiveC<T>(
   _ x: AnyObject,
   _: T.Type
@@ -246,8 +246,8 @@
 
 /// Attempt to convert `x` from its Objective-C representation to its Swift
 /// representation.
-/// COMPILER_INTRINSIC
-@inlinable // FIXME(sil-serialize-all)
+// COMPILER_INTRINSIC
+@inlinable
 public func _conditionallyBridgeFromObjectiveC_bridgeable<T:_ObjectiveCBridgeable>(
   _ x: T._ObjectiveCType,
   _: T.Type
@@ -258,7 +258,8 @@
 }
 
 @_silgen_name("")
-public func _bridgeNonVerbatimFromObjectiveC<T>(
+@usableFromInline
+internal func _bridgeNonVerbatimFromObjectiveC<T>(
   _ x: AnyObject,
   _ nativeType: T.Type,
   _ result: inout T?
@@ -558,8 +559,8 @@
 
 /// Convert `x` from its Objective-C representation to its Swift
 /// representation.
-/// COMPILER_INTRINSIC
-@inlinable // FIXME(sil-serialize-all)
+// COMPILER_INTRINSIC
+@inlinable
 public func _forceBridgeFromObjectiveC_bridgeable<T:_ObjectiveCBridgeable> (
   _ x: T._ObjectiveCType,
   _: T.Type
@@ -571,8 +572,8 @@
 
 /// Attempt to convert `x` from its Objective-C representation to its Swift
 /// representation.
-/// COMPILER_INTRINSIC
-@inlinable // FIXME(sil-serialize-all)
+// COMPILER_INTRINSIC
+@inlinable
 public func _conditionallyBridgeFromObjectiveC_bridgeable<T:_ObjectiveCBridgeable>(
   _ x: T._ObjectiveCType,
   _: T.Type
@@ -648,13 +649,12 @@
 @_silgen_name("_swift_bridgeToObjectiveCUsingProtocolIfPossible")
 public func _bridgeToObjectiveCUsingProtocolIfPossible<T>(_ value: T) -> AnyObject?
 
-@usableFromInline
-protocol _Unwrappable {
-  func unwrap() -> Any?
+internal protocol _Unwrappable {
+  func _unwrap() -> Any?
 }
 
 extension Optional: _Unwrappable {
-  func unwrap() -> Any? {
+  internal func _unwrap() -> Any? {
     return self
   }
 }
@@ -692,7 +692,7 @@
 ///   that is `id`-compatible and dynamically castable back to the type of
 ///   the boxed value, but is otherwise opaque.
 ///
-/// COMPILER_INTRINSIC
+// COMPILER_INTRINSIC
 public func _bridgeAnythingToObjectiveC<T>(_ x: T) -> AnyObject {
   var done = false
   var result: AnyObject!
@@ -705,7 +705,7 @@
   }
   
   if !done, let wrapper = source as? _Unwrappable {
-    if let value = wrapper.unwrap() {
+    if let value = wrapper._unwrap() {
       result = value as AnyObject
     } else {
       result = _nullPlaceholder
diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift
index dc805bd..d7ebebd 100644
--- a/stdlib/public/core/Builtin.swift
+++ b/stdlib/public/core/Builtin.swift
@@ -658,6 +658,9 @@
   return Bool(Builtin.isUnique(&object))
 }
 
+@_silgen_name("_swift_reallocObject")
+internal func _reallocObject(_ object: UnsafeMutableRawPointer, _ newSizeInBytes: Int) -> UnsafeMutableRawPointer?
+
 /// Returns `true` if `object` is uniquely referenced.
 /// This provides sanity checks on top of the Builtin.
 @_transparent
diff --git a/stdlib/public/core/CocoaArray.swift b/stdlib/public/core/CocoaArray.swift
index daf0d2a..82db7db 100644
--- a/stdlib/public/core/CocoaArray.swift
+++ b/stdlib/public/core/CocoaArray.swift
@@ -28,7 +28,9 @@
 @usableFromInline
 @_fixed_layout
 internal struct _CocoaArrayWrapper : RandomAccessCollection {
+  @usableFromInline
   typealias Indices = Range<Int>
+
   @inlinable
   internal var startIndex: Int {
     return 0
diff --git a/stdlib/public/core/Collection.swift b/stdlib/public/core/Collection.swift
index 1462f75..2f311c2 100644
--- a/stdlib/public/core/Collection.swift
+++ b/stdlib/public/core/Collection.swift
@@ -929,12 +929,9 @@
     using generator: inout T
   ) -> Element? {
     guard !isEmpty else { return nil }
-    let random = generator.next(upperBound: UInt(count))
-    let index = self.index(
-      startIndex,
-      offsetBy: numericCast(random)
-    )
-    return self[index]
+    let random = Int.random(in: 0 ..< count, using: &generator)
+    let idx = index(startIndex, offsetBy: random)
+    return self[idx]
   }
 
   /// Returns a random element of the collection.
diff --git a/stdlib/public/core/CollectionAlgorithms.swift b/stdlib/public/core/CollectionAlgorithms.swift
index 650006d..8c83b5f 100644
--- a/stdlib/public/core/CollectionAlgorithms.swift
+++ b/stdlib/public/core/CollectionAlgorithms.swift
@@ -320,14 +320,21 @@
   ) rethrows -> Index {
     let maybeOffset = try _withUnsafeMutableBufferPointerIfSupported {
       (bufferPointer) -> Int in
-      let unsafeBufferPivot = try bufferPointer.partition(
+      let unsafeBufferPivot = try bufferPointer._partitionImpl(
         by: belongsInSecondPartition)
       return unsafeBufferPivot - bufferPointer.startIndex
     }
     if let offset = maybeOffset {
-      return index(startIndex, offsetBy: numericCast(offset))
+      return index(startIndex, offsetBy: offset)
+    } else {
+      return try _partitionImpl(by: belongsInSecondPartition)
     }
-
+  }
+  
+  @usableFromInline
+  internal mutating func _partitionImpl(
+    by belongsInSecondPartition: (Element) throws -> Bool
+  ) rethrows -> Index {
     var lo = startIndex
     var hi = endIndex
 
@@ -445,16 +452,15 @@
   public mutating func shuffle<T: RandomNumberGenerator>(
     using generator: inout T
   ) {
-    let count = self.count
     guard count > 1 else { return }
     var amount = count
     var currentIndex = startIndex
     while amount > 1 {
-      let random = generator.next(upperBound: UInt(amount))
+      let random = Int.random(in: 0 ..< amount, using: &generator)
       amount -= 1
       swapAt(
         currentIndex,
-        index(currentIndex, offsetBy: numericCast(random))
+        index(currentIndex, offsetBy: random)
       )
       formIndex(after: &currentIndex)
     }
diff --git a/stdlib/public/core/ContiguousArray.swift b/stdlib/public/core/ContiguousArray.swift
index 0bf8f43..f463347 100644
--- a/stdlib/public/core/ContiguousArray.swift
+++ b/stdlib/public/core/ContiguousArray.swift
@@ -1041,7 +1041,7 @@
   ///   method's execution.
   /// - Returns: The return value, if any, of the `body` closure parameter.
   @_semantics("array.withUnsafeMutableBufferPointer")
-  @inline(__always) // Performance: This method should get inlined into the
+  @inlinable @inline(__always) // Performance: This method should get inlined into the
   // caller such that we can combine the partial apply with the apply in this
   // function saving on allocating a closure context. This becomes unnecessary
   // once we allocate noescape closures on the stack.
diff --git a/stdlib/public/core/ContiguousArrayBuffer.swift b/stdlib/public/core/ContiguousArrayBuffer.swift
index 1f511d8..c7dec40 100644
--- a/stdlib/public/core/ContiguousArrayBuffer.swift
+++ b/stdlib/public/core/ContiguousArrayBuffer.swift
@@ -71,13 +71,13 @@
 }
 
 // The class that implements the storage for a ContiguousArray<Element>
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout
 @usableFromInline
 internal final class _ContiguousArrayStorage<
   Element
 > : __ContiguousArrayStorageBase {
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   deinit {
     _elementPointer.deinitialize(count: countAndCapacity.count)
     _fixLifetime(self)
@@ -551,6 +551,7 @@
     return count
   }
 
+  @usableFromInline
   internal typealias Indices = Range<Int>
 }
 
@@ -654,7 +655,7 @@
 
   /// Initialize the buffer with an initial size of `initialCapacity`
   /// elements.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @inline(__always) // For performance reasons.
   internal init(initialCapacity: Int) {
     if initialCapacity == 0 {
@@ -670,7 +671,7 @@
   }
 
   /// Add an element to the buffer, reallocating if necessary.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @inline(__always) // For performance reasons.
   internal mutating func add(_ element: Element) {
     if remainingCapacity == 0 {
@@ -693,7 +694,7 @@
   }
 
   /// Add an element to the buffer, which must have remaining capacity.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @inline(__always) // For performance reasons.
   internal mutating func addWithExistingCapacity(_ element: Element) {
     _sanityCheck(remainingCapacity > 0,
@@ -709,7 +710,7 @@
   ///
   /// Returns the fully-initialized buffer. `self` is reset to contain an
   /// empty buffer and cannot be used afterward.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @inline(__always) // For performance reasons.
   internal mutating func finish() -> ContiguousArray<Element> {
     // Adjust the initialized count of the buffer.
@@ -724,7 +725,7 @@
   ///
   /// Returns the fully-initialized buffer. `self` is reset to contain an
   /// empty buffer and cannot be used afterward.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @inline(__always) // For performance reasons.
   internal mutating func finishWithOriginalCount() -> ContiguousArray<Element> {
     _sanityCheck(remainingCapacity == result.capacity - result.count,
diff --git a/stdlib/public/core/DictionaryStorage.swift b/stdlib/public/core/DictionaryStorage.swift
index dc64d5e..7debee5 100644
--- a/stdlib/public/core/DictionaryStorage.swift
+++ b/stdlib/public/core/DictionaryStorage.swift
@@ -16,7 +16,7 @@
 /// Enough bytes are allocated to hold the bitmap for marking valid entries,
 /// keys, and values. The data layout starts with the bitmap, followed by the
 /// keys, followed by the values.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout
 @usableFromInline
 @_objc_non_lazy_realization
 internal class _RawDictionaryStorage: __SwiftNativeNSDictionary {
@@ -192,7 +192,6 @@
   }
 }
 
-@_fixed_layout // FIXME(sil-serialize-all)
 @usableFromInline
 final internal class _DictionaryStorage<Key: Hashable, Value>
   : _RawDictionaryStorage, _NSDictionaryCore {
diff --git a/stdlib/public/core/FixedArray.swift.gyb b/stdlib/public/core/FixedArray.swift.gyb
index dc8e40d..e01448b 100644
--- a/stdlib/public/core/FixedArray.swift.gyb
+++ b/stdlib/public/core/FixedArray.swift.gyb
@@ -21,13 +21,10 @@
 
 % for N in sizes:
 
-@usableFromInline // FIXME(sil-serialize-all)
-@_fixed_layout // FIXME(sil-serialize-all)
 internal struct _FixedArray${N}<T> {
   // ABI TODO: The has assumptions about tuple layout in the ABI, namely that
   // they are laid out contiguously and individually addressable (i.e. strided).
   //
-  @usableFromInline // FIXME(sil-serialize-all)
   internal var storage: (
     // A ${N}-wide tuple of type T
 % for i in range(0, N-1):
@@ -36,23 +33,18 @@
     T
   )
 
-  @usableFromInline // FIXME(sil-serialize-all)
   var _count: Int8
 }
 
-
 extension _FixedArray${N} {
-  @inlinable // FIXME(sil-serialize-all)
   internal static var capacity: Int {
     @inline(__always) get { return ${N} }
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   internal var capacity: Int {
     @inline(__always) get { return ${N} }
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   internal var count: Int {
     @inline(__always) get { return Int(truncatingIfNeeded: _count) }
     @inline(__always) set { _count = Int8(newValue) }
@@ -60,20 +52,16 @@
 }
 
 extension _FixedArray${N} : RandomAccessCollection, MutableCollection {
-  @usableFromInline
   internal typealias Index = Int
 
-  @inlinable // FIXME(sil-serialize-all)
   internal var startIndex : Index {
     return 0
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   internal var endIndex : Index {
     return count
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   internal subscript(i: Index) -> T {
     @inline(__always)
     get {
@@ -99,13 +87,11 @@
     }
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   @inline(__always)
   internal func index(after i: Index) -> Index {
     return i+1
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   @inline(__always)
   internal func index(before i: Index) -> Index {
     return i-1
@@ -113,7 +99,6 @@
 }
 
 extension _FixedArray${N} {
-  @inlinable // FIXME(sil-serialize-all)
   internal mutating func append(_ newElement: T) {
     _sanityCheck(count < capacity)
     _count += 1
@@ -122,7 +107,6 @@
 }
 
 extension _FixedArray${N} where T : ExpressibleByIntegerLiteral {
-  @inlinable // FIXME(sil-serialize-all)
   @inline(__always)
   internal init(count: Int) {
     _sanityCheck(count >= 0 && count <= _FixedArray${N}.capacity)
@@ -135,13 +119,11 @@
     self._count = Int8(truncatingIfNeeded: count)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   @inline(__always)
   internal init() {
     self.init(count: 0)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   @inline(__always)
   internal init(allZeros: ()) {
     self.init(count: ${N})
@@ -149,7 +131,6 @@
 }
 
 extension _FixedArray${N} {
-  @inlinable // FIXME(sil-serialize-all)
   internal mutating func withUnsafeMutableBufferPointer<R>(
     _ body: (UnsafeMutableBufferPointer<Element>) throws -> R
   ) rethrows -> R {
@@ -165,7 +146,6 @@
     }
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   internal mutating func withUnsafeBufferPointer<R>(
     _ body: (UnsafeBufferPointer<Element>) throws -> R
   ) rethrows -> R {
diff --git a/stdlib/public/core/FloatingPoint.swift b/stdlib/public/core/FloatingPoint.swift
index caae17d..373c766 100644
--- a/stdlib/public/core/FloatingPoint.swift
+++ b/stdlib/public/core/FloatingPoint.swift
@@ -1722,7 +1722,7 @@
   /// - If `x` is `leastNonzeroMagnitude`, then `x.nextDown` is `0.0`.
   /// - If `x` is zero, then `x.nextDown` is `-leastNonzeroMagnitude`.
   /// - If `x` is `-greatestFiniteMagnitude`, then `x.nextDown` is `-infinity`.
-  public var nextDown: Self {
+  @inlinable public var nextDown: Self {
     @inline(__always)
     get {
       return -(-self).nextUp
@@ -1760,7 +1760,7 @@
   /// - Parameter other: The value to use when dividing this value.
   /// - Returns: The remainder of this value divided by `other` using
   ///   truncating division.
-  @inline(__always)
+  @inlinable @inline(__always)
   public func truncatingRemainder(dividingBy other: Self) -> Self {
     var lhs = self
     lhs.formTruncatingRemainder(dividingBy: other)
@@ -1799,7 +1799,7 @@
   ///
   /// - Parameter other: The value to use when dividing this value.
   /// - Returns: The remainder of this value divided by `other`.
-  @inline(__always)
+  @inlinable @inline(__always)
   public func remainder(dividingBy other: Self) -> Self {
     var lhs = self
     lhs.formRemainder(dividingBy: other)
diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb
index 7361166..bdd4aae 100644
--- a/stdlib/public/core/FloatingPointTypes.swift.gyb
+++ b/stdlib/public/core/FloatingPointTypes.swift.gyb
@@ -175,24 +175,24 @@
   }
 
   //  Implementation details.
-  @usableFromInline
+  @inlinable
   internal static var _infinityExponent: UInt {
     @inline(__always) get { return 1 &<< UInt(exponentBitCount) - 1 }
   }
 
-  @usableFromInline
+  @inlinable
   internal static var _exponentBias: UInt {
     @inline(__always) get { return _infinityExponent &>> 1 }
   }
 
-  @usableFromInline
+  @inlinable
   internal static var _significandMask: ${RawSignificand} {
     @inline(__always) get {
       return 1 &<< ${RawSignificand}(significandBitCount) - 1
     }
   }
 
-  @usableFromInline
+  @inlinable
   internal static var _quietNaNMask: ${RawSignificand} {
     @inline(__always) get {
       return 1 &<< ${RawSignificand}(significandBitCount - 1)
@@ -1103,7 +1103,7 @@
   /// `formRemainder(dividingBy:)` method is always exact.
   ///
   /// - Parameter other: The value to use when dividing this value.
-  @inline(__always)
+  @inlinable @inline(__always)
   public mutating func formRemainder(dividingBy other: ${Self}) {
     self = _stdlib_remainder${cFuncSuffix}(self, other)
   }
@@ -1137,7 +1137,7 @@
   /// method is always exact.
   ///
   /// - Parameter other: The value to use when dividing this value.
-  @inline(__always)
+  @inlinable @inline(__always)
   public mutating func formTruncatingRemainder(dividingBy other: ${Self}) {
     _value = Builtin.frem_FPIEEE${bits}(self._value, other._value)
   }
@@ -1258,7 +1258,7 @@
   /// A *normal* value is a finite number that uses the full precision
   /// available to values of a type. Zero is neither a normal nor a subnormal
   /// number.
-  public var isNormal: Bool {
+  @inlinable public var isNormal: Bool {
     @inline(__always)
     get {
       return exponentBitPattern > 0 && isFinite
@@ -1269,7 +1269,7 @@
   ///
   /// All values other than NaN and infinity are considered finite, whether
   /// normal or subnormal.
-  public var isFinite: Bool {
+  @inlinable public var isFinite: Bool {
     @inline(__always)
     get {
       return exponentBitPattern < ${Self}._infinityExponent
@@ -1285,7 +1285,7 @@
   ///     let x = -0.0
   ///     x.isZero        // true
   ///     x == 0.0        // true
-  public var isZero: Bool {
+  @inlinable public var isZero: Bool {
     @inline(__always)
     get {
       return exponentBitPattern == 0 && significandBitPattern == 0
@@ -1301,7 +1301,7 @@
   /// Zero is neither a normal nor a subnormal number. Subnormal numbers are
   /// often called *denormal* or *denormalized*---these are different names
   /// for the same concept.
-  public var isSubnormal:  Bool {
+  @inlinable public var isSubnormal:  Bool {
     @inline(__always)
     get {
       return exponentBitPattern == 0 && significandBitPattern != 0
@@ -1312,7 +1312,7 @@
   ///
   /// Note that `isFinite` and `isInfinite` do not form a dichotomy, because
   /// they are not total: If `x` is `NaN`, then both properties are `false`.
-  public var isInfinite:  Bool {
+  @inlinable public var isInfinite:  Bool {
     @inline(__always)
     get {
       return !isFinite && significandBitPattern == 0
@@ -1342,7 +1342,7 @@
   ///     // Prints "true"
   ///
   /// This property is `true` for both quiet and signaling NaNs.
-  public var isNaN:  Bool {
+  @inlinable public var isNaN:  Bool {
     @inline(__always)
     get {
       return !isFinite && significandBitPattern != 0
@@ -1353,7 +1353,7 @@
   ///
   /// Signaling NaNs typically raise the Invalid flag when used in general
   /// computing operations.
-  public var isSignalingNaN: Bool {
+  @inlinable public var isSignalingNaN: Bool {
     @inline(__always)
     get {
       return isNaN && (significandBitPattern & ${Self}._quietNaNMask) == 0
@@ -1447,7 +1447,7 @@
   ///     // x == 21.25
   ///
   /// - Parameter value: The new floating-point value.
-  @inline(__always)
+  @inlinable @inline(__always)
   public init(floatLiteral value: ${Self}) {
     self = value
   }
@@ -1590,7 +1590,7 @@
   ///     // Use 'abs(_:)' instead of 'magnitude'
   ///     print("Missed the target by \(abs(margin)) meters.")
   ///     // Prints "Missed the target by 0.25 meters."
-  public var magnitude: ${Self} {
+  @inlinable public var magnitude: ${Self} {
     @inline(__always)
     get {
       return ${Self}(Builtin.int_fabs_FPIEEE${bits}(_value))
@@ -1614,14 +1614,14 @@
 
   // We "shouldn't" need this, but the typechecker barfs on an expression
   // in the test suite without it.
-  @inline(__always)
+  @inlinable @inline(__always)
   public init(_ v: Int) {
     _value = Builtin.sitofp_Int${word_bits}_FPIEEE${bits}(v._value)
   }
 
   // Fast-path for conversion when the source is representable as a 64-bit int,
   // falling back on the generic _convert operation otherwise.
-  @inline(__always)
+  @inlinable @inline(__always)
   public init<Source : BinaryInteger>(_ value: Source) {
     if value.bitWidth <= ${word_bits} {
       if Source.isSigned {
@@ -1666,7 +1666,7 @@
   ///     // z.isNaN == true
   ///
   /// - Parameter other: The value to use for the new instance.
-  @inline(__always)
+  @inlinable @inline(__always)
   public init(_ other: ${That}) {
 %   if srcBits > bits:
     _value = Builtin.fptrunc_FPIEEE${srcBits}_FPIEEE${bits}(other._value)
diff --git a/stdlib/public/core/Hasher.swift b/stdlib/public/core/Hasher.swift
index c185095..a419d01 100644
--- a/stdlib/public/core/Hasher.swift
+++ b/stdlib/public/core/Hasher.swift
@@ -16,33 +16,6 @@
 
 import SwiftShims
 
-// FIXME: Remove @usableFromInline once Hasher is resilient.
-// rdar://problem/38549901
-@usableFromInline
-internal protocol _HasherCore {
-  init(rawSeed: (UInt64, UInt64))
-  mutating func compress(_ value: UInt64)
-  mutating func finalize(tailAndByteCount: UInt64) -> UInt64
-}
-
-extension _HasherCore {
-  @inline(__always)
-  internal init() {
-    self.init(rawSeed: Hasher._executionSeed)
-  }
-
-  @inline(__always)
-  internal init(seed: Int) {
-    let executionSeed = Hasher._executionSeed
-    // Prevent sign-extending the supplied seed; this makes testing slightly
-    // easier.
-    let seed = UInt(bitPattern: seed)
-    self.init(rawSeed: (
-      executionSeed.0 ^ UInt64(truncatingIfNeeded: seed),
-      executionSeed.1))
-  }
-}
-
 @inline(__always)
 internal func _loadPartialUnalignedUInt64LE(
   _ p: UnsafeRawPointer,
@@ -78,197 +51,201 @@
   }
 }
 
-/// This is a buffer for segmenting arbitrary data into 8-byte chunks.  Buffer
-/// storage is represented by a single 64-bit value in the format used by the
-/// finalization step of SipHash. (The least significant 56 bits hold the
-/// trailing bytes, while the most significant 8 bits hold the count of bytes
-/// appended so far, modulo 256. The count of bytes currently stored in the
-/// buffer is in the lower three bits of the byte count.)
-// FIXME: Remove @usableFromInline and @_fixed_layout once Hasher is resilient.
-// rdar://problem/38549901
-@usableFromInline @_fixed_layout
-internal struct _HasherTailBuffer {
-  // msb                                                             lsb
-  // +---------+-------+-------+-------+-------+-------+-------+-------+
-  // |byteCount|                 tail (<= 56 bits)                     |
-  // +---------+-------+-------+-------+-------+-------+-------+-------+
-  internal var value: UInt64
+extension Hasher {
+  /// This is a buffer for segmenting arbitrary data into 8-byte chunks.  Buffer
+  /// storage is represented by a single 64-bit value in the format used by the
+  /// finalization step of SipHash. (The least significant 56 bits hold the
+  /// trailing bytes, while the most significant 8 bits hold the count of bytes
+  /// appended so far, modulo 256. The count of bytes currently stored in the
+  /// buffer is in the lower three bits of the byte count.)
+  // FIXME: Remove @usableFromInline and @_fixed_layout once Hasher is resilient.
+  // rdar://problem/38549901
+  @usableFromInline @_fixed_layout
+  internal struct _TailBuffer {
+    // msb                                                             lsb
+    // +---------+-------+-------+-------+-------+-------+-------+-------+
+    // |byteCount|                 tail (<= 56 bits)                     |
+    // +---------+-------+-------+-------+-------+-------+-------+-------+
+    internal var value: UInt64
 
-  @inline(__always)
-  internal init() {
-    self.value = 0
-  }
-
-  @inline(__always)
-  internal init(tail: UInt64, byteCount: UInt64) {
-    // byteCount can be any value, but we only keep the lower 8 bits.  (The
-    // lower three bits specify the count of bytes stored in this buffer.)
-    // FIXME: This should be a single expression, but it causes exponential
-    // behavior in the expression type checker <rdar://problem/42672946>.
-    let shiftedByteCount: UInt64 = ((byteCount & 7) << 3)
-    let mask: UInt64 = (1 << shiftedByteCount - 1)
-    _sanityCheck(tail & ~mask == 0)
-    self.value = (byteCount &<< 56 | tail)
-  }
-
-  @inline(__always)
-  internal init(tail: UInt64, byteCount: Int) {
-    self.init(tail: tail, byteCount: UInt64(truncatingIfNeeded: byteCount))
-  }
-
-  internal var tail: UInt64 {
     @inline(__always)
-    get { return value & ~(0xFF &<< 56) }
-  }
+    internal init() {
+      self.value = 0
+    }
 
-  internal var byteCount: UInt64 {
     @inline(__always)
-    get { return value &>> 56 }
-  }
+    internal init(tail: UInt64, byteCount: UInt64) {
+      // byteCount can be any value, but we only keep the lower 8 bits.  (The
+      // lower three bits specify the count of bytes stored in this buffer.)
+      // FIXME: This should be a single expression, but it causes exponential
+      // behavior in the expression type checker <rdar://problem/42672946>.
+      let shiftedByteCount: UInt64 = ((byteCount & 7) << 3)
+      let mask: UInt64 = (1 << shiftedByteCount - 1)
+      _sanityCheck(tail & ~mask == 0)
+      self.value = (byteCount &<< 56 | tail)
+    }
 
-  @inline(__always)
-  internal mutating func append(_ bytes: UInt64) -> UInt64 {
-    let c = byteCount & 7
-    if c == 0 {
-      value = value &+ (8 &<< 56)
-      return bytes
+    @inline(__always)
+    internal init(tail: UInt64, byteCount: Int) {
+      self.init(tail: tail, byteCount: UInt64(truncatingIfNeeded: byteCount))
     }
-    let shift = c &<< 3
-    let chunk = tail | (bytes &<< shift)
-    value = (((value &>> 56) &+ 8) &<< 56) | (bytes &>> (64 - shift))
-    return chunk
-  }
 
-  @inline(__always)
-  internal
-  mutating func append(_ bytes: UInt64, count: UInt64) -> UInt64? {
-    _sanityCheck(count >= 0 && count < 8)
-    _sanityCheck(bytes & ~((1 &<< (count &<< 3)) &- 1) == 0)
-    let c = byteCount & 7
-    let shift = c &<< 3
-    if c + count < 8 {
-      value = (value | (bytes &<< shift)) &+ (count &<< 56)
-      return nil
+    internal var tail: UInt64 {
+      @inline(__always)
+      get { return value & ~(0xFF &<< 56) }
     }
-    let chunk = tail | (bytes &<< shift)
-    value = ((value &>> 56) &+ count) &<< 56
-    if c + count > 8 {
-      value |= bytes &>> (64 - shift)
+
+    internal var byteCount: UInt64 {
+      @inline(__always)
+      get { return value &>> 56 }
     }
-    return chunk
+
+    @inline(__always)
+    internal mutating func append(_ bytes: UInt64) -> UInt64 {
+      let c = byteCount & 7
+      if c == 0 {
+        value = value &+ (8 &<< 56)
+        return bytes
+      }
+      let shift = c &<< 3
+      let chunk = tail | (bytes &<< shift)
+      value = (((value &>> 56) &+ 8) &<< 56) | (bytes &>> (64 - shift))
+      return chunk
+    }
+
+    @inline(__always)
+    internal
+    mutating func append(_ bytes: UInt64, count: UInt64) -> UInt64? {
+      _sanityCheck(count >= 0 && count < 8)
+      _sanityCheck(bytes & ~((1 &<< (count &<< 3)) &- 1) == 0)
+      let c = byteCount & 7
+      let shift = c &<< 3
+      if c + count < 8 {
+        value = (value | (bytes &<< shift)) &+ (count &<< 56)
+        return nil
+      }
+      let chunk = tail | (bytes &<< shift)
+      value = ((value &>> 56) &+ count) &<< 56
+      if c + count > 8 {
+        value |= bytes &>> (64 - shift)
+      }
+      return chunk
+    }
   }
 }
 
-// FIXME: Remove @usableFromInline and @_fixed_layout once Hasher is resilient.
-// rdar://problem/38549901
-@usableFromInline @_fixed_layout
-internal struct _BufferingHasher<Core: _HasherCore> {
-  private var _buffer: _HasherTailBuffer
-  private var _core: Core
+extension Hasher {
+  // FIXME: Remove @usableFromInline and @_fixed_layout once Hasher is resilient.
+  // rdar://problem/38549901
+  @usableFromInline @_fixed_layout
+  internal struct _Core {
+    private var _buffer: _TailBuffer
+    private var _state: Hasher._State
 
-  @inline(__always)
-  internal init(core: Core) {
-    self._buffer = _HasherTailBuffer()
-    self._core = core
-  }
+    @inline(__always)
+    internal init(state: Hasher._State) {
+      self._buffer = _TailBuffer()
+      self._state = state
+    }
 
-  @inline(__always)
-  internal init() {
-    self.init(core: Core())
-  }
+    @inline(__always)
+    internal init() {
+      self.init(state: _State())
+    }
 
-  @inline(__always)
-  internal init(seed: Int) {
-    self.init(core: Core(seed: seed))
-  }
+    @inline(__always)
+    internal init(seed: Int) {
+      self.init(state: _State(seed: seed))
+    }
 
-  @inline(__always)
-  internal mutating func combine(_ value: UInt) {
+    @inline(__always)
+    internal mutating func combine(_ value: UInt) {
 #if arch(i386) || arch(arm)
-    combine(UInt32(truncatingIfNeeded: value))
+      combine(UInt32(truncatingIfNeeded: value))
 #else
-    combine(UInt64(truncatingIfNeeded: value))
+      combine(UInt64(truncatingIfNeeded: value))
 #endif
-  }
-
-  @inline(__always)
-  internal mutating func combine(_ value: UInt64) {
-    _core.compress(_buffer.append(value))
-  }
-
-  @inline(__always)
-  internal mutating func combine(_ value: UInt32) {
-    let value = UInt64(truncatingIfNeeded: value)
-    if let chunk = _buffer.append(value, count: 4) {
-      _core.compress(chunk)
     }
-  }
 
-  @inline(__always)
-  internal mutating func combine(_ value: UInt16) {
-    let value = UInt64(truncatingIfNeeded: value)
-    if let chunk = _buffer.append(value, count: 2) {
-      _core.compress(chunk)
+    @inline(__always)
+    internal mutating func combine(_ value: UInt64) {
+      _state.compress(_buffer.append(value))
     }
-  }
 
-  @inline(__always)
-  internal mutating func combine(_ value: UInt8) {
-    let value = UInt64(truncatingIfNeeded: value)
-    if let chunk = _buffer.append(value, count: 1) {
-      _core.compress(chunk)
-    }
-  }
-
-  @inline(__always)
-  internal mutating func combine(bytes: UInt64, count: Int) {
-    _sanityCheck(count >= 0 && count < 8)
-    let count = UInt64(truncatingIfNeeded: count)
-    if let chunk = _buffer.append(bytes, count: count) {
-      _core.compress(chunk)
-    }
-  }
-
-  @inline(__always)
-  internal mutating func combine(bytes: UnsafeRawBufferPointer) {
-    var remaining = bytes.count
-    guard remaining > 0 else { return }
-    var data = bytes.baseAddress!
-
-    // Load first unaligned partial word of data
-    do {
-      let start = UInt(bitPattern: data)
-      let end = _roundUp(start, toAlignment: MemoryLayout<UInt64>.alignment)
-      let c = min(remaining, Int(end - start))
-      if c > 0 {
-        let chunk = _loadPartialUnalignedUInt64LE(data, byteCount: c)
-        combine(bytes: chunk, count: c)
-        data += c
-        remaining -= c
+    @inline(__always)
+    internal mutating func combine(_ value: UInt32) {
+      let value = UInt64(truncatingIfNeeded: value)
+      if let chunk = _buffer.append(value, count: 4) {
+        _state.compress(chunk)
       }
     }
-    _sanityCheck(
-      remaining == 0 ||
-      Int(bitPattern: data) & (MemoryLayout<UInt64>.alignment - 1) == 0)
 
-    // Load as many aligned words as there are in the input buffer
-    while remaining >= MemoryLayout<UInt64>.size {
-      combine(UInt64(littleEndian: data.load(as: UInt64.self)))
-      data += MemoryLayout<UInt64>.size
-      remaining -= MemoryLayout<UInt64>.size
+    @inline(__always)
+    internal mutating func combine(_ value: UInt16) {
+      let value = UInt64(truncatingIfNeeded: value)
+      if let chunk = _buffer.append(value, count: 2) {
+        _state.compress(chunk)
+      }
     }
 
-    // Load last partial word of data
-    _sanityCheck(remaining >= 0 && remaining < 8)
-    if remaining > 0 {
-      let chunk = _loadPartialUnalignedUInt64LE(data, byteCount: remaining)
-      combine(bytes: chunk, count: remaining)
+    @inline(__always)
+    internal mutating func combine(_ value: UInt8) {
+      let value = UInt64(truncatingIfNeeded: value)
+      if let chunk = _buffer.append(value, count: 1) {
+        _state.compress(chunk)
+      }
     }
-  }
 
-  @inline(__always)
-  internal mutating func finalize() -> UInt64 {
-    return _core.finalize(tailAndByteCount: _buffer.value)
+    @inline(__always)
+    internal mutating func combine(bytes: UInt64, count: Int) {
+      _sanityCheck(count >= 0 && count < 8)
+      let count = UInt64(truncatingIfNeeded: count)
+      if let chunk = _buffer.append(bytes, count: count) {
+        _state.compress(chunk)
+      }
+    }
+
+    @inline(__always)
+    internal mutating func combine(bytes: UnsafeRawBufferPointer) {
+      var remaining = bytes.count
+      guard remaining > 0 else { return }
+      var data = bytes.baseAddress!
+
+      // Load first unaligned partial word of data
+      do {
+        let start = UInt(bitPattern: data)
+        let end = _roundUp(start, toAlignment: MemoryLayout<UInt64>.alignment)
+        let c = min(remaining, Int(end - start))
+        if c > 0 {
+          let chunk = _loadPartialUnalignedUInt64LE(data, byteCount: c)
+          combine(bytes: chunk, count: c)
+          data += c
+          remaining -= c
+        }
+      }
+      _sanityCheck(
+        remaining == 0 ||
+        Int(bitPattern: data) & (MemoryLayout<UInt64>.alignment - 1) == 0)
+
+      // Load as many aligned words as there are in the input buffer
+      while remaining >= MemoryLayout<UInt64>.size {
+        combine(UInt64(littleEndian: data.load(as: UInt64.self)))
+        data += MemoryLayout<UInt64>.size
+        remaining -= MemoryLayout<UInt64>.size
+      }
+
+      // Load last partial word of data
+      _sanityCheck(remaining >= 0 && remaining < 8)
+      if remaining > 0 {
+        let chunk = _loadPartialUnalignedUInt64LE(data, byteCount: remaining)
+        combine(bytes: chunk, count: remaining)
+      }
+    }
+
+    @inline(__always)
+    internal mutating func finalize() -> UInt64 {
+      return _state.finalize(tailAndByteCount: _buffer.value)
+    }
   }
 }
 
@@ -297,12 +274,7 @@
 ///   versions of the standard library.
 @_fixed_layout // FIXME: Should be resilient (rdar://problem/38549901)
 public struct Hasher {
-  // FIXME: Remove @usableFromInline once Hasher is resilient.
-  // rdar://problem/38549901
-  @usableFromInline
-  internal typealias _BufferingCore = _BufferingHasher<_Core>
-
-  internal var _core: _BufferingCore
+  internal var _core: _Core
 
   /// Creates a new hasher.
   ///
@@ -310,7 +282,7 @@
   /// startup, usually from a high-quality random source.
   @_effects(releasenone)
   public init() {
-    self._core = _BufferingCore()
+    self._core = _Core()
   }
 
   /// Initialize a new hasher using the specified seed value.
@@ -318,14 +290,14 @@
   @usableFromInline
   @_effects(releasenone)
   internal init(_seed: Int) {
-    self._core = _BufferingCore(seed: _seed)
+    self._core = _Core(seed: _seed)
   }
 
   /// Initialize a new hasher using the specified seed value.
   @usableFromInline // @testable
   @_effects(releasenone)
   internal init(_rawSeed: (UInt64, UInt64)) {
-    self._core = _BufferingCore(core: _Core(rawSeed: _rawSeed))
+    self._core = _Core(state: _State(rawSeed: _rawSeed))
   }
 
   /// Indicates whether we're running in an environment where hashing needs to
@@ -441,27 +413,27 @@
   @_effects(readnone)
   @usableFromInline
   internal static func _hash(seed: Int, _ value: UInt64) -> Int {
-    var core = _Core(seed: seed)
-    core.compress(value)
-    let tbc = _HasherTailBuffer(tail: 0, byteCount: 8)
-    return Int(truncatingIfNeeded: core.finalize(tailAndByteCount: tbc.value))
+    var state = _State(seed: seed)
+    state.compress(value)
+    let tbc = _TailBuffer(tail: 0, byteCount: 8)
+    return Int(truncatingIfNeeded: state.finalize(tailAndByteCount: tbc.value))
   }
 
   @_effects(readnone)
   @usableFromInline
   internal static func _hash(seed: Int, _ value: UInt) -> Int {
-    var core = _Core(seed: seed)
+    var state = _State(seed: seed)
 #if arch(i386) || arch(arm)
     _sanityCheck(UInt.bitWidth < UInt64.bitWidth)
-    let tbc = _HasherTailBuffer(
+    let tbc = _TailBuffer(
       tail: UInt64(truncatingIfNeeded: value),
       byteCount: UInt.bitWidth &>> 3)
 #else
     _sanityCheck(UInt.bitWidth == UInt64.bitWidth)
-    core.compress(UInt64(truncatingIfNeeded: value))
-    let tbc = _HasherTailBuffer(tail: 0, byteCount: 8)
+    state.compress(UInt64(truncatingIfNeeded: value))
+    let tbc = _TailBuffer(tail: 0, byteCount: 8)
 #endif
-    return Int(truncatingIfNeeded: core.finalize(tailAndByteCount: tbc.value))
+    return Int(truncatingIfNeeded: state.finalize(tailAndByteCount: tbc.value))
   }
 
   @_effects(readnone)
@@ -471,9 +443,9 @@
     bytes value: UInt64,
     count: Int) -> Int {
     _sanityCheck(count >= 0 && count < 8)
-    var core = _Core(seed: seed)
-    let tbc = _HasherTailBuffer(tail: value, byteCount: count)
-    return Int(truncatingIfNeeded: core.finalize(tailAndByteCount: tbc.value))
+    var state = _State(seed: seed)
+    let tbc = _TailBuffer(tail: value, byteCount: count)
+    return Int(truncatingIfNeeded: state.finalize(tailAndByteCount: tbc.value))
   }
 
   @_effects(readnone)
@@ -481,7 +453,7 @@
   internal static func _hash(
     seed: Int,
     bytes: UnsafeRawBufferPointer) -> Int {
-    var core = _BufferingCore(seed: seed)
+    var core = _Core(seed: seed)
     core.combine(bytes: bytes)
     return Int(truncatingIfNeeded: core.finalize())
   }
diff --git a/stdlib/public/core/Integers.swift b/stdlib/public/core/Integers.swift
index 1eb4226..87c8c89 100644
--- a/stdlib/public/core/Integers.swift
+++ b/stdlib/public/core/Integers.swift
@@ -24,81 +24,16 @@
 }
 
 //===----------------------------------------------------------------------===//
-//===--- Numeric ----------------------------------------------------------===//
+//===--- AdditiveArithmetic -----------------------------------------------===//
 //===----------------------------------------------------------------------===//
 
-/// Declares methods backing binary arithmetic operators--such as `+`, `-` and
-/// `*`--and their mutating counterparts.
-///
-/// The `Numeric` protocol provides a suitable basis for arithmetic on
-/// scalar values, such as integers and floating-point numbers. You can write
-/// generic methods that operate on any numeric type in the standard library
-/// by using the `Numeric` protocol as a generic constraint.
-///
-/// The following example declares a method that calculates the total of any
-/// sequence with `Numeric` elements.
-///
-///     extension Sequence where Element: Numeric {
-///         func sum() -> Element {
-///             return reduce(0, +)
-///         }
-///     }
-///
-/// The `sum()` method is now available on any sequence or collection with
-/// numeric values, whether it is an array of `Double` or a countable range of
-/// `Int`.
-///
-///     let arraySum = [1.1, 2.2, 3.3, 4.4, 5.5].sum()
-///     // arraySum == 16.5
-///
-///     let rangeSum = (1..<10).sum()
-///     // rangeSum == 45
-///
-/// Conforming to the Numeric Protocol
-/// =====================================
-///
-/// To add `Numeric` protocol conformance to your own custom type, implement
-/// the required mutating methods. Extensions to `Numeric` provide default
-/// implementations for the protocol's nonmutating methods based on the
-/// mutating variants.
-public protocol Numeric : Equatable, ExpressibleByIntegerLiteral {
-  /// Creates a new instance from the given integer, if it can be represented
-  /// exactly.
+// FIXME: Add doc comment.
+public protocol AdditiveArithmetic : Equatable {
+  /// The zero value.
   ///
-  /// If the value passed as `source` is not representable exactly, the result
-  /// is `nil`. In the following example, the constant `x` is successfully
-  /// created from a value of `100`, while the attempt to initialize the
-  /// constant `y` from `1_000` fails because the `Int8` type can represent
-  /// `127` at maximum:
-  ///
-  ///     let x = Int8(exactly: 100)
-  ///     // x == Optional(100)
-  ///     let y = Int8(exactly: 1_000)
-  ///     // y == nil
-  ///
-  /// - Parameter source: A value to convert to this type.
-  init?<T : BinaryInteger>(exactly source: T)
-
-  /// A type that can represent the absolute value of any possible value of the
-  /// conforming type.
-  associatedtype Magnitude : Comparable, Numeric
-
-  /// The magnitude of this value.
-  ///
-  /// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.
-  /// You can use the `magnitude` property in operations that are simpler to
-  /// implement in terms of unsigned values, such as printing the value of an
-  /// integer, which is just printing a '-' character in front of an absolute
-  /// value.
-  ///
-  ///     let x = -200
-  ///     // x.magnitude == 200
-  ///
-  /// The global `abs(_:)` function provides more familiar syntax when you need
-  /// to find an absolute value. In addition, because `abs(_:)` always returns
-  /// a value of the same type, even in a generic context, using the function
-  /// instead of the `magnitude` property is encouraged.
-  var magnitude: Magnitude { get }
+  /// - Note: Zero is the identity element for addition; for any value,
+  ///   `x + .zero == x` and `.zero + x == x`.
+  static var zero: Self { get }
 
   /// Adds two values and produces their sum.
   ///
@@ -158,6 +93,91 @@
   ///   - lhs: A numeric value.
   ///   - rhs: The value to subtract from `lhs`.
   static func -=(lhs: inout Self, rhs: Self)
+}
+
+public extension AdditiveArithmetic where Self : ExpressibleByIntegerLiteral {
+  static var zero: Self {
+    return 0
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//===--- Numeric ----------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+
+// FIXME: Update comment based on the `AdditiveArithmetic` change.
+/// Declares methods backing binary arithmetic operators--such as `+`, `-` and
+/// `*`--and their mutating counterparts.
+///
+/// The `Numeric` protocol provides a suitable basis for arithmetic on
+/// scalar values, such as integers and floating-point numbers. You can write
+/// generic methods that operate on any numeric type in the standard library
+/// by using the `Numeric` protocol as a generic constraint.
+///
+/// The following example declares a method that calculates the total of any
+/// sequence with `Numeric` elements.
+///
+///     extension Sequence where Element: Numeric {
+///         func sum() -> Element {
+///             return reduce(0, +)
+///         }
+///     }
+///
+/// The `sum()` method is now available on any sequence or collection with
+/// numeric values, whether it is an array of `Double` or a countable range of
+/// `Int`.
+///
+///     let arraySum = [1.1, 2.2, 3.3, 4.4, 5.5].sum()
+///     // arraySum == 16.5
+///
+///     let rangeSum = (1..<10).sum()
+///     // rangeSum == 45
+///
+/// Conforming to the Numeric Protocol
+/// =====================================
+///
+/// To add `Numeric` protocol conformance to your own custom type, implement
+/// the required mutating methods. Extensions to `Numeric` provide default
+/// implementations for the protocol's nonmutating methods based on the
+/// mutating variants.
+public protocol Numeric : AdditiveArithmetic, ExpressibleByIntegerLiteral {
+  /// Creates a new instance from the given integer, if it can be represented
+  /// exactly.
+  ///
+  /// If the value passed as `source` is not representable exactly, the result
+  /// is `nil`. In the following example, the constant `x` is successfully
+  /// created from a value of `100`, while the attempt to initialize the
+  /// constant `y` from `1_000` fails because the `Int8` type can represent
+  /// `127` at maximum:
+  ///
+  ///     let x = Int8(exactly: 100)
+  ///     // x == Optional(100)
+  ///     let y = Int8(exactly: 1_000)
+  ///     // y == nil
+  ///
+  /// - Parameter source: A value to convert to this type.
+  init?<T : BinaryInteger>(exactly source: T)
+
+  /// A type that can represent the absolute value of any possible value of the
+  /// conforming type.
+  associatedtype Magnitude : Comparable, Numeric
+
+  /// The magnitude of this value.
+  ///
+  /// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.
+  /// You can use the `magnitude` property in operations that are simpler to
+  /// implement in terms of unsigned values, such as printing the value of an
+  /// integer, which is just printing a '-' character in front of an absolute
+  /// value.
+  ///
+  ///     let x = -200
+  ///     // x.magnitude == 200
+  ///
+  /// The global `abs(_:)` function provides more familiar syntax when you need
+  /// to find an absolute value. In addition, because `abs(_:)` always returns
+  /// a value of the same type, even in a generic context, using the function
+  /// instead of the `magnitude` property is encouraged.
+  var magnitude: Magnitude { get }
 
   /// Multiplies two values and produces their product.
   ///
@@ -327,7 +347,7 @@
   return x < (0 as T) ? -x : x
 }
 
-extension Numeric {
+extension AdditiveArithmetic {
   /// Returns the given number unchanged.
   ///
   /// You can use the unary plus operator (`+`) to provide symmetry in your
@@ -1430,8 +1450,6 @@
 //===----------------------------------------------------------------------===//
 
 extension BinaryInteger {
-  @usableFromInline
-  @_transparent
   internal func _description(radix: Int, uppercase: Bool) -> String {
     _precondition(2...36 ~= radix, "Radix must be between 2 and 36")
 
@@ -3031,7 +3049,7 @@
   ///     // 'y' has a binary representation of 11111111_11101011
   ///
   /// - Parameter source: An integer to convert to this type.
-  @inline(__always)
+  @inlinable @inline(__always)
   public init<T : BinaryInteger>(truncatingIfNeeded source: T) {
     if Self.bitWidth <= Int.bitWidth {
       self = Self(_truncatingBits: source._lowWord)
@@ -3272,7 +3290,7 @@
   /// to find an absolute value. In addition, because `abs(_:)` always returns
   /// a value of the same type, even in a generic context, using the function
   /// instead of the `magnitude` property is encouraged.
-  public var magnitude: Self {
+  @inlinable public var magnitude: Self {
     @inline(__always)
     get { return self }
   }
@@ -3280,7 +3298,7 @@
   /// A Boolean value indicating whether this type is a signed integer type.
   ///
   /// This property is always `false` for unsigned integer types.
-  public static var isSigned: Bool {
+  @inlinable public static var isSigned: Bool {
     @inline(__always)
     get { return false }
   }
@@ -3307,7 +3325,7 @@
   /// - Parameter source: A value to convert to this type of integer. The value
   ///   passed as `source` must be representable in this type.
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  @inline(__always)
+  @inlinable @inline(__always)
   public init<T : BinaryInteger>(_ source: T) {
     // This check is potentially removable by the optimizer
     if T.isSigned {
@@ -3337,7 +3355,7 @@
   ///
   /// - Parameter source: A value to convert to this type of integer.
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  @inline(__always)
+  @inlinable @inline(__always)
   public init?<T : BinaryInteger>(exactly source: T) {
     // This check is potentially removable by the optimizer
     if T.isSigned && source < (0 as T) {
@@ -3381,7 +3399,7 @@
   /// A Boolean value indicating whether this type is a signed integer type.
   ///
   /// This property is always `true` for signed integer types.
-  public static var isSigned: Bool {
+  @inlinable public static var isSigned: Bool {
     @inline(__always)
     get { return true }
   }
@@ -3408,7 +3426,7 @@
   /// - Parameter source: A value to convert to this type of integer. The value
   ///   passed as `source` must be representable in this type.
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  @inline(__always)
+  @inlinable @inline(__always)
   public init<T : BinaryInteger>(_ source: T) {
     // This check is potentially removable by the optimizer
     if T.isSigned && source.bitWidth > Self.bitWidth {
@@ -3440,7 +3458,7 @@
   ///
   /// - Parameter source: A value to convert to this type of integer.
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  @inline(__always)
+  @inlinable @inline(__always)
   public init?<T : BinaryInteger>(exactly source: T) {
     // This check is potentially removable by the optimizer
     if T.isSigned && source.bitWidth > Self.bitWidth && source < Self.min {
diff --git a/stdlib/public/core/KeyPath.swift b/stdlib/public/core/KeyPath.swift
index e7d5a80..b9cb0fb 100644
--- a/stdlib/public/core/KeyPath.swift
+++ b/stdlib/public/core/KeyPath.swift
@@ -433,28 +433,19 @@
 }
 
 internal struct ComputedPropertyID: Hashable {
-  internal init(value: Int, isStoredProperty: Bool, isTableOffset: Bool) {
-    self.value = value
-    self.isStoredProperty = isStoredProperty
-    self.isTableOffset = isTableOffset
-  }
-
   internal var value: Int
-  internal var isStoredProperty: Bool
-  internal var isTableOffset: Bool
+  internal var kind: KeyPathComputedIDKind
 
   internal static func ==(
     x: ComputedPropertyID, y: ComputedPropertyID
   ) -> Bool {
     return x.value == y.value
-      && x.isStoredProperty == y.isStoredProperty
-      && x.isTableOffset == x.isTableOffset
+      && x.kind == y.kind
   }
 
   internal func hash(into hasher: inout Hasher) {
     hasher.combine(value)
-    hasher.combine(isStoredProperty)
-    hasher.combine(isTableOffset)
+    hasher.combine(kind)
   }
 }
 
@@ -731,6 +722,18 @@
   }
 }
 
+internal typealias KeyPathComputedArgumentLayoutFn = @convention(thin)
+  (_ patternArguments: UnsafeRawPointer) -> (size: Int, alignmentMask: Int)
+internal typealias KeyPathComputedArgumentInitializerFn = @convention(thin)
+  (_ patternArguments: UnsafeRawPointer,
+   _ instanceArguments: UnsafeMutableRawPointer) -> ()
+
+internal enum KeyPathComputedIDKind {
+  case pointer
+  case storedPropertyIndex
+  case vtableOffset
+}
+
 internal struct RawKeyPathComponent {
   internal init(header: Header, body: UnsafeRawBufferPointer) {
     self.header = header
@@ -824,6 +827,21 @@
     internal static var computedIDByVTableOffsetFlag: UInt32 {
       return _SwiftKeyPathComponentHeader_ComputedIDByVTableOffsetFlag
     }
+    internal var computedIDKind: KeyPathComputedIDKind {
+      let storedProperty = _value & Header.computedIDByStoredPropertyFlag != 0
+      let vtableOffset = _value & Header.computedIDByVTableOffsetFlag != 0
+
+      switch (storedProperty, vtableOffset) {
+      case (true, true):
+        _sanityCheckFailure("not allowed")
+      case (true, false):
+        return .storedPropertyIndex
+      case (false, true):
+        return .vtableOffset
+      case (false, false):
+        return .pointer
+      }
+    }
 
     internal static var computedHasArgumentsFlag: UInt32 {
       return _SwiftKeyPathComponentHeader_ComputedHasArgumentsFlag
@@ -867,11 +885,23 @@
     internal static var computedIDUnresolvedIndirectPointer: UInt32 {
       return _SwiftKeyPathComponentHeader_ComputedIDUnresolvedIndirectPointer
     }
+    internal var isComputedIDResolved: Bool {
+      return
+        payload & Header.computedIDResolutionMask == Header.computedIDResolved
+    }
     
     internal var _value: UInt32
     
     internal var discriminator: UInt32 {
-      return (_value & Header.discriminatorMask) >> Header.discriminatorShift
+      get {
+        return (_value & Header.discriminatorMask) >> Header.discriminatorShift
+      }
+      set {
+        let shifted = newValue << Header.discriminatorShift
+        _sanityCheck(shifted & Header.discriminatorMask == shifted,
+                     "discriminator doesn't fit")
+        _value = _value & ~Header.discriminatorMask | shifted
+      }
     }
     internal var payload: UInt32 {
       get {
@@ -959,45 +989,117 @@
       switch kind {
       case .struct, .class:
         if storedOffsetPayload == Header.unresolvedFieldOffsetPayload
-           || storedOffsetPayload == Header.outOfLineOffsetPayload {
+           || storedOffsetPayload == Header.outOfLineOffsetPayload
+           || storedOffsetPayload == Header.unresolvedIndirectOffsetPayload {
           // A 32-bit offset is stored in the body.
           return MemoryLayout<UInt32>.size
         }
-        if storedOffsetPayload == Header.unresolvedIndirectOffsetPayload {
-          // A pointer-aligned, pointer-sized pointer is stored in the body.
-          return Header.pointerAlignmentSkew + MemoryLayout<Int>.size
-        }
         // Otherwise, there's no body.
-        return Header.pointerAlignmentSkew
+        return 0
 
       case .external:
         // The body holds a pointer to the external property descriptor,
         // and some number of substitution arguments, the count of which is
         // in the payload.
-        return Header.pointerAlignmentSkew
-          + MemoryLayout<Int>.size * (1 + Int(payload))
+        return 4 * (1 + Int(payload))
 
       case .computed:
         // The body holds at minimum the id and getter.
-        var size = Header.pointerAlignmentSkew + MemoryLayout<Int>.size * 2
+        var size = 8
         // If settable, it also holds the setter.
         if isComputedSettable {
-          size += MemoryLayout<Int>.size
+          size += 4
         }
         // If there are arguments, there's also a layout function,
         // witness table, and initializer function.
         // Property descriptors never carry argument information, though.
         if !forPropertyDescriptor && hasComputedArguments {
-          size += MemoryLayout<Int>.size * 3
+          size += 12
         }
 
         return size
 
       case .optionalForce, .optionalChain, .optionalWrap:
         // Otherwise, there's no body.
-        return Header.pointerAlignmentSkew
+        return 0
       }
     }
+
+    init(discriminator: UInt32, payload: UInt32) {
+      _value = 0
+      self.discriminator = discriminator
+      self.payload = payload
+    }
+
+    init(optionalForce: ()) {
+      self.init(discriminator: Header.optionalTag,
+                payload: Header.optionalForcePayload)
+    }
+
+    init(optionalWrap: ()) {
+      self.init(discriminator: Header.optionalTag,
+                payload: Header.optionalWrapPayload)
+    }
+
+    init(optionalChain: ()) {
+      self.init(discriminator: Header.optionalTag,
+                payload: Header.optionalChainPayload)
+    }
+
+    init(stored kind: KeyPathStructOrClass,
+         mutable: Bool,
+         inlineOffset: UInt32) {
+      let discriminator: UInt32
+      switch kind {
+      case .struct: discriminator = Header.structTag
+      case .class: discriminator = Header.classTag
+      }
+
+      _sanityCheck(inlineOffset <= Header.maximumOffsetPayload)
+      let payload = inlineOffset
+        | (mutable ? Header.storedMutableFlag : 0)
+      self.init(discriminator: discriminator,
+                payload: payload)
+    }
+
+    init(storedWithOutOfLineOffset kind: KeyPathStructOrClass,
+         mutable: Bool) {
+      let discriminator: UInt32
+      switch kind {
+      case .struct: discriminator = Header.structTag
+      case .class: discriminator = Header.classTag
+      }
+
+      let payload = Header.outOfLineOffsetPayload
+        | (mutable ? Header.storedMutableFlag : 0)
+
+      self.init(discriminator: discriminator,
+                payload: payload)
+    }
+
+    init(computedWithIDKind kind: KeyPathComputedIDKind,
+         mutating: Bool,
+         settable: Bool,
+         hasArguments: Bool,
+         instantiatedFromExternalWithArguments: Bool) {
+      let discriminator = Header.computedTag
+      var payload =
+          (mutating ? Header.computedMutatingFlag : 0)
+        | (settable ? Header.computedSettableFlag : 0)
+        | (hasArguments ? Header.computedHasArgumentsFlag : 0)
+        | (instantiatedFromExternalWithArguments
+             ? Header.computedInstantiatedFromExternalWithArgumentsFlag : 0)
+      switch kind {
+      case .pointer:
+        break
+      case .storedPropertyIndex:
+        payload |= Header.computedIDByStoredPropertyFlag
+      case .vtableOffset:
+        payload |= Header.computedIDByVTableOffsetFlag
+      }
+      self.init(discriminator: discriminator,
+                payload: payload)
+    }
   }
 
   internal var bodySize: Int {
@@ -1009,9 +1111,7 @@
       }
       return 0
     case .external:
-      // align to pointer + pointer to external descriptor
-      // + N generic argument accessors (N in payload)
-      return Header.pointerAlignmentSkew + ptrSize * (1 + Int(header.payload))
+      _sanityCheckFailure("should be instantiated away")
     case .optionalChain, .optionalForce, .optionalWrap:
       return 0
     case .computed:
@@ -1057,11 +1157,12 @@
   }
 
   internal var _computedID: ComputedPropertyID {
-    let payload = header.payload
+    _sanityCheck(header.kind == .computed,
+                 "not a computed property")
+
     return ComputedPropertyID(
       value: _computedIDValue,
-      isStoredProperty: payload & Header.computedIDByStoredPropertyFlag != 0,
-      isTableOffset: payload & Header.computedIDByVTableOffsetFlag != 0)
+      kind: header.computedIDKind)
   }
 
   internal var _computedGetter: UnsafeRawPointer {
@@ -1082,12 +1183,6 @@
       as: UnsafeRawPointer.self)
   }
 
-  internal typealias ComputedArgumentLayoutFn = @convention(thin)
-    (_ patternArguments: UnsafeRawPointer) -> (size: Int, alignmentMask: Int)
-  internal typealias ComputedArgumentInitializerFn = @convention(thin)
-    (_ patternArguments: UnsafeRawPointer,
-     _ instanceArguments: UnsafeMutableRawPointer) -> ()
-
   internal var _computedArgumentHeaderPointer: UnsafeRawPointer {
     _sanityCheck(header.hasComputedArguments, "no arguments")
 
@@ -1474,6 +1569,27 @@
   }
 }
 
+internal func _pop<T>(from: inout UnsafeRawBufferPointer,
+                      as type: T.Type) -> T {
+  let buffer = _pop(from: &from, as: type, count: 1)
+  return buffer.baseAddress.unsafelyUnwrapped.pointee
+}
+internal func _pop<T>(from: inout UnsafeRawBufferPointer,
+                      as: T.Type,
+                      count: Int) -> UnsafeBufferPointer<T> {
+  _sanityCheck(_isPOD(T.self), "should be POD")
+  from = MemoryLayout<T>._roundingUpBaseToAlignment(from)
+  let byteCount = MemoryLayout<T>.stride * count
+  let result = UnsafeBufferPointer(
+    start: from.baseAddress.unsafelyUnwrapped.assumingMemoryBound(to: T.self),
+    count: count)
+
+  from = UnsafeRawBufferPointer(
+    start: from.baseAddress.unsafelyUnwrapped + byteCount,
+    count: from.count - byteCount)
+  return result
+}
+  
 internal struct KeyPathBuffer {
   internal var data: UnsafeRawBufferPointer
   internal var trivial: Bool
@@ -1563,7 +1679,7 @@
   }
   
   internal mutating func next() -> (RawKeyPathComponent, Any.Type?) {
-    let header = pop(RawKeyPathComponent.Header.self)
+    let header = _pop(from: &data, as: RawKeyPathComponent.Header.self)
     // Track if this is the last component of the reference prefix.
     if header.endOfReferencePrefix {
       _sanityCheck(self.hasReferencePrefix,
@@ -1576,60 +1692,37 @@
     let size = component.bodySize
     component.body = UnsafeRawBufferPointer(start: component.body.baseAddress,
                                             count: size)
-    _ = popRaw(size: size, alignment: Int8.self)
+    _ = _pop(from: &data, as: Int8.self, count: size)
 
     // fetch type, which is in the buffer unless it's the final component
     let nextType: Any.Type?
     if data.count == 0 {
       nextType = nil
     } else {
-      nextType = pop(Any.Type.self)
+      nextType = _pop(from: &data, as: Any.Type.self)
     }
     return (component, nextType)
   }
-  
-  internal mutating func pop<T>(_ type: T.Type) -> T {
-    _sanityCheck(_isPOD(T.self), "should be POD")
-    let raw = popRaw(size: MemoryLayout<T>.size,
-                     alignment: T.self)
-    let resultBuf = UnsafeMutablePointer<T>.allocate(capacity: 1)
-    _memcpy(dest: resultBuf,
-            src: raw.baseAddress.unsafelyUnwrapped,
-            size: UInt(MemoryLayout<T>.size))
-    let result = resultBuf.pointee
-    resultBuf.deallocate()
-    return result
-  }
-  internal mutating func popRaw<Alignment>(
-    size: Int, alignment: Alignment.Type
-  ) -> UnsafeRawBufferPointer {
-    data = MemoryLayout<Alignment>._roundingUpBaseToAlignment(data)
-    let result = UnsafeRawBufferPointer(start: data.baseAddress, count: size)
-    data = UnsafeRawBufferPointer(
-      start: data.baseAddress.unsafelyUnwrapped + size,
-      count: data.count - size)
-    return result
-  }
 }
 
 // MARK: Library intrinsics for projecting key paths.
 
-@inlinable
+@_silgen_name("swift_getAtPartialKeyPath")
 public // COMPILER_INTRINSIC
-func _projectKeyPathPartial<Root>(
+func _getAtPartialKeyPath<Root>(
   root: Root,
   keyPath: PartialKeyPath<Root>
 ) -> Any {
   func open<Value>(_: Value.Type) -> Any {
-    return _projectKeyPathReadOnly(root: root,
+    return _getAtKeyPath(root: root,
       keyPath: unsafeDowncast(keyPath, to: KeyPath<Root, Value>.self))
   }
   return _openExistential(type(of: keyPath).valueType, do: open)
 }
 
-@inlinable
+@_silgen_name("swift_getAtAnyKeyPath")
 public // COMPILER_INTRINSIC
-func _projectKeyPathAny<RootValue>(
+func _getAtAnyKeyPath<RootValue>(
   root: RootValue,
   keyPath: AnyKeyPath
 ) -> Any? {
@@ -1639,7 +1732,7 @@
       return nil
     }
     func openValue<Value>(_: Value.Type) -> Any {
-      return _projectKeyPathReadOnly(root: rootForKeyPath,
+      return _getAtKeyPath(root: rootForKeyPath,
         keyPath: unsafeDowncast(keyPath, to: KeyPath<KeyPathRoot, Value>.self))
     }
     return _openExistential(keyPathValue, do: openValue)
@@ -1647,41 +1740,59 @@
   return _openExistential(keyPathRoot, do: openRoot)
 }
 
-@inlinable
+@_silgen_name("swift_getAtKeyPath")
 public // COMPILER_INTRINSIC
-func _projectKeyPathReadOnly<Root, Value>(
+func _getAtKeyPath<Root, Value>(
   root: Root,
   keyPath: KeyPath<Root, Value>
 ) -> Value {
   return keyPath._projectReadOnly(from: root)
 }
 
-// The compiler can't tell which calls might begin an access.
-// That means it can't eliminate dominated checks even when it can prove
-// that the dominated scope has no internal nested conflicts.
-// We use the @_semantics("keypath.entry") annotation:
-// This doesn't solve the deinit ending a scope problem,
-// but it solves the much more important half of the problem:
-// identifying the beginning of an access scope -
-// would allow dominance based optimization:
-@_semantics("keypath.entry")
-public // COMPILER_INTRINSIC
-func _projectKeyPathWritable<Root, Value>(
-  root: UnsafeMutablePointer<Root>,
+@_silgen_name("_swift_modifyAtWritableKeyPath_impl")
+public // runtime entrypoint
+func _modifyAtWritableKeyPath_impl<Root, Value>(
+  root: inout Root,
   keyPath: WritableKeyPath<Root, Value>
 ) -> (UnsafeMutablePointer<Value>, AnyObject?) {
-  return keyPath._projectMutableAddress(from: root)
+  return keyPath._projectMutableAddress(from: &root)
 }
 
-@_semantics("keypath.entry")
-public // COMPILER_INTRINSIC
-func _projectKeyPathReferenceWritable<Root, Value>(
+@_silgen_name("_swift_modifyAtReferenceWritableKeyPath_impl")
+public // runtime entrypoint
+func _modifyAtReferenceWritableKeyPath_impl<Root, Value>(
   root: Root,
   keyPath: ReferenceWritableKeyPath<Root, Value>
 ) -> (UnsafeMutablePointer<Value>, AnyObject?) {
   return keyPath._projectMutableAddress(from: root)
 }
 
+@_silgen_name("swift_setAtWritableKeyPath")
+public // COMPILER_INTRINSIC
+func _setAtWritableKeyPath<Root, Value>(
+  root: inout Root,
+  keyPath: WritableKeyPath<Root, Value>,
+  value: __owned Value
+) {
+  // TODO: we should be able to do this more efficiently than projecting.
+  let (addr, owner) = keyPath._projectMutableAddress(from: &root)
+  addr.pointee = value
+  _fixLifetime(owner)
+}
+
+@_silgen_name("swift_setAtReferenceWritableKeyPath")
+public // COMPILER_INTRINSIC
+func _setAtReferenceWritableKeyPath<Root, Value>(
+  root: Root,
+  keyPath: ReferenceWritableKeyPath<Root, Value>,
+  value: __owned Value
+) {
+  // TODO: we should be able to do this more efficiently than projecting.
+  let (addr, owner) = keyPath._projectMutableAddress(from: root)
+  addr.pointee = value
+  _fixLifetime(owner)
+}
+
 // MARK: Appending type system
 
 // FIXME(ABI): The type relationships between KeyPath append operands are tricky
@@ -2133,6 +2244,10 @@
   return MemoryLayout<HeapObject>.size + MemoryLayout<Int>.size
 }
 
+internal var keyPathPatternHeaderSize: Int {
+  return 12
+}
+
 // Runtime entry point to instantiate a key path object.
 // Note that this has a compatibility override shim in the runtime so that
 // future compilers can backward-deploy support for instantiating new key path
@@ -2143,149 +2258,699 @@
     -> UnsafeRawPointer {
   // The key path pattern is laid out like a key path object, with a few
   // modifications:
+  // - Pointers in the instantiated object are compressed into 32-bit
+  //   relative offsets in the pattern.
+  // - The pattern begins with a field that's either zero, for a pattern that
+  //   depends on instantiation arguments, or that's a relative reference to
+  //   a global mutable pointer variable, which can be initialized to a single
+  //   shared instantiation of this pattern.
   // - Instead of the two-word object header with isa and refcount, two
   //   pointers to metadata accessors are provided for the root and leaf
   //   value types of the key path.
-  // - The header reuses the "trivial" bit to mean "instantiable in-line",
-  //   meaning that the key path described by this pattern has no contextually
-  //   dependent parts (no dependence on generic parameters, subscript indexes,
-  //   etc.), so it can be set up as a global object once. (The resulting
-  //   global object will itself always have the "trivial" bit set, since it
-  //   never needs to be destroyed.)
   // - Components may have unresolved forms that require instantiation.
-  // - Type metadata pointers are unresolved, and instead
-  //   point to accessor functions that instantiate the metadata.
+  // - Type metadata and protocol conformance pointers are replaced with
+  //   relative-referenced accessor functions that instantiate the
+  //   needed generic argument when called.
   //
   // The pattern never precomputes the capabilities of the key path (readonly/
   // writable/reference-writable), nor does it encode the reference prefix.
   // These are resolved dynamically, so that they always reflect the dynamic
   // capability of the properties involved.
-  let oncePtr = pattern
-  let patternPtr = pattern.advanced(by: MemoryLayout<Int>.size)
-  let bufferPtr = patternPtr.advanced(by: keyPathObjectHeaderSize)
 
-  // If the pattern is instantiable in-line, do a dispatch_once to
-  // initialize it. (The resulting object will still have the
-  // "trivial" bit set, since a global object never needs destruction.)
-  let bufferHeader = bufferPtr.load(as: KeyPathBuffer.Header.self)
+  let oncePtrPtr = pattern
+  let patternPtr = pattern.advanced(by: 4)
+
+  let bufferHeader = patternPtr.load(fromByteOffset: keyPathPatternHeaderSize,
+                                     as: KeyPathBuffer.Header.self)
   bufferHeader.validateReservedBits()
 
-  if bufferHeader.instantiableInLine {
-    Builtin.onceWithContext(oncePtr._rawValue, _getKeyPath_instantiateInline,
-                            patternPtr._rawValue)
+  // If the first word is nonzero, it relative-references a cache variable
+  // we can use to reference a single shared instantiation of this key path.
+  let oncePtrOffset = oncePtrPtr.load(as: Int32.self)
+  let oncePtr: UnsafeRawPointer?
+  if oncePtrOffset != 0 {
+    let theOncePtr = _resolveRelativeAddress(oncePtrPtr, oncePtrOffset)
+    oncePtr = theOncePtr
 
-    // Return the instantiated object at +1.
-    let objectPtr: UnsafeRawPointer
-
-    // If in-place instantiation failed, then the first word of the pattern
-    // buffer will be null, and the second word will contain the out-of-line
-    // object that was instantiated instead.
-    let firstWord = patternPtr.load(as: UnsafeRawPointer?.self)
-    if firstWord == nil {
-      objectPtr = patternPtr.load(fromByteOffset: MemoryLayout<Int>.size,
-                                  as: UnsafeRawPointer.self)
-    } else {
-      objectPtr = UnsafeRawPointer(patternPtr)
+    // See whether we already instantiated this key path.
+    // This is a non-atomic load because the instantiated pointer will be
+    // written with a release barrier, and loads of the instantiated key path
+    // ought to carry a dependency through this loaded pointer.
+    let existingInstance = theOncePtr.load(as: UnsafeRawPointer?.self)
+    
+    if let existingInstance = existingInstance {
+      // Return the instantiated object at +1.
+      let object = Unmanaged<AnyKeyPath>.fromOpaque(existingInstance)
+      // TODO: This retain will be unnecessary once we support global objects
+      // with inert refcounting.
+      _ = object.retain()
+      return existingInstance
     }
-
-    let object = Unmanaged<AnyKeyPath>.fromOpaque(objectPtr)
-    // TODO: This retain will be unnecessary once we support global objects
-    // with inert refcounting.
-    _ = object.retain()
-    return objectPtr
+  } else {
+    oncePtr = nil
   }
 
-  // Otherwise, instantiate a new key path object modeled on the pattern.
+  // Instantiate a new key path object modeled on the pattern.
   // Do a pass to determine the class of the key path we'll be instantiating
   // and how much space we'll need for it.
-  let (keyPathClass, rootType, size, alignmentMask)
+  let (keyPathClass, rootType, size, _)
     = _getKeyPathClassAndInstanceSizeFromPattern(patternPtr, arguments)
-  return _getKeyPath_instantiateOutOfLine(
-    pattern: patternPtr,
-    arguments: arguments,
-    keyPathClass: keyPathClass,
-    rootType: rootType,
-    size: size,
-    alignmentMask: alignmentMask)
-}
 
-internal func _getKeyPath_instantiateOutOfLine(
-  pattern: UnsafeRawPointer,
-  arguments: UnsafeRawPointer,
-  keyPathClass: AnyKeyPath.Type,
-  rootType: Any.Type,
-  size: Int,
-  alignmentMask: Int)
-    -> UnsafeRawPointer {
   // Allocate the instance.
   let instance = keyPathClass._create(capacityInBytes: size) { instanceData in
     // Instantiate the pattern into the instance.
-    let patternBufferPtr = pattern.advanced(by: keyPathObjectHeaderSize)
-    let patternBuffer = KeyPathBuffer(base: patternBufferPtr)
-
-    _instantiateKeyPathBuffer(patternBuffer, instanceData, rootType, arguments)
+    _instantiateKeyPathBuffer(patternPtr, instanceData, rootType, arguments)
   }
-  // Take the KVC string from the pattern.
-  let kvcStringPtr = pattern.advanced(by: MemoryLayout<HeapObject>.size)
-  instance._kvcKeyPathStringPtr = kvcStringPtr
-    .load(as: Optional<UnsafePointer<CChar>>.self)
 
-  // Hand it off at +1.
+  // Adopt the KVC string from the pattern.
+  let kvcStringBase = patternPtr.advanced(by: 8)
+  let kvcStringOffset = kvcStringBase.load(as: Int32.self)
+
+  if kvcStringOffset == 0 {
+    // Null pointer.
+    instance._kvcKeyPathStringPtr = nil
+  } else {
+    let kvcStringPtr = _resolveRelativeAddress(kvcStringBase, kvcStringOffset)
+    instance._kvcKeyPathStringPtr =
+      kvcStringPtr.assumingMemoryBound(to: CChar.self)
+  }
+
+  // If we can cache this instance as a shared instance, do so.
+  if let oncePtr = oncePtr {
+    // Try to replace a null pointer in the cache variable with the instance
+    // pointer.
+    let instancePtr = Unmanaged.passRetained(instance)
+
+    while true {
+      let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Word(
+        oncePtr._rawValue,
+        0._builtinWordValue,
+        UInt(bitPattern: instancePtr.toOpaque())._builtinWordValue)
+
+      // If the exchange succeeds, then the instance we formed is the canonical
+      // one.
+      if Bool(won) {
+        break
+      }
+
+      // Otherwise, someone raced with us to instantiate the key path pattern
+      // and won. Their instance should be just as good as ours, so we can take
+      // that one and let ours get deallocated.
+      if let existingInstance = UnsafeRawPointer(bitPattern: Int(oldValue)) {
+        // Return the instantiated object at +1.
+        let object = Unmanaged<AnyKeyPath>.fromOpaque(existingInstance)
+        // TODO: This retain will be unnecessary once we support global objects
+        // with inert refcounting.
+        _ = object.retain()
+        // Release the instance we created.
+        instancePtr.release()
+        return existingInstance
+      } else {
+        // Try the cmpxchg again if it spuriously failed.
+        continue
+      }
+    }
+  }
+
   return UnsafeRawPointer(Unmanaged.passRetained(instance).toOpaque())
 }
 
-internal func _getKeyPath_instantiateInline(
-  _ objectRawPtr: Builtin.RawPointer
-) {
-  let objectPtr = UnsafeMutableRawPointer(objectRawPtr)
+// A reference to metadata, which is a pointer to a mangled name.
+internal typealias MetadataReference = UnsafeRawPointer
 
-  // Do a pass to determine the class of the key path we'll be instantiating
-  // and how much space we'll need for it.
-  // The pattern argument doesn't matter since an in-place pattern should never
-  // have arguments.
-  let (keyPathClass, rootType, instantiatedSize, alignmentMask)
-    = _getKeyPathClassAndInstanceSizeFromPattern(objectPtr, objectPtr)
-  _sanityCheck(alignmentMask < MemoryLayout<Int>.alignment,
-               "overalignment not implemented")
+// Determine the length of the given mangled name.
+internal func _getSymbolicMangledNameLength(_ base: UnsafeRawPointer) -> Int {
+  var end = base
+  while let current = Optional(end.load(as: UInt8.self)), current != 0 {
+    // Skip the current character
+    end = end + 1
 
-  let bufferPtr = objectPtr.advanced(by: keyPathObjectHeaderSize)
-  let buffer = KeyPathBuffer(base: bufferPtr)
-  let totalSize = buffer.data.count + MemoryLayout<Int>.size
-  let bufferData = UnsafeMutableRawBufferPointer(
-    start: bufferPtr,
-    count: instantiatedSize)
-
-  // Do the instantiation in place if the final object fits.
-  if instantiatedSize <= totalSize {
-    _instantiateKeyPathBuffer(buffer, bufferData, rootType, bufferPtr)
-
-    _swift_instantiateInertHeapObject(objectPtr,
-      unsafeBitCast(keyPathClass, to: OpaquePointer.self))
-  } else {
-    // Otherwise, we'll need to instantiate out-of-place.
-    let object = _getKeyPath_instantiateOutOfLine(
-      pattern: objectPtr,
-      arguments: objectPtr,
-      keyPathClass: keyPathClass,
-      rootType: rootType,
-      size: instantiatedSize,
-      alignmentMask: alignmentMask)
-
-    // Write a null pointer to the first word of the in-place buffer as
-    // a signal that this isn't a valid object.
-    // We rely on the heap object header size being >=2 words to get away with
-    // this.
-    assert(keyPathObjectHeaderSize >= MemoryLayout<Int>.size * 2)
-    objectPtr.storeBytes(of: nil, as: UnsafeRawPointer?.self)
-
-    // Put the pointer to the out-of-line object in the second word.
-    objectPtr.storeBytes(of: object, toByteOffset: MemoryLayout<Int>.size,
-                         as: UnsafeRawPointer.self)
+    // Skip over a symbolic reference
+    if current >= 0x1 && current <= 0x17 {
+      end += 4
+    } else if current >= 0x18 && current <= 0x1F {
+      end += MemoryLayout<Int>.size
+    }
   }
+
+  return end - base
 }
 
-internal typealias MetadataAccessor =
-  @convention(c) (UnsafeRawPointer) -> UnsafeRawPointer
+// Resolve the given generic argument reference to a generic argument.
+internal func _resolveKeyPathGenericArgReference(_ reference: UnsafeRawPointer,
+                                                 arguments: UnsafeRawPointer)
+    -> UnsafeRawPointer {
+  // If the low bit is clear, it's a direct reference to the argument.
+  if (UInt(bitPattern: reference) & 0x01 == 0) {
+    return reference;
+  }
+
+  // Adjust the reference.
+  let referenceStart = reference - 1
+
+  // If we have a symbolic reference to an accessor, call it.
+  let first = referenceStart.load(as: UInt8.self)
+  if first == 9 {
+    typealias MetadataAccessor =
+      @convention(c) (UnsafeRawPointer) -> UnsafeRawPointer
+
+    // Unaligned load of the offset.
+    var offset: Int32 = 0
+    _memcpy(dest: &offset, src: reference, size: 4)
+
+    let accessorPtr = _resolveRelativeAddress(reference, offset)
+    let accessor = unsafeBitCast(accessorPtr, to: MetadataAccessor.self)
+    return accessor(arguments)
+  }
+
+  let nameLength = _getSymbolicMangledNameLength(referenceStart)
+  let namePtr = referenceStart.bindMemory(to: UInt8.self,
+                                          capacity: nameLength + 1)
+  // FIXME: Could extract this information from the mangled name.
+  let parametersPerLevel: [UInt] = []
+  let substitutions: [Any.Type] = []
+  guard let result = _getTypeByMangledName(namePtr, UInt(nameLength), 0,
+                                           parametersPerLevel, substitutions)
+    else {
+      let nameStr = String._fromUTF8Repairing(
+        UnsafeBufferPointer(start: namePtr, count: nameLength)
+      ).0
+
+      fatalError("could not demangle keypath type from '\(nameStr)'")
+    }
+
+  return unsafeBitCast(result, to: UnsafeRawPointer.self)
+}
+
+// Resolve the given metadata reference to (type) metadata.
+internal func _resolveKeyPathMetadataReference(_ reference: UnsafeRawPointer,
+                                               arguments: UnsafeRawPointer)
+    -> Any.Type {
+  return unsafeBitCast(
+           _resolveKeyPathGenericArgReference(reference, arguments: arguments),
+           to: Any.Type.self)
+}
+
+internal enum KeyPathStructOrClass {
+  case `struct`, `class`
+}
+internal enum KeyPathPatternStoredOffset {
+  case inline(UInt32)
+  case outOfLine(UInt32)
+  case unresolvedFieldOffset(UInt32)
+  case unresolvedIndirectOffset(UnsafePointer<UInt32>)
+}
+internal struct KeyPathPatternComputedArguments {
+  var getLayout: KeyPathComputedArgumentLayoutFn
+  var witnesses: UnsafePointer<ComputedArgumentWitnesses>
+  var initializer: KeyPathComputedArgumentInitializerFn
+}
+
+internal protocol KeyPathPatternVisitor {
+  mutating func visitHeader(rootMetadataRef: MetadataReference,
+                            leafMetadataRef: MetadataReference,
+                            kvcCompatibilityString: UnsafeRawPointer)
+  mutating func visitStoredComponent(kind: KeyPathStructOrClass,
+                                     mutable: Bool,
+                                     offset: KeyPathPatternStoredOffset)
+  mutating func visitComputedComponent(mutating: Bool,
+                                       idKind: KeyPathComputedIDKind,
+                                       idResolved: Bool,
+                                       idValueBase: UnsafeRawPointer,
+                                       idValue: Int32,
+                                       getter: UnsafeRawPointer,
+                                       setter: UnsafeRawPointer?,
+                                       arguments: KeyPathPatternComputedArguments?,
+                                       externalArgs: UnsafeBufferPointer<Int32>?)
+  mutating func visitOptionalChainComponent()
+  mutating func visitOptionalForceComponent()
+  mutating func visitOptionalWrapComponent()
+
+  mutating func visitIntermediateComponentType(metadataRef: MetadataReference)
+
+  mutating func finish()
+}
+
+internal func _resolveRelativeAddress(_ base: UnsafeRawPointer,
+                                      _ offset: Int32) -> UnsafeRawPointer {
+  // Sign-extend the offset to pointer width and add with wrap on overflow.
+  return UnsafeRawPointer(bitPattern: Int(bitPattern: base) &+ Int(offset))
+    .unsafelyUnwrapped
+}
+internal func _resolveRelativeIndirectableAddress(_ base: UnsafeRawPointer,
+                                                  _ offset: Int32)
+    -> UnsafeRawPointer {
+  // Low bit indicates whether the reference is indirected or not.
+  if offset & 1 != 0 {
+    let ptrToPtr = _resolveRelativeAddress(base, offset - 1)
+    return ptrToPtr.load(as: UnsafeRawPointer.self)
+  }
+  return _resolveRelativeAddress(base, offset)
+}
+internal func _loadRelativeAddress<T>(at: UnsafeRawPointer,
+                                      fromByteOffset: Int = 0,
+                                      as: T.Type) -> T {
+  let offset = at.load(fromByteOffset: fromByteOffset, as: Int32.self)
+  return unsafeBitCast(_resolveRelativeAddress(at + fromByteOffset, offset),
+                       to: T.self)
+}
+
+internal func _walkKeyPathPattern<W: KeyPathPatternVisitor>(
+                                  _ pattern: UnsafeRawPointer,
+                                  walker: inout W) {
+  // Visit the header.
+  let rootMetadataRef = _loadRelativeAddress(at: pattern,
+                                             as: MetadataReference.self)
+  let leafMetadataRef = _loadRelativeAddress(at: pattern, fromByteOffset: 4,
+                                             as: MetadataReference.self)
+  let kvcString = _loadRelativeAddress(at: pattern, fromByteOffset: 8,
+                                       as: UnsafeRawPointer.self)
+
+  walker.visitHeader(rootMetadataRef: rootMetadataRef,
+                     leafMetadataRef: leafMetadataRef,
+                     kvcCompatibilityString: kvcString)
+
+  func visitStored(header: RawKeyPathComponent.Header,
+                   componentBuffer: inout UnsafeRawBufferPointer) {
+    // Decode a stored property. A small offset may be stored inline in the
+    // header word, or else be stored out-of-line, or need instantiation of some
+    // kind.
+    let offset: KeyPathPatternStoredOffset
+    switch header.storedOffsetPayload {
+    case RawKeyPathComponent.Header.outOfLineOffsetPayload:
+      offset = .outOfLine(_pop(from: &componentBuffer,
+                               as: UInt32.self))
+    case RawKeyPathComponent.Header.unresolvedFieldOffsetPayload:
+      offset = .unresolvedFieldOffset(_pop(from: &componentBuffer,
+                                           as: UInt32.self))
+    case RawKeyPathComponent.Header.unresolvedIndirectOffsetPayload:
+      let base = componentBuffer.baseAddress.unsafelyUnwrapped
+      let relativeOffset = _pop(from: &componentBuffer,
+                                as: Int32.self)
+      let ptr = _resolveRelativeIndirectableAddress(base, relativeOffset)
+      offset = .unresolvedIndirectOffset(
+                                       ptr.assumingMemoryBound(to: UInt32.self))
+    default:
+      offset = .inline(header.storedOffsetPayload)
+    }
+    let kind: KeyPathStructOrClass = header.kind == .struct 
+      ? .struct : .class
+    walker.visitStoredComponent(kind: kind,
+                                mutable: header.isStoredMutable,
+                                offset: offset)
+  }
+
+  func popComputedAccessors(header: RawKeyPathComponent.Header,
+                            componentBuffer: inout UnsafeRawBufferPointer)
+      -> (idValueBase: UnsafeRawPointer,
+          idValue: Int32,
+          getter: UnsafeRawPointer,
+          setter: UnsafeRawPointer?) {
+    let idValueBase = componentBuffer.baseAddress.unsafelyUnwrapped
+    let idValue = _pop(from: &componentBuffer, as: Int32.self)
+    let getterBase = componentBuffer.baseAddress.unsafelyUnwrapped
+    let getterRef = _pop(from: &componentBuffer, as: Int32.self)
+    let getter = _resolveRelativeAddress(getterBase, getterRef)
+    let setter: UnsafeRawPointer?
+    if header.isComputedSettable {
+      let setterBase = componentBuffer.baseAddress.unsafelyUnwrapped
+      let setterRef = _pop(from: &componentBuffer, as: Int32.self)
+      setter = _resolveRelativeAddress(setterBase, setterRef)
+    } else {
+      setter = nil
+    }
+    return (idValueBase: idValueBase, idValue: idValue,
+            getter: getter, setter: setter)
+  }
+
+  func popComputedArguments(header: RawKeyPathComponent.Header,
+                            componentBuffer: inout UnsafeRawBufferPointer)
+      -> KeyPathPatternComputedArguments? {
+    if header.hasComputedArguments {
+      let getLayoutBase = componentBuffer.baseAddress.unsafelyUnwrapped
+      let getLayoutRef = _pop(from: &componentBuffer, as: Int32.self)
+      let getLayoutRaw = _resolveRelativeAddress(getLayoutBase, getLayoutRef)
+      let getLayout = unsafeBitCast(getLayoutRaw,
+                                    to: KeyPathComputedArgumentLayoutFn.self)
+
+      let witnessesBase = componentBuffer.baseAddress.unsafelyUnwrapped
+      let witnessesRef = _pop(from: &componentBuffer, as: Int32.self)
+      let witnesses: UnsafeRawPointer
+      if witnessesRef == 0 {
+        witnesses = __swift_keyPathGenericWitnessTable_addr()
+      } else {
+        witnesses = _resolveRelativeAddress(witnessesBase, witnessesRef)
+      }
+
+      let initializerBase = componentBuffer.baseAddress.unsafelyUnwrapped
+      let initializerRef = _pop(from: &componentBuffer, as: Int32.self)
+      let initializerRaw = _resolveRelativeAddress(initializerBase,
+                                                   initializerRef)
+      let initializer = unsafeBitCast(initializerRaw,
+                                  to: KeyPathComputedArgumentInitializerFn.self)
+
+      return KeyPathPatternComputedArguments(getLayout: getLayout,
+        witnesses:
+              witnesses.assumingMemoryBound(to: ComputedArgumentWitnesses.self),
+        initializer: initializer)
+    } else {
+      return nil
+    }
+  }
+
+  // We declare this down here to avoid the temptation to use it within
+  // the functions above.
+  let bufferPtr = pattern.advanced(by: keyPathPatternHeaderSize)
+  let bufferHeader = bufferPtr.load(as: KeyPathBuffer.Header.self)
+  var buffer = UnsafeRawBufferPointer(start: bufferPtr + 4,
+                                      count: bufferHeader.size)
+
+  while !buffer.isEmpty {
+    let header = _pop(from: &buffer,
+                      as: RawKeyPathComponent.Header.self)
+
+    // Ensure that we pop an amount of data consistent with what
+    // RawKeyPathComponent.Header.patternComponentBodySize computes.
+    var bufferSizeBefore = 0
+    var expectedPop = 0
+
+    _sanityCheck({
+      bufferSizeBefore = buffer.count
+      expectedPop = header.patternComponentBodySize
+      return true
+    }())
+
+    switch header.kind {
+    case .class, .struct:
+      visitStored(header: header, componentBuffer: &buffer)
+    case .computed:
+      let (idValueBase, idValue, getter, setter)
+        = popComputedAccessors(header: header,
+                               componentBuffer: &buffer)
+
+      // If there are arguments, gather those too.
+      let arguments = popComputedArguments(header: header,
+                                           componentBuffer: &buffer)
+
+      walker.visitComputedComponent(mutating: header.isComputedMutating,
+                                    idKind: header.computedIDKind,
+                                    idResolved: header.isComputedIDResolved,
+                                    idValueBase: idValueBase,
+                                    idValue: idValue,
+                                    getter: getter,
+                                    setter: setter,
+                                    arguments: arguments,
+                                    externalArgs: nil)
+
+    case .optionalChain:
+      walker.visitOptionalChainComponent()
+    case .optionalWrap:
+      walker.visitOptionalWrapComponent()
+    case .optionalForce:
+      walker.visitOptionalForceComponent()
+    case .external:
+      // Look at the external property descriptor to see if we should take it
+      // over the component given in the pattern.
+      let genericParamCount = Int(header.payload)
+      let descriptorBase = buffer.baseAddress.unsafelyUnwrapped
+      let descriptorOffset = _pop(from: &buffer,
+                                  as: Int32.self)
+      let descriptor =
+        _resolveRelativeIndirectableAddress(descriptorBase, descriptorOffset)
+      let descriptorHeader =
+        descriptor.load(as: RawKeyPathComponent.Header.self)
+      if descriptorHeader.isTrivialPropertyDescriptor {
+        // If the descriptor is trivial, then use the local candidate.
+        // Skip the external generic parameter accessors to get to it.
+        _ = _pop(from: &buffer, as: Int32.self, count: genericParamCount)
+        continue
+      }
+      
+      // Grab the generic parameter accessors to pass to the external component.
+      let externalArgs = _pop(from: &buffer, as: Int32.self,
+                              count: genericParamCount)
+
+      // Grab the header for the local candidate in case we need it for
+      // a computed property.
+      let localCandidateHeader = _pop(from: &buffer,
+                                      as: RawKeyPathComponent.Header.self)
+      let localCandidateSize = localCandidateHeader.patternComponentBodySize
+      _sanityCheck({
+        expectedPop += localCandidateSize + 4
+        return true
+      }())
+
+      let descriptorSize = descriptorHeader.propertyDescriptorBodySize
+      var descriptorBuffer = UnsafeRawBufferPointer(start: descriptor + 4,
+                                                    count: descriptorSize)
+
+      // Look at what kind of component the external property has.
+      switch descriptorHeader.kind {
+      case .struct, .class:
+        // A stored component. We can instantiate it
+        // without help from the local candidate.
+        _ = _pop(from: &buffer, as: UInt8.self, count: localCandidateSize)
+
+        visitStored(header: descriptorHeader,
+                    componentBuffer: &descriptorBuffer)
+        
+      case .computed:
+        // A computed component. The accessors come from the descriptor.
+        let (idValueBase, idValue, getter, setter)
+          = popComputedAccessors(header: descriptorHeader,
+                                 componentBuffer: &descriptorBuffer)
+        
+        // Get the arguments from the external descriptor and/or local candidate
+        // component.
+        let arguments: KeyPathPatternComputedArguments?
+        if localCandidateHeader.kind == .computed
+            && localCandidateHeader.hasComputedArguments {
+          // If both have arguments, then we have to build a bit of a chimera.
+          // The canonical identity and accessors come from the descriptor,
+          // but the argument equality/hash handling is still as described
+          // in the local candidate.
+          // We don't need the local candidate's accessors.
+          _ = popComputedAccessors(header: localCandidateHeader,
+                                   componentBuffer: &buffer)
+          // We do need the local arguments.
+          arguments = popComputedArguments(header: localCandidateHeader,
+                                           componentBuffer: &buffer)
+        } else {
+          // If the local candidate doesn't have arguments, we don't need
+          // anything from it at all.
+          _ = _pop(from: &buffer, as: UInt8.self, count: localCandidateSize)
+          arguments = nil
+        }
+
+        walker.visitComputedComponent(
+          mutating: descriptorHeader.isComputedMutating,
+          idKind: descriptorHeader.computedIDKind,
+          idResolved: descriptorHeader.isComputedIDResolved,
+          idValueBase: idValueBase,
+          idValue: idValue,
+          getter: getter,
+          setter: setter,
+          arguments: arguments,
+          externalArgs: genericParamCount > 0 ? externalArgs : nil)
+      case .optionalChain, .optionalWrap, .optionalForce, .external:
+        _sanityCheckFailure("not possible for property descriptor")
+      }
+    }
+
+    // Check that we consumed the expected amount of data from the pattern.
+    _sanityCheck(
+      {
+        // Round the amount of data we read up to alignment.
+        let popped = MemoryLayout<Int32>._roundingUpToAlignment(
+           bufferSizeBefore - buffer.count)
+        return expectedPop == popped
+      }(),
+      """
+      component size consumed during pattern walk does not match \
+      component size returned by patternComponentBodySize
+      """)
+
+    // Break if this is the last component.
+    if buffer.isEmpty { break }
+
+    // Otherwise, pop the intermediate component type accessor and
+    // go around again.
+    let componentTypeBase = buffer.baseAddress.unsafelyUnwrapped
+    let componentTypeOffset = _pop(from: &buffer, as: Int32.self)
+    let componentTypeRef = _resolveRelativeAddress(componentTypeBase,
+                                                   componentTypeOffset)
+    walker.visitIntermediateComponentType(metadataRef: componentTypeRef)
+    _sanityCheck(!buffer.isEmpty)
+  }
+
+  // We should have walked the entire pattern.
+  _sanityCheck(buffer.isEmpty, "did not walk entire pattern buffer")
+  walker.finish()
+}
+
+internal struct GetKeyPathClassAndInstanceSizeFromPattern
+    : KeyPathPatternVisitor {
+  var size: Int = MemoryLayout<Int>.size // start with one word for the header
+  var capability: KeyPathKind = .value
+  var didChain: Bool = false
+  var root: Any.Type!
+  var leaf: Any.Type!
+  let patternArgs: UnsafeRawPointer
+
+  init(patternArgs: UnsafeRawPointer) {
+    self.patternArgs = patternArgs
+  }
+
+  mutating func roundUpToPointerAlignment() {
+    size = MemoryLayout<Int>._roundingUpToAlignment(size)
+  }
+
+  mutating func visitHeader(rootMetadataRef: MetadataReference,
+                            leafMetadataRef: MetadataReference,
+                            kvcCompatibilityString: UnsafeRawPointer) {
+    // Get the root and leaf type metadata so we can form the class type
+    // for the entire key path.
+    root = _resolveKeyPathMetadataReference(rootMetadataRef,
+                                            arguments: patternArgs)
+    leaf = _resolveKeyPathMetadataReference(leafMetadataRef,
+                                            arguments: patternArgs)
+  }
+
+  mutating func visitStoredComponent(kind: KeyPathStructOrClass,
+                                     mutable: Bool,
+                                     offset: KeyPathPatternStoredOffset) {
+    // Mutable class properties can be the root of a reference mutation.
+    // Mutable struct properties pass through the existing capability.
+    if mutable {
+      switch kind {
+      case .class:
+        capability = .reference
+      case .struct:
+        break
+      }
+    } else {
+      // Immutable properties can only be read.
+      capability = .readOnly
+    }
+
+    // The size of the instantiated component depends on whether we can fit
+    // the offset inline.
+    switch offset {
+    case .inline:
+      size += 4
+
+    case .outOfLine, .unresolvedFieldOffset, .unresolvedIndirectOffset:
+      size += 8
+    }
+  }
+
+  mutating func visitComputedComponent(mutating: Bool,
+                                   idKind: KeyPathComputedIDKind,
+                                   idResolved: Bool,
+                                   idValueBase: UnsafeRawPointer,
+                                   idValue: Int32,
+                                   getter: UnsafeRawPointer,
+                                   setter: UnsafeRawPointer?,
+                                   arguments: KeyPathPatternComputedArguments?,
+                                   externalArgs: UnsafeBufferPointer<Int32>?) {
+    let settable = setter != nil
+
+    switch (settable, mutating) {
+    case (false, false):
+      // If the property is get-only, the capability becomes read-only, unless
+      // we get another reference-writable component.
+      capability = .readOnly
+    case (true, false):
+      capability = .reference
+    case (true, true):
+      // Writable if the base is. No effect.
+      break
+    case (false, true):
+      _sanityCheckFailure("unpossible")
+    }
+
+    // Save space for the header...
+    size += 4
+    roundUpToPointerAlignment()
+    // ...id, getter, and maybe setter...
+    size += MemoryLayout<Int>.size * 2
+    if settable {
+      size += MemoryLayout<Int>.size
+    }
+    
+    // ...and the arguments, if any.
+    let argumentHeaderSize = MemoryLayout<Int>.size * 2
+    switch (arguments, externalArgs) {
+    case (nil, nil):
+      break
+    case (let arguments?, nil):
+      size += argumentHeaderSize
+      // If we have arguments, calculate how much space they need by invoking
+      // the layout function.
+      let (addedSize, addedAlignmentMask) = arguments.getLayout(patternArgs)
+      // TODO: Handle over-aligned values
+      _sanityCheck(addedAlignmentMask < MemoryLayout<Int>.alignment,
+                   "overaligned computed property element not supported")
+      size += addedSize
+    
+    case (let arguments?, let externalArgs?):
+      // If we're referencing an external declaration, and it takes captured
+      // arguments, then we have to build a bit of a chimera. The canonical
+      // identity and accessors come from the descriptor, but the argument
+      // handling is still as described in the local candidate.
+      size += argumentHeaderSize
+      let (addedSize, addedAlignmentMask) = arguments.getLayout(patternArgs)
+      // TODO: Handle over-aligned values
+      _sanityCheck(addedAlignmentMask < MemoryLayout<Int>.alignment,
+                   "overaligned computed property element not supported")
+      size += addedSize
+      // We also need to store the size of the local arguments so we can
+      // find the external component arguments.
+      roundUpToPointerAlignment()
+      size += RawKeyPathComponent.Header.externalWithArgumentsExtraSize
+      size += MemoryLayout<Int>.size * externalArgs.count
+
+    case (nil, let externalArgs?):
+      // If we're instantiating an external property with a local
+      // candidate that has no arguments, then things are a little
+      // easier. We only need to instantiate the generic
+      // arguments for the external component's accessors.
+      size += argumentHeaderSize
+      size += MemoryLayout<Int>.size * externalArgs.count
+    }
+  }
+
+  mutating func visitOptionalChainComponent() {
+    // Optional chaining forces the entire keypath to be read-only, even if
+    // there are further reference-writable components.
+    didChain = true
+    capability = .readOnly
+    size += 4
+  }
+  mutating func visitOptionalWrapComponent() {
+    // Optional chaining forces the entire keypath to be read-only, even if
+    // there are further reference-writable components.
+    didChain = true
+    capability = .readOnly
+    size += 4
+  }
+
+  mutating func visitOptionalForceComponent() {
+    // Force-unwrapping passes through the mutability of the preceding keypath.
+    size += 4
+  }
+
+  mutating
+  func visitIntermediateComponentType(metadataRef _: MetadataReference) {
+    // The instantiated component type will be stored in the instantiated
+    // object.
+    roundUpToPointerAlignment()
+    size += MemoryLayout<Int>.size
+  }
+
+  mutating func finish() {
+  }
+}
 
 internal func _getKeyPathClassAndInstanceSizeFromPattern(
   _ pattern: UnsafeRawPointer,
@@ -2296,315 +2961,18 @@
   size: Int,
   alignmentMask: Int
 ) {
-  // Resolve the root and leaf types.
-  let rootAccessor = pattern.load(as: MetadataAccessor.self)
-  let leafAccessor = pattern.load(fromByteOffset: MemoryLayout<Int>.size,
-                                    as: MetadataAccessor.self)
-
-  let root = unsafeBitCast(rootAccessor(arguments), to: Any.Type.self)
-  let leaf = unsafeBitCast(leafAccessor(arguments), to: Any.Type.self)
-
-  // Scan the pattern to figure out the dynamic capability of the key path.
-  // Start off assuming the key path is writable.
-  var capability: KeyPathKind = .value
-  var didChain = false
-
-  let bufferPtr = pattern.advanced(by: keyPathObjectHeaderSize)
-  var buffer = KeyPathBuffer(base: bufferPtr)
-  var size = buffer.data.count + MemoryLayout<Int>.size
-
-  if !buffer.data.isEmpty {
-   while true {
-    let header = buffer.pop(RawKeyPathComponent.Header.self)
-
-    // Ensure that we pop an amount of data consistent with what
-    // RawKeyPathComponent.Header.patternComponentBodySize computes.
-    var bufferSizeBefore = 0
-    var expectedPop = 0
-
-    _sanityCheck({
-      bufferSizeBefore = buffer.data.count
-      expectedPop = header.patternComponentBodySize
-      return true
-    }())
-
-    func setStoredCapability(for header: RawKeyPathComponent.Header) {
-      // Mutable class properties can be the root of a reference mutation.
-      // Mutable struct properties pass through the existing capability.
-      if header.isStoredMutable {
-        if header.kind == .class { capability = .reference }
-      } else {
-        // Immutable properties can only be read.
-        capability = .readOnly
-      }
-    }
-
-    func setComputedCapability(for header: RawKeyPathComponent.Header) {
-      let settable = header.isComputedSettable
-      let mutating = header.isComputedMutating
-
-      switch (settable, mutating) {
-      case (false, false):
-        // If the property is get-only, the capability becomes read-only, unless
-        // we get another reference-writable component.
-        capability = .readOnly
-      case (true, false):
-        capability = .reference
-      case (true, true):
-        // Writable if the base is. No effect.
-        break
-      case (false, true):
-        _sanityCheckFailure("unpossible")
-      }
-    }
-
-    switch header.kind {
-    case .class, .struct:
-      setStoredCapability(for: header)
-
-      // Check the final instantiated size of the offset.
-      if header.storedOffsetPayload == RawKeyPathComponent.Header.unresolvedFieldOffsetPayload
-        || header.storedOffsetPayload == RawKeyPathComponent.Header.outOfLineOffsetPayload {
-        _ = buffer.pop(UInt32.self)
-      }
-      if header.storedOffsetPayload == RawKeyPathComponent.Header.unresolvedIndirectOffsetPayload {
-        _ = buffer.pop(Int.self)
-        // On 64-bit systems the pointer to the ivar offset variable is
-        // pointer-sized and -aligned, but the resulting offset ought to be
-        // 32 bits only and fit into padding between the 4-byte header and
-        // pointer-aligned type word. We don't need this space after
-        // instantiation.
-        if MemoryLayout<Int>.size == 8 {
-          size -= MemoryLayout<UnsafeRawPointer>.size
-        }
-      }
-
-    case .external:
-      // Look at the external property descriptor to see if we should take it
-      // over the component given in the pattern.
-      let genericParamCount = Int(header.payload)
-      let descriptor = buffer.pop(UnsafeRawPointer.self)
-      let descriptorHeader = descriptor.load(as: RawKeyPathComponent.Header.self)
-      if descriptorHeader.isTrivialPropertyDescriptor {
-        // If the descriptor is trivial, then use the local candidate.
-        // Leave this external reference out of the final object size.
-        size -= (2 + genericParamCount) * MemoryLayout<Int>.size
-        // Skip the generic parameter accessors to get to the local candidate.
-        _ = buffer.popRaw(size: MemoryLayout<Int>.size * genericParamCount,
-                          alignment: Int.self)
-        continue
-      }
-
-      // Drop this external reference...
-      size -= (header.patternComponentBodySize
-               + MemoryLayout<RawKeyPathComponent.Header>.size)
-      _ = buffer.popRaw(size: MemoryLayout<Int>.size * genericParamCount,
-                        alignment: Int.self)
-      // ...and the local candidate, which is the component following this
-      // one.
-      let localCandidateHeader = buffer.pop(RawKeyPathComponent.Header.self)
-      let localCandidateSize = localCandidateHeader.patternComponentBodySize
-      size -= (localCandidateSize
-               + MemoryLayout<RawKeyPathComponent.Header>.size)
-
-      // (Note that we don't pop the local candidate from the pattern buffer
-      // just yet, since we may need parts of it to instantiate the final
-      // component in some cases below. It still ought to be consumed
-      // in the computation below.)
-      _sanityCheck({
-        expectedPop += localCandidateSize
-                    +  MemoryLayout<RawKeyPathComponent.Header>.size
-        return true
-      }())
-
-      // Measure the instantiated size of the external component.
-      let newComponentSize: Int
-      switch descriptorHeader.kind {
-      case .class, .struct:
-        setStoredCapability(for: descriptorHeader)
-
-        // Discard the local candidate.
-        _ = buffer.popRaw(size: localCandidateSize,
-                          alignment: Int32.self)
-
-        // The final component will be a stored component with just an offset.
-        // If the offset requires resolution, then it'll be stored out of
-        // line after the header.
-        if descriptorHeader.storedOffsetPayload
-            > RawKeyPathComponent.Header.maximumOffsetPayload {
-          newComponentSize = MemoryLayout<RawKeyPathComponent.Header>.size
-                           + MemoryLayout<UInt32>.size
-        } else {
-          newComponentSize = MemoryLayout<RawKeyPathComponent.Header>.size
-        }
-
-      case .computed:
-        // The final component will be an instantiation of the computed
-        // component.
-        setComputedCapability(for: descriptorHeader)
-
-        // If the external declaration is computed, and it takes captured
-        // arguments, then we have to build a bit of a chimera. The canonical
-        // identity and accessors come from the descriptor, but the argument
-        // handling is still as described in the local candidate.
-        if descriptorHeader.hasComputedArguments {
-          // We always start with the buffer size and witnesses.
-          var argumentBufferSize = MemoryLayout<Int>.size * 2
-
-          if localCandidateHeader.kind == .computed
-              && localCandidateHeader.hasComputedArguments {
-            // We don't need the local candidate's accessors.
-            _ /*id*/ = buffer.pop(UnsafeRawPointer.self)
-            _ /*getter*/ = buffer.pop(UnsafeRawPointer.self)
-            if localCandidateHeader.isComputedSettable {
-              _ /*setter*/ = buffer.pop(UnsafeRawPointer.self)
-            }
-
-            // Get the instantiated size of the component's own argument
-            // file.
-            let getLayoutRaw = buffer.pop(UnsafeRawPointer.self)
-            let _ /*witnesses*/ = buffer.pop(UnsafeRawPointer.self)
-            let _ /*initializer*/ = buffer.pop(UnsafeRawPointer.self)
-
-            let getLayout = unsafeBitCast(getLayoutRaw,
-              to: RawKeyPathComponent.ComputedArgumentLayoutFn.self)
-
-            let (addedSize, addedAlignmentMask) = getLayout(arguments)
-            // TODO: Handle over-aligned values
-            _sanityCheck(addedAlignmentMask < MemoryLayout<Int>.alignment,
-                         "overaligned computed property element not supported")
-
-            argumentBufferSize += addedSize
-
-            // If the property descriptor also has generic arguments, we need
-            // to store the size so we can invoke the local witnesses on
-            // the arguments. We'll also store those generic arguments at
-            // pointer alignment after the local candidate's arguments.
-            if genericParamCount > 0 {
-              argumentBufferSize =
-                MemoryLayout<Int>._roundingUpToAlignment(argumentBufferSize)
-              argumentBufferSize +=
-                RawKeyPathComponent.Header.externalWithArgumentsExtraSize
-            }
-          } else {
-            // If the local candidate has no arguments, then things are a
-            // little easier. We only need to instantiate the generic arguments
-            // for the external component's accessors.
-            // Discard the local candidate.
-            _ = buffer.popRaw(size: localCandidateSize,
-                              alignment: UInt32.self)
-          }
-
-          // Add the property descriptor's generic arguments to the end, if
-          // any.
-          if genericParamCount > 0 {
-            argumentBufferSize += MemoryLayout<Int>.size * genericParamCount
-          }
-          newComponentSize = MemoryLayout<RawKeyPathComponent.Header>.size
-                           + descriptorHeader.propertyDescriptorBodySize
-                           + argumentBufferSize
-        } else {
-          // If there aren't any captured arguments expected in the external
-          // component, then we only need to adopt its accessors.
-          // Discard the local candidate.
-          _ = buffer.popRaw(size: localCandidateSize,
-                            alignment: UInt32.self)
-          // With no arguments, the instantiated size will be the
-          // same as the pattern size.
-          newComponentSize = MemoryLayout<RawKeyPathComponent.Header>.size
-                           + descriptorHeader.propertyDescriptorBodySize
-        }
-
-      case .external, .optionalChain, .optionalForce, .optionalWrap:
-        _sanityCheckFailure("should not appear as property descriptor")
-      }
-
-      // Round up to pointer alignment if there are following components.
-      if !buffer.data.isEmpty {
-        size += MemoryLayout<Int>._roundingUpToAlignment(newComponentSize)
-      } else {
-        size += newComponentSize
-      }
-
-    case .computed:
-      let settable = header.isComputedSettable
-      let hasArguments = header.hasComputedArguments
-
-      setComputedCapability(for: header)
-
-      _ = buffer.popRaw(size: MemoryLayout<Int>.size * (settable ? 3 : 2),
-                        alignment: Int.self)
-
-      // Get the instantiated size and alignment of the argument payload
-      // by asking the layout function to compute it for our given argument
-      // file.
-      if hasArguments {
-        let getLayoutRaw = buffer.pop(UnsafeRawPointer.self)
-        let _ /*witnesses*/ = buffer.pop(UnsafeRawPointer.self)
-        let _ /*initializer*/ = buffer.pop(UnsafeRawPointer.self)
-
-        let getLayout = unsafeBitCast(getLayoutRaw,
-          to: RawKeyPathComponent.ComputedArgumentLayoutFn.self)
-
-        let (addedSize, addedAlignmentMask) = getLayout(arguments)
-        // TODO: Handle over-aligned values
-        _sanityCheck(addedAlignmentMask < MemoryLayout<Int>.alignment,
-                     "overaligned computed property element not supported")
-
-        // Argument payload replaces the space taken by the initializer
-        // function pointer in the pattern.
-        size += MemoryLayout<Int>._roundingUpToAlignment(addedSize)
-              - MemoryLayout<Int>.size
-      }
-
-    case .optionalChain,
-         .optionalWrap:
-      // Chaining always renders the whole key path read-only.
-      didChain = true
-      break
-
-    case .optionalForce:
-      // No effect.
-      break
-    }
-
-    // Check that we consumed the expected amount of data from the pattern.
-    _sanityCheck(
-      {
-        // Round the amount of data we read up to alignment to include padding,
-        // skewed by the header size.
-        let popped = MemoryLayout<Int>._roundingUpToAlignment(
-           bufferSizeBefore - buffer.data.count
-           - RawKeyPathComponent.Header.pointerAlignmentSkew)
-          + RawKeyPathComponent.Header.pointerAlignmentSkew
-
-        return expectedPop == popped
-      }(),
-      """
-      component size consumed during instance size measurement does not match \
-      component size returned by patternComponentBodySize
-      """)
-
-    // Break if this is the last component.
-    if buffer.data.count == 0 { break }
-
-    // Pop the type accessor reference.
-    _ = buffer.popRaw(size: MemoryLayout<Int>.size,
-                      alignment: Int.self)
-   }
-  }
-
-  _sanityCheck(buffer.data.isEmpty, "didn't read entire pattern")
+  var walker = GetKeyPathClassAndInstanceSizeFromPattern(patternArgs: arguments)
+  _walkKeyPathPattern(pattern, walker: &walker)
 
   // Chaining always renders the whole key path read-only.
-  if didChain {
-    capability = .readOnly
+  if walker.didChain {
+    walker.capability = .readOnly
   }
 
   // Grab the class object for the key path type we'll end up with.
   func openRoot<Root>(_: Root.Type) -> AnyKeyPath.Type {
     func openLeaf<Leaf>(_: Leaf.Type) -> AnyKeyPath.Type {
-      switch capability {
+      switch walker.capability {
       case .readOnly:
         return KeyPath<Root, Leaf>.self
       case .value:
@@ -2613,35 +2981,39 @@
         return ReferenceWritableKeyPath<Root, Leaf>.self
       }
     }
-    return _openExistential(leaf, do: openLeaf)
+    return _openExistential(walker.leaf!, do: openLeaf)
   }
-  let classTy = _openExistential(root, do: openRoot)
+  let classTy = _openExistential(walker.root!, do: openRoot)
 
-  return (keyPathClass: classTy, rootType: root,
-          size: size,
+  return (keyPathClass: classTy,
+          rootType: walker.root!,
+          size: walker.size,
           // FIXME: Handle overalignment
           alignmentMask: MemoryLayout<Int>._alignmentMask)
 }
 
-internal func _instantiateKeyPathBuffer(
-  _ origPatternBuffer: KeyPathBuffer,
-  _ origDestData: UnsafeMutableRawBufferPointer,
-  _ rootType: Any.Type,
-  _ arguments: UnsafeRawPointer
-) {
-  // NB: patternBuffer and destData alias when the pattern is instantiable
-  // in-line. Therefore, do not read from patternBuffer after the same position
-  // in destData has been written to.
+internal struct InstantiateKeyPathBuffer : KeyPathPatternVisitor {
+  var destData: UnsafeMutableRawBufferPointer
+  let patternArgs: UnsafeRawPointer
+  var base: Any.Type
 
-  var patternBuffer = origPatternBuffer
-  let destHeaderPtr = origDestData.baseAddress.unsafelyUnwrapped
-  var destData = UnsafeMutableRawBufferPointer(
-    start: destHeaderPtr.advanced(by: MemoryLayout<Int>.size),
-    count: origDestData.count - MemoryLayout<Int>.size)
+  init(destData: UnsafeMutableRawBufferPointer,
+       patternArgs: UnsafeRawPointer,
+       root: Any.Type) {
+    self.destData = destData
+    self.patternArgs = patternArgs
+    self.base = root
+  }
 
-  func pushDest<T>(_ value: T) {
+  // Track the triviality of the resulting object data.
+  var isTrivial: Bool = true
+
+  // Track where the reference prefix begins.
+  var endOfReferencePrefixComponent: UnsafeMutableRawPointer? = nil
+  var previousComponentAddr: UnsafeMutableRawPointer? = nil
+
+  mutating func pushDest<T>(_ value: T) {
     _sanityCheck(_isPOD(T.self))
-    var value2 = value
     let size = MemoryLayout<T>.size
     let alignment = MemoryLayout<T>.alignment
     var baseAddress = destData.baseAddress.unsafelyUnwrapped
@@ -2650,400 +3022,372 @@
       misalign = alignment - misalign
       baseAddress = baseAddress.advanced(by: misalign)
     }
-    _memcpy(dest: baseAddress, src: &value2,
-            size: UInt(size))
+    withUnsafeBytes(of: value) {
+      _memcpy(dest: baseAddress, src: $0.baseAddress.unsafelyUnwrapped,
+              size: UInt(size))
+    }
     destData = UnsafeMutableRawBufferPointer(
       start: baseAddress + size,
       count: destData.count - size - misalign)
   }
 
-  // Track the triviality of the resulting object data.
-  var isTrivial = true
+  mutating func updatePreviousComponentAddr() -> UnsafeMutableRawPointer? {
+    let oldValue = previousComponentAddr
+    previousComponentAddr = destData.baseAddress.unsafelyUnwrapped
+    return oldValue
+  }
 
-  // Track where the reference prefix begins.
-  var endOfReferencePrefixComponent: UnsafeMutableRawPointer? = nil
-  var previousComponentAddr: UnsafeMutableRawPointer? = nil
+  mutating func visitHeader(rootMetadataRef: MetadataReference,
+                            leafMetadataRef: MetadataReference,
+                            kvcCompatibilityString: UnsafeRawPointer) {
+  }
 
-  // Instantiate components that need it.
-  var base: Any.Type = rootType
-  // Some pattern forms are pessimistically larger than what we need in the
-  // instantiated key path. Keep track of this.
-  if !patternBuffer.data.isEmpty {
-   while true {
-    let componentAddr = destData.baseAddress.unsafelyUnwrapped
-    let header = patternBuffer.pop(RawKeyPathComponent.Header.self)
+  mutating func visitStoredComponent(kind: KeyPathStructOrClass,
+                                     mutable: Bool,
+                                     offset: KeyPathPatternStoredOffset) {
+    let previous = updatePreviousComponentAddr()
+    switch kind {
+    case .class:
+      // A mutable class property can end the reference prefix.
+      if mutable {
+        endOfReferencePrefixComponent = previous
+      }
+      fallthrough
 
-    // Ensure that we pop an amount of data consistent with what
-    // RawKeyPathComponent.Header.patternComponentBodySize computes.
-    var bufferSizeBefore = 0
-    var expectedPop = 0
-
-    _sanityCheck({
-      bufferSizeBefore = patternBuffer.data.count
-      expectedPop = header.patternComponentBodySize
-      return true
-    }())
-
-    func tryToResolveOffset(header: RawKeyPathComponent.Header,
-                            getOutOfLineOffset: () -> UInt32) {
-      if header.storedOffsetPayload == RawKeyPathComponent.Header.unresolvedFieldOffsetPayload {
-        // Look up offset in type metadata. The value in the pattern is the
-        // offset within the metadata object.
+    case .struct:
+      // Resolve the offset.
+      switch offset {
+      case .inline(let value):
+        let header = RawKeyPathComponent.Header(stored: kind,
+                                                mutable: mutable,
+                                                inlineOffset: value)
+        pushDest(header)
+      case .outOfLine(let offset):
+        let header = RawKeyPathComponent.Header(storedWithOutOfLineOffset: kind,
+                                                mutable: mutable)
+        pushDest(header)
+        pushDest(offset)
+      case .unresolvedFieldOffset(let offsetOfOffset):
+        // Look up offset in the type metadata. The value in the pattern is
+        // the offset within the metadata object.
         let metadataPtr = unsafeBitCast(base, to: UnsafeRawPointer.self)
-        let offsetOfOffset = getOutOfLineOffset()
-
         let offset: UInt32
-        if (header.kind == .struct) {
-          offset = UInt32(metadataPtr.load(fromByteOffset: Int(offsetOfOffset),
-                                           as: UInt32.self))
-        } else {
+        switch kind {
+        case .class:
           offset = UInt32(metadataPtr.load(fromByteOffset: Int(offsetOfOffset),
                                            as: UInt.self))
+        case .struct:
+          offset = UInt32(metadataPtr.load(fromByteOffset: Int(offsetOfOffset),
+                                           as: UInt32.self))
         }
 
-        // Rewrite the header for a resolved offset.
-        var newHeader = header
-        newHeader.storedOffsetPayload = RawKeyPathComponent.Header.outOfLineOffsetPayload
-        pushDest(newHeader)
+        let header = RawKeyPathComponent.Header(storedWithOutOfLineOffset: kind,
+                                                mutable: mutable)
+        pushDest(header)
         pushDest(offset)
-        return
-      }
-
-      if header.storedOffsetPayload == RawKeyPathComponent.Header.unresolvedIndirectOffsetPayload {
+      case .unresolvedIndirectOffset(let pointerToOffset):
         // Look up offset in the indirectly-referenced variable we have a
         // pointer.
-        let offsetVar = patternBuffer.pop(UnsafeRawPointer.self)
-        let offsetValue = UInt32(offsetVar.load(as: UInt.self))
-        // Rewrite the header for a resolved offset.
-        var newHeader = header
-        newHeader.storedOffsetPayload = RawKeyPathComponent.Header.outOfLineOffsetPayload
-        pushDest(newHeader)
-        pushDest(offsetValue)
-        return
-      }
-
-      // Otherwise, just transfer the pre-resolved component.
-      pushDest(header)
-      if header.storedOffsetPayload == RawKeyPathComponent.Header.outOfLineOffsetPayload {
-        let offset = getOutOfLineOffset() //patternBuffer.pop(UInt32.self)
+        let offset = UInt32(pointerToOffset.pointee)
+        let header = RawKeyPathComponent.Header(storedWithOutOfLineOffset: kind,
+                                                mutable: mutable)
+        pushDest(header)
         pushDest(offset)
       }
     }
+  }
 
-    func tryToResolveComputedAccessors(header: RawKeyPathComponent.Header,
-                                       accessorsBuffer: inout KeyPathBuffer) {
-      // A nonmutating settable property can end the reference prefix and
-      // makes the following key path potentially reference-writable.
-      if header.isComputedSettable && !header.isComputedMutating {
-        endOfReferencePrefixComponent = previousComponentAddr
-      }
-
-      // The ID may need resolution if the property is keyed by a selector.
-      var newHeader = header
-      var id = accessorsBuffer.pop(Int.self)
-      switch header.payload
-                         & RawKeyPathComponent.Header.computedIDResolutionMask {
-      case RawKeyPathComponent.Header.computedIDResolved:
-        // Nothing to do.
-        break
-      case RawKeyPathComponent.Header.computedIDUnresolvedIndirectPointer:
-        // The value in the pattern is a pointer to the actual unique word-sized
-        // value in memory.
-        let idPtr = UnsafeRawPointer(bitPattern: id).unsafelyUnwrapped
-        id = idPtr.load(as: Int.self)
-      default:
-        _sanityCheckFailure("unpossible")
-      }
-      newHeader.payload &= ~RawKeyPathComponent.Header.computedIDResolutionMask
-      pushDest(newHeader)
-      pushDest(id)
-      // Carry over the accessors.
-      let getter = accessorsBuffer.pop(UnsafeRawPointer.self)
-      pushDest(getter)
-      if header.isComputedSettable {
-        let setter = accessorsBuffer.pop(UnsafeRawPointer.self)
-        pushDest(setter)
-      }
+  mutating func visitComputedComponent(mutating: Bool,
+                                   idKind: KeyPathComputedIDKind,
+                                   idResolved: Bool,
+                                   idValueBase: UnsafeRawPointer,
+                                   idValue: Int32,
+                                   getter: UnsafeRawPointer,
+                                   setter: UnsafeRawPointer?,
+                                   arguments: KeyPathPatternComputedArguments?,
+                                   externalArgs: UnsafeBufferPointer<Int32>?) {
+    let previous = updatePreviousComponentAddr()
+    let settable = setter != nil
+    // A nonmutating settable property can end the reference prefix.
+    if settable && !mutating {
+      endOfReferencePrefixComponent = previous
     }
 
-    func readComputedArgumentBuffer(argsBuffer: inout KeyPathBuffer)
-        -> (getLayout: RawKeyPathComponent.ComputedArgumentLayoutFn,
-            witnesses: UnsafePointer<ComputedArgumentWitnesses>,
-            initializer: RawKeyPathComponent.ComputedArgumentInitializerFn) {
-      let getLayoutRaw = argsBuffer.pop(UnsafeRawPointer.self)
-      let getLayout = unsafeBitCast(getLayoutRaw,
-        to: RawKeyPathComponent.ComputedArgumentLayoutFn.self)
+    // Resolve the ID.
+    let resolvedID: UnsafeRawPointer?
 
-      let witnesses = argsBuffer.pop(
-        UnsafePointer<ComputedArgumentWitnesses>.self)
+    switch idKind {
+    case .storedPropertyIndex, .vtableOffset:
+      _sanityCheck(idResolved)
+      // Zero-extend the integer value to get the instantiated id.
+      let value = UInt(UInt32(bitPattern: idValue))
+      resolvedID = UnsafeRawPointer(bitPattern: value)
 
-      if let _ = witnesses.pointee.destroy {
-        isTrivial = false
+    case .pointer:
+      // Resolve the sign-extended relative reference.
+      var absoluteID: UnsafeRawPointer? = idValueBase + Int(idValue)
+
+      // If the pointer ID is "unresolved", then it needs another indirection
+      // to get the final value.
+      if !idResolved {
+        absoluteID = absoluteID.unsafelyUnwrapped
+          .load(as: UnsafeRawPointer?.self)
       }
-
-      let initializerRaw = argsBuffer.pop(UnsafeRawPointer.self)
-      let initializer = unsafeBitCast(initializerRaw,
-        to: RawKeyPathComponent.ComputedArgumentInitializerFn.self)
-
-      return (getLayout, witnesses, initializer)
+      resolvedID = absoluteID
     }
 
-    func tryToResolveComputedArguments(argsBuffer: inout KeyPathBuffer) {
-      guard header.hasComputedArguments else { return }
+    // Bring over the header, getter, and setter.
+    let header = RawKeyPathComponent.Header(computedWithIDKind: idKind,
+          mutating: mutating,
+          settable: settable,
+          hasArguments: arguments != nil || externalArgs != nil,
+          instantiatedFromExternalWithArguments:
+            arguments != nil && externalArgs != nil)
+    pushDest(header)
+    pushDest(resolvedID)
+    pushDest(getter)
+    if let setter = setter {
+      pushDest(setter)
+    }
 
-      let (getLayout, witnesses, initializer)
-        = readComputedArgumentBuffer(argsBuffer: &argsBuffer)
-
-      // Carry over the arguments.
-      let (size, alignmentMask) = getLayout(arguments)
+    if let arguments = arguments {
+      // Instantiate the arguments.
+      let (baseSize, alignmentMask) = arguments.getLayout(patternArgs)
       _sanityCheck(alignmentMask < MemoryLayout<Int>.alignment,
                    "overaligned computed arguments not implemented yet")
 
       // The real buffer stride will be rounded up to alignment.
-      let stride = (size + alignmentMask) & ~alignmentMask
-      pushDest(stride)
-      pushDest(witnesses)
+      var totalSize = (baseSize + alignmentMask) & ~alignmentMask
 
+      // If an external property descriptor also has arguments, they'll be
+      // added to the end with pointer alignment.
+      if let externalArgs = externalArgs {
+        totalSize = MemoryLayout<Int>._roundingUpToAlignment(totalSize)
+        totalSize += MemoryLayout<Int>.size * externalArgs.count
+      }
+
+      pushDest(totalSize)
+      pushDest(arguments.witnesses)
+
+      // A nonnull destructor in the witnesses file indicates the instantiated
+      // payload is nontrivial.
+      if let _ = arguments.witnesses.pointee.destroy {
+        isTrivial = false
+      }
+
+      // If the descriptor has arguments, store the size of its specific
+      // arguments here, so we can drop them when trying to invoke
+      // the component's witnesses.
+      if let externalArgs = externalArgs {
+        pushDest(externalArgs.count * MemoryLayout<Int>.size)
+      }
+
+      // Initialize the local candidate arguments here.
       _sanityCheck(Int(bitPattern: destData.baseAddress) & alignmentMask == 0,
                    "argument destination not aligned")
-      initializer(arguments, destData.baseAddress.unsafelyUnwrapped)
+      arguments.initializer(patternArgs,
+                            destData.baseAddress.unsafelyUnwrapped)
 
       destData = UnsafeMutableRawBufferPointer(
-        start: destData.baseAddress.unsafelyUnwrapped + stride,
-        count: destData.count - stride)
+        start: destData.baseAddress.unsafelyUnwrapped + baseSize,
+        count: destData.count - baseSize)
     }
-
-    switch header.kind {
-    case .struct:
-      // The offset may need to be resolved dynamically.
-      tryToResolveOffset(header: header,
-                         getOutOfLineOffset: { patternBuffer.pop(UInt32.self) })
-    case .class:
-      // Accessing a mutable class property can end the reference prefix, and
-      // makes the following key path potentially reference-writable.
-      if header.isStoredMutable {
-        endOfReferencePrefixComponent = previousComponentAddr
-      }
-      // The offset may need to be resolved dynamically.
-      tryToResolveOffset(header: header,
-                         getOutOfLineOffset: { patternBuffer.pop(UInt32.self) })
-    case .optionalChain,
-         .optionalWrap,
-         .optionalForce:
-      // No instantiation necessary.
-      pushDest(header)
-      break
-    case .computed:
-      tryToResolveComputedAccessors(header: header,
-                                    accessorsBuffer: &patternBuffer)
-      tryToResolveComputedArguments(argsBuffer: &patternBuffer)
-    case .external:
-      // Look at the external property descriptor to see if we should take it
-      // over the component given in the pattern.
-      let genericParamCount = Int(header.payload)
-      let descriptor = patternBuffer.pop(UnsafeRawPointer.self)
-      var descriptorHeader = descriptor.load(as: RawKeyPathComponent.Header.self)
-
-      // Save the generic arguments to the external descriptor.
-      let descriptorGenericArgsBuf = patternBuffer.popRaw(
-        size: MemoryLayout<Int>.size * genericParamCount,
-        alignment: Int.self)
-
-      if descriptorHeader.isTrivialPropertyDescriptor {
-        // If the descriptor is trivial, then instantiate the local candidate.
-        // Continue to keep reading from the buffer as if we started with the
-        // local candidate.
-        continue
+    
+    if let externalArgs = externalArgs {
+      if arguments == nil {
+        // If we're instantiating an external property without any local
+        // arguments, then we only need to instantiate the arguments to the
+        // property descriptor.
+        let stride = MemoryLayout<Int>.size * externalArgs.count
+        pushDest(stride)
+        pushDest(__swift_keyPathGenericWitnessTable_addr())
       }
 
-      // Grab the local candidate header. We may need parts of it to complete
-      // the final component.
-      let localCandidateHeader = patternBuffer.pop(RawKeyPathComponent.Header.self)
-      let localCandidateSize = localCandidateHeader.patternComponentBodySize
-
-      // ...though we still ought to fully consume it before proceeding.
-      _sanityCheck({
-        expectedPop += localCandidateSize
-                    +  MemoryLayout<RawKeyPathComponent.Header>.size
-        return true
-      }())
-
-
-      // Instantiate the component according to the external property
-      // descriptor.
-      switch descriptorHeader.kind {
-      case .class:
-        // Accessing a mutable class property can end the reference prefix,
-        // and makes the following key path potentially reference-writable.
-        if descriptorHeader.isStoredMutable {
-          endOfReferencePrefixComponent = previousComponentAddr
-        }
-        fallthrough
-
-      case .struct:
-        // Drop the local candidate.
-        _ = patternBuffer.popRaw(size: localCandidateSize,
-                                 alignment: Int32.self)
-
-        // Instantiate the offset using the info from the descriptor.
-        tryToResolveOffset(header: descriptorHeader,
-                           getOutOfLineOffset: {
-                             descriptor.load(fromByteOffset: 4,
-                                             as: UInt32.self)
-                           })
-
-      case .computed:
-        var descriptorBuffer = KeyPathBuffer(
-          partialData: UnsafeRawBufferPointer(
-            start: descriptor + MemoryLayout<RawKeyPathComponent.Header>.size,
-            count: descriptorHeader.propertyDescriptorBodySize))
-
-        // If the external declaration is computed, and it takes captured
-        // arguments, then we have to build a bit of a chimera. The canonical
-        // identity and accessors come from the descriptor, but the argument
-        // handling is still as described in the local candidate.
-        if descriptorHeader.hasComputedArguments {
-          // Loop through instantiating all the property descriptor's
-          // generic arguments. We don't write
-          // these immediately, because the computed header and accessors
-          // come first, and if we're instantiating in-place,
-          // they will overwrite the information in the pattern.
-          let genericArgs: [UnsafeRawPointer]
-            = (0 ..< genericParamCount).map {
-              let instantiationFn = descriptorGenericArgsBuf
-                .load(fromByteOffset: MemoryLayout<Int>.size * $0,
-                      as: MetadataAccessor.self)
-              return instantiationFn(arguments)
-            }
-
-          // If the descriptor has generic arguments, record this in the
-          // header. We'll store the size of the external generic arguments
-          // so we can invoke the local candidate's argument witnesses.
-          let localCandidateHasArguments =
-            localCandidateHeader.kind == .computed
-              && localCandidateHeader.hasComputedArguments
-          let descriptorHasArguments = genericParamCount > 0
-          if localCandidateHasArguments && descriptorHasArguments {
-            descriptorHeader.isComputedInstantiatedFromExternalWithArguments =
-              true
-          }
-
-          // Bring in the accessors from the descriptor.
-          tryToResolveComputedAccessors(header: descriptorHeader,
-                                        accessorsBuffer: &descriptorBuffer)
-          _sanityCheck(descriptorBuffer.data.isEmpty)
-
-          if localCandidateHasArguments {
-            // We don't need the local candidate's accessors.
-            _ /*id*/ = patternBuffer.pop(UnsafeRawPointer.self)
-            _ /*getter*/ = patternBuffer.pop(UnsafeRawPointer.self)
-            if localCandidateHeader.isComputedSettable {
-              _ /*setter*/ = patternBuffer.pop(UnsafeRawPointer.self)
-            }
-
-            // Instantiate the arguments from the local candidate.
-            let (getLayout, witnesses, initializer) =
-              readComputedArgumentBuffer(argsBuffer: &patternBuffer)
-
-            // Carry over the arguments.
-            let (baseSize, alignmentMask) = getLayout(arguments)
-            _sanityCheck(alignmentMask < MemoryLayout<Int>.alignment,
-                         "overaligned computed arguments not implemented yet")
-
-            // The real buffer stride will be rounded up to alignment.
-            var totalSize = (baseSize + alignmentMask) & ~alignmentMask
-
-            // If the descriptor also has arguments, they'll be added to the
-            // end with pointer alignment.
-            if descriptorHasArguments {
-              totalSize = MemoryLayout<Int>._roundingUpToAlignment(totalSize)
-              totalSize += MemoryLayout<Int>.size * genericParamCount
-            }
-
-            pushDest(totalSize)
-            pushDest(witnesses)
-
-            // If the descriptor has arguments, store the size of its specific
-            // arguments here, so we can drop them when trying to invoke
-            // the component's witnesses.
-            if descriptorHasArguments {
-              pushDest(genericParamCount * MemoryLayout<Int>.size)
-            }
-
-            // Initialize the local candidate arguments here.
-            _sanityCheck(Int(bitPattern: destData.baseAddress) & alignmentMask == 0,
-                         "argument destination not aligned")
-            initializer(arguments, destData.baseAddress.unsafelyUnwrapped)
-
-            destData = UnsafeMutableRawBufferPointer(
-              start: destData.baseAddress.unsafelyUnwrapped + baseSize,
-              count: destData.count - baseSize)
-
-          } else {
-            // If the local candidate has no arguments, then things are a
-            // little easier. We only need to instantiate the generic arguments
-            // for the external component's accessors.
-            // Discard the local candidate.
-            _ = patternBuffer.popRaw(size: localCandidateSize,
-                                     alignment: Int32.self)
-
-            // Write out the header with the instantiated size and
-            // witnesses of the descriptor.
-            let stride = MemoryLayout<Int>.size * genericParamCount
-            pushDest(stride)
-            pushDest(__swift_keyPathGenericWitnessTable_addr())
-          }
-          // Write the descriptor's generic arguments.
-          for arg in genericArgs {
-            pushDest(arg)
-          }
-        } else {
-          // Discard the local candidate.
-          _ = patternBuffer.popRaw(size: localCandidateSize,
-                                   alignment: Int32.self)
-
-          // The final component is an instantiation of the computed
-          // component from the descriptor.
-          tryToResolveComputedAccessors(header: descriptorHeader,
-                                        accessorsBuffer: &descriptorBuffer)
-          _sanityCheck(descriptorBuffer.data.isEmpty)
-
-          // We know there are no arguments to instantiate.
-        }
-      case .external, .optionalChain, .optionalForce, .optionalWrap:
-        _sanityCheckFailure("should not appear as property descriptor")
+      // Write the descriptor's generic arguments, which should all be relative
+      // references to metadata accessor functions.
+      for i in externalArgs.indices {
+        let base = externalArgs.baseAddress.unsafelyUnwrapped + i
+        let offset = base.pointee
+        let metadataRef = UnsafeRawPointer(base) + Int(offset)
+        let result = _resolveKeyPathGenericArgReference(metadataRef,
+                                                       arguments: patternArgs)
+        pushDest(result)
       }
     }
-
-    // Check that we consumed the expected amount of data from the pattern.
-    _sanityCheck(
-      {
-        let popped = MemoryLayout<Int>._roundingUpToAlignment(
-           bufferSizeBefore - patternBuffer.data.count
-           - RawKeyPathComponent.Header.pointerAlignmentSkew)
-          + RawKeyPathComponent.Header.pointerAlignmentSkew
-        return expectedPop == popped
-      }(),
-      """
-      component size consumed during instantiation does not match \
-      component size returned by patternComponentBodySize
-      """)
-
-    // Break if this is the last component.
-    if patternBuffer.data.count == 0 { break }
-
-    // Resolve the component type.
-    let componentTyAccessor = patternBuffer.pop(MetadataAccessor.self)
-    base = unsafeBitCast(componentTyAccessor(arguments), to: Any.Type.self)
-    pushDest(base)
-    previousComponentAddr = componentAddr
-   }
   }
 
-  // We should have traversed both buffers.
-  _sanityCheck(patternBuffer.data.isEmpty, "did not read the entire pattern")
-  _sanityCheck(destData.count == 0,
-               "did not write to all of the allocated space")
+  mutating func visitOptionalChainComponent() {
+    let _ = updatePreviousComponentAddr()
+    let header = RawKeyPathComponent.Header(optionalChain: ())
+    pushDest(header)
+  }
+  mutating func visitOptionalWrapComponent() {
+    let _ = updatePreviousComponentAddr()
+    let header = RawKeyPathComponent.Header(optionalWrap: ())
+    pushDest(header)
+  }
+  mutating func visitOptionalForceComponent() {
+    let _ = updatePreviousComponentAddr()
+    let header = RawKeyPathComponent.Header(optionalForce: ())
+    pushDest(header)
+  }
+
+  mutating func visitIntermediateComponentType(metadataRef: MetadataReference) {
+    // Get the metadata for the intermediate type.
+    let metadata = _resolveKeyPathMetadataReference(metadataRef,
+                                                    arguments: patternArgs)
+    pushDest(metadata)
+    base = metadata
+  }
+  
+  mutating func finish() {
+    // Should have filled the entire buffer by the time we reach the end of the
+    // pattern.
+    _sanityCheck(destData.isEmpty,
+                 "should have filled entire destination buffer")
+  }
+}
+
+#if INTERNAL_CHECKS_ENABLED
+// In debug builds of the standard library, check that instantiation produces
+// components whose sizes are consistent with the sizing visitor pass.
+internal struct ValidatingInstantiateKeyPathBuffer: KeyPathPatternVisitor {
+  var sizeVisitor: GetKeyPathClassAndInstanceSizeFromPattern
+  var instantiateVisitor: InstantiateKeyPathBuffer
+  let origDest: UnsafeMutableRawPointer
+
+  init(sizeVisitor: GetKeyPathClassAndInstanceSizeFromPattern,
+       instantiateVisitor: InstantiateKeyPathBuffer) {
+    self.sizeVisitor = sizeVisitor
+    self.instantiateVisitor = instantiateVisitor
+    origDest = self.instantiateVisitor.destData.baseAddress.unsafelyUnwrapped
+  }
+
+  mutating func visitHeader(rootMetadataRef: MetadataReference,
+                            leafMetadataRef: MetadataReference,
+                            kvcCompatibilityString: UnsafeRawPointer) {
+    sizeVisitor.visitHeader(rootMetadataRef: rootMetadataRef,
+                            leafMetadataRef: leafMetadataRef,
+                            kvcCompatibilityString: kvcCompatibilityString)
+    instantiateVisitor.visitHeader(rootMetadataRef: rootMetadataRef,
+                                 leafMetadataRef: leafMetadataRef,
+                                 kvcCompatibilityString: kvcCompatibilityString)
+  }
+  mutating func visitStoredComponent(kind: KeyPathStructOrClass,
+                                     mutable: Bool,
+                                     offset: KeyPathPatternStoredOffset) {
+    sizeVisitor.visitStoredComponent(kind: kind, mutable: mutable,
+                                     offset: offset)
+    instantiateVisitor.visitStoredComponent(kind: kind, mutable: mutable,
+                                            offset: offset)
+    checkSizeConsistency()
+  }
+  mutating func visitComputedComponent(mutating: Bool,
+                                   idKind: KeyPathComputedIDKind,
+                                   idResolved: Bool,
+                                   idValueBase: UnsafeRawPointer,
+                                   idValue: Int32,
+                                   getter: UnsafeRawPointer,
+                                   setter: UnsafeRawPointer?,
+                                   arguments: KeyPathPatternComputedArguments?,
+                                   externalArgs: UnsafeBufferPointer<Int32>?) {
+    sizeVisitor.visitComputedComponent(mutating: mutating,
+                                       idKind: idKind,
+                                       idResolved: idResolved,
+                                       idValueBase: idValueBase,
+                                       idValue: idValue,
+                                       getter: getter,
+                                       setter: setter,
+                                       arguments: arguments,
+                                       externalArgs: externalArgs)
+    instantiateVisitor.visitComputedComponent(mutating: mutating,
+                                       idKind: idKind,
+                                       idResolved: idResolved,
+                                       idValueBase: idValueBase,
+                                       idValue: idValue,
+                                       getter: getter,
+                                       setter: setter,
+                                       arguments: arguments,
+                                       externalArgs: externalArgs)
+    checkSizeConsistency()
+  }
+  mutating func visitOptionalChainComponent() {
+    sizeVisitor.visitOptionalChainComponent()
+    instantiateVisitor.visitOptionalChainComponent()
+    checkSizeConsistency()
+  }
+  mutating func visitOptionalWrapComponent() {
+    sizeVisitor.visitOptionalWrapComponent()
+    instantiateVisitor.visitOptionalWrapComponent()
+    checkSizeConsistency()
+  }
+  mutating func visitOptionalForceComponent() {
+    sizeVisitor.visitOptionalForceComponent()
+    instantiateVisitor.visitOptionalForceComponent()
+    checkSizeConsistency()
+  }
+  mutating func visitIntermediateComponentType(metadataRef: MetadataReference) {
+    sizeVisitor.visitIntermediateComponentType(metadataRef: metadataRef)
+    instantiateVisitor.visitIntermediateComponentType(metadataRef: metadataRef)
+    checkSizeConsistency()
+  }
+
+  mutating func finish() {
+    sizeVisitor.finish()
+    instantiateVisitor.finish()
+    checkSizeConsistency()
+  }
+
+  func checkSizeConsistency() {
+    let nextDest = instantiateVisitor.destData.baseAddress.unsafelyUnwrapped
+    let curSize = nextDest - origDest + MemoryLayout<Int>.size
+
+    _sanityCheck(curSize == sizeVisitor.size,
+                 "size and instantiation visitors out of sync")
+  }
+}
+#endif // INTERNAL_CHECKS_ENABLED
+
+internal func _instantiateKeyPathBuffer(
+  _ pattern: UnsafeRawPointer,
+  _ origDestData: UnsafeMutableRawBufferPointer,
+  _ rootType: Any.Type,
+  _ arguments: UnsafeRawPointer
+) {
+  let destHeaderPtr = origDestData.baseAddress.unsafelyUnwrapped
+  var destData = UnsafeMutableRawBufferPointer(
+    start: destHeaderPtr.advanced(by: MemoryLayout<Int>.size),
+    count: origDestData.count - MemoryLayout<Int>.size)
+
+#if INTERNAL_CHECKS_ENABLED
+  // If checks are enabled, use a validating walker that ensures that the
+  // size pre-walk and instantiation walk are in sync.
+  let sizeWalker = GetKeyPathClassAndInstanceSizeFromPattern(
+    patternArgs: arguments)
+  let instantiateWalker = InstantiateKeyPathBuffer(
+    destData: destData,
+    patternArgs: arguments,
+    root: rootType)
+  
+  var walker = ValidatingInstantiateKeyPathBuffer(sizeVisitor: sizeWalker,
+                                          instantiateVisitor: instantiateWalker)
+#else
+  var walker = InstantiateKeyPathBuffer(
+    destData: destData,
+    patternArgs: arguments,
+    root: rootType)
+#endif
+
+  _walkKeyPathPattern(pattern, walker: &walker)
+
+#if INTERNAL_CHECKS_ENABLED
+  let isTrivial = walker.instantiateVisitor.isTrivial
+  let endOfReferencePrefixComponent =
+    walker.instantiateVisitor.endOfReferencePrefixComponent
+#else
+  let isTrivial = walker.isTrivial
+  let endOfReferencePrefixComponent = walker.endOfReferencePrefixComponent
+#endif
 
   // Write out the header.
   let destHeader = KeyPathBuffer.Header(
diff --git a/stdlib/public/core/ManagedBuffer.swift b/stdlib/public/core/ManagedBuffer.swift
index 0d2dd57..5ed33c5 100644
--- a/stdlib/public/core/ManagedBuffer.swift
+++ b/stdlib/public/core/ManagedBuffer.swift
@@ -34,13 +34,26 @@
 /// any live elements in the `deinit` of a subclass.
 /// - Note: Subclasses must not have any stored properties; any storage
 ///   needed should be included in `Header`.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout
 open class ManagedBuffer<Header, Element> {
+  /// The stored `Header` instance.
+  ///
+  /// During instance creation, in particular during
+  /// `ManagedBuffer.create`'s call to initialize, `ManagedBuffer`'s
+  /// `header` property is as-yet uninitialized, and therefore
+  /// reading the `header` property during `ManagedBuffer.create` is undefined.
+  public final var header: Header
 
+  internal init(_doNotCallMe: ()) {
+    _sanityCheckFailure("Only initialize these by calling create")
+  }
+}
+
+extension ManagedBuffer {
   /// Create a new instance of the most-derived class, calling
   /// `factory` on the partially-constructed object to generate
   /// an initial `Header`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public final class func create(
     minimumCapacity: Int,
     makingHeaderWith factory: (
@@ -56,7 +69,7 @@
     // The _fixLifetime is not really needed, because p is used afterwards.
     // But let's be conservative and fix the lifetime after we use the
     // headerAddress.
-    _fixLifetime(p) 
+    _fixLifetime(p)
     return p
   }
 
@@ -65,7 +78,7 @@
   /// This header may be nontrivial to compute; it is usually a good
   /// idea to store this information in the "header" area when
   /// an instance is created.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public final var capacity: Int {
     let storageAddr = UnsafeMutableRawPointer(Builtin.bridgeToRawPointer(self))
     let endAddr = storageAddr + _swift_stdlib_malloc_size(storageAddr)
@@ -74,13 +87,13 @@
     return realCapacity
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal final var firstElementAddress: UnsafeMutablePointer<Element> {
-    return UnsafeMutablePointer(Builtin.projectTailElems(self,
-                                                         Element.self))
+    return UnsafeMutablePointer(
+      Builtin.projectTailElems(self, Element.self))
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal final var headerAddress: UnsafeMutablePointer<Header> {
     return UnsafeMutablePointer<Header>(Builtin.addressof(&header))
   }
@@ -90,7 +103,7 @@
   ///
   /// - Note: This pointer is valid only for the duration of the
   ///   call to `body`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public final func withUnsafeMutablePointerToHeader<R>(
     _ body: (UnsafeMutablePointer<Header>) throws -> R
   ) rethrows -> R {
@@ -102,7 +115,7 @@
   ///
   /// - Note: This pointer is valid only for the duration of the
   ///   call to `body`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public final func withUnsafeMutablePointerToElements<R>(
     _ body: (UnsafeMutablePointer<Element>) throws -> R
   ) rethrows -> R {
@@ -114,28 +127,36 @@
   ///
   /// - Note: These pointers are valid only for the duration of the
   ///   call to `body`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public final func withUnsafeMutablePointers<R>(
     _ body: (UnsafeMutablePointer<Header>, UnsafeMutablePointer<Element>) throws -> R
   ) rethrows -> R {
     defer { _fixLifetime(self) }
     return try body(headerAddress, firstElementAddress)
   }
+}
 
-  /// The stored `Header` instance.
-  ///
-  /// During instance creation, in particular during
-  /// `ManagedBuffer.create`'s call to initialize, `ManagedBuffer`'s
-  /// `header` property is as-yet uninitialized, and therefore
-  /// reading the `header` property during `ManagedBuffer.create` is undefined.
-  public final var header: Header
+@inline(never)
+public func tryReallocateUniquelyReferenced<Header, Element, Buffer: ManagedBuffer<Header, Element>>(
+  buffer: inout Buffer,
+  newMinimumCapacity: Int
+) -> Bool {
+  precondition(_isBitwiseTakable(Header.self))
+  precondition(_isBitwiseTakable(Element.self))
+  precondition(isKnownUniquelyReferenced(&buffer))
 
-  //===--- internal/private API -------------------------------------------===//
+  let newSizeInBytes = MemoryLayout<Header>.stride
+    + newMinimumCapacity * MemoryLayout<Element>.stride
 
-  /// Make ordinary initialization unavailable
-  @inlinable // FIXME(sil-serialize-all)
-  internal init(_doNotCallMe: ()) {
-    _sanityCheckFailure("Only initialize these by calling create")
+  return withUnsafeMutablePointer(to: &buffer) {
+    $0.withMemoryRebound(to: UnsafeMutableRawPointer.self, capacity: 1) {
+      if let reallocdObject = _reallocObject($0.pointee, newSizeInBytes) {
+        $0.pointee = reallocdObject
+        return true
+      } else {
+        return false
+      }
+    }
   }
 }
 
@@ -175,7 +196,10 @@
 ///      }
 ///
 @_fixed_layout
-public struct ManagedBufferPointer<Header, Element> : Equatable {
+public struct ManagedBufferPointer<Header, Element> {
+
+  @usableFromInline
+  internal var _nativeBuffer: Builtin.NativeObject
 
   /// Create with new storage containing an initial `Header` and space
   /// for at least `minimumCapacity` `element`s.
@@ -192,7 +216,7 @@
   ///   `bufferClass` is a non-`@objc` class with no declared stored
   ///   properties.  The `deinit` of `bufferClass` must destroy its
   ///   stored `Header` and any constructed `Element`s.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public init(
     bufferClass: AnyClass,
     minimumCapacity: Int,
@@ -220,13 +244,15 @@
   ///
   /// - Precondition: `buffer` is an instance of a non-`@objc` class whose
   ///   `deinit` destroys its stored `Header` and any constructed `Element`s.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public init(unsafeBufferObject buffer: AnyObject) {
     ManagedBufferPointer._checkValidBufferClass(type(of: buffer))
 
     self._nativeBuffer = Builtin.unsafeCastToNativeObject(buffer)
   }
 
+  //===--- internal/private API -------------------------------------------===//
+
   /// Internal version for use by _ContiguousArrayBuffer where we know that we
   /// have a valid buffer class.
   /// This version of the init function gets called from
@@ -235,86 +261,12 @@
   /// _debugPreconditions in _checkValidBufferClass for any array. Since we know
   /// for the _ContiguousArrayBuffer that this check must always succeed we omit
   /// it in this specialized constructor.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal init(_uncheckedUnsafeBufferObject buffer: AnyObject) {
     ManagedBufferPointer._sanityCheckValidBufferClass(type(of: buffer))
     self._nativeBuffer = Builtin.unsafeCastToNativeObject(buffer)
   }
 
-  /// The stored `Header` instance.
-  @inlinable // FIXME(sil-serialize-all)
-  public var header: Header {
-    addressWithNativeOwner {
-      return (UnsafePointer(_headerPointer), _nativeBuffer)
-    }
-    _modify {
-      yield &_headerPointer.pointee
-    }
-  }
-
-  /// Returns the object instance being used for storage.
-  @inlinable // FIXME(sil-serialize-all)
-  public var buffer: AnyObject {
-    return Builtin.castFromNativeObject(_nativeBuffer)
-  }
-
-  /// The actual number of elements that can be stored in this object.
-  ///
-  /// This value may be nontrivial to compute; it is usually a good
-  /// idea to store this information in the "header" area when
-  /// an instance is created.
-  @inlinable // FIXME(sil-serialize-all)
-  public var capacity: Int {
-    return (_capacityInBytes &- _My._elementOffset) / MemoryLayout<Element>.stride
-  }
-
-  /// Call `body` with an `UnsafeMutablePointer` to the stored
-  /// `Header`.
-  ///
-  /// - Note: This pointer is valid only
-  ///   for the duration of the call to `body`.
-  @inlinable // FIXME(sil-serialize-all)
-  public func withUnsafeMutablePointerToHeader<R>(
-    _ body: (UnsafeMutablePointer<Header>) throws -> R
-  ) rethrows -> R {
-    return try withUnsafeMutablePointers { (v, _) in return try body(v) }
-  }
-
-  /// Call `body` with an `UnsafeMutablePointer` to the `Element`
-  /// storage.
-  ///
-  /// - Note: This pointer is valid only for the duration of the
-  ///   call to `body`.
-  @inlinable // FIXME(sil-serialize-all)
-  public func withUnsafeMutablePointerToElements<R>(
-    _ body: (UnsafeMutablePointer<Element>) throws -> R
-  ) rethrows -> R {
-    return try withUnsafeMutablePointers { return try body($1) }
-  }
-
-  /// Call `body` with `UnsafeMutablePointer`s to the stored `Header`
-  /// and raw `Element` storage.
-  ///
-  /// - Note: These pointers are valid only for the duration of the
-  ///   call to `body`.
-  @inlinable // FIXME(sil-serialize-all)
-  public func withUnsafeMutablePointers<R>(
-    _ body: (UnsafeMutablePointer<Header>, UnsafeMutablePointer<Element>) throws -> R
-  ) rethrows -> R {
-    defer { _fixLifetime(_nativeBuffer) }
-    return try body(_headerPointer, _elementPointer)
-  }
-
-  /// Returns `true` iff `self` holds the only strong reference to its buffer.
-  ///
-  /// See `isUniquelyReferenced` for details.
-  @inlinable // FIXME(sil-serialize-all)
-  public mutating func isUniqueReference() -> Bool {
-    return _isUnique(&_nativeBuffer)
-  }
-
-  //===--- internal/private API -------------------------------------------===//
-
   /// Create with new storage containing space for an initial `Header`
   /// and at least `minimumCapacity` `element`s.
   ///
@@ -326,7 +278,7 @@
   ///   `bufferClass` is a non-`@objc` class with no declared stored
   ///   properties.  The `deinit` of `bufferClass` must destroy its
   ///   stored `Header` and any constructed `Element`s.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal init(
     bufferClass: AnyClass,
     minimumCapacity: Int
@@ -342,7 +294,7 @@
 
   /// Internal version for use by _ContiguousArrayBuffer.init where we know that
   /// we have a valid buffer class and that the capacity is >= 0.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal init(
     _uncheckedBufferClass: AnyClass,
     minimumCapacity: Int
@@ -352,13 +304,13 @@
       minimumCapacity >= 0,
       "ManagedBufferPointer must have non-negative capacity")
 
-    let totalSize = _My._elementOffset
+    let totalSize = ManagedBufferPointer._elementOffset
       +  minimumCapacity * MemoryLayout<Element>.stride
 
     let newBuffer: AnyObject = _swift_bufferAllocate(
       bufferType: _uncheckedBufferClass,
       size: totalSize,
-      alignmentMask: _My._alignmentMask)
+      alignmentMask: ManagedBufferPointer._alignmentMask)
 
     self._nativeBuffer = Builtin.unsafeCastToNativeObject(newBuffer)
   }
@@ -367,15 +319,90 @@
   ///
   /// - Note: It is an error to use the `header` property of the resulting
   ///   instance unless it has been initialized.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal init(_ buffer: ManagedBuffer<Header, Element>) {
     _nativeBuffer = Builtin.unsafeCastToNativeObject(buffer)
   }
+}
 
-  @usableFromInline // FIXME(sil-serialize-all)
-  internal typealias _My = ManagedBufferPointer
+extension ManagedBufferPointer {
+  /// The stored `Header` instance.
+  @inlinable
+  public var header: Header {
+    _read {
+      yield _headerPointer.pointee
+    }
+    _modify {
+      yield &_headerPointer.pointee
+    }
+  }
 
-  @inlinable // FIXME(sil-serialize-all)
+  /// Returns the object instance being used for storage.
+  @inlinable
+  public var buffer: AnyObject {
+    return Builtin.castFromNativeObject(_nativeBuffer)
+  }
+
+  /// The actual number of elements that can be stored in this object.
+  ///
+  /// This value may be nontrivial to compute; it is usually a good
+  /// idea to store this information in the "header" area when
+  /// an instance is created.
+  @inlinable
+  public var capacity: Int {
+    return (
+      _capacityInBytes &- ManagedBufferPointer._elementOffset
+    ) / MemoryLayout<Element>.stride
+  }
+
+  /// Call `body` with an `UnsafeMutablePointer` to the stored
+  /// `Header`.
+  ///
+  /// - Note: This pointer is valid only
+  ///   for the duration of the call to `body`.
+  @inlinable
+  public func withUnsafeMutablePointerToHeader<R>(
+    _ body: (UnsafeMutablePointer<Header>) throws -> R
+  ) rethrows -> R {
+    return try withUnsafeMutablePointers { (v, _) in return try body(v) }
+  }
+
+  /// Call `body` with an `UnsafeMutablePointer` to the `Element`
+  /// storage.
+  ///
+  /// - Note: This pointer is valid only for the duration of the
+  ///   call to `body`.
+  @inlinable
+  public func withUnsafeMutablePointerToElements<R>(
+    _ body: (UnsafeMutablePointer<Element>) throws -> R
+  ) rethrows -> R {
+    return try withUnsafeMutablePointers { return try body($1) }
+  }
+
+  /// Call `body` with `UnsafeMutablePointer`s to the stored `Header`
+  /// and raw `Element` storage.
+  ///
+  /// - Note: These pointers are valid only for the duration of the
+  ///   call to `body`.
+  @inlinable
+  public func withUnsafeMutablePointers<R>(
+    _ body: (UnsafeMutablePointer<Header>, UnsafeMutablePointer<Element>) throws -> R
+  ) rethrows -> R {
+    defer { _fixLifetime(_nativeBuffer) }
+    return try body(_headerPointer, _elementPointer)
+  }
+
+  /// Returns `true` iff `self` holds the only strong reference to its buffer.
+  ///
+  /// See `isUniquelyReferenced` for details.
+  @inlinable
+  public mutating func isUniqueReference() -> Bool {
+    return _isUnique(&_nativeBuffer)
+  }
+}
+
+extension ManagedBufferPointer {
+  @inlinable
   internal static func _checkValidBufferClass(
     _ bufferClass: AnyClass, creating: Bool = false
   ) {
@@ -393,7 +420,7 @@
     )
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal static func _sanityCheckValidBufferClass(
     _ bufferClass: AnyClass, creating: Bool = false
   ) {
@@ -410,9 +437,11 @@
       "ManagedBufferPointer buffer class must be non-@objc"
     )
   }
+}
 
+extension ManagedBufferPointer {
   /// The required alignment for allocations of this type, minus 1
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal static var _alignmentMask: Int {
     return max(
       MemoryLayout<_HeapObject>.alignment,
@@ -420,19 +449,19 @@
   }
 
   /// The actual number of bytes allocated for this object.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var _capacityInBytes: Int {
     return _swift_stdlib_malloc_size(_address)
   }
 
   /// The address of this instance in a convenient pointer-to-bytes form
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var _address: UnsafeMutableRawPointer {
     return UnsafeMutableRawPointer(Builtin.bridgeToRawPointer(_nativeBuffer))
   }
 
   /// Offset from the allocated storage for `self` to the stored `Header`
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal static var _headerOffset: Int {
     _onFastPath()
     return _roundUp(
@@ -443,41 +472,41 @@
   /// An **unmanaged** pointer to the storage for the `Header`
   /// instance.  Not safe to use without _fixLifetime calls to
   /// guarantee it doesn't dangle
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var _headerPointer: UnsafeMutablePointer<Header> {
     _onFastPath()
-    return (_address + _My._headerOffset).assumingMemoryBound(
+    return (_address + ManagedBufferPointer._headerOffset).assumingMemoryBound(
       to: Header.self)
   }
 
   /// An **unmanaged** pointer to the storage for `Element`s.  Not
   /// safe to use without _fixLifetime calls to guarantee it doesn't
   /// dangle.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var _elementPointer: UnsafeMutablePointer<Element> {
     _onFastPath()
-    return (_address + _My._elementOffset).assumingMemoryBound(
+    return (_address + ManagedBufferPointer._elementOffset).assumingMemoryBound(
       to: Element.self)
   }
 
   /// Offset from the allocated storage for `self` to the `Element` storage
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal static var _elementOffset: Int {
     _onFastPath()
     return _roundUp(
       _headerOffset + MemoryLayout<Header>.size,
       toAlignment: MemoryLayout<Element>.alignment)
   }
-  
-  @inlinable // FIXME(sil-serialize-all)
+}
+
+extension ManagedBufferPointer: Equatable {
+  @inlinable
   public static func == (
-    lhs: ManagedBufferPointer, rhs: ManagedBufferPointer
+    lhs: ManagedBufferPointer,
+    rhs: ManagedBufferPointer
   ) -> Bool {
     return lhs._address == rhs._address
   }
-
-  @usableFromInline
-  internal var _nativeBuffer: Builtin.NativeObject
 }
 
 // FIXME: when our calling convention changes to pass self at +0,
diff --git a/stdlib/public/core/Misc.swift b/stdlib/public/core/Misc.swift
index b9ccb57..871a6c8 100644
--- a/stdlib/public/core/Misc.swift
+++ b/stdlib/public/core/Misc.swift
@@ -51,7 +51,6 @@
 ///
 /// This function is primarily useful to call various runtime functions
 /// written in C++.
-@inlinable // FIXME(sil-serialize-all)
 internal func _withUninitializedString<R>(
   _ body: (UnsafeMutablePointer<String>) -> R
 ) -> (R, String) {
@@ -67,13 +66,11 @@
 // with type names that we are nested in.
 // But we can place it behind #if _runtime(_Native) and remove it from ABI on
 // Apple platforms, deferring discussions mentioned above.
-@inlinable // FIXME(sil-serialize-all)
 @_silgen_name("swift_getTypeName")
 public func _getTypeName(_ type: Any.Type, qualified: Bool)
   -> (UnsafePointer<UInt8>, Int)
 
 /// Returns the demangled qualified name of a metatype.
-@inlinable // FIXME(sil-serialize-all)
 public // @testable
 func _typeName(_ type: Any.Type, qualified: Bool = true) -> String {
   let (stringPtr, count) = _getTypeName(type, qualified: qualified)
diff --git a/stdlib/public/core/NativeDictionary.swift b/stdlib/public/core/NativeDictionary.swift
index da0cd44..f3302c2 100644
--- a/stdlib/public/core/NativeDictionary.swift
+++ b/stdlib/public/core/NativeDictionary.swift
@@ -121,7 +121,7 @@
     return _values[bucket.offset]
   }
 
-  @usableFromInline
+  @inlinable
   @inline(__always)
   internal func uncheckedInitialize(
     at bucket: Bucket,
@@ -133,7 +133,7 @@
     (_values + bucket.offset).initialize(to: value)
   }
 
-  @usableFromInline
+  @inlinable
   @inline(__always)
   internal func uncheckedDestroy(at bucket: Bucket) {
     defer { _fixLifetime(self) }
diff --git a/stdlib/public/core/NewtypeWrapper.swift b/stdlib/public/core/NewtypeWrapper.swift
index 090156f..cbaa7d8 100644
--- a/stdlib/public/core/NewtypeWrapper.swift
+++ b/stdlib/public/core/NewtypeWrapper.swift
@@ -33,7 +33,7 @@
     hasher.combine(rawValue)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public func _rawHashValue(seed: Int) -> Int {
     return rawValue._rawHashValue(seed: seed)
   }
@@ -105,11 +105,11 @@
   // Fortunately the others don't need it.
   public typealias _ObjectiveCType = Self.RawValue._ObjectiveCType
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public func _bridgeToObjectiveC() -> Self.RawValue._ObjectiveCType {
     return rawValue._bridgeToObjectiveC()
   }
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public static func _forceBridgeFromObjectiveC(
     _ source: Self.RawValue._ObjectiveCType,
     result: inout Self?
@@ -119,7 +119,7 @@
     result = innerResult.flatMap { Self(rawValue: $0) }
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public static func _conditionallyBridgeFromObjectiveC(
     _ source: Self.RawValue._ObjectiveCType,
     result: inout Self?
@@ -132,7 +132,7 @@
     return success
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @_effects(readonly)
   public static func _unconditionallyBridgeFromObjectiveC(
     _ source: Self.RawValue._ObjectiveCType?
@@ -143,12 +143,12 @@
 }
 
 extension _SwiftNewtypeWrapper where Self.RawValue: AnyObject {
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public func _bridgeToObjectiveC() -> Self.RawValue {
     return rawValue
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public static func _forceBridgeFromObjectiveC(
     _ source: Self.RawValue,
     result: inout Self?
@@ -156,7 +156,7 @@
     result = Self(rawValue: source)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public static func _conditionallyBridgeFromObjectiveC(
     _ source: Self.RawValue,
     result: inout Self?
@@ -165,7 +165,7 @@
     return result != nil
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @_effects(readonly)
   public static func _unconditionallyBridgeFromObjectiveC(
     _ source: Self.RawValue?
diff --git a/stdlib/public/core/Pointer.swift b/stdlib/public/core/Pointer.swift
index b662ff6..5b8da3c 100644
--- a/stdlib/public/core/Pointer.swift
+++ b/stdlib/public/core/Pointer.swift
@@ -387,7 +387,6 @@
 }
 
 /// Derive a UTF-8 pointer argument from a value string parameter.
-@inlinable // FIXME(sil-serialize-all)
 public // COMPILER_INTRINSIC
 func _convertConstStringToUTF8PointerArgument<
   ToPointer : _Pointer
diff --git a/stdlib/public/core/Policy.swift b/stdlib/public/core/Policy.swift
index 2420a7a..adadb48 100644
--- a/stdlib/public/core/Policy.swift
+++ b/stdlib/public/core/Policy.swift
@@ -396,7 +396,7 @@
 prefix operator --
 prefix operator !
 prefix operator ~ : BinaryInteger
-prefix operator + : Numeric
+prefix operator + : AdditiveArithmetic
 prefix operator - : SignedNumeric
 prefix operator ...
 prefix operator ..<
@@ -420,9 +420,9 @@
 
 // "Additive"
 
-infix operator   + : AdditionPrecedence, Numeric, String, Strideable
+infix operator   + : AdditionPrecedence, AdditiveArithmetic, String, Strideable
 infix operator  &+ : AdditionPrecedence, FixedWidthInteger
-infix operator   - : AdditionPrecedence, Numeric, Strideable
+infix operator   - : AdditionPrecedence, AdditiveArithmetic, Strideable
 infix operator  &- : AdditionPrecedence, FixedWidthInteger
 infix operator   | : AdditionPrecedence, BinaryInteger
 infix operator   ^ : AdditionPrecedence, BinaryInteger
@@ -474,9 +474,9 @@
 infix operator  &*= : AssignmentPrecedence, FixedWidthInteger
 infix operator   /= : AssignmentPrecedence, BinaryInteger
 infix operator   %= : AssignmentPrecedence, BinaryInteger
-infix operator   += : AssignmentPrecedence, Numeric, String, Strideable
+infix operator   += : AssignmentPrecedence, AdditiveArithmetic, String, Strideable
 infix operator  &+= : AssignmentPrecedence, FixedWidthInteger
-infix operator   -= : AssignmentPrecedence, Numeric, Strideable
+infix operator   -= : AssignmentPrecedence, AdditiveArithmetic, Strideable
 infix operator  &-= : AssignmentPrecedence, FixedWidthInteger
 infix operator  <<= : AssignmentPrecedence, BinaryInteger
 infix operator &<<= : AssignmentPrecedence, FixedWidthInteger
diff --git a/stdlib/public/core/REPL.swift b/stdlib/public/core/REPL.swift
index c3ecd0f..e7c8c6a 100644
--- a/stdlib/public/core/REPL.swift
+++ b/stdlib/public/core/REPL.swift
@@ -11,7 +11,6 @@
 //===----------------------------------------------------------------------===//
 
 /// Print a string as is to stdout.
-@inlinable // FIXME(sil-serialize-all)
 public // COMPILER_INTRINSIC
 func _replPrintLiteralString(_ text: String) {
   print(text, terminator: "")
diff --git a/stdlib/public/core/Random.swift b/stdlib/public/core/Random.swift
index 8fc5510..81ed3ff 100644
--- a/stdlib/public/core/Random.swift
+++ b/stdlib/public/core/Random.swift
@@ -61,27 +61,6 @@
   ///
   /// - Returns: An unsigned 64-bit random value.
   mutating func next() -> UInt64
-
-  // FIXME: De-underscore after swift-evolution amendment
-  mutating func _fill(bytes buffer: UnsafeMutableRawBufferPointer)
-}
-
-extension RandomNumberGenerator {
-  @inlinable
-  public mutating func _fill(bytes buffer: UnsafeMutableRawBufferPointer) {
-    // FIXME: Optimize
-    var chunk: UInt64 = 0
-    var chunkBytes = 0
-    for i in 0..<buffer.count {
-      if chunkBytes == 0 {
-        chunk = next()
-        chunkBytes = UInt64.bitWidth / 8
-      }
-      buffer[i] = UInt8(truncatingIfNeeded: chunk)
-      chunk >>= UInt8.bitWidth
-      chunkBytes -= 1
-    }
-  }
 }
 
 extension RandomNumberGenerator {
@@ -167,11 +146,4 @@
     swift_stdlib_random(&random, MemoryLayout<UInt64>.size)
     return random
   }
-
-  @inlinable
-  public mutating func _fill(bytes buffer: UnsafeMutableRawBufferPointer) {
-    if !buffer.isEmpty {
-      swift_stdlib_random(buffer.baseAddress!, buffer.count)
-    }
-  }
 }
diff --git a/stdlib/public/core/Runtime.swift.gyb b/stdlib/public/core/Runtime.swift.gyb
index 19356f8..c4fc476 100644
--- a/stdlib/public/core/Runtime.swift.gyb
+++ b/stdlib/public/core/Runtime.swift.gyb
@@ -102,136 +102,6 @@
   return wonRace
 }
 
-% for bits in [ 32, 64 ]:
-
-@_transparent
-public // @testable
-func _stdlib_atomicCompareExchangeStrongUInt${bits}(
-  object target: UnsafeMutablePointer<UInt${bits}>,
-  expected: UnsafeMutablePointer<UInt${bits}>,
-  desired: UInt${bits}) -> Bool {
-
-  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int${bits}(
-    target._rawValue, expected.pointee._value, desired._value)
-  expected.pointee._value = oldValue
-  return Bool(won)
-}
-
-@_transparent
-public // @testable
-func _stdlib_atomicCompareExchangeStrongInt${bits}(
-  object target: UnsafeMutablePointer<Int${bits}>,
-  expected: UnsafeMutablePointer<Int${bits}>,
-  desired: Int${bits}) -> Bool {
-
-  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int${bits}(
-    target._rawValue, expected.pointee._value, desired._value)
-  expected.pointee._value = oldValue
-  return Bool(won)
-}
-
-@_transparent
-public // @testable
-func _swift_stdlib_atomicStoreUInt${bits}(
-  object target: UnsafeMutablePointer<UInt${bits}>,
-  desired: UInt${bits}) {
-
-  Builtin.atomicstore_seqcst_Int${bits}(target._rawValue, desired._value)
-}
-
-@inlinable // FIXME(sil-serialize-all)
-internal func _swift_stdlib_atomicStoreInt${bits}(
-  object target: UnsafeMutablePointer<Int${bits}>,
-  desired: Int${bits}) {
-
-  Builtin.atomicstore_seqcst_Int${bits}(target._rawValue, desired._value)
-}
-
-@inlinable // FIXME(sil-serialize-all)
-public // @testable
-func _swift_stdlib_atomicLoadUInt${bits}(
-  object target: UnsafeMutablePointer<UInt${bits}>) -> UInt${bits} {
-
-  let value = Builtin.atomicload_seqcst_Int${bits}(target._rawValue)
-  return UInt${bits}(value)
-}
-
-@inlinable // FIXME(sil-serialize-all)
-internal func _swift_stdlib_atomicLoadInt${bits}(
-  object target: UnsafeMutablePointer<Int${bits}>) -> Int${bits} {
-
-  let value = Builtin.atomicload_seqcst_Int${bits}(target._rawValue)
-  return Int${bits}(value)
-}
-
-%   for operation in ['Add', 'And', 'Or', 'Xor']:
-// Warning: no overflow checking.
-@_transparent
-public // @testable
-func _swift_stdlib_atomicFetch${operation}UInt${bits}(
-  object target: UnsafeMutablePointer<UInt${bits}>,
-  operand: UInt${bits}) -> UInt${bits} {
-
-  let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
-    target._rawValue, operand._value)
-
-  return UInt${bits}(value)
-}
-
-// Warning: no overflow checking.
-@inlinable // FIXME(sil-serialize-all)
-internal func _swift_stdlib_atomicFetch${operation}Int${bits}(
-  object target: UnsafeMutablePointer<Int${bits}>,
-  operand: Int${bits}) -> Int${bits} {
-
-  let value = Builtin.atomicrmw_${operation.lower()}_seqcst_Int${bits}(
-    target._rawValue, operand._value)
-
-  return Int${bits}(value)
-}
-%   end
-
-% end
-
-@inlinable // FIXME(sil-serialize-all)
-internal func _stdlib_atomicCompareExchangeStrongInt(
-  object target: UnsafeMutablePointer<Int>,
-  expected: UnsafeMutablePointer<Int>,
-  desired: Int) -> Bool {
-#if arch(i386) || arch(arm)
-  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
-    target._rawValue, expected.pointee._value, desired._value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int64(
-    target._rawValue, expected.pointee._value, desired._value)
-#endif
-  expected.pointee._value = oldValue
-  return Bool(won)
-}
-
-@inlinable // FIXME(sil-serialize-all)
-internal func _swift_stdlib_atomicStoreInt(
-  object target: UnsafeMutablePointer<Int>,
-  desired: Int) {
-#if arch(i386) || arch(arm)
-  Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
-#endif
-}
-
-@_transparent
-public func _swift_stdlib_atomicLoadInt(
-  object target: UnsafeMutablePointer<Int>) -> Int {
-#if arch(i386) || arch(arm)
-  let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
-  return Int(value)
-#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
-  return Int(value)
-#endif
-}
-
 @_transparent
 public // @testable
 func _stdlib_atomicLoadARCRef(
@@ -244,102 +114,68 @@
   return nil
 }
 
-% for operation in ['Add', 'And', 'Or', 'Xor']:
+//===----------------------------------------------------------------------===//
+// These pieces are used in ThreadLocalStorage.swift in debug builds.
+// For tests, see similar functions from SwiftPrivate/AtomicInt.swift.gyb
+//===----------------------------------------------------------------------===//
+internal func _swift_stdlib_atomicLoadInt(
+  object target: UnsafeMutablePointer<Int>) -> Int {
+#if arch(i386) || arch(arm)
+  let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
+  return Int(value)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
+  let value = Builtin.atomicload_seqcst_Int64(target._rawValue)
+  return Int(value)
+#endif
+}
+
+% for bits in [ 32, 64 ]:
+
 // Warning: no overflow checking.
-@inlinable // FIXME(sil-serialize-all)
-public func _swift_stdlib_atomicFetch${operation}Int(
+internal func _swift_stdlib_atomicFetchAddInt${bits}(
+  object target: UnsafeMutablePointer<Int${bits}>,
+  operand: Int${bits}) -> Int${bits} {
+
+  let value = Builtin.atomicrmw_add_seqcst_Int${bits}(
+    target._rawValue, operand._value)
+
+  return Int${bits}(value)
+}
+
+% end
+
+// Warning: no overflow checking.
+internal func _swift_stdlib_atomicFetchAddInt(
   object target: UnsafeMutablePointer<Int>,
   operand: Int) -> Int {
   let rawTarget = UnsafeMutableRawPointer(target)
 #if arch(i386) || arch(arm)
-  let value = _swift_stdlib_atomicFetch${operation}Int32(
+  let value = _swift_stdlib_atomicFetchAddInt32(
     object: rawTarget.assumingMemoryBound(to: Int32.self),
     operand: Int32(operand))
 #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
-  let value = _swift_stdlib_atomicFetch${operation}Int64(
+  let value = _swift_stdlib_atomicFetchAddInt64(
     object: rawTarget.assumingMemoryBound(to: Int64.self),
     operand: Int64(operand))
 #endif
   return Int(value)
 }
-% end
-
-@_fixed_layout // FIXME(sil-serialize-all)
-public final class _stdlib_AtomicInt {
-  @usableFromInline // FIXME(sil-serialize-all)
-  internal var _value: Int
-
-  @inlinable // FIXME(sil-serialize-all)
-  internal var _valuePtr: UnsafeMutablePointer<Int> {
-    return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
-      to: Int.self)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  public init(_ value: Int = 0) {
-    _value = value
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  deinit {}
-
-  @inlinable // FIXME(sil-serialize-all)
-  public func store(_ desired: Int) {
-    return _swift_stdlib_atomicStoreInt(object: _valuePtr, desired: desired)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  public func load() -> Int {
-    return _swift_stdlib_atomicLoadInt(object: _valuePtr)
-  }
-
-% for operation_name, operation in [ ('Add', '+'), ('And', '&'), ('Or', '|'), ('Xor', '^') ]:
-  @inlinable // FIXME(sil-serialize-all)
-  @discardableResult
-  public func fetchAnd${operation_name}(_ operand: Int) -> Int {
-    return _swift_stdlib_atomicFetch${operation_name}Int(
-      object: _valuePtr,
-      operand: operand)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  public func ${operation_name.lower()}AndFetch(_ operand: Int) -> Int {
-    return fetchAnd${operation_name}(operand) ${operation} operand
-  }
-% end
-
-  @inlinable // FIXME(sil-serialize-all)
-  public func compareExchange(expected: inout Int, desired: Int) -> Bool {
-    var expectedVar = expected
-    let result = _stdlib_atomicCompareExchangeStrongInt(
-      object: _valuePtr,
-      expected: &expectedVar,
-      desired: desired)
-    expected = expectedVar
-    return result
-  }
-}
+//===----------------------------------------------------------------------===//
 
 //===----------------------------------------------------------------------===//
 // Conversion of primitive types to `String`
 //===----------------------------------------------------------------------===//
 
 /// A 32 byte buffer.
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
 internal struct _Buffer32 {
-  @inlinable // FIXME(sil-serialize-all)
   internal init() {}
 % for i in range(32):
-  @usableFromInline // FIXME(sil-serialize-all)
   internal var _x${i}: UInt8 = 0
 % end
 
-  @inlinable // FIXME(sil-serialize-all)
   internal mutating func withBytes<Result>(
     _ body: (UnsafeMutablePointer<UInt8>) throws -> Result
-  ) rethrows -> Result
-  {
+  ) rethrows -> Result {
     return try withUnsafeMutablePointer(to: &self) {
       try body(UnsafeMutableRawPointer($0).assumingMemoryBound(to: UInt8.self))
     }
@@ -347,21 +183,15 @@
 }
 
 /// A 72 byte buffer.
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
 internal struct _Buffer72 {
-  @inlinable // FIXME(sil-serialize-all)
   internal init() {}
 % for i in range(72):
-  @usableFromInline // FIXME(sil-serialize-all)
   internal var _x${i}: UInt8 = 0
 % end
 
-  @inlinable // FIXME(sil-serialize-all)
   internal mutating func withBytes<Result>(
     _ body: (UnsafeMutablePointer<UInt8>) throws -> Result
-  ) rethrows -> Result
-  {
+  ) rethrows -> Result {
     return try withUnsafeMutablePointer(to: &self) {
       try body(UnsafeMutableRawPointer($0).assumingMemoryBound(to: UInt8.self))
     }
@@ -398,7 +228,6 @@
 
 % end
 
-@usableFromInline // FIXME(sil-serialize-all)
 @_silgen_name("swift_int64ToString")
 internal func _int64ToStringImpl(
   _ buffer: UnsafeMutablePointer<UTF8.CodeUnit>,
@@ -406,7 +235,6 @@
   _ radix: Int64, _ uppercase: Bool
 ) -> UInt
 
-@inlinable // FIXME(sil-serialize-all)
 internal func _int64ToString(
   _ value: Int64, radix: Int64 = 10, uppercase: Bool = false
 ) -> String {
@@ -429,14 +257,12 @@
   }
 }
 
-@usableFromInline // FIXME(sil-serialize-all)
 @_silgen_name("swift_uint64ToString")
 internal func _uint64ToStringImpl(
   _ buffer: UnsafeMutablePointer<UTF8.CodeUnit>,
   _ bufferLength: UInt, _ value: UInt64, _ radix: Int64, _ uppercase: Bool
 ) -> UInt
 
-@inlinable // FIXME(sil-serialize-all)
 public // @testable
 func _uint64ToString(
     _ value: UInt64, radix: Int64 = 10, uppercase: Bool = false
@@ -486,57 +312,50 @@
 // coexist, so they were renamed. The old names must not be used in the
 // new runtime.
 
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
+@_fixed_layout
+@usableFromInline
 @objc @_swift_native_objc_runtime_base(__SwiftNativeNSArrayBase)
 internal class __SwiftNativeNSArray {
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @nonobjc
   internal init() {}
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   deinit {}
 }
 
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
+@_fixed_layout
+@usableFromInline
 @objc @_swift_native_objc_runtime_base(__SwiftNativeNSDictionaryBase)
 internal class __SwiftNativeNSDictionary {
-  @inlinable // FIXME(sil-serialize-all)
   @nonobjc
   internal init() {}
-  @inlinable // FIXME(sil-serialize-all)
   deinit {}
 }
 
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
+@_fixed_layout
+@usableFromInline
 @objc @_swift_native_objc_runtime_base(__SwiftNativeNSSetBase)
 internal class __SwiftNativeNSSet {
-  @inlinable // FIXME(sil-serialize-all)
   @nonobjc
   internal init() {}
-  @inlinable // FIXME(sil-serialize-all)
   deinit {}
 }
 
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
-@objc @_swift_native_objc_runtime_base(__SwiftNativeNSEnumeratorBase)
+@objc
+@_swift_native_objc_runtime_base(__SwiftNativeNSEnumeratorBase)
 internal class __SwiftNativeNSEnumerator {
-  @inlinable // FIXME(sil-serialize-all)
   @nonobjc
   internal init() {}
-  @inlinable // FIXME(sil-serialize-all)
   deinit {}
 }
 
 // FIXME(ABI)#60 : move into the Foundation overlay and remove 'open'
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout
 @objc @_swift_native_objc_runtime_base(__SwiftNativeNSDataBase)
 open class __SwiftNativeNSData {
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @objc public init() {}
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   deinit {}
 }
 
@@ -579,28 +398,28 @@
 }
 #else
 
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
+@_fixed_layout
+@usableFromInline
 internal class __SwiftNativeNSArray {
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal init() {}
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   deinit {}
 }
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
+@_fixed_layout
+@usableFromInline
 internal class __SwiftNativeNSDictionary {
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal init() {}
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   deinit {}
 }
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
+@_fixed_layout
+@usableFromInline
 internal class __SwiftNativeNSSet {
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal init() {}
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   deinit {}
 }
 
diff --git a/stdlib/public/core/SetStorage.swift b/stdlib/public/core/SetStorage.swift
index d4fa272..64f4139 100644
--- a/stdlib/public/core/SetStorage.swift
+++ b/stdlib/public/core/SetStorage.swift
@@ -16,7 +16,7 @@
 /// Enough bytes are allocated to hold the bitmap for marking valid entries,
 /// keys, and values. The data layout starts with the bitmap, followed by the
 /// keys, followed by the values.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout
 @usableFromInline
 @_objc_non_lazy_realization
 internal class _RawSetStorage: __SwiftNativeNSSet {
@@ -175,7 +175,6 @@
 #endif
 }
 
-@_fixed_layout // FIXME(sil-serialize-all)
 @usableFromInline
 final internal class _SetStorage<Element: Hashable>
   : _RawSetStorage, _NSSetCore {
diff --git a/stdlib/public/core/SipHash.swift b/stdlib/public/core/SipHash.swift
index e13be21..3aa81d4 100644
--- a/stdlib/public/core/SipHash.swift
+++ b/stdlib/public/core/SipHash.swift
@@ -25,82 +25,89 @@
   @usableFromInline @_fixed_layout
   internal struct _State {
     // "somepseudorandomlygeneratedbytes"
-    fileprivate var v0: UInt64 = 0x736f6d6570736575
-    fileprivate var v1: UInt64 = 0x646f72616e646f6d
-    fileprivate var v2: UInt64 = 0x6c7967656e657261
-    fileprivate var v3: UInt64 = 0x7465646279746573
+    private var v0: UInt64 = 0x736f6d6570736575
+    private var v1: UInt64 = 0x646f72616e646f6d
+    private var v2: UInt64 = 0x6c7967656e657261
+    private var v3: UInt64 = 0x7465646279746573
     // The fields below are reserved for future use. They aren't currently used.
-    fileprivate var v4: UInt64 = 0
-    fileprivate var v5: UInt64 = 0
-    fileprivate var v6: UInt64 = 0
-    fileprivate var v7: UInt64 = 0
+    private var v4: UInt64 = 0
+    private var v5: UInt64 = 0
+    private var v6: UInt64 = 0
+    private var v7: UInt64 = 0
 
     @inline(__always)
-    fileprivate init(rawSeed: (UInt64, UInt64)) {
+    internal init(rawSeed: (UInt64, UInt64)) {
       v3 ^= rawSeed.1
       v2 ^= rawSeed.0
       v1 ^= rawSeed.1
       v0 ^= rawSeed.0
     }
-
-    @inline(__always)
-    fileprivate
-    static func _rotateLeft(_ x: UInt64, by amount: UInt64) -> UInt64 {
-      return (x &<< amount) | (x &>> (64 - amount))
-    }
-
-    @inline(__always)
-    fileprivate mutating func _round() {
-      v0 = v0 &+ v1
-      v1 = Hasher._State._rotateLeft(v1, by: 13)
-      v1 ^= v0
-      v0 = Hasher._State._rotateLeft(v0, by: 32)
-      v2 = v2 &+ v3
-      v3 = Hasher._State._rotateLeft(v3, by: 16)
-      v3 ^= v2
-      v0 = v0 &+ v3
-      v3 = Hasher._State._rotateLeft(v3, by: 21)
-      v3 ^= v0
-      v2 = v2 &+ v1
-      v1 = Hasher._State._rotateLeft(v1, by: 17)
-      v1 ^= v2
-      v2 = Hasher._State._rotateLeft(v2, by: 32)
-    }
-
-    @inline(__always)
-    fileprivate func _extract() -> UInt64 {
-      return v0 ^ v1 ^ v2 ^ v3
-    }
   }
 }
 
-extension Hasher {
-  // FIXME: Remove @usableFromInline and @_fixed_layout once Hasher is resilient.
-  // rdar://problem/38549901
-  @usableFromInline @_fixed_layout
-  internal struct _Core: _HasherCore {
-    private var _state: Hasher._State
+extension Hasher._State {
+  @inline(__always)
+  private static func _rotateLeft(_ x: UInt64, by amount: UInt64) -> UInt64 {
+    return (x &<< amount) | (x &>> (64 - amount))
+  }
 
-    @inline(__always)
-    internal init(rawSeed: (UInt64, UInt64)) {
-      _state = Hasher._State(rawSeed: rawSeed)
-    }
+  @inline(__always)
+  private mutating func _round() {
+    v0 = v0 &+ v1
+    v1 = Hasher._State._rotateLeft(v1, by: 13)
+    v1 ^= v0
+    v0 = Hasher._State._rotateLeft(v0, by: 32)
+    v2 = v2 &+ v3
+    v3 = Hasher._State._rotateLeft(v3, by: 16)
+    v3 ^= v2
+    v0 = v0 &+ v3
+    v3 = Hasher._State._rotateLeft(v3, by: 21)
+    v3 ^= v0
+    v2 = v2 &+ v1
+    v1 = Hasher._State._rotateLeft(v1, by: 17)
+    v1 ^= v2
+    v2 = Hasher._State._rotateLeft(v2, by: 32)
+  }
 
-    @inline(__always)
-    internal mutating func compress(_ m: UInt64) {
-      _state.v3 ^= m
-      _state._round()
-      _state.v0 ^= m
-    }
+  @inline(__always)
+  private func _extract() -> UInt64 {
+    return v0 ^ v1 ^ v2 ^ v3
+  }
+}
 
-    @inline(__always)
-    internal mutating func finalize(tailAndByteCount: UInt64) -> UInt64 {
-      compress(tailAndByteCount)
-      _state.v2 ^= 0xff
-      for _ in 0..<3 {
-        _state._round()
-      }
-      return _state._extract()
+extension Hasher._State {
+  @inline(__always)
+  internal mutating func compress(_ m: UInt64) {
+    v3 ^= m
+    _round()
+    v0 ^= m
+  }
+
+  @inline(__always)
+  internal mutating func finalize(tailAndByteCount: UInt64) -> UInt64 {
+    compress(tailAndByteCount)
+    v2 ^= 0xff
+    for _ in 0..<3 {
+      _round()
     }
+    return _extract()
+  }
+}
+
+extension Hasher._State {
+  @inline(__always)
+  internal init() {
+    self.init(rawSeed: Hasher._executionSeed)
+  }
+
+  @inline(__always)
+  internal init(seed: Int) {
+    let executionSeed = Hasher._executionSeed
+    // Prevent sign-extending the supplied seed; this makes testing slightly
+    // easier.
+    let seed = UInt(bitPattern: seed)
+    self.init(rawSeed: (
+        executionSeed.0 ^ UInt64(truncatingIfNeeded: seed),
+        executionSeed.1))
   }
 }
diff --git a/stdlib/public/core/SliceBuffer.swift b/stdlib/public/core/SliceBuffer.swift
index 253ff38..7ea4dc4 100644
--- a/stdlib/public/core/SliceBuffer.swift
+++ b/stdlib/public/core/SliceBuffer.swift
@@ -64,19 +64,19 @@
     }
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var _hasNativeBuffer: Bool {
     return (endIndexAndFlags & 1) != 0
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var nativeBuffer: NativeBuffer {
     _sanityCheck(_hasNativeBuffer)
     return NativeBuffer(
       owner as? __ContiguousArrayStorageBase ?? _emptyArrayStorage)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var nativeOwner: AnyObject {
     _sanityCheck(_hasNativeBuffer, "Expect a native array")
     return owner
@@ -88,7 +88,7 @@
   /// - Precondition: This buffer is backed by a uniquely-referenced
   ///   `_ContiguousArrayBuffer` and
   ///   `insertCount <= numericCast(newValues.count)`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal mutating func replaceSubrange<C>(
     _ subrange: Range<Int>,
     with insertCount: Int,
@@ -125,7 +125,7 @@
   /// A value that identifies the storage used by the buffer.  Two
   /// buffers address the same elements when they have the same
   /// identity and count.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var identity: UnsafeRawPointer {
     return UnsafeRawPointer(firstElementAddress)
   }
@@ -136,12 +136,12 @@
   @usableFromInline
   internal let subscriptBaseAddress: UnsafeMutablePointer<Element>
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var firstElementAddress: UnsafeMutablePointer<Element> {
     return subscriptBaseAddress + startIndex
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var firstElementAddressIfContiguous: UnsafeMutablePointer<Element>? {
     return firstElementAddress
   }
@@ -152,7 +152,7 @@
 
   //===--- Non-essential bits ---------------------------------------------===//
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal mutating func requestUniqueMutableBackingBuffer(
     minimumCapacity: Int
   ) -> NativeBuffer? {
@@ -210,7 +210,7 @@
   /// If this buffer is backed by a `_ContiguousArrayBuffer`
   /// containing the same number of elements as `self`, return it.
   /// Otherwise, return `nil`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal func requestNativeBuffer() -> _ContiguousArrayBuffer<Element>? {
     _invariantCheck()
     if _fastPath(_hasNativeBuffer && nativeBuffer.count == count) {
@@ -219,7 +219,7 @@
     return nil
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @discardableResult
   internal __consuming func _copyContents(
     subRange bounds: Range<Int>,
@@ -235,12 +235,12 @@
   }
 
   /// True, if the array is native and does not need a deferred type check.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var arrayPropertyIsNativeTypeChecked: Bool {
     return _hasNativeBuffer
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var count: Int {
     get {
       return endIndex - startIndex
@@ -257,13 +257,13 @@
 
   /// Traps unless the given `index` is valid for subscripting, i.e.
   /// `startIndex ≤ index < endIndex`
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal func _checkValidSubscript(_ index : Int) {
     _precondition(
       index >= startIndex && index < endIndex, "Index out of bounds")
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var capacity: Int {
     let count = self.count
     if _slowPath(!_hasNativeBuffer) {
@@ -277,12 +277,12 @@
     return count
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal mutating func isUniquelyReferenced() -> Bool {
     return isKnownUniquelyReferenced(&owner)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal func getElement(_ i: Int) -> Element {
     _sanityCheck(i >= startIndex, "slice index is out of range (before startIndex)")
     _sanityCheck(i < endIndex, "slice index is out of range")
@@ -293,7 +293,7 @@
   ///
   /// - Precondition: `position` is a valid position in `self` and
   ///   `position != endIndex`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal subscript(position: Int) -> Element {
     get {
       return getElement(position)
@@ -305,7 +305,7 @@
     }
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal subscript(bounds: Range<Int>) -> _SliceBuffer {
     get {
       _sanityCheck(bounds.lowerBound >= startIndex)
@@ -334,7 +334,7 @@
   ///
   /// `endIndex` is always reachable from `startIndex` by zero or more
   /// applications of `index(after:)`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal var endIndex: Int {
     get {
       return Int(endIndexAndFlags >> 1)
@@ -344,6 +344,7 @@
     }
   }
 
+  @usableFromInline
   internal typealias Indices = Range<Int>
 
   //===--- misc -----------------------------------------------------------===//
@@ -371,7 +372,7 @@
 }
 
 extension _SliceBuffer {
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   internal __consuming func _copyToContiguousArray() -> ContiguousArray<Element> {
     if _hasNativeBuffer {
       let n = nativeBuffer
diff --git a/stdlib/public/core/SmallString.swift b/stdlib/public/core/SmallString.swift
index f423973..329cedb 100644
--- a/stdlib/public/core/SmallString.swift
+++ b/stdlib/public/core/SmallString.swift
@@ -192,7 +192,7 @@
     }
   }
 
-  @usableFromInline // testable
+  @inlinable // testable
   internal subscript(_ bounds: Range<Index>) -> SubSequence {
     @inline(__always) get {
       // TODO(String performance): In-vector-register operation
diff --git a/stdlib/public/core/Sort.swift b/stdlib/public/core/Sort.swift
index 622f27a..e250731 100644
--- a/stdlib/public/core/Sort.swift
+++ b/stdlib/public/core/Sort.swift
@@ -21,9 +21,6 @@
   /// You can sort any sequence of elements that conform to the `Comparable`
   /// protocol by calling this method. Elements are sorted in ascending order.
   ///
-  /// The sorting algorithm is not stable. A nonstable sort may change the
-  /// relative order of elements that compare equal.
-  ///
   /// Here's an example of sorting a list of students' names. Strings in Swift
   /// conform to the `Comparable` protocol, so the names are sorted in
   /// ascending order according to the less-than operator (`<`).
@@ -40,6 +37,9 @@
   ///     print(descendingStudents)
   ///     // Prints "["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"
   ///
+  /// The sorting algorithm is not guaranteed to be stable. A stable sort
+  /// preserves the relative order of elements that compare equal.
+  ///
   /// - Returns: A sorted array of the sequence's elements.
   ///
   /// - Complexity: O(*n* log *n*), where *n* is the length of the sequence.
@@ -55,26 +55,9 @@
   ///
   /// When you want to sort a sequence of elements that don't conform to the
   /// `Comparable` protocol, pass a predicate to this method that returns
-  /// `true` when the first element passed should be ordered before the
-  /// second. The elements of the resulting array are ordered according to the
-  /// given predicate.
-  ///
-  /// The predicate must be a *strict weak ordering* over the elements. That
-  /// is, for any elements `a`, `b`, and `c`, the following conditions must
-  /// hold:
-  ///
-  /// - `areInIncreasingOrder(a, a)` is always `false`. (Irreflexivity)
-  /// - If `areInIncreasingOrder(a, b)` and `areInIncreasingOrder(b, c)` are
-  ///   both `true`, then `areInIncreasingOrder(a, c)` is also `true`.
-  ///   (Transitive comparability)
-  /// - Two elements are *incomparable* if neither is ordered before the other
-  ///   according to the predicate. If `a` and `b` are incomparable, and `b`
-  ///   and `c` are incomparable, then `a` and `c` are also incomparable.
-  ///   (Transitive incomparability)
-  ///
-  /// The sorting algorithm is not stable. A nonstable sort may change the
-  /// relative order of elements for which `areInIncreasingOrder` does not
-  /// establish an order.
+  /// `true` when the first element should be ordered before the second. The
+  /// elements of the resulting array are ordered according to the given
+  /// predicate.
   ///
   /// In the following example, the predicate provides an ordering for an array
   /// of a custom `HTTPResponse` type. The predicate orders errors before
@@ -121,6 +104,23 @@
   ///     print(students.sorted(by: <))
   ///     // Prints "["Abena", "Akosua", "Kofi", "Kweku", "Peter"]"
   ///
+  /// The predicate must be a *strict weak ordering* over the elements. That
+  /// is, for any elements `a`, `b`, and `c`, the following conditions must
+  /// hold:
+  ///
+  /// - `areInIncreasingOrder(a, a)` is always `false`. (Irreflexivity)
+  /// - If `areInIncreasingOrder(a, b)` and `areInIncreasingOrder(b, c)` are
+  ///   both `true`, then `areInIncreasingOrder(a, c)` is also `true`.
+  ///   (Transitive comparability)
+  /// - Two elements are *incomparable* if neither is ordered before the other
+  ///   according to the predicate. If `a` and `b` are incomparable, and `b`
+  ///   and `c` are incomparable, then `a` and `c` are also incomparable.
+  ///   (Transitive incomparability)
+  ///
+  /// The sorting algorithm is not guaranteed to be stable. A stable sort
+  /// preserves the relative order of elements for which
+  /// `areInIncreasingOrder` does not establish an order.
+  ///
   /// - Parameter areInIncreasingOrder: A predicate that returns `true` if its
   ///   first argument should be ordered before its second argument;
   ///   otherwise, `false`.
@@ -146,9 +146,6 @@
   /// `Comparable` protocol by calling this method. Elements are sorted in
   /// ascending order.
   ///
-  /// The sorting algorithm is not stable. A nonstable sort may change the
-  /// relative order of elements that compare equal.
-  ///
   /// Here's an example of sorting a list of students' names. Strings in Swift
   /// conform to the `Comparable` protocol, so the names are sorted in
   /// ascending order according to the less-than operator (`<`).
@@ -165,6 +162,9 @@
   ///     print(students)
   ///     // Prints "["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"
   ///
+  /// The sorting algorithm is not guaranteed to be stable. A stable sort
+  /// preserves the relative order of elements that compare equal.
+  ///
   /// - Complexity: O(*n* log *n*), where *n* is the length of the collection.
   @inlinable
   public mutating func sort() {
@@ -176,27 +176,9 @@
   /// Sorts the collection in place, using the given predicate as the
   /// comparison between elements.
   ///
-  /// When you want to sort a collection of elements that doesn't conform to
+  /// When you want to sort a collection of elements that don't conform to
   /// the `Comparable` protocol, pass a closure to this method that returns
-  /// `true` when the first element passed should be ordered before the
-  /// second.
-  ///
-  /// The predicate must be a *strict weak ordering* over the elements. That
-  /// is, for any elements `a`, `b`, and `c`, the following conditions must
-  /// hold:
-  ///
-  /// - `areInIncreasingOrder(a, a)` is always `false`. (Irreflexivity)
-  /// - If `areInIncreasingOrder(a, b)` and `areInIncreasingOrder(b, c)` are
-  ///   both `true`, then `areInIncreasingOrder(a, c)` is also `true`.
-  ///   (Transitive comparability)
-  /// - Two elements are *incomparable* if neither is ordered before the other
-  ///   according to the predicate. If `a` and `b` are incomparable, and `b`
-  ///   and `c` are incomparable, then `a` and `c` are also incomparable.
-  ///   (Transitive incomparability)
-  ///
-  /// The sorting algorithm is not stable. A nonstable sort may change the
-  /// relative order of elements for which `areInIncreasingOrder` does not
-  /// establish an order.
+  /// `true` when the first element should be ordered before the second.
   ///
   /// In the following example, the closure provides an ordering for an array
   /// of a custom enumeration that describes an HTTP response. The predicate
@@ -236,6 +218,23 @@
   ///     print(students)
   ///     // Prints "["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"
   ///
+  /// `areInIncreasingOrder` must be a *strict weak ordering* over the
+  /// elements. That is, for any elements `a`, `b`, and `c`, the following
+  /// conditions must hold:
+  ///
+  /// - `areInIncreasingOrder(a, a)` is always `false`. (Irreflexivity)
+  /// - If `areInIncreasingOrder(a, b)` and `areInIncreasingOrder(b, c)` are
+  ///   both `true`, then `areInIncreasingOrder(a, c)` is also `true`.
+  ///   (Transitive comparability)
+  /// - Two elements are *incomparable* if neither is ordered before the other
+  ///   according to the predicate. If `a` and `b` are incomparable, and `b`
+  ///   and `c` are incomparable, then `a` and `c` are also incomparable.
+  ///   (Transitive incomparability)
+  ///
+  /// The sorting algorithm is not guaranteed to be stable. A stable sort
+  /// preserves the relative order of elements for which
+  /// `areInIncreasingOrder` does not establish an order.
+  ///
   /// - Parameter areInIncreasingOrder: A predicate that returns `true` if its
   ///   first argument should be ordered before its second argument;
   ///   otherwise, `false`. If `areInIncreasingOrder` throws an error during
@@ -249,310 +248,454 @@
   ) rethrows {
     let didSortUnsafeBuffer = try _withUnsafeMutableBufferPointerIfSupported {
       buffer -> Void? in
-        try buffer.sort(by: areInIncreasingOrder)
+        try buffer._stableSortImpl(by: areInIncreasingOrder)
     }
     if didSortUnsafeBuffer == nil {
-      try _introSort(within: startIndex..<endIndex, by: areInIncreasingOrder)
+      // Fallback since we can't use an unsafe buffer: sort into an outside
+      // array, then copy elements back in.
+      let sortedElements = try sorted(by: areInIncreasingOrder)
+      for (i, j) in zip(indices, sortedElements.indices) {
+        self[i] = sortedElements[j]
+      }
     }
   }
 }
 
 extension MutableCollection where Self: BidirectionalCollection {
+  /// Sorts `self[range]` according to `areInIncreasingOrder`. Stable.
+  ///
+  /// - Precondition: `sortedEnd != range.lowerBound`
+  /// - Precondition: `elements[..<sortedEnd]` are already in order.
   @inlinable
   internal mutating func _insertionSort(
-    within range: Range<Index>, 
+    within range: Range<Index>,
+    sortedEnd: Index,
     by areInIncreasingOrder: (Element, Element) throws -> Bool
   ) rethrows {
-
-    guard !range.isEmpty else { return }
-
-    let start = range.lowerBound
-
-    // Keep track of the end of the initial sequence of sorted elements. One
-    // element is trivially already-sorted, thus pre-increment Continue until
-    // the sorted elements cover the whole sequence
-    var sortedEnd = index(after: start)
-
+    var sortedEnd = sortedEnd
+    
+    // Continue sorting until the sorted elements cover the whole sequence.
     while sortedEnd != range.upperBound {
-      // get the first unsorted element
-      // FIXME: by stashing the element, instead of using indexing and swapAt,
-      // this method won't work for collections of move-only types.
-      let x = self[sortedEnd]
-
-      // Look backwards for x's position in the sorted sequence,
-      // moving elements forward to make room.
       var i = sortedEnd
+      // Look backwards for `self[i]`'s position in the sorted sequence,
+      // moving each element forward to make room.
       repeat {
         let j = index(before: i)
-        let predecessor = self[j]
-
-        // If closure throws, put the element at right place and rethrow.
-        do {
-          // if x doesn't belong before y, we've found its position
-          if try !areInIncreasingOrder(x, predecessor) {
-            break
-          }
-        } catch {
-          self[i] = x
-          throw error
+        
+        // If `self[i]` doesn't belong before `self[j]`, we've found
+        // its position.
+        if try !areInIncreasingOrder(self[i], self[j]) {
+          break
         }
-
-        // Move y forward
-        self[i] = predecessor
+        
+        swapAt(i, j)
         i = j
-      } while i != start
-
-      if i != sortedEnd {
-        // Plop x into position
-        self[i] = x
-      }
+      } while i != range.lowerBound
+      
       formIndex(after: &sortedEnd)
     }
   }
-}
-
-extension MutableCollection {
-  /// Sorts the elements at `elements[a]`, `elements[b]`, and `elements[c]`.
-  /// Stable.
-  ///
-  /// The indices passed as `a`, `b`, and `c` do not need to be consecutive, but
-  /// must be in strict increasing order.
-  ///
-  /// - Precondition: `a < b && b < c`
-  /// - Postcondition: `self[a] <= self[b] && self[b] <= self[c]`
+  
+  /// Sorts `self[range]` according to `areInIncreasingOrder`. Stable.
   @inlinable
   public // @testable
-  mutating func _sort3(
-    _ a: Index, _ b: Index, _ c: Index, 
+  mutating func _insertionSort(
+    within range: Range<Index>,
     by areInIncreasingOrder: (Element, Element) throws -> Bool
   ) rethrows {
-    // There are thirteen possible permutations for the original ordering of
-    // the elements at indices `a`, `b`, and `c`. The comments in the code below
-    // show the relative ordering of the three elements using a three-digit
-    // number as shorthand for the position and comparative relationship of
-    // each element. For example, "312" indicates that the element at `a` is the
-    // largest of the three, the element at `b` is the smallest, and the element
-    // at `c` is the median. This hypothetical input array has a 312 ordering for
-    // `a`, `b`, and `c`:
-    //
-    //      [ 7, 4, 3, 9, 2, 0, 3, 7, 6, 5 ]
-    //        ^              ^           ^
-    //        a              b           c
-    //
-    // - If each of the three elements is distinct, they could be ordered as any
-    //   of the permutations of 1, 2, and 3: 123, 132, 213, 231, 312, or 321.
-    // - If two elements are equivalent and one is distinct, they could be
-    //   ordered as any permutation of 1, 1, and 2 or 1, 2, and 2: 112, 121, 211,
-    //   122, 212, or 221.
-    // - If all three elements are equivalent, they are already in order: 111.
-
-    switch try (areInIncreasingOrder(self[b], self[a]),
-                areInIncreasingOrder(self[c], self[b])) {
-    case (false, false):
-      // 0 swaps: 123, 112, 122, 111
-      break
-
-    case (true, true):
-      // 1 swap: 321
-      // swap(a, c): 312->123
-      swapAt(a, c)
-
-    case (true, false):
-      // 1 swap: 213, 212 --- 2 swaps: 312, 211
-      // swap(a, b): 213->123, 212->122, 312->132, 211->121
-      swapAt(a, b)
-
-      if try areInIncreasingOrder(self[c], self[b]) {
-        // 132 (started as 312), 121 (started as 211)
-        // swap(b, c): 132->123, 121->112
-        swapAt(b, c)
-      }
-
-    case (false, true):
-      // 1 swap: 132, 121 --- 2 swaps: 231, 221
-      // swap(b, c): 132->123, 121->112, 231->213, 221->212
-      swapAt(b, c)
-
-      if try areInIncreasingOrder(self[b], self[a]) {
-        // 213 (started as 231), 212 (started as 221)
-        // swap(a, b): 213->123, 212->122
-        swapAt(a, b)
-      }
+    if range.isEmpty {
+      return
+    }
+    
+    // One element is trivially already-sorted, so the actual sort can
+    // start on the second element.
+    let sortedEnd = index(after: range.lowerBound)
+    try _insertionSort(
+      within: range, sortedEnd: sortedEnd, by: areInIncreasingOrder)
+  }
+  
+  /// Reverses the elements in the given range.
+  @inlinable
+  internal mutating func _reverse(
+    within range: Range<Index>
+  ) {
+    var f = range.lowerBound
+    var l = range.upperBound
+    while f < l {
+      formIndex(before: &l)
+      swapAt(f, l)
+      formIndex(after: &f)
     }
   }
 }
 
-extension MutableCollection where Self: RandomAccessCollection {
-  /// Reorders the collection and returns an index `p` such that every element
-  /// in `range.lowerBound..<p` is less than every element in
-  /// `p..<range.upperBound`.
-  ///
-  /// - Precondition: The count of `range` must be >= 3 i.e.
-  ///   `distance(from: range.lowerBound, to: range.upperBound) >= 3`
-  @inlinable
-  internal mutating func _partition(
-    within range: Range<Index>,
-    by areInIncreasingOrder: (Element, Element) throws -> Bool
-  ) rethrows -> Index {
-    var lo = range.lowerBound
-    var hi = index(before: range.upperBound)
+/// Merges the elements in the ranges `lo..<mid` and `mid..<hi` using `buffer`
+/// as out-of-place storage. Stable.
+///
+/// - Precondition: `lo..<mid` and `mid..<hi` must already be sorted according
+///   to `areInIncreasingOrder`.
+/// - Precondition: `buffer` must point to a region of memory at least as large
+///   as `min(mid - lo, hi - mid)`.
+/// - Postcondition: `lo..<hi` is sorted according to `areInIncreasingOrder`.
+@inlinable
+internal func _merge<Element>(
+  low: UnsafeMutablePointer<Element>,
+  mid: UnsafeMutablePointer<Element>,
+  high: UnsafeMutablePointer<Element>,
+  buffer: UnsafeMutablePointer<Element>,
+  by areInIncreasingOrder: (Element, Element) throws -> Bool
+) rethrows -> Bool {
+  let lowCount = mid - low
+  let highCount = high - mid
+  
+  var destLow = low         // Lower bound of uninitialized storage
+  var bufferLow = buffer    // Lower bound of the initialized buffer
+  var bufferHigh = buffer   // Upper bound of the initialized buffer
 
-    // Sort the first, middle, and last elements, then use the middle value
-    // as the pivot for the partition.
-    let half = distance(from: lo, to: hi) / 2
-    let mid = index(lo, offsetBy: half)
-    try _sort3(lo, mid, hi, by: areInIncreasingOrder)
-    let pivot = self[mid]
-
-    // Loop invariants:
-    // * lo < hi
-    // * self[i] < pivot, for i in range.lowerBound..<lo
-    // * pivot <= self[i] for i in hi..<range.upperBound
-    Loop: while true {
-      FindLo: do {
-        formIndex(after: &lo)
-        while lo != hi {
-          if try !areInIncreasingOrder(self[lo], pivot) { break FindLo }
-          formIndex(after: &lo)
-        }
-        break Loop
-      }
-
-      FindHi: do {
-        formIndex(before: &hi)
-        while hi != lo {
-          if try areInIncreasingOrder(self[hi], pivot) { break FindHi }
-          formIndex(before: &hi)
-        }
-        break Loop
-      }
-
-      swapAt(lo, hi)
-    }
-
-    return lo
+  // When we exit the merge, move any remaining elements from the buffer back
+  // into `destLow` (aka the collection we're sorting). The buffer can have
+  // remaining elements if `areIncreasingOrder` throws, or more likely if the
+  // merge runs out of elements from the array before exhausting the buffer.
+  defer {
+    destLow.moveInitialize(from: bufferLow, count: bufferHigh - bufferLow)
   }
+  
+  if lowCount < highCount {
+    // Move the lower group of elements into the buffer, then traverse from
+    // low to high in both the buffer and the higher group of elements.
+    //
+    // After moving elements, the storage and buffer look like this, where
+    // `x` is uninitialized memory:
+    //
+    // Storage: [x, x, x, x, x, 6, 8, 8, 10, 12, 15]
+    //           ^              ^
+    //        destLow        srcLow
+    //
+    // Buffer:  [4, 4, 7, 8, 9, x, ...]
+    //           ^              ^
+    //        bufferLow     bufferHigh
+    buffer.moveInitialize(from: low, count: lowCount)
+    bufferHigh = bufferLow + lowCount
+    
+    var srcLow = mid
 
-  @inlinable
-  public // @testable
-  mutating func _introSort(
-    within range: Range<Index>,
-    by areInIncreasingOrder: (Element, Element) throws -> Bool
-  ) rethrows {
-
-    let n = distance(from: range.lowerBound, to: range.upperBound)
-    guard n > 1 else { return }
-
-    // Set max recursion depth to 2*floor(log(N)), as suggested in the introsort
-    // paper: http://www.cs.rpi.edu/~musser/gp/introsort.ps
-    let depthLimit = 2 * n._binaryLogarithm()
-    try _introSortImpl(
-      within: range,
-      by: areInIncreasingOrder,
-      depthLimit: depthLimit)
-  }
-
-  @inlinable
-  internal mutating func _introSortImpl(
-    within range: Range<Index>,
-    by areInIncreasingOrder: (Element, Element) throws -> Bool,
-    depthLimit: Int
-  ) rethrows {
-
-    // Insertion sort is better at handling smaller regions.
-    if distance(from: range.lowerBound, to: range.upperBound) < 20 {
-      try _insertionSort(within: range, by: areInIncreasingOrder)
-    } else if depthLimit == 0 {
-      try _heapSort(within: range, by: areInIncreasingOrder)
-    } else {
-      // Partition and sort.
-      // We don't check the depthLimit variable for underflow because this
-      // variable is always greater than zero (see check above).
-      let partIdx = try _partition(within: range, by: areInIncreasingOrder)
-      try _introSortImpl(
-        within: range.lowerBound..<partIdx,
-        by: areInIncreasingOrder, 
-        depthLimit: depthLimit &- 1)
-      try _introSortImpl(
-        within: partIdx..<range.upperBound,
-        by: areInIncreasingOrder, 
-        depthLimit: depthLimit &- 1)      
-    }
-  }
-
-  @inlinable
-  internal mutating func _siftDown(
-    _ idx: Index,
-    within range: Range<Index>,
-    by areInIncreasingOrder: (Element, Element) throws -> Bool
-  ) rethrows {
-    var idx = idx
-    var countToIndex = distance(from: range.lowerBound, to: idx)
-    var countFromIndex = distance(from: idx, to: range.upperBound)
-    // Check if left child is within bounds. If not, stop iterating, because
-    // there are no children of the given node in the heap.
-    while countToIndex + 1 < countFromIndex {
-      let left = index(idx, offsetBy: countToIndex + 1)
-      var largest = idx
-      if try areInIncreasingOrder(self[largest], self[left]) {
-        largest = left
-      }
-      // Check if right child is also within bounds before trying to examine it.
-      if countToIndex + 2 < countFromIndex {
-        let right = index(after: left)
-        if try areInIncreasingOrder(self[largest], self[right]) {
-          largest = right
-        }
-      }
-      // If a child is bigger than the current node, swap them and continue 
-      // sifting down.
-      if largest != idx {
-        swapAt(idx, largest)
-        idx = largest
-        countToIndex = distance(from: range.lowerBound, to: idx)
-        countFromIndex = distance(from: idx, to: range.upperBound)
+    // Each iteration moves the element that compares lower into `destLow`,
+    // preferring the buffer when equal to maintain stability. Elements are
+    // moved from either `bufferLow` or `srcLow`, with those pointers
+    // incrementing as elements are moved.
+    while bufferLow < bufferHigh && srcLow < high {
+      if try areInIncreasingOrder(srcLow.pointee, bufferLow.pointee) {
+        destLow.moveInitialize(from: srcLow, count: 1)
+        srcLow += 1
       } else {
+        destLow.moveInitialize(from: bufferLow, count: 1)
+        bufferLow += 1
+      }
+      destLow += 1
+    }
+  } else {
+    // Move the higher group of elements into the buffer, then traverse from
+    // high to low in both the buffer and the lower group of elements.
+    //
+    // After moving elements, the storage and buffer look like this, where
+    // `x` is uninitialized memory:
+    //
+    // Storage: [4, 4, 7, 8, 9, 6, x, x,  x,  x,  x]
+    //                          ^  ^                 ^
+    //                    srcHigh  destLow        destHigh (past the end)
+    //
+    // Buffer:                    [8, 8, 10, 12, 15, x, ...]
+    //                             ^                 ^
+    //                          bufferLow        bufferHigh
+    buffer.moveInitialize(from: mid, count: highCount)
+    bufferHigh = bufferLow + highCount
+    
+    var destHigh = high
+    var srcHigh = mid
+    destLow = mid
+
+    // Each iteration moves the element that compares higher into `destHigh`,
+    // preferring the buffer when equal to maintain stability. Elements are
+    // moved from either `bufferHigh - 1` or `srcHigh - 1`, with those
+    // pointers decrementing as elements are moved.
+    //
+    // Note: At the start of each iteration, each `...High` pointer points one
+    // past the element they're referring to.
+    while bufferHigh > bufferLow && srcHigh > low {
+      destHigh -= 1
+      if try areInIncreasingOrder(
+        (bufferHigh - 1).pointee, (srcHigh - 1).pointee
+      ) {
+        srcHigh -= 1
+        destHigh.moveInitialize(from: srcHigh, count: 1)
+        
+        // Moved an element from the lower initialized portion to the upper,
+        // sorted, initialized portion, so `destLow` moves down one.
+        destLow -= 1
+      } else {
+        bufferHigh -= 1
+        destHigh.moveInitialize(from: bufferHigh, count: 1)
+      }
+    }
+  }
+
+  // FIXME: Remove this, it works around rdar://problem/45044610
+  return true
+}
+
+/// Calculates an optimal minimum run length for sorting a collection.
+///
+/// "... pick a minrun in range(32, 65) such that N/minrun is exactly a power
+/// of 2, or if that isn't possible, is close to, but strictly less than, a
+/// power of 2. This is easier to do than it may sound: take the first 6 bits
+/// of N, and add 1 if any of the remaining bits are set."
+/// - From the Timsort introduction, at
+///   https://svn.python.org/projects/python/trunk/Objects/listsort.txt
+///
+/// - Parameter c: The number of elements in a collection.
+/// - Returns: If `c <= 64`, returns `c`. Otherwise, returns a value in
+///   `32...64`.
+@inlinable
+internal func _minimumMergeRunLength(_ c: Int) -> Int {
+  // Max out at `2^6 == 64` elements
+  let bitsToUse = 6
+  
+  if c < 1 << bitsToUse {
+    return c
+  }
+  let offset = (Int.bitWidth - bitsToUse) - c.leadingZeroBitCount
+  let mask = (1 << offset) - 1
+  return c >> offset + (c & mask == 0 ? 0 : 1)
+}
+
+/// Returns the end of the next in-order run along with a Boolean value
+/// indicating whether the elements in `start..<end` are in descending order.
+///
+/// - Precondition: `start < elements.endIndex`
+@inlinable
+internal func _findNextRun<C: RandomAccessCollection>(
+  in elements: C,
+  from start: C.Index,
+  by areInIncreasingOrder: (C.Element, C.Element) throws -> Bool
+) rethrows -> (end: C.Index, descending: Bool) {
+  _sanityCheck(start < elements.endIndex)
+
+  var previous = start
+  var current = elements.index(after: start)
+  guard current < elements.endIndex else {
+    // This is a one-element run, so treating it as ascending saves a
+    // meaningless call to `reverse()`.
+    return (current, false)
+  }
+
+  // Check whether the run beginning at `start` is ascending or descending.
+  // An ascending run can include consecutive equal elements, but because a
+  // descending run will be reversed, it must be strictly descending.
+  let isDescending =
+    try areInIncreasingOrder(elements[current], elements[previous])
+  
+  // Advance `current` until there's a break in the ascending / descending
+  // pattern.
+  repeat {
+    previous = current
+    elements.formIndex(after: &current)
+  } while try current < elements.endIndex &&
+    isDescending == areInIncreasingOrder(elements[current], elements[previous])
+    
+  return(current, isDescending)
+}
+
+extension UnsafeMutableBufferPointer {
+  /// Merges the elements at `runs[i]` and `runs[i - 1]`, using `buffer` as
+  /// out-of-place storage.
+  ///
+  /// - Precondition: `runs.count > 1` and `i > 0`
+  /// - Precondition: `buffer` must have at least
+  ///   `min(runs[i].count, runs[i - 1].count)` uninitialized elements.
+  @inlinable
+  public mutating func _mergeRuns(
+    _ runs: inout [Range<Index>],
+    at i: Int,
+    buffer: UnsafeMutablePointer<Element>,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool
+  ) rethrows -> Bool {
+    _sanityCheck(runs[i - 1].upperBound == runs[i].lowerBound)
+    let low = runs[i - 1].lowerBound
+    let middle = runs[i].lowerBound
+    let high = runs[i].upperBound
+    
+    let result = try _merge(
+      low: baseAddress! + low,
+      mid: baseAddress! + middle,
+      high: baseAddress! + high,
+      buffer: buffer,
+      by: areInIncreasingOrder)
+    
+    runs[i - 1] = low..<high
+    runs.remove(at: i)
+
+    // FIXME: Remove this, it works around rdar://problem/45044610
+    return result
+  }
+  
+  /// Merges upper elements of `runs` until the required invariants are
+  /// satisfied.
+  ///
+  /// - Precondition: `buffer` must have at least
+  ///   `min(runs[i].count, runs[i - 1].count)` uninitialized elements.
+  /// - Precondition: The ranges in `runs` must be consecutive, such that for
+  ///   any i, `runs[i].upperBound == runs[i + 1].lowerBound`.
+  @inlinable
+  public mutating func _mergeTopRuns(
+    _ runs: inout [Range<Index>],
+    buffer: UnsafeMutablePointer<Element>,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool
+  ) rethrows -> Bool {
+    // The invariants for the `runs` array are:
+    // (a) - for all i in 2..<runs.count:
+    //         - runs[i - 2].count > runs[i - 1].count + runs[i].count
+    // (b) - for c = runs.count - 1:
+    //         - runs[i - 1].count > runs[i].count
+    //
+    // Loop until the invariant is satisified for the top four elements of
+    // `runs`. Because this method is called for every added run, and only
+    // the top three runs are ever merged, this guarantees the invariant holds
+    // for the whole array.
+    //
+    // At all times, `runs` is one of the following, where W, X, Y, and Z are
+    // the counts of their respective ranges:
+    // - [ ...?, W, X, Y, Z ]
+    // - [ X, Y, Z ]
+    // - [ Y, Z ]
+    //
+    // If W > X + Y, X > Y + Z, and Y > Z, then the invariants are satisfied
+    // for the entirety of `runs`.
+    
+    // FIXME: Remove this, it works around rdar://problem/45044610
+    var result = true
+
+    // The invariant is always in place for a single element.
+    while runs.count > 1 {
+      var lastIndex = runs.count - 1
+      
+      // Check for the three invariant-breaking conditions, and break out of
+      // the while loop if none are met.
+      if lastIndex >= 3 &&
+        (runs[lastIndex - 3].count <=
+          runs[lastIndex - 2].count + runs[lastIndex - 1].count)
+      {
+        // Second-to-last three runs do not follow W > X + Y.
+        // Always merge Y with the smaller of X or Z.
+        if runs[lastIndex - 2].count < runs[lastIndex].count {
+          lastIndex -= 1
+        }
+      } else if lastIndex >= 2 &&
+        (runs[lastIndex - 2].count <=
+          runs[lastIndex - 1].count + runs[lastIndex].count)
+      {
+        // Last three runs do not follow X > Y + Z.
+        // Always merge Y with the smaller of X or Z.
+        if runs[lastIndex - 2].count < runs[lastIndex].count {
+          lastIndex -= 1
+        }
+      } else if runs[lastIndex - 1].count <= runs[lastIndex].count {
+        // Last two runs do not follow Y > Z, so merge Y and Z.
+        // This block is intentionally blank--the merge happens below.
+      } else {
+        // All invariants satisfied!
         break
       }
+      
+      // Merge the runs at `i` and `i - 1`.
+      result = try result && _mergeRuns(
+        &runs, at: lastIndex, buffer: buffer, by: areInIncreasingOrder)
     }
-  }
 
+    return result
+  }
+  
+  /// Merges elements of `runs` until only one run remains.
+  ///
+  /// - Precondition: `buffer` must have at least
+  ///   `min(runs[i].count, runs[i - 1].count)` uninitialized elements.
+  /// - Precondition: The ranges in `runs` must be consecutive, such that for
+  ///   any i, `runs[i].upperBound == runs[i + 1].lowerBound`.
   @inlinable
-  internal mutating func _heapify(
-    within range: Range<Index>, 
+  public mutating func _finalizeRuns(
+    _ runs: inout [Range<Index>],
+    buffer: UnsafeMutablePointer<Element>,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool
+  ) rethrows -> Bool {
+    // FIXME: Remove this, it works around rdar://problem/45044610
+    var result = true
+    while runs.count > 1 {
+      result = try result && _mergeRuns(
+        &runs, at: runs.count - 1, buffer: buffer, by: areInIncreasingOrder)
+    }
+    return result
+  }
+  
+  /// Sorts the elements of this buffer according to `areInIncreasingOrder`,
+  /// using a stable, adaptive merge sort.
+  ///
+  /// The adaptive algorithm used is Timsort, modified to perform a straight
+  /// merge of the elements using a temporary buffer.
+  @inlinable
+  public mutating func _stableSortImpl(
     by areInIncreasingOrder: (Element, Element) throws -> Bool
   ) rethrows {
-    // Here we build a heap starting from the lowest nodes and moving to the
-    // root. On every step we sift down the current node to obey the max-heap
-    // property:
-    //   parent >= max(leftChild, rightChild)
+    let minimumRunLength = _minimumMergeRunLength(count)
+    if count <= minimumRunLength {
+      try _insertionSort(
+        within: startIndex..<endIndex, by: areInIncreasingOrder)
+      return
+    }
+
+    // FIXME: Remove this, it works around rdar://problem/45044610
+    var result = true
+
+    // Use array's allocating initializer to create a temporary buffer---this
+    // keeps the buffer allocation going through the same tail-allocated path
+    // as other allocating methods.
     //
-    // We skip the rightmost half of the array, because these nodes don't have
-    // any children.
-    let root = range.lowerBound
-    let half = distance(from: range.lowerBound, to: range.upperBound) / 2
-    var node = index(root, offsetBy: half)
-
-    while node != root {
-      formIndex(before: &node)
-      try _siftDown(node, within: range, by: areInIncreasingOrder)
+    // There's no need to set the initialized count within the initializing
+    // closure, since the buffer is guaranteed to be uninitialized at exit.
+    _ = try Array<Element>(_unsafeUninitializedCapacity: count / 2) {
+      buffer, _ in
+      var runs: [Range<Index>] = []
+      
+      var start = startIndex
+      while start < endIndex {
+        // Find the next consecutive run, reversing it if necessary.
+        var (end, descending) =
+          try _findNextRun(in: self, from: start, by: areInIncreasingOrder)
+        if descending {
+          _reverse(within: start..<end)
+        }
+        
+        // If the current run is shorter than the minimum length, use the
+        // insertion sort to extend it.
+        if end < endIndex && end - start < minimumRunLength {
+          let newEnd = Swift.min(endIndex, start + minimumRunLength)
+          try _insertionSort(
+            within: start..<newEnd, sortedEnd: end, by: areInIncreasingOrder)
+          end = newEnd
+        }
+        
+        // Append this run and merge down as needed to maintain the `runs`
+        // invariants.
+        runs.append(start..<end)
+        result = try result && _mergeTopRuns(
+          &runs, buffer: buffer.baseAddress!, by: areInIncreasingOrder)
+        start = end
+      }
+      
+      result = try result && _finalizeRuns(
+        &runs, buffer: buffer.baseAddress!, by: areInIncreasingOrder)
+      assert(runs.count == 1, "Didn't complete final merge")
     }
-  }
 
-  @inlinable
-  public // @testable
-  mutating func _heapSort(
-    within range: Range<Index>,
-    by areInIncreasingOrder: (Element, Element) throws -> Bool
-  ) rethrows {
-    var hi = range.upperBound
-    let lo = range.lowerBound
-    try _heapify(within: range, by: areInIncreasingOrder)
-    formIndex(before: &hi)
-    while hi != lo {
-      swapAt(lo, hi)
-      try _siftDown(lo, within: lo..<hi, by: areInIncreasingOrder)
-      formIndex(before: &hi)
-    }
+    // FIXME: Remove this, it works around rdar://problem/45044610
+    precondition(result)
   }
 }
diff --git a/stdlib/public/core/StringBridge.swift b/stdlib/public/core/StringBridge.swift
index f7c9cd8..99d22e1 100644
--- a/stdlib/public/core/StringBridge.swift
+++ b/stdlib/public/core/StringBridge.swift
@@ -12,14 +12,15 @@
 
 import SwiftShims
 
+/// Effectively an untyped NSString that doesn't require foundation.
+@usableFromInline
+internal typealias _CocoaString = AnyObject
+
 #if _runtime(_ObjC)
 // Swift's String bridges NSString via this protocol and these
 // variables, allowing the core stdlib to remain decoupled from
 // Foundation.
 
-/// Effectively an untyped NSString that doesn't require foundation.
-public typealias _CocoaString = AnyObject
-
 @usableFromInline // @testable
 @_effects(releasenone)
 internal func _stdlib_binary_CFStringCreateCopy(
@@ -68,6 +69,30 @@
   return _swift_stdlib_CFStringGetCharacterAtIndex(cfSelf, position)
 }
 
+@_effects(readonly)
+internal func _cocoaStringCompare(
+  _ string: _CocoaString, _ other: _CocoaString
+) -> Int {
+  let cfSelf: _swift_shims_CFStringRef = string
+  let cfOther: _swift_shims_CFStringRef = other
+  return _swift_stdlib_CFStringCompare(cfSelf, cfOther)
+}
+
+@_effects(readonly)
+internal func _cocoaHashString(
+  _ string: _CocoaString
+  ) -> UInt {
+  return _swift_stdlib_CFStringHashNSString(string)
+}
+
+@_effects(readonly)
+internal func _cocoaHashASCIIBytes(
+  _ bytes: UnsafePointer<UInt8>,
+  length: Int
+  ) -> UInt {
+  return _swift_stdlib_CFStringHashCString(bytes, length)
+}
+
 //
 // Conversion from NSString to Swift's native representation
 //
@@ -224,36 +249,6 @@
   deinit {}
 }
 
-/// A shadow for the "core operations" of NSString.
-///
-/// Covers a set of operations everyone needs to implement in order to
-/// be a useful `NSString` subclass.
-@objc
-public protocol _NSStringCore : _NSCopying /* _NSFastEnumeration */ {
-
-  // The following methods should be overridden when implementing an
-  // NSString subclass.
-
-  @objc(length)
-  var length: Int { get }
-
-  @objc(characterAtIndex:)
-  func character(at index: Int) -> UInt16
-
- // We also override the following methods for efficiency.
-
-  @objc(getCharacters:range:)
-  func getCharacters(
-   _ buffer: UnsafeMutablePointer<UInt16>,
-   range aRange: _SwiftNSRange)
-
-  @objc(_fastCharacterContents)
-  func _fastCharacterContents() -> UnsafePointer<UInt16>?
-
-  @objc(_fastCStringContents)
-  func _fastCStringContents() -> UnsafePointer<CChar>?
-}
-
 // Called by the SwiftObject implementation to get the description of a value
 // as an NSString.
 @_silgen_name("swift_stdlib_getDescription")
@@ -263,15 +258,11 @@
 
 #else // !_runtime(_ObjC)
 
-@_fixed_layout // FIXME(sil-serialize-all)
-public class __SwiftNativeNSString {
-  @usableFromInline // FIXME(sil-serialize-all)
+internal class __SwiftNativeNSString {
   internal init() {}
   deinit {}
 }
 
-public protocol _NSStringCore: class {}
-
 #endif
 
 // Special-case Index <-> Offset converters for bridging and use in accelerating
diff --git a/stdlib/public/core/StringCharacterView.swift b/stdlib/public/core/StringCharacterView.swift
index 4dad60c..96c4c2a 100644
--- a/stdlib/public/core/StringCharacterView.swift
+++ b/stdlib/public/core/StringCharacterView.swift
@@ -50,6 +50,7 @@
   }
 
   /// The number of characters in a string.
+  @inlinable
   public var count: Int {
     @inline(__always) get {
       return distance(from: startIndex, to: endIndex)
@@ -197,16 +198,8 @@
 
       let i = _guts.scalarAlign(i)
       let distance = _characterStride(startingAt: i)
-
-      if _fastPath(_guts.isFastUTF8) {
-        let start = i.encodedOffset
-        let end = start + distance
-        return _guts.withFastUTF8(range: start..<end) { utf8 in
-          return Character(unchecked: String._uncheckedFromUTF8(utf8))
-        }
-      }
-
-      return _foreignSubscript(position: i, distance: distance)
+      return _guts.errorCorrectedCharacter(
+        startingAt: i.encodedOffset, endingAt: i.encodedOffset &+ distance)
     }
   }
 
@@ -228,40 +221,40 @@
   }
 }
 
-// Foreign string support
 extension String {
-  @usableFromInline @inline(never)
-  @_effects(releasenone)
-  internal func _foreignSubscript(position: Index, distance: Int) -> Character {
-#if _runtime(_ObjC)
-    _sanityCheck(_guts.isForeign)
+  @_fixed_layout
+  public struct Iterator: IteratorProtocol {
+    @usableFromInline
+    internal var _guts: _StringGuts
 
-    // Both a fast-path for single-code-unit graphemes and validation:
-    //   ICU treats isolated surrogates as isolated graphemes
-    if distance == 1 {
-      return Character(
-        String(_guts.foreignErrorCorrectedScalar(startingAt: position).0))
+    @usableFromInline
+    internal var _position: Int = 0
+
+    @usableFromInline
+    internal var _end: Int
+
+    @inlinable
+    internal init(_ guts: _StringGuts) {
+      self._guts = guts
+      self._end = guts.count
     }
 
-    let start = position.encodedOffset
-    let end = start + distance
-    let count = end - start
+    @inlinable
+    public mutating func next() -> Character? {
+      guard _fastPath(_position < _end) else { return nil }
 
-    // TODO(String performance): Stack buffer if small enough
+      let len = _guts._opaqueCharacterStride(startingAt: _position)
+      let nextPosition = _position &+ len
+      let result = _guts.errorCorrectedCharacter(
+        startingAt: _position, endingAt: nextPosition)
+      _position = nextPosition
+      return result
+    }
+  }
 
-    var cus = Array<UInt16>(repeating: 0, count: count)
-    cus.withUnsafeMutableBufferPointer {
-      _cocoaStringCopyCharacters(
-        from: _guts._object.cocoaObject,
-        range: start..<end,
-        into: $0.baseAddress._unsafelyUnwrappedUnchecked)
-    }
-    return cus.withUnsafeBufferPointer {
-      return Character(String._uncheckedFromUTF16($0))
-    }
-#else
-    fatalError("No foreign strings on Linux in this version of Swift")
-#endif
+  @inlinable
+  public __consuming func makeIterator() -> Iterator {
+    return Iterator(_guts)
   }
 }
 
diff --git a/stdlib/public/core/StringGuts.swift b/stdlib/public/core/StringGuts.swift
index 74d4e7a..e51299e 100644
--- a/stdlib/public/core/StringGuts.swift
+++ b/stdlib/public/core/StringGuts.swift
@@ -55,7 +55,7 @@
     self.init(_StringObject(immortal: bufPtr, isASCII: isASCII))
   }
 
-  @inlinable @inline(__always)
+  @inline(__always)
   internal init(_ storage: _StringStorage) {
     self.init(_StringObject(storage))
   }
diff --git a/stdlib/public/core/StringGutsRangeReplaceable.swift b/stdlib/public/core/StringGutsRangeReplaceable.swift
index d98497f..012c5b6 100644
--- a/stdlib/public/core/StringGutsRangeReplaceable.swift
+++ b/stdlib/public/core/StringGutsRangeReplaceable.swift
@@ -40,7 +40,7 @@
     }
   }
 
-  @usableFromInline // @testable
+  @inlinable // @testable
   internal var isUniqueNative: Bool {
     @inline(__always) mutating get {
       // Note: mutating so that self is `inout`.
diff --git a/stdlib/public/core/StringLegacy.swift b/stdlib/public/core/StringLegacy.swift
index 976d821..6d5bf58 100644
--- a/stdlib/public/core/StringLegacy.swift
+++ b/stdlib/public/core/StringLegacy.swift
@@ -181,7 +181,6 @@
   ///   - uppercase: Pass `true` to use uppercase letters to represent numerals
   ///     greater than 9, or `false` to use lowercase letters. The default is
   ///     `false`.
-  @inlinable // FIXME(sil-serialize-all)
   public init<T : BinaryInteger>(
     _ value: T, radix: Int = 10, uppercase: Bool = false
   ) {
diff --git a/stdlib/public/core/StringObject.swift b/stdlib/public/core/StringObject.swift
index 5e4bad6..2c92d42 100644
--- a/stdlib/public/core/StringObject.swift
+++ b/stdlib/public/core/StringObject.swift
@@ -81,7 +81,7 @@
   @usableFromInline @_frozen
   internal enum Variant {
     case immortal(UInt)
-    case native(_AbstractStringStorage)
+    case native(AnyObject)
     case bridged(_CocoaString)
 
     @inlinable @inline(__always)
@@ -1029,7 +1029,6 @@
     }
   }
 
-  @inlinable
   internal var nativeStorage: _StringStorage {
     @inline(__always) get {
 #if arch(i386) || arch(arm)
@@ -1187,7 +1186,7 @@
 #endif
   }
 
-  @inlinable @inline(__always)
+  @inline(__always)
   internal init(_ storage: _StringStorage) {
 #if arch(i386) || arch(arm)
     self.init(
diff --git a/stdlib/public/core/StringStorage.swift b/stdlib/public/core/StringStorage.swift
index 6964f6a..4dec7e5 100644
--- a/stdlib/public/core/StringStorage.swift
+++ b/stdlib/public/core/StringStorage.swift
@@ -12,66 +12,19 @@
 
 import SwiftShims
 
-@_fixed_layout
-@usableFromInline
-internal class _AbstractStringStorage: __SwiftNativeNSString, _NSStringCore {
-  // Abstract interface
-  internal var asString: String { get { Builtin.unreachable() } }
-  internal var count: Int { get { Builtin.unreachable() } }
-  internal func getOrComputeBreadcrumbs() -> _StringBreadcrumbs {
-    Builtin.unreachable()
-  }
-}
-
-// ObjC interfaces
 #if _runtime(_ObjC)
-extension _AbstractStringStorage {
-  @objc(length)
-  final internal var length: Int { return asString.utf16.count }
 
-  @objc(characterAtIndex:)
-  final internal func character(at offset: Int) -> UInt16 {
-    let str = asString
-    return str.utf16[str._toUTF16Index(offset)]
-  }
-
-  @objc(getCharacters:range:)
-  final internal func getCharacters(
-   _ buffer: UnsafeMutablePointer<UInt16>,
-   range aRange: _SwiftNSRange) {
-    _precondition(aRange.location >= 0 && aRange.length >= 0,
-      "Range out of bounds")
-    _precondition(aRange.location + aRange.length <= Int(count),
-      "Range out of bounds")
-
-    let range = Range(
-      uncheckedBounds: (aRange.location, aRange.location+aRange.length))
-    let str = asString
-    str._copyUTF16CodeUnits(
-      into: UnsafeMutableBufferPointer(start: buffer, count: range.count),
-      range: range)
-  }
-
-  @objc(_fastCharacterContents)
-  final internal func _fastCharacterContents() -> UnsafePointer<UInt16>? {
-    return nil
-  }
-
-  @objc(_fastCStringContents)
-  final internal func _fastCStringContents() -> UnsafePointer<CChar>? {
-    if let native = self as? _StringStorage, native.isASCII {
-      return native.start._asCChar
-    }
-
-    // TODO(String performance): Check for nul-terminated shared strings, which
-    // could be from bridged literals two/from ObjC (alternatively: reconsider
-    // our bridging model for literals).
-
-    return nil
-  }
-
+internal class _AbstractStringStorage: __SwiftNativeNSString, _NSCopying {
+  // Abstract interface
+  internal var asGuts: _StringGuts { @_effects(readonly) get { Builtin.unreachable() } }
+  final internal var asString: String { @_effects(readonly) get { return String(asGuts) } }
+  internal var count: Int { @_effects(readonly) get { Builtin.unreachable() } }
+  
+  //Having these in an extension creates an ObjC category, which we don't want
+  //in UTF16 code units
+  @objc(length) internal var length: Int { @_effects(readonly) get { Builtin.unreachable() } }
+  
   @objc(copyWithZone:)
-  @usableFromInline
   final internal func copy(with zone: _SwiftNSZone?) -> AnyObject {
     // While _StringStorage instances aren't immutable in general,
     // mutations may only occur when instances are uniquely referenced.
@@ -80,6 +33,107 @@
     return self
   }
 }
+
+#else
+
+internal class _AbstractStringStorage: __SwiftNativeNSString {
+  // Abstract interface
+  internal var asGuts: _StringGuts { @_effects(readonly) get { Builtin.unreachable() } }
+  final internal var asString: String { @_effects(readonly) get { return String(asGuts) } }
+  internal var count: Int { @_effects(readonly) get { Builtin.unreachable() } }
+}
+
+#endif
+
+// ObjC interfaces
+#if _runtime(_ObjC)
+
+@inline(__always)
+@_effects(releasenone)
+private func _getCharacters<T:_AbstractStringStorage>(_ this:T,
+   _ buffer: UnsafeMutablePointer<UInt16>,
+   _ aRange: _SwiftNSRange) {
+  _precondition(aRange.location >= 0 && aRange.length >= 0,
+    "Range out of bounds")
+  _precondition(aRange.location + aRange.length <= Int(this.count),
+    "Range out of bounds")
+
+  let range = Range(
+    uncheckedBounds: (aRange.location, aRange.location+aRange.length))
+  let str = this.asString
+  str._copyUTF16CodeUnits(
+    into: UnsafeMutableBufferPointer(start: buffer, count: range.count),
+    range: range)
+}
+
+@inline(never) //hide the shim call so we can use @_effects
+@_effects(readonly)
+private func _isNSString(_ str:AnyObject) -> UInt8 {
+  return _swift_stdlib_isNSString(str)
+}
+
+//This used to be on _AbstractStringStorage, which meant it went through the
+//dynamic version of asString.
+//Making it generic and calling it from the subclasses lets us avoid that.
+@_effects(readonly)
+private func _isEqual<T:_AbstractStringStorage>(_ this:T, _ other:AnyObject?)
+  -> Int8 {
+  guard let other = other else {
+    return 0
+  }
+
+  if this === other {
+    return 1
+  }
+ 
+  let ourGuts = this.asGuts
+  defer { _fixLifetime(ourGuts) }
+
+  //Handle the case where both strings were bridged from Swift.
+  //We can't use String.== because it doesn't match NSString semantics.
+  if let otherGuts = (other as? _AbstractStringStorage)?.asGuts {
+    if otherGuts.count != ourGuts.count {
+      return 0
+    }
+    return ourGuts.withFastUTF8 { ourBytes in
+      return otherGuts.withFastUTF8 { otherBytes in
+        return (ourBytes.baseAddress == otherBytes.baseAddress ||
+          (memcmp(ourBytes.baseAddress!, otherBytes.baseAddress!, ourBytes.count) == 0)) ? 1 : 0
+      }
+    }
+  }
+  
+  //we're allowed to crash, but for compatibility reasons NSCFString allows non-strings here
+  if _isNSString(other) != 1 {
+    return 0
+  }
+  
+  //At this point we've proven that it is an NSString of some sort, but not one of ours
+  if this.length != _stdlib_binary_CFStringGetLength(other) {
+    return 0
+  }
+  
+  defer {
+    _fixLifetime(other)
+  }
+
+  //CFString will only give us ASCII bytes here, but that's fine
+  //We already handled non-ASCII UTF8 strings earlier since they're Swift
+  if let otherBytes = _cocoaUTF8Pointer(other) {
+    return ourGuts.withFastUTF8 { ourBytes in
+      return (ourBytes.baseAddress == otherBytes ||
+        (memcmp(ourBytes.baseAddress!, otherBytes, ourBytes.count) == 0)) ? 1 : 0
+    }
+  }
+  
+  /*
+  The abstract implementation of -isEqualToString: falls back to -compare:
+  immediately, so when we run out of fast options to try, do the same.
+  We can likely be more clever here if need be
+  */
+  return _cocoaStringCompare(this, other) == 0 ? 1 : 0
+}
+
 #endif // _runtime(_ObjC)
 
 #if arch(i386) || arch(arm)
@@ -93,19 +147,14 @@
 // Optional<_StringBreadcrumbs>.
 //
 
-@_fixed_layout
-@usableFromInline
 final internal class _StringStorage: _AbstractStringStorage {
 #if arch(i386) || arch(arm)
   // The total allocated storage capacity. Note that this includes the required
   // nul-terminator
-  @usableFromInline
   internal var _realCapacity: Int
 
-  @usableFromInline
   internal var _count: Int
 
-  @usableFromInline
   internal var _flags: _StringObject.Flags
 
   internal var _reserved: UInt16
@@ -118,13 +167,10 @@
 #else
   // The capacity of our allocation. Note that this includes the nul-terminator,
   // which is not available for overridding.
-  @usableFromInline
   internal var _realCapacityAndFlags: UInt64
 
-  @usableFromInline
   internal var _countAndFlags: _StringObject.CountAndFlags
 
-  @inlinable
   override internal var count: Int {
     @inline(__always) get { return _countAndFlags.count }
     @inline(__always) set { _countAndFlags.count = newValue }
@@ -140,10 +186,76 @@
   }
 #endif
 
-  override internal var asString: String {
-    @inline(__always) get { return String(_StringGuts(self)) }
+  override final internal var asGuts: _StringGuts {
+    @inline(__always) @_effects(readonly) get {
+      return _StringGuts(self)
+    }
   }
 
+#if _runtime(_ObjC)
+  
+  @objc(length)
+  override final internal var length: Int {
+    @_effects(readonly) @inline(__always) get {
+      if isASCII {
+        return count
+      }
+      return asString.utf16.count
+    }
+  }
+
+  @objc final internal var hash: UInt {
+    @_effects(readonly) get {
+      if isASCII {
+        return _cocoaHashASCIIBytes(start, length: count)
+      }
+      return _cocoaHashString(self)
+    }
+  }
+
+  @objc(characterAtIndex:)
+  @_effects(readonly)
+  final internal func character(at offset: Int) -> UInt16 {
+    let str = asString
+    return str.utf16[str._toUTF16Index(offset)]
+  }
+
+  @objc(getCharacters:range:)
+  @_effects(releasenone)
+  final internal func getCharacters(
+   _ buffer: UnsafeMutablePointer<UInt16>,
+   range aRange: _SwiftNSRange) {
+    _getCharacters(self, buffer, aRange)
+  }
+
+  @objc(_fastCStringContents:)
+  @_effects(readonly)
+  final internal func _fastCStringContents(_ requiresNulTermination:Int8) -> UnsafePointer<CChar>? {
+    if isASCII {
+      return start._asCChar
+    }
+
+    return nil
+  }
+
+  @objc
+  final internal var fastestEncoding: Int {
+    @_effects(readonly) get {
+      if isASCII {
+        return 1 /* NSASCIIStringEncoding */
+      }
+      return 4 /* NSUTF8StringEncoding */
+    }
+  }
+
+  @objc(isEqualToString:)
+  @_effects(readonly)
+  final internal func isEqual(to other:AnyObject?) -> Int8 {
+    return _isEqual(self, other)
+  }
+
+#endif // _runtime(_ObjC)
+
   private init(_doNotCallMe: ()) {
     _sanityCheckFailure("Use the create method")
   }
@@ -187,7 +299,6 @@
 
 // Creation
 extension _StringStorage {
-  @inline(never) // rdar://problem/44542202
   @_effects(releasenone)
   private static func create(
     realCodeUnitCapacity: Int, countAndFlags: CountAndFlags
@@ -545,8 +656,85 @@
     super.init()
     self._invariantCheck()
   }
+  
+  fileprivate var isASCII: Bool {
+    #if arch(i386) || arch(arm)
+    return _flags.isASCII
+    #else
+    return _countAndFlags.isASCII
+    #endif
+  }
 
-  override internal var asString: String { return String(_StringGuts(self)) }
+  override final internal var asGuts: _StringGuts {
+    @_effects(readonly) get {
+      return _StringGuts(self)
+    }
+  }
+
+#if _runtime(_ObjC)
+  
+  @objc(length)
+  override final internal var length: Int {
+    @_effects(readonly) get {
+      if isASCII {
+        return count
+      }
+      return asString.utf16.count
+    }
+  }
+  
+  @objc final internal var hash: UInt {
+    @_effects(readonly) get {
+      if isASCII {
+        return _cocoaHashASCIIBytes(start, length: count)
+      }
+      return _cocoaHashString(self)
+    }
+  }
+  
+  @objc(characterAtIndex:)
+  @_effects(readonly)
+  final internal func character(at offset: Int) -> UInt16 {
+    let str = asString
+    return str.utf16[str._toUTF16Index(offset)]
+  }
+  
+  @objc(getCharacters:range:)
+  @_effects(releasenone)
+  final internal func getCharacters(
+    _ buffer: UnsafeMutablePointer<UInt16>,
+    range aRange: _SwiftNSRange) {
+    _getCharacters(self, buffer, aRange)
+  }
+  
+  @objc
+  final internal var fastestEncoding: Int {
+    @_effects(readonly) get {
+      if isASCII {
+        return 1 /* NSASCIIStringEncoding */
+      }
+      return 4 /* NSUTF8StringEncoding */
+    }
+  }
+  
+  @objc(_fastCStringContents:)
+  @_effects(readonly)
+  final internal func _fastCStringContents(_ requiresNulTermination:Int8) -> UnsafePointer<CChar>? {
+    if isASCII {
+      return start._asCChar
+    }
+    
+    return nil
+  }
+
+  @objc(isEqualToString:)
+  @_effects(readonly)
+  final internal func isEqual(to other:AnyObject?) -> Int8 {
+    return _isEqual(self, other)
+  }
+
+#endif // _runtime(_ObjC)
+
 }
 
 extension _SharedStringStorage {
diff --git a/stdlib/public/core/StringSwitch.swift b/stdlib/public/core/StringSwitch.swift
index 6f8cf4c..28cab78 100644
--- a/stdlib/public/core/StringSwitch.swift
+++ b/stdlib/public/core/StringSwitch.swift
@@ -39,13 +39,9 @@
   var b: Builtin.Word
 }
 
-@usableFromInline // FIXME(sil-serialize-all)
 internal typealias _StringSwitchCache = Dictionary<String, Int>
 
-@_fixed_layout // FIXME(sil-serialize-all)
-@usableFromInline // FIXME(sil-serialize-all)
 internal struct _StringSwitchContext {
-  @inlinable // FIXME(sil-serialize-all)
   internal init(
     cases: [StaticString],
     cachePtr: UnsafeMutablePointer<_StringSwitchCache>
@@ -54,9 +50,7 @@
     self.cachePtr = cachePtr
   }
 
-  @usableFromInline // FIXME(sil-serialize-all)
   internal let cases: [StaticString]
-  @usableFromInline // FIXME(sil-serialize-all)
   internal let cachePtr: UnsafeMutablePointer<_StringSwitchCache>
 }
 
@@ -94,7 +88,6 @@
 }
 
 /// Builds the string switch case.
-@inlinable // FIXME(sil-serialize-all)
 internal func _createStringTableCache(_ cacheRawPtr: Builtin.RawPointer) {
   let context = UnsafePointer<_StringSwitchContext>(cacheRawPtr).pointee
   var cache = _StringSwitchCache()
diff --git a/stdlib/public/core/StringUnicodeScalarView.swift b/stdlib/public/core/StringUnicodeScalarView.swift
index 819bdf4..5a58c20 100644
--- a/stdlib/public/core/StringUnicodeScalarView.swift
+++ b/stdlib/public/core/StringUnicodeScalarView.swift
@@ -161,15 +161,44 @@
     @inline(__always) get {
       String(_guts)._boundsCheck(position)
       let i = _guts.scalarAlign(position)
-      if _fastPath(_guts.isFastUTF8) {
-        return _guts.fastUTF8Scalar(startingAt: i.encodedOffset)
-      }
-
-      return _foreignSubscript(aligned: i)
+      return _guts.errorCorrectedScalar(startingAt: i.encodedOffset).0
     }
   }
 }
 
+extension String.UnicodeScalarView {
+  @_fixed_layout
+  public struct Iterator: IteratorProtocol {
+    @usableFromInline
+    internal var _guts: _StringGuts
+
+    @usableFromInline
+    internal var _position: Int = 0
+
+    @usableFromInline
+    internal var _end: Int
+
+    @inlinable
+    internal init(_ guts: _StringGuts) {
+      self._guts = guts
+      self._end = guts.count
+    }
+
+    @inlinable
+    public mutating func next() -> Unicode.Scalar? {
+      guard _fastPath(_position < _end) else { return nil }
+
+      let (result, len) = _guts.errorCorrectedScalar(startingAt: _position)
+      _position &+= len
+      return result
+    }
+  }
+  @inlinable
+  public __consuming func makeIterator() -> Iterator {
+    return Iterator(_guts)
+  }
+}
+
 extension String.UnicodeScalarView: CustomStringConvertible {
  @inlinable
  public var description: String {
@@ -403,14 +432,4 @@
 
     return i.encoded(offsetBy: -len)
   }
-
-  @usableFromInline @inline(never)
-  @_effects(releasenone)
-  internal func _foreignSubscript(aligned i: Index) -> Unicode.Scalar {
-    _sanityCheck(_guts.isForeign)
-    _sanityCheck(_guts.isOnUnicodeScalarBoundary(i),
-      "should of been aligned prior")
-
-    return _guts.foreignErrorCorrectedScalar(startingAt: i).0
-  }
 }
diff --git a/stdlib/public/core/SwiftNativeNSArray.swift b/stdlib/public/core/SwiftNativeNSArray.swift
index 853af62..ff14429 100644
--- a/stdlib/public/core/SwiftNativeNSArray.swift
+++ b/stdlib/public/core/SwiftNativeNSArray.swift
@@ -41,15 +41,15 @@
 /// NOTE: older runtimes called this
 /// _SwiftNativeNSArrayWithContiguousStorage. The two must coexist, so
 /// it was renamed. The old name must not be used in the new runtime.
-@_fixed_layout // FIXME(sil-serialize-all)
+@_fixed_layout
 @usableFromInline
 internal class __SwiftNativeNSArrayWithContiguousStorage
   : __SwiftNativeNSArray { // Provides NSArray inheritance and native refcounting
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @nonobjc internal override init() {}
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   deinit {}
 
   // Operate on our contiguous storage
diff --git a/stdlib/public/core/ThreadLocalStorage.swift b/stdlib/public/core/ThreadLocalStorage.swift
index 6e57cd4..3497217 100644
--- a/stdlib/public/core/ThreadLocalStorage.swift
+++ b/stdlib/public/core/ThreadLocalStorage.swift
@@ -15,8 +15,33 @@
 // For testing purposes, a thread-safe counter to guarantee that destructors get
 // called by pthread.
 #if INTERNAL_CHECKS_ENABLED
+internal class _TLSAtomicInt {
+  internal var value: Int
+  internal init() { self.value = 0 }
+
+  internal var valuePtr: UnsafeMutablePointer<Int> {
+    return _getUnsafePointerToStoredProperties(self).assumingMemoryBound(
+      to: Int.self)
+  }
+
+  internal func increment() {
+    _ = _swift_stdlib_atomicFetchAddInt(
+      object: valuePtr,
+      operand: 1)
+  }
+
+  internal func load() -> Int {
+    return _swift_stdlib_atomicLoadInt(object: valuePtr)
+  }
+}
+
+internal let _destroyTLSCounter = _TLSAtomicInt()
+
 public // @testable
-let _destroyTLSCounter = _stdlib_AtomicInt()
+func _loadDestroyTLSCounter() -> Int {
+  return _destroyTLSCounter.load()
+}
+
 #endif
 
 // Thread local storage for all of the Swift standard library
@@ -124,7 +149,7 @@
 
 #if INTERNAL_CHECKS_ENABLED
   // Log the fact we've destroyed our storage
-  _destroyTLSCounter.fetchAndAdd(1)
+  _destroyTLSCounter.increment()
 #endif
 }
 
diff --git a/stdlib/public/core/Unicode.swift b/stdlib/public/core/Unicode.swift
index 5e3efd6..acd2eb8 100644
--- a/stdlib/public/core/Unicode.swift
+++ b/stdlib/public/core/Unicode.swift
@@ -478,13 +478,6 @@
   public mutating func decode<I : IteratorProtocol>(
     _ input: inout I
   ) -> UnicodeDecodingResult where I.Element == CodeUnit {
-    return UTF32._decode(&input)
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  internal static func _decode<I : IteratorProtocol>(
-    _ input: inout I
-  ) -> UnicodeDecodingResult where I.Element == CodeUnit {
     var parser = ForwardParser()
     
     switch parser.parseScalar(from: &input) {
diff --git a/stdlib/public/core/UnicodeHelpers.swift b/stdlib/public/core/UnicodeHelpers.swift
index 071fd80..dc66ece 100644
--- a/stdlib/public/core/UnicodeHelpers.swift
+++ b/stdlib/public/core/UnicodeHelpers.swift
@@ -172,7 +172,7 @@
 // Scalar helpers
 //
 extension _StringGuts {
-  @usableFromInline @inline(__always) // fast-path: fold common fastUTF8 check
+  @inlinable @inline(__always) // fast-path: fold common fastUTF8 check
   internal func scalarAlign(_ idx: Index) -> Index {
     // TODO(String performance): isASCII check
 
@@ -262,6 +262,7 @@
 #endif
   }
 
+  @usableFromInline
   @_effects(releasenone)
   internal func foreignErrorCorrectedScalar(
     startingAt idx: String.Index
@@ -374,4 +375,65 @@
       "Error-correction shouldn't give trailing surrogate at position zero")
     return String.Index(encodedOffset: idx.encodedOffset &- 1)
   }
+
+  @usableFromInline @inline(never)
+  @_effects(releasenone)
+  internal func foreignErrorCorrectedGrapheme(
+    startingAt start: Int, endingAt end: Int
+  ) -> Character {
+#if _runtime(_ObjC)
+    _sanityCheck(self.isForeign)
+
+    // Both a fast-path for single-code-unit graphemes and validation:
+    //   ICU treats isolated surrogates as isolated graphemes
+    let count = end &- start
+    if start &- end == 1 {
+      return Character(String(self.foreignErrorCorrectedScalar(
+        startingAt: String.Index(encodedOffset: start)
+      ).0))
+    }
+
+    // TODO(String performance): Stack buffer if small enough
+    var cus = Array<UInt16>(repeating: 0, count: count)
+    cus.withUnsafeMutableBufferPointer {
+      _cocoaStringCopyCharacters(
+        from: self._object.cocoaObject,
+        range: start..<end,
+        into: $0.baseAddress._unsafelyUnwrappedUnchecked)
+    }
+    return cus.withUnsafeBufferPointer {
+      return Character(String._uncheckedFromUTF16($0))
+    }
+#else
+    fatalError("No foreign strings on Linux in this version of Swift")
+#endif
+  }
+}
+
+// Higher level aggregate operations. These should only be called when the
+// result is the sole operation done by a caller, otherwise it's always more
+// efficient to use `withFastUTF8` in the caller.
+extension _StringGuts {
+  @inlinable @inline(__always)
+  internal func errorCorrectedScalar(
+    startingAt i: Int
+  ) -> (Unicode.Scalar, scalarLength: Int) {
+    if _fastPath(isFastUTF8) {
+      return withFastUTF8 { _decodeScalar($0, startingAt: i) }
+    }
+    return foreignErrorCorrectedScalar(
+      startingAt: String.Index(encodedOffset: i))
+  }
+  @inlinable @inline(__always)
+  internal func errorCorrectedCharacter(
+    startingAt start: Int, endingAt end: Int
+  ) -> Character {
+    if _fastPath(isFastUTF8) {
+      return withFastUTF8(range: start..<end) { utf8 in
+        return Character(unchecked: String._uncheckedFromUTF8(utf8))
+      }
+    }
+
+    return foreignErrorCorrectedGrapheme(startingAt: start, endingAt: end)
+  }
 }
diff --git a/stdlib/public/core/UnicodeParser.swift b/stdlib/public/core/UnicodeParser.swift
index 444a633..9d17dae 100644
--- a/stdlib/public/core/UnicodeParser.swift
+++ b/stdlib/public/core/UnicodeParser.swift
@@ -57,79 +57,6 @@
   where I.Element == Encoding.CodeUnit
 }
 
-extension _UnicodeParser {
-  @inlinable // FIXME(sil-serialize-all)
-  @inline(__always)
-  @discardableResult
-  internal static func _parse<I: IteratorProtocol>(
-    _ input: inout I,
-    repairingIllFormedSequences makeRepairs: Bool = true,
-    into output: (Encoding.EncodedScalar)->Void
-  ) -> Int
-  where I.Element == Encoding.CodeUnit
-  {
-    var errorCount = 0
-    var d = Self()
-    while true {
-      switch d.parseScalar(from: &input) {
-      case let .valid(scalarContent):
-        output(scalarContent)
-      case .error:
-        if _slowPath(!makeRepairs) { return 1 }
-        errorCount += 1
-        output(Encoding.encodedReplacementCharacter)
-      case .emptyInput:
-        return errorCount
-      }
-    }
-  }
-
-  @inlinable // FIXME(sil-serialize-all)
-  @inline(__always)
-  @discardableResult
-  public static func _decode<I: IteratorProtocol>(
-    _ input: inout I,
-    repairingIllFormedSequences makeRepairs: Bool,
-    into output: (Unicode.Scalar)->Void
-  ) -> Int
-  where I.Element == Encoding.CodeUnit
-  {
-    return _parse(&input, repairingIllFormedSequences: makeRepairs) {
-      output(Encoding.decode($0))
-    }
-  }
-}
-
 extension Unicode {
   public typealias Parser = _UnicodeParser
 }
-
-extension Unicode {
-  @_fixed_layout
-  public // @testable
-  struct _ParsingIterator<
-    CodeUnitIterator : IteratorProtocol, 
-    Parser: Unicode.Parser
-  > where Parser.Encoding.CodeUnit == CodeUnitIterator.Element {
-    @inline(__always)
-    @inlinable
-    public init(codeUnits: CodeUnitIterator, parser: Parser) {
-      self.codeUnits = codeUnits
-      self.parser = parser
-    }
-    public var codeUnits: CodeUnitIterator
-    public var parser: Parser
-  }
-}
-
-extension Unicode._ParsingIterator : IteratorProtocol, Sequence {
-  @inline(__always)
-  @inlinable
-  public mutating func next() -> Parser.Encoding.EncodedScalar? {
-    switch parser.parseScalar(from: &codeUnits) {
-    case let .valid(scalarContent): return scalarContent
-    case .error: return Parser.Encoding.encodedReplacementCharacter
-    case .emptyInput: return nil
-    }
-  }
-}
diff --git a/stdlib/public/core/UnsafeBufferPointer.swift.gyb b/stdlib/public/core/UnsafeBufferPointer.swift.gyb
index 55b13e9..92a56d4 100644
--- a/stdlib/public/core/UnsafeBufferPointer.swift.gyb
+++ b/stdlib/public/core/UnsafeBufferPointer.swift.gyb
@@ -408,6 +408,13 @@
     count = other.count
   }
 
+  @inlinable
+  public mutating func _withUnsafeMutableBufferPointerIfSupported<R>(
+    _ body: (inout UnsafeMutableBufferPointer<Element>) throws -> R
+  ) rethrows -> R? {
+    return try body(&self)
+  }
+
 %  else:
 
   /// Creates an immutable typed buffer pointer referencing the same memory as the 
diff --git a/stdlib/public/runtime/AnyHashableSupport.cpp b/stdlib/public/runtime/AnyHashableSupport.cpp
index 63e8b07..29d4300 100644
--- a/stdlib/public/runtime/AnyHashableSupport.cpp
+++ b/stdlib/public/runtime/AnyHashableSupport.cpp
@@ -70,7 +70,7 @@
 // FIXME(performance): consider merging this cache into the regular
 // protocol conformance cache.
 static ConcurrentMap<HashableConformanceEntry, /*Destructor*/ false>
-HashableConformances;
+  HashableConformances;
 
 template<bool KnownToConformToHashable>
 LLVM_ATTRIBUTE_ALWAYS_INLINE
@@ -80,16 +80,18 @@
           HashableConformances.find(HashableConformanceKey{type})) {
     return entry->baseTypeThatConformsToHashable;
   }
-  if (!KnownToConformToHashable &&
-      !swift_conformsToProtocol(type, &HashableProtocolDescriptor)) {
+
+  auto witnessTable =
+    swift_conformsToProtocol(type, &HashableProtocolDescriptor);
+  if (!KnownToConformToHashable && !witnessTable) {
     // Don't cache the negative response because we don't invalidate
     // this cache when a new conformance is loaded dynamically.
     return nullptr;
   }
   // By this point, `type` is known to conform to `Hashable`.
-
+  const auto *conformance = witnessTable->Description;
   const Metadata *baseTypeThatConformsToHashable =
-    findConformingSuperclass(type, &HashableProtocolDescriptor);
+    findConformingSuperclass(type, conformance);
   HashableConformances.getOrInsert(HashableConformanceKey{type},
                                    baseTypeThatConformsToHashable);
   return baseTypeThatConformsToHashable;
diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt
index 6a6508f..79ca2af 100644
--- a/stdlib/public/runtime/CMakeLists.txt
+++ b/stdlib/public/runtime/CMakeLists.txt
@@ -56,6 +56,7 @@
     ImageInspectionMachO.cpp
     ImageInspectionELF.cpp
     ImageInspectionCOFF.cpp
+    KeyPaths.cpp
     KnownMetadata.cpp
     LLVMSupport.cpp
     Metadata.cpp
diff --git a/stdlib/public/runtime/Enum.cpp b/stdlib/public/runtime/Enum.cpp
index 86f2c1b..83a519a 100644
--- a/stdlib/public/runtime/Enum.cpp
+++ b/stdlib/public/runtime/Enum.cpp
@@ -81,9 +81,9 @@
     size = payloadSize;
     unusedExtraInhabitants = payloadNumExtraInhabitants - emptyCases;
   } else {
-    size = payloadSize + getNumTagBytes(payloadSize,
+    size = payloadSize + getEnumTagCounts(payloadSize,
                                       emptyCases - payloadNumExtraInhabitants,
-                                      1 /*payload case*/);
+                                        1 /*payload case*/).numTagBytes; ;
   }
 
   auto vwtable = getMutableVWTableForInit(self, layoutFlags);
@@ -169,6 +169,12 @@
                                 numExtraInhabitants, storeExtraInhabitant);
 }
 
+static int32_t getMultiPayloadExtraInhabitantIndex(const OpaqueValue *value,
+                                                   const Metadata *enumType);
+static void storeMultiPayloadExtraInhabitant(OpaqueValue *value,
+                                             int32_t index,
+                                             const Metadata *enumType);
+
 void
 swift::swift_initEnumMetadataMultiPayload(EnumMetadata *enumType,
                                      EnumLayoutFlags layoutFlags,
@@ -190,29 +196,41 @@
   assignUnlessEqual(enumType->getPayloadSize(), payloadSize);
   
   // The total size includes space for the tag.
-  unsigned totalSize = payloadSize + getNumTagBytes(payloadSize,
+  auto tagCounts = getEnumTagCounts(payloadSize,
                                 enumType->getDescription()->getNumEmptyCases(),
                                 numPayloads);
+  unsigned totalSize = payloadSize + tagCounts.numTagBytes;
+  
+  // See whether there are extra inhabitants in the tag.
+  unsigned numExtraInhabitants = tagCounts.numTagBytes == 4
+    ? INT_MAX
+    : (1 << (tagCounts.numTagBytes * 8)) - tagCounts.numTags;
 
   auto vwtable = getMutableVWTableForInit(enumType, layoutFlags);
 
   // Set up the layout info in the vwtable.
-  TypeLayout layout;
-  layout.size = totalSize;
-  layout.flags = ValueWitnessFlags()
+  auto rawStride = (totalSize + alignMask) & ~alignMask;
+  TypeLayout layout{totalSize,
+                    ValueWitnessFlags()
                      .withAlignmentMask(alignMask)
                      .withPOD(isPOD)
                      .withBitwiseTakable(isBT)
-                     // TODO: Extra inhabitants
-                     .withExtraInhabitants(false)
+                     .withExtraInhabitants(numExtraInhabitants > 0)
                      .withEnumWitnesses(true)
                      .withInlineStorage(ValueWitnessTable::isValueInline(
-                         isBT, totalSize, alignMask + 1));
-  auto rawStride = (totalSize + alignMask) & ~alignMask;
-  layout.stride = rawStride == 0 ? 1 : rawStride;
-  
-  installCommonValueWitnesses(layout, vwtable);
+                         isBT, totalSize, alignMask + 1)),
+                    rawStride == 0 ? 1 : rawStride,
+                    numExtraInhabitants > 0
+                      ? ExtraInhabitantFlags()
+                          .withNumExtraInhabitants(numExtraInhabitants)
+                      : ExtraInhabitantFlags()};
 
+  installCommonValueWitnesses(layout, vwtable);
+  if (numExtraInhabitants > 0) {
+    vwtable->extraInhabitantFlags = layout.getExtraInhabitantFlags();
+    vwtable->storeExtraInhabitant = storeMultiPayloadExtraInhabitant;
+    vwtable->getExtraInhabitantIndex = getMultiPayloadExtraInhabitantIndex;
+  }
   vwtable->publishLayout(layout);
 }
 
@@ -271,10 +289,11 @@
 }
 
 static unsigned loadMultiPayloadTag(const OpaqueValue *value,
-                                    MultiPayloadLayout layout) {
+                                    MultiPayloadLayout layout,
+                                    unsigned baseValue = 0) {
   auto tagBytes = reinterpret_cast<const char *>(value) + layout.payloadSize;
 
-  unsigned tag = 0;
+  unsigned tag = baseValue;
 #if defined(__BIG_ENDIAN__)
   small_memcpy(reinterpret_cast<char *>(&tag) + 4 - layout.numTagBytes,
                tagBytes, layout.numTagBytes);
@@ -301,6 +320,23 @@
   return payloadValue;
 }
 
+static int32_t getMultiPayloadExtraInhabitantIndex(const OpaqueValue *value,
+                                                   const Metadata *enumType) {
+  auto layout = getMultiPayloadLayout(cast<EnumMetadata>(enumType));
+  unsigned index = ~loadMultiPayloadTag(value, layout, ~0u);
+  
+  if (index >= enumType->getValueWitnesses()->getNumExtraInhabitants())
+    return -1;
+  return index;
+}
+static void storeMultiPayloadExtraInhabitant(OpaqueValue *value,
+                                             int32_t index,
+                                             const Metadata *enumType) {
+  auto layout = getMultiPayloadLayout(cast<EnumMetadata>(enumType));
+  storeMultiPayloadTag(value, layout, ~index);
+}
+
+
 void
 swift::swift_storeEnumTagMultiPayload(OpaqueValue *value,
                                       const EnumMetadata *enumType,
diff --git a/stdlib/public/runtime/EnumImpl.h b/stdlib/public/runtime/EnumImpl.h
index 2b3e754..d0471f9 100644
--- a/stdlib/public/runtime/EnumImpl.h
+++ b/stdlib/public/runtime/EnumImpl.h
@@ -16,6 +16,8 @@
 #ifndef SWIFT_RUNTIME_ENUMIMPL_H
 #define SWIFT_RUNTIME_ENUMIMPL_H
 
+#include "swift/ABI/Enum.h"
+
 namespace swift {
 
 /// This is a small and fast implementation of memcpy with a constant count. It
@@ -59,29 +61,6 @@
   }
 }
 
-inline unsigned getNumTagBytes(size_t size, unsigned emptyCases,
-                               unsigned payloadCases) {
-  // We can use the payload area with a tag bit set somewhere outside of the
-  // payload area to represent cases. See how many bytes we need to cover
-  // all the empty cases.
-
-  unsigned numTags = payloadCases;
-  if (emptyCases > 0) {
-    if (size >= 4)
-      // Assume that one tag bit is enough if the precise calculation overflows
-      // an int32.
-      numTags += 1;
-    else {
-      unsigned bits = size * 8U;
-      unsigned casesPerTagBitValue = 1U << bits;
-      numTags += ((emptyCases + (casesPerTagBitValue-1U)) >> bits);
-    }
-  }
-  return (numTags <=    1 ? 0 :
-          numTags <   256 ? 1 :
-          numTags < 65536 ? 2 : 4);
-}
-
 inline unsigned getEnumTagSinglePayloadImpl(
     const OpaqueValue *enumAddr, unsigned emptyCases, const Metadata *payload,
     size_t payloadSize, size_t payloadNumExtraInhabitants,
@@ -93,8 +72,9 @@
     auto *extraTagBitAddr = valueAddr + payloadSize;
     unsigned extraTagBits = 0;
     unsigned numBytes =
-        getNumTagBytes(payloadSize, emptyCases - payloadNumExtraInhabitants,
-                       1 /*payload case*/);
+        getEnumTagCounts(payloadSize,
+                         emptyCases - payloadNumExtraInhabitants,
+                         1 /*payload case*/).numTagBytes;
 
 #if defined(__BIG_ENDIAN__)
     small_memcpy(reinterpret_cast<uint8_t *>(&extraTagBits) + 4 - numBytes,
@@ -154,8 +134,9 @@
   auto *extraTagBitAddr = valueAddr + payloadSize;
   unsigned numExtraTagBytes =
       emptyCases > payloadNumExtraInhabitants
-          ? getNumTagBytes(payloadSize, emptyCases - payloadNumExtraInhabitants,
-                           1 /*payload case*/)
+          ? getEnumTagCounts(payloadSize,
+                             emptyCases - payloadNumExtraInhabitants,
+                             1 /*payload case*/).numTagBytes
           : 0;
 
   // For payload or extra inhabitant cases, zero-initialize the extra tag bits,
diff --git a/stdlib/public/runtime/Errors.cpp b/stdlib/public/runtime/Errors.cpp
index 8d35cfc..d718f59 100644
--- a/stdlib/public/runtime/Errors.cpp
+++ b/stdlib/public/runtime/Errors.cpp
@@ -419,3 +419,17 @@
                       "the object was already deallocated");
   }
 }
+
+/// Halt due to enabling an already enabled dynamic replacement().
+void swift::swift_abortDynamicReplacementEnabling() {
+  swift::fatalError(FatalErrorFlags::ReportBacktrace,
+                    "Fatal error: trying to enable a dynamic replacement "
+                    "that is already enabled");
+}
+
+/// Halt due to disabling an already disabled dynamic replacement().
+void swift::swift_abortDynamicReplacementDisabling() {
+  swift::fatalError(FatalErrorFlags::ReportBacktrace,
+                    "Fatal error: trying to disable a dynamic replacement "
+                    "that is already disabled");
+}
diff --git a/stdlib/public/runtime/ImageInspection.h b/stdlib/public/runtime/ImageInspection.h
index 71f22b0..fc3b075 100644
--- a/stdlib/public/runtime/ImageInspection.h
+++ b/stdlib/public/runtime/ImageInspection.h
@@ -45,12 +45,16 @@
 /// Load the metadata from the image necessary to find a type by name.
 void initializeTypeMetadataRecordLookup();
 
+/// Load the metadata from the image necessary to perform dynamic replacements.
+void initializeDynamicReplacementLookup();
+
 // Callbacks to register metadata from an image to the runtime.
 void addImageProtocolsBlockCallback(const void *start, uintptr_t size);
 void addImageProtocolConformanceBlockCallback(const void *start,
                                               uintptr_t size);
 void addImageTypeMetadataRecordBlockCallback(const void *start,
                                              uintptr_t size);
+void addImageDynamicReplacementBlockCallback(const void *start, uintptr_t size);
 
 int lookupSymbol(const void *address, SymbolInfo *info);
 void *lookupSection(const char *segment, const char *section, size_t *outSize);
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.cpp b/stdlib/public/runtime/ImageInspectionCOFF.cpp
index eeb682f..2ca78ea 100644
--- a/stdlib/public/runtime/ImageInspectionCOFF.cpp
+++ b/stdlib/public/runtime/ImageInspectionCOFF.cpp
@@ -82,6 +82,9 @@
   }
 }
 
+void swift::initializeDynamicReplacementLookup() {
+}
+
 SWIFT_RUNTIME_EXPORT
 void swift_addNewDSOImage(const void *addr) {
   const swift::MetadataSections *sections =
@@ -106,6 +109,13 @@
   const void *metadata = reinterpret_cast<void *>(type_metadata.start);
   if (type_metadata.length)
     addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
+
+  const auto &dynamic_replacements = sections->swift5_repl;
+  const auto *replacements =
+      reinterpret_cast<void *>(dynamic_replacements.start);
+  if (dynamic_replacements.length)
+    addImageDynamicReplacementBlockCallback(replacements, dynamic_replacements.length);
+
 }
 
 int swift::lookupSymbol(const void *address, SymbolInfo *info) {
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.h b/stdlib/public/runtime/ImageInspectionCOFF.h
index 75e0266..02161b6 100644
--- a/stdlib/public/runtime/ImageInspectionCOFF.h
+++ b/stdlib/public/runtime/ImageInspectionCOFF.h
@@ -52,6 +52,7 @@
   Range swift5_reflstr;
   Range swift5_fieldmd;
   Range swift5_assocty;
+  Range swift5_repl;
 };
 } // namespace swift
 
diff --git a/stdlib/public/runtime/ImageInspectionELF.cpp b/stdlib/public/runtime/ImageInspectionELF.cpp
index c494171..a675ea0 100644
--- a/stdlib/public/runtime/ImageInspectionELF.cpp
+++ b/stdlib/public/runtime/ImageInspectionELF.cpp
@@ -86,6 +86,9 @@
   }
 }
 
+void swift::initializeDynamicReplacementLookup() {
+}
+
 // As ELF images are loaded, ImageInspectionInit:sectionDataInit() will call
 // addNewDSOImage() with an address in the image that can later be used via
 // dladdr() to dlopen() the image after the appropriate initialize*Lookup()
@@ -114,6 +117,13 @@
   const void *metadata = reinterpret_cast<void *>(type_metadata.start);
   if (type_metadata.length)
     addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
+
+  const auto &dynamic_replacements = sections->swift5_replace;
+  const auto *replacements =
+      reinterpret_cast<void *>(dynamic_replacements.start);
+  if (dynamic_replacements.length)
+    addImageDynamicReplacementBlockCallback(replacements,
+                                            dynamic_replacements.length);
 }
 
 int swift::lookupSymbol(const void *address, SymbolInfo *info) {
diff --git a/stdlib/public/runtime/ImageInspectionELF.h b/stdlib/public/runtime/ImageInspectionELF.h
index 9505360..e5f0caf 100644
--- a/stdlib/public/runtime/ImageInspectionELF.h
+++ b/stdlib/public/runtime/ImageInspectionELF.h
@@ -52,6 +52,7 @@
   Range swift5_reflstr;
   Range swift5_fieldmd;
   Range swift5_assocty;
+  Range swift5_replace;
 };
 } // namespace swift
 
diff --git a/stdlib/public/runtime/ImageInspectionMachO.cpp b/stdlib/public/runtime/ImageInspectionMachO.cpp
index 2a0e8e1..ea91f9e 100644
--- a/stdlib/public/runtime/ImageInspectionMachO.cpp
+++ b/stdlib/public/runtime/ImageInspectionMachO.cpp
@@ -38,6 +38,11 @@
 /// The Mach-O section name for the section containing type references.
 /// This lives within SEG_TEXT.
 constexpr const char TypeMetadataRecordSection[] = "__swift5_types";
+/// The Mach-O section name for the section containing dynamic replacements.
+/// This lives within SEG_TEXT.
+constexpr const char DynamicReplacementSection[] = "__swift5_replace";
+
+constexpr const char TextSegment[] = SEG_TEXT;
 
 #if __POINTER_WIDTH__ == 64
 using mach_header_platform = mach_header_64;
@@ -47,7 +52,7 @@
 
 extern "C" void *_NSGetMachExecuteHeader();
 
-template<const char *SECTION_NAME,
+template <const char *SEGMENT_NAME, const char *SECTION_NAME,
          void CONSUME_BLOCK(const void *start, uintptr_t size)>
 void addImageCallback(const mach_header *mh, intptr_t vmaddr_slide) {
 #if __POINTER_WIDTH__ == 64
@@ -58,7 +63,7 @@
   unsigned long size;
   const uint8_t *section =
   getsectiondata(reinterpret_cast<const mach_header_platform *>(mh),
-                 SEG_TEXT, SECTION_NAME,
+                 SEGMENT_NAME, SECTION_NAME,
                  &size);
   
   if (!section)
@@ -71,20 +76,25 @@
 
 void swift::initializeProtocolLookup() {
   _dyld_register_func_for_add_image(
-    addImageCallback<ProtocolsSection,
+    addImageCallback<TextSegment, ProtocolsSection,
                      addImageProtocolsBlockCallback>);
 }
 
 void swift::initializeProtocolConformanceLookup() {
   _dyld_register_func_for_add_image(
-    addImageCallback<ProtocolConformancesSection,
+    addImageCallback<TextSegment, ProtocolConformancesSection,
                      addImageProtocolConformanceBlockCallback>);
 }
 void swift::initializeTypeMetadataRecordLookup() {
   _dyld_register_func_for_add_image(
-    addImageCallback<TypeMetadataRecordSection,
+    addImageCallback<TextSegment, TypeMetadataRecordSection,
                      addImageTypeMetadataRecordBlockCallback>);
-  
+}
+
+void swift::initializeDynamicReplacementLookup() {
+  _dyld_register_func_for_add_image(
+      addImageCallback<TextSegment, DynamicReplacementSection,
+                       addImageDynamicReplacementBlockCallback>);
 }
 
 int swift::lookupSymbol(const void *address, SymbolInfo *info) {
diff --git a/stdlib/public/runtime/KeyPaths.cpp b/stdlib/public/runtime/KeyPaths.cpp
new file mode 100644
index 0000000..f0cad6a
--- /dev/null
+++ b/stdlib/public/runtime/KeyPaths.cpp
@@ -0,0 +1,173 @@
+//===--- KeyPaths.cpp - Key path helper symbols ---------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "swift/Runtime/HeapObject.h"
+#include "swift/Runtime/Metadata.h"
+#include <cstdint>
+#include <cstring>
+
+using namespace swift;
+
+SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
+void swift_copyKeyPathTrivialIndices(const void *src, void *dest, size_t bytes) {
+  memcpy(dest, src, bytes);
+}
+
+SWIFT_CC(swift)
+static bool equateGenericArguments(const void *a, const void *b, size_t bytes) {
+  // Generic arguments can't affect equality, since an equivalent key path may
+  // have been formed in a fully concrete context without capturing generic
+  // arguments.
+  return true;
+}
+
+SWIFT_CC(swift)
+static intptr_t hashGenericArguments(const void *src, size_t bytes) {
+  // Generic arguments can't affect equality, since an equivalent key path may
+  // have been formed in a fully concrete context without capturing generic
+  // arguments. The implementation recognizes a hash value return of '0' as
+  // "no effect on the hash".
+  return 0;
+}
+
+/// A prefab witness table for computed key path components that only include
+/// captured generic arguments.
+SWIFT_RUNTIME_EXPORT
+void *(swift_keyPathGenericWitnessTable[]) = {
+  nullptr, // no destructor necessary
+  (void*)(uintptr_t)swift_copyKeyPathTrivialIndices,
+  (void*)(uintptr_t)equateGenericArguments,
+  (void*)(uintptr_t)hashGenericArguments,
+};
+
+/****************************************************************************/
+/** Projection functions ****************************************************/
+/****************************************************************************/
+
+namespace {
+  struct AddrAndOwner {
+    OpaqueValue *Addr;
+    HeapObject *Owner;
+  };
+}
+
+// These functions are all implemented in the stdlib.  Their type
+// parameters are passed impliictly in the isa of the key path.
+
+extern "C"
+SWIFT_CC(swift) void
+swift_getAtKeyPath(SWIFT_INDIRECT_RESULT void *result,
+                   const OpaqueValue *root, void *keyPath);
+
+extern "C"
+SWIFT_CC(swift) AddrAndOwner
+_swift_modifyAtWritableKeyPath_impl(OpaqueValue *root, void *keyPath);
+
+extern "C"
+SWIFT_CC(swift) AddrAndOwner
+_swift_modifyAtReferenceWritableKeyPath_impl(const OpaqueValue *root,
+                                             void *keyPath);
+
+namespace {
+  struct YieldOnceTemporary {
+    const Metadata *Type;
+
+    // Yield-once buffers can't be memcpy'ed, so it doesn't matter that
+    // isValueInline() returns false for non-bitwise-takable types --- but
+    // it doesn't hurt, either.
+    ValueBuffer Buffer;
+
+    YieldOnceTemporary(const Metadata *type) : Type(type) {}
+
+    static OpaqueValue *allocateIn(const Metadata *type,
+                                   YieldOnceBuffer *buffer) {
+      auto *temp =
+        new (reinterpret_cast<void*>(buffer)) YieldOnceTemporary(type);
+      return type->allocateBufferIn(&temp->Buffer);
+    }
+
+    static void destroyAndDeallocateIn(YieldOnceBuffer *buffer) {
+      auto *temp = reinterpret_cast<YieldOnceTemporary*>(buffer);
+      temp->Type->vw_destroy(temp->Type->projectBufferFrom(&temp->Buffer));
+      temp->Type->deallocateBufferIn(&temp->Buffer);
+    }
+  };
+
+  static_assert(sizeof(YieldOnceTemporary) <= sizeof(YieldOnceBuffer) &&
+                alignof(YieldOnceTemporary) <= alignof(YieldOnceBuffer),
+                "temporary doesn't fit in a YieldOnceBuffer");
+}
+
+static SWIFT_CC(swift)
+void _destroy_temporary_continuation(YieldOnceBuffer *buffer, bool forUnwind) {
+  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) {
+  // The Value type parameter is passed in the class of the key path object.
+  // 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));
+  const Metadata *valueTy = keyPathGenericArgs[1];
+
+  // Allocate the buffer.
+  auto result = YieldOnceTemporary::allocateIn(valueTy, buffer);
+
+  // Read into the buffer.
+  swift_getAtKeyPath(result, root, keyPath);
+
+  // Return a continuation that destroys the value in the buffer
+  // and deallocates it.
+  return { &_destroy_temporary_continuation, result };
+}
+
+static SWIFT_CC(swift)
+void _release_owner_continuation(YieldOnceBuffer *buffer, bool forUnwind) {
+  swift_unknownObjectRelease(buffer->Data[0]);
+}
+
+YieldOnceResult<OpaqueValue*>
+swift::swift_modifyAtWritableKeyPath(YieldOnceBuffer *buffer,
+                                     OpaqueValue *root, void *keyPath) {
+  auto addrAndOwner =
+    _swift_modifyAtWritableKeyPath_impl(root, keyPath);
+  buffer->Data[0] = addrAndOwner.Owner;
+
+  return { &_release_owner_continuation, addrAndOwner.Addr };
+}
+
+YieldOnceResult<OpaqueValue*>
+swift::swift_modifyAtReferenceWritableKeyPath(YieldOnceBuffer *buffer,
+                                              const OpaqueValue *root,
+                                              void *keyPath) {
+  auto addrAndOwner =
+    _swift_modifyAtReferenceWritableKeyPath_impl(root, keyPath);
+  buffer->Data[0] = addrAndOwner.Owner;
+
+  return { &_release_owner_continuation, addrAndOwner.Addr };
+}
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 66829a7..7742ddc 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -3712,6 +3712,13 @@
   return reinterpret_cast<OpaqueValue *>(ptr);
 }
 
+template <> OpaqueValue *Metadata::projectBufferFrom(ValueBuffer *buffer) const{
+  auto *vwt = getValueWitnesses();
+  if (vwt->isValueInline())
+    return reinterpret_cast<OpaqueValue *>(buffer);
+  return reinterpret_cast<OpaqueValue *>(buffer->PrivateData[0]);
+}
+
 template <> void Metadata::deallocateBufferIn(ValueBuffer *buffer) const {
   auto *vwt = getValueWitnesses();
   if (vwt->isValueInline())
@@ -4117,7 +4124,7 @@
     // For a class, chase the superclass chain up until we hit the
     // type that specified the conformance.
     auto originalConformingType = findConformingSuperclass(conformingType,
-                                                           protocol);
+                                                           conformance);
     SubstGenericParametersFromMetadata substitutions(originalConformingType);
     assocTypeMetadata = _getTypeByMangledName(mangledName, substitutions);
   }
@@ -4151,6 +4158,70 @@
   return response;
 }
 
+const WitnessTable *swift::swift_getAssociatedConformanceWitness(
+                                  WitnessTable *wtable,
+                                  const Metadata *conformingType,
+                                  const Metadata *assocType,
+                                  const ProtocolRequirement *reqBase,
+                                  const ProtocolRequirement *assocConformance) {
+#ifndef NDEBUG
+  {
+    const ProtocolConformanceDescriptor *conformance = wtable->Description;
+    const ProtocolDescriptor *protocol = conformance->getProtocol();
+    auto requirements = protocol->getRequirements();
+    assert(assocConformance >= requirements.begin() &&
+           assocConformance < requirements.end());
+    assert(reqBase == requirements.data() - WitnessTableFirstRequirementOffset);
+    assert(assocConformance->Flags.getKind() ==
+           ProtocolRequirementFlags::Kind::AssociatedConformanceAccessFunction);
+  }
+#endif
+
+  // Call the access function.
+  unsigned witnessIndex = assocConformance - reqBase;
+  auto witness = ((const void* const *)wtable)[witnessIndex];
+  // Fast path: we've already resolved this to a witness table, so return it.
+  if (LLVM_LIKELY((uintptr_t(witness) &
+         ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0)) {
+    return static_cast<const WitnessTable *>(witness);
+  }
+
+  // Find the mangled name.
+  const char *mangledNameBase =
+    (const char *)(uintptr_t(witness) &
+                     ~ProtocolRequirementFlags::AssociatedTypeMangledNameBit);
+
+
+  // Extract the mangled name itself.
+  StringRef mangledName =
+    Demangle::makeSymbolicMangledNameStringRef(mangledNameBase);
+
+  // Relative reference to an associate conformance witness function.
+  // FIXME: This is intended to be a temporary mangling, to be replaced
+  // by a real "protocol conformance" mangling.
+  if (mangledName.size() == 5 &&
+      (mangledName[0] == '\x07' || mangledName[0] == '\x08')) {
+    // Resolve the relative reference to the witness function.
+    int32_t offset;
+    memcpy(&offset, mangledName.data() + 1, 4);
+    auto ptr = detail::applyRelativeOffset(mangledName.data() + 1, offset);
+
+    // Call the witness function.
+    auto witnessFn = (AssociatedWitnessTableAccessFunction *)ptr;
+    auto assocWitnessTable = witnessFn(assocType, conformingType, wtable);
+
+    assert((uintptr_t(assocWitnessTable) &
+            ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0);
+
+    // Update the cache.
+    reinterpret_cast<const void**>(wtable)[witnessIndex] = assocWitnessTable;
+
+    return assocWitnessTable;
+  }
+
+  swift_runtime_unreachable("Invalid mangled associate conformance");
+}
+
 /***************************************************************************/
 /*** Recursive metadata dependencies ***************************************/
 /***************************************************************************/
diff --git a/stdlib/public/runtime/MetadataImpl.h b/stdlib/public/runtime/MetadataImpl.h
index a5f82e9..b6677ff 100644
--- a/stdlib/public/runtime/MetadataImpl.h
+++ b/stdlib/public/runtime/MetadataImpl.h
@@ -407,9 +407,6 @@
 /// A box implementation class for BridgeObject.
 struct BridgeObjectBox :
     RetainableBoxBase<BridgeObjectBox, void*> {
-  // TODO: Enable the nil extra inhabitant.
-  static constexpr unsigned numExtraInhabitants = 1;
-      
   static void *retain(void *obj) {
     return swift_bridgeObjectRetain(obj);
   }
@@ -417,14 +414,6 @@
   static void release(void *obj) {
     swift_bridgeObjectRelease(obj);
   }
-      
-  static void storeExtraInhabitant(void **dest, int index) {
-    *dest = nullptr;
-  }
-
-  static int getExtraInhabitantIndex(void* const *src) {
-    return *src == nullptr ? 0 : -1;
-  }
 };
   
 /// A box implementation class for unmanaged, pointer-aligned pointers.
diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp
index 52b4c6f..0df5e88 100644
--- a/stdlib/public/runtime/MetadataLookup.cpp
+++ b/stdlib/public/runtime/MetadataLookup.cpp
@@ -22,8 +22,10 @@
 #include "swift/ABI/TypeIdentity.h"
 #include "swift/Runtime/Casting.h"
 #include "swift/Runtime/Concurrent.h"
+#include "swift/Runtime/Debug.h"
 #include "swift/Runtime/HeapObject.h"
 #include "swift/Runtime/Metadata.h"
+#include "swift/Runtime/Mutex.h"
 #include "swift/Strings.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Optional.h"
@@ -225,6 +227,29 @@
 _findNominalTypeDescriptor(Demangle::NodePointer node,
                            Demangle::Demangler &Dem);
 
+/// Find the context descriptor for the type extended by the given extension.
+static const TypeContextDescriptor *
+_findExtendedTypeContextDescriptor(const ExtensionContextDescriptor *extension,
+                                   Demangle::NodePointer *demangledNode
+                                     = nullptr) {
+  Demangle::NodePointer localNode;
+  Demangle::NodePointer &node = demangledNode ? *demangledNode : localNode;
+
+  auto mangledName = extension->getMangledExtendedContext();
+  auto demangler = getDemanglerForRuntimeTypeResolution();
+  node = demangler.demangleType(mangledName);
+  if (!node)
+    return nullptr;
+  if (node->getKind() == Node::Kind::Type) {
+    if (node->getNumChildren() < 1)
+      return nullptr;
+    node = node->getChild(0);
+  }
+  node = stripGenericArgsFromContextNode(node, demangler);
+
+  return _findNominalTypeDescriptor(node, demangler);
+}
+
 /// Recognize imported tag types, which have a special mangling rule.
 ///
 /// This should be kept in sync with the AST mangler and with
@@ -390,24 +415,15 @@
       
       // Check that the context being extended matches as well.
       auto extendedContextNode = node->getChild(1);
-      auto extendedContextMangledName = extension->getMangledExtendedContext();
       auto demangler = getDemanglerForRuntimeTypeResolution();
-      auto extendedContextDemangled =
-         demangler.demangleType(extendedContextMangledName);
-      if (!extendedContextDemangled)
-        return false;
-      if (extendedContextDemangled->getKind() == Node::Kind::Type) {
-        if (extendedContextDemangled->getNumChildren() < 1)
-          return false;
-        extendedContextDemangled = extendedContextDemangled->getChild(0);
-      }
-      extendedContextDemangled =
-        stripGenericArgsFromContextNode(extendedContextDemangled, demangler);
-      
+
       auto extendedDescriptorFromNode =
         _findNominalTypeDescriptor(extendedContextNode, demangler);
+
+      Demangle::NodePointer extendedContextDemangled;
       auto extendedDescriptorFromDemangled =
-        _findNominalTypeDescriptor(extendedContextDemangled, demangler);
+        _findExtendedTypeContextDescriptor(extension,
+                                           &extendedContextDemangled);
 
       // Determine whether the contexts match.
       bool contextsMatch =
@@ -416,6 +432,7 @@
                       extendedDescriptorFromDemangled);
       
 #if SWIFT_OBJC_INTEROP
+      // If we have manglings of the same Objective-C type, the contexts match.
       if (!contextsMatch &&
           (!extendedDescriptorFromNode || !extendedDescriptorFromDemangled) &&
           sameObjCTypeManglings(extendedContextNode,
@@ -802,6 +819,13 @@
 bool swift::_gatherGenericParameterCounts(
                                  const ContextDescriptor *descriptor,
                                  std::vector<unsigned> &genericParamCounts) {
+  // If we have an extension descriptor, extract the extended type and use
+  // that.
+  if (auto extension = dyn_cast<ExtensionContextDescriptor>(descriptor)) {
+    if (auto extendedType = _findExtendedTypeContextDescriptor(extension))
+      descriptor = extendedType;
+  }
+
   // Once we hit a non-generic descriptor, we're done.
   if (!descriptor->isGeneric()) return false;
 
@@ -946,8 +970,7 @@
 #if SWIFT_OBJC_INTEROP
     // Look for a Swift-defined @objc protocol with the Swift 3 mangling that
     // is used for Objective-C entities.
-    std::string objcMangledName =
-      "_TtP" + mangledName.substr(0, mangledName.size()-1) + "_";
+    std::string objcMangledName = "_Tt" + mangleNodeOld(node) + "_";
     if (auto protocol = objc_getProtocol(objcMangledName.c_str()))
       return ProtocolDescriptorRef::forObjC(protocol);
 #endif
@@ -1395,6 +1418,25 @@
   return nullptr;
 }
 
+/// Demangle the given type name to a generic parameter reference, which
+/// will be returned as (depth, index).
+static Optional<std::pair<unsigned, unsigned>>
+demangleToGenericParamRef(StringRef typeName) {
+  Demangler demangler;
+  NodePointer node = demangler.demangleType(typeName);
+  if (!node)
+    return None;
+
+  // Find the flat index that the right-hand side refers to.
+  if (node->getKind() == Demangle::Node::Kind::Type)
+    node = node->getChild(0);
+  if (node->getKind() != Demangle::Node::Kind::DependentGenericParamType)
+    return None;
+
+  return std::pair<unsigned, unsigned>(node->getChild(0)->getIndex(),
+                                       node->getChild(1)->getIndex());
+}
+
 void swift::gatherWrittenGenericArgs(
                              const Metadata *metadata,
                              const TypeContextDescriptor *description,
@@ -1461,21 +1503,23 @@
     if (req.Flags.getKind() != GenericRequirementKind::SameType)
       continue;
 
-    // Where the left-hand side is a generic parameter.
-    if (req.Param.begin() != req.Param.end())
+    auto lhsParam = demangleToGenericParamRef(req.getParam());
+    if (!lhsParam)
       continue;
 
     // If we don't yet have an argument for this parameter, it's a
     // same-type-to-concrete constraint.
-    unsigned lhsFlatIndex = req.Param.getRootParamIndex();
-    if (lhsFlatIndex >= allGenericArgs.size())
+    auto lhsFlatIndex =
+      _depthIndexToFlatIndex(lhsParam->first, lhsParam->second,
+                             genericParamCounts);
+    if (!lhsFlatIndex || *lhsFlatIndex >= allGenericArgs.size())
       continue;
 
-    if (!allGenericArgs[lhsFlatIndex]) {
+    if (!allGenericArgs[*lhsFlatIndex]) {
       // Substitute into the right-hand side.
       SubstGenericParametersFromWrittenArgs substitutions(allGenericArgs,
                                                           genericParamCounts);
-      allGenericArgs[lhsFlatIndex] =
+      allGenericArgs[*lhsFlatIndex] =
           _getTypeByMangledName(req.getMangledTypeName(), substitutions);
       continue;
     }
@@ -1483,30 +1527,139 @@
     // If we do have an argument for this parameter, it might be that
     // the right-hand side is itself a generic parameter, which means
     // we have a same-type constraint A == B where A is already filled in.
-    Demangler demangler;
-    NodePointer node = demangler.demangleType(req.getMangledTypeName());
-    if (!node)
-      continue;
-
-    // Find the flat index that the right-hand side refers to.
-    if (node->getKind() == Demangle::Node::Kind::Type)
-      node = node->getChild(0);
-    if (node->getKind() != Demangle::Node::Kind::DependentGenericParamType)
+    auto rhsParam = demangleToGenericParamRef(req.getMangledTypeName());
+    if (!rhsParam)
       continue;
 
     auto rhsFlatIndex =
-      _depthIndexToFlatIndex(node->getChild(0)->getIndex(),
-                             node->getChild(1)->getIndex(),
+      _depthIndexToFlatIndex(rhsParam->first, rhsParam->second,
                              genericParamCounts);
     if (!rhsFlatIndex || *rhsFlatIndex >= allGenericArgs.size())
       continue;
 
-    if (allGenericArgs[*rhsFlatIndex] || !allGenericArgs[lhsFlatIndex])
+    if (allGenericArgs[*rhsFlatIndex] || !allGenericArgs[*lhsFlatIndex])
       continue;
 
-    allGenericArgs[*rhsFlatIndex] = allGenericArgs[lhsFlatIndex];
+    allGenericArgs[*rhsFlatIndex] = allGenericArgs[*lhsFlatIndex];
   }
 }
 
+struct InitializeDynamicReplacementLookup {
+  InitializeDynamicReplacementLookup() {
+    initializeDynamicReplacementLookup();
+  }
+};
+
+SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_BEGIN
+static InitializeDynamicReplacementLookup initDynamicReplacements;
+SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END
+
+void DynamicReplacementDescriptor::enableReplacement() const {
+  auto *chainRoot = const_cast<DynamicReplacementChainEntry *>(
+      replacedFunctionKey->root.get());
+
+  // Make sure this entry is not already enabled.
+  for (auto *curr = chainRoot; curr != nullptr; curr = curr->next) {
+    if (curr == chainEntry.get()) {
+      swift::swift_abortDynamicReplacementEnabling();
+    }
+  }
+
+  // Unlink the previous entry if we are not chaining.
+  if (!shouldChain() && chainRoot->next) {
+    auto *previous = chainRoot->next;
+    chainRoot->next = previous->next;
+    chainRoot->implementationFunction = previous->implementationFunction;
+  }
+
+  // First populate the current replacement's chain entry.
+  auto *currentEntry =
+      const_cast<DynamicReplacementChainEntry *>(chainEntry.get());
+  currentEntry->implementationFunction = chainRoot->implementationFunction;
+  currentEntry->next = chainRoot->next;
+
+  // Link the replacement entry.
+  chainRoot->next = chainEntry.get();
+  chainRoot->implementationFunction = replacementFunction.get();
+}
+
+void DynamicReplacementDescriptor::disableReplacement() const {
+  const auto *chainRoot = replacedFunctionKey->root.get();
+  auto *thisEntry =
+      const_cast<DynamicReplacementChainEntry *>(chainEntry.get());
+
+  // Find the entry previous to this one.
+  auto *prev = chainRoot;
+  while (prev && prev->next != thisEntry)
+    prev = prev->next;
+  if (!prev) {
+    swift::swift_abortDynamicReplacementDisabling();
+    return;
+  }
+
+  // Unlink this entry.
+  auto *previous = const_cast<DynamicReplacementChainEntry *>(prev);
+  previous->next = thisEntry->next;
+  previous->implementationFunction = thisEntry->implementationFunction;
+}
+
+/// An automatic dymamic replacement entry.
+class AutomaticDynamicReplacementEntry {
+  RelativeDirectPointer<DynamicReplacementScope, false> replacementScope;
+  uint32_t flags;
+
+public:
+  void enable() const { replacementScope->enable(); }
+
+  uint32_t getFlags() { return flags; }
+};
+
+/// A list of automatic dynamic replacement scopes.
+class AutomaticDynamicReplacements
+    : private swift::ABI::TrailingObjects<AutomaticDynamicReplacements,
+                                          AutomaticDynamicReplacementEntry> {
+  uint32_t flags;
+  uint32_t numScopes;
+
+  using TrailingObjects =
+      swift::ABI::TrailingObjects<AutomaticDynamicReplacements,
+                                  AutomaticDynamicReplacementEntry>;
+  friend TrailingObjects;
+
+
+  ArrayRef<AutomaticDynamicReplacementEntry> getReplacementEntries() const {
+    return {
+        this->template getTrailingObjects<AutomaticDynamicReplacementEntry>(),
+        numScopes};
+  }
+
+public:
+  void enableReplacements() const {
+    for (auto &replacementEntry : getReplacementEntries())
+      replacementEntry.enable();
+  }
+};
+
+namespace {
+  static Lazy<Mutex> DynamicReplacementLock;
+}
+
+void swift::addImageDynamicReplacementBlockCallback(
+    const void *replacements, uintptr_t replacementsSize) {
+  auto *automaticReplacements =
+      reinterpret_cast<const AutomaticDynamicReplacements *>(replacements);
+  DynamicReplacementLock.get().withLock(
+      [&] { automaticReplacements->enableReplacements(); });
+}
+
+void swift::swift_enableDynamicReplacementScope(
+    const DynamicReplacementScope *scope) {
+  DynamicReplacementLock.get().withLock([=] { scope->enable(); });
+}
+
+void swift::swift_disableDynamicReplacementScope(
+    const DynamicReplacementScope *scope) {
+  DynamicReplacementLock.get().withLock([=] { scope->disable(); });
+}
 #define OVERRIDE_METADATALOOKUP COMPATIBILITY_OVERRIDE
 #include "CompatibilityOverride.def"
diff --git a/stdlib/public/runtime/Private.h b/stdlib/public/runtime/Private.h
index f1b6961..74bdb92 100644
--- a/stdlib/public/runtime/Private.h
+++ b/stdlib/public/runtime/Private.h
@@ -452,11 +452,11 @@
                            ProtocolDescriptorRef protocol,
                            const WitnessTable **conformance);
 
-  /// Given a type that we know conforms to the given protocol, find the
-  /// superclass that introduced the conformance.
-  const Metadata *findConformingSuperclass(const Metadata *type,
-                                           const ProtocolDescriptor *protocol);
-
+  /// Given a type that we know can be used with the given conformance, find
+  /// the superclass that introduced the conformance.
+  const Metadata *findConformingSuperclass(
+                             const Metadata *type,
+                             const ProtocolConformanceDescriptor *conformance);
 } // end namespace swift
 
 #endif /* SWIFT_RUNTIME_PRIVATE_H */
diff --git a/stdlib/public/runtime/ProtocolConformance.cpp b/stdlib/public/runtime/ProtocolConformance.cpp
index a0b9970..2658656 100644
--- a/stdlib/public/runtime/ProtocolConformance.cpp
+++ b/stdlib/public/runtime/ProtocolConformance.cpp
@@ -456,42 +456,74 @@
     return ConformanceCacheResult::cacheMiss();
 }
 
-/// Checks if a given candidate is a type itself, one of its
-/// superclasses or a related generic type.
-///
-/// This check is supposed to use the same logic that is used
-/// by searchInConformanceCache.
-///
-/// \param candidate Pointer to a Metadata or a NominalTypeDescriptor.
-///
-static
-bool isRelatedType(const Metadata *type, const void *candidate,
-                   bool candidateIsMetadata) {
+namespace {
+  /// Describes a protocol conformance "candidate" that can be checked
+  /// against the
+  class ConformanceCandidate {
+    const void *candidate;
+    bool candidateIsMetadata;
 
-  while (true) {
-    // Check whether the types match.
-    if (candidateIsMetadata && type == candidate)
-      return true;
+  public:
+    ConformanceCandidate() : candidate(0), candidateIsMetadata(false) { }
 
-    // Check whether the nominal type descriptors match.
-    if (!candidateIsMetadata) {
-      const auto *description = type->getTypeContextDescriptor();
-      auto candidateDescription =
-        static_cast<const TypeContextDescriptor *>(candidate);
-      if (description && equalContexts(description, candidateDescription))
+    ConformanceCandidate(const ProtocolConformanceDescriptor &conformance)
+      : ConformanceCandidate()
+    {
+      if (auto metadata = conformance.getCanonicalTypeMetadata()) {
+        candidate = metadata;
+        candidateIsMetadata = true;
+        return;
+      }
+
+      if (auto description = conformance.getTypeContextDescriptor()) {
+        candidate = description;
+        candidateIsMetadata = false;
+        return;
+      }
+    }
+
+    /// Retrieve the conforming type as metadata, or NULL if the candidate's
+    /// conforming type is described in another way (e.g., a nominal type
+    /// descriptor).
+    const Metadata *getConformingTypeAsMetadata() const {
+      return candidateIsMetadata ? static_cast<const Metadata *>(candidate)
+                                 : nullptr;
+    }
+
+    /// Whether the conforming type exactly matches the conformance candidate.
+    bool matches(const Metadata *conformingType) const {
+      // Check whether the types match.
+      if (candidateIsMetadata && conformingType == candidate)
         return true;
+
+      // Check whether the nominal type descriptors match.
+      if (!candidateIsMetadata) {
+        const auto *description = conformingType->getTypeContextDescriptor();
+        auto candidateDescription =
+          static_cast<const TypeContextDescriptor *>(candidate);
+        if (description && equalContexts(description, candidateDescription))
+          return true;
+      }
+
+      return false;
     }
 
-    // If there is a superclass, look there.
-    if (auto superclass = _swift_class_getSuperclass(type)) {
-      type = superclass;
-      continue;
+    /// Retrieve the type that matches the conformance candidate, which may
+    /// be a superclass of the given type. Returns null if this type does not
+    /// match this conformance.
+    const Metadata *getMatchingType(const Metadata *conformingType) const {
+      while (conformingType) {
+        // Check for a match.
+        if (matches(conformingType))
+          return conformingType;
+
+        // Look for a superclass.
+        conformingType = _swift_class_getSuperclass(conformingType);
+      }
+
+      return nullptr;
     }
-
-    break;
-  }
-
-  return false;
+  };
 }
 
 static const WitnessTable *
@@ -541,38 +573,18 @@
     for (const auto &record : section) {
       auto &descriptor = *record.get();
 
-      // If the record applies to a specific type, cache it.
-      if (auto metadata = descriptor.getCanonicalTypeMetadata()) {
-        auto P = descriptor.getProtocol();
+      // We only care about conformances for this protocol.
+      if (descriptor.getProtocol() != protocol)
+        continue;
 
-        // Look for an exact match.
-        if (protocol != P)
-          continue;
+      // If there's a matching type, record the positive result.
+      ConformanceCandidate candidate(descriptor);
+      if (candidate.getMatchingType(type)) {
+        const Metadata *matchingType = candidate.getConformingTypeAsMetadata();
+        if (!matchingType)
+          matchingType = type;
 
-        if (!isRelatedType(type, metadata, /*candidateIsMetadata=*/true))
-          continue;
-
-        // Record the witness table.
-        recordWitnessTable(descriptor, metadata);
-
-      // TODO: "Nondependent witness table" probably deserves its own flag.
-      // An accessor function might still be necessary even if the witness table
-      // can be shared.
-      } else if (descriptor.getTypeKind()
-                   == TypeReferenceKind::DirectNominalTypeDescriptor ||
-                 descriptor.getTypeKind()
-                  == TypeReferenceKind::IndirectNominalTypeDescriptor) {
-        auto R = descriptor.getTypeContextDescriptor();
-        auto P = descriptor.getProtocol();
-
-        // Look for an exact match.
-        if (protocol != P)
-          continue;
-
-        if (!isRelatedType(type, R, /*candidateIsMetadata=*/false))
-          continue;
-
-        recordWitnessTable(descriptor, type);
+        recordWitnessTable(descriptor, matchingType);
       }
     }
   }
@@ -604,36 +616,6 @@
   return nullptr;
 }
 
-/// Resolve a reference to a generic parameter to type metadata.
-static const Metadata *resolveGenericParamRef(
-                            const GenericParamRef &param,
-                            SubstFlatGenericParameterFn substFlatGenericParam) {
-  // Resolve the root generic parameter.
-  const Metadata *current = substFlatGenericParam(param.getRootParamIndex());
-  if (!current) return nullptr;
-
-  // Follow the associated type path.
-  for (const auto &assocTypeRef : param) {
-    // Look for the witness table.
-    auto witnessTable =
-      swift_conformsToProtocol(current, assocTypeRef.Protocol);
-    if (!witnessTable) return nullptr;
-
-    // Retrieve the associated type.
-    auto assocTypeReq = assocTypeRef.Requirement.get();
-    current = swift_getAssociatedTypeWitness(
-                                    MetadataState::Abstract,
-                                    const_cast<WitnessTable *>(witnessTable),
-                                    current,
-                                    assocTypeRef.Protocol
-                                      ->getRequirementBaseDescriptor(),
-                                    assocTypeReq).Value;
-    if (!current) return nullptr;
-  }
-
-  return current;
-}
-
 bool swift::_checkGenericRequirements(
                       llvm::ArrayRef<GenericRequirementDescriptor> requirements,
                       std::vector<const void *> &extraArguments,
@@ -644,9 +626,10 @@
     if (!req.hasKnownKind()) return true;
 
     // Resolve the subject generic parameter.
-    auto subjectType =
-      resolveGenericParamRef(req.getParam(), substFlatGenericParam);
-    if (!subjectType) return true;
+    const Metadata *subjectType =
+      _getTypeByMangledName(req.getParam(), substGenericParam);
+    if (!subjectType)
+      return true;
 
     // Check the requirement.
     switch (req.getKind()) {
@@ -721,18 +704,13 @@
 }
 
 const Metadata *swift::findConformingSuperclass(
-                                          const Metadata *type,
-                                          const ProtocolDescriptor *protocol) {
-  const Metadata *conformingType = type;
-  while (true) {
-    const Metadata *superclass = _swift_class_getSuperclass(conformingType);
-    if (!superclass)
-      break;
-    if (!swift_conformsToProtocol(superclass, protocol))
-      break;
-    conformingType = superclass;
-  }
+                            const Metadata *type,
+                            const ProtocolConformanceDescriptor *conformance) {
+  // Figure out which type we're looking for.
+  ConformanceCandidate candidate(*conformance);
 
+  const Metadata *conformingType = candidate.getMatchingType(type);
+  assert(conformingType);
   return conformingType;
 }
 
diff --git a/stdlib/public/runtime/SwiftObject.h b/stdlib/public/runtime/SwiftObject.h
index a730d51..10e6d68 100644
--- a/stdlib/public/runtime/SwiftObject.h
+++ b/stdlib/public/runtime/SwiftObject.h
@@ -88,4 +88,11 @@
 
 #endif
 
+namespace swift {
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
+HeapObject *_swift_reallocObject(HeapObject *obj, size_t size);
+
+}
+
 #endif
diff --git a/stdlib/public/runtime/SwiftObject.mm b/stdlib/public/runtime/SwiftObject.mm
index 6e84958..abea0bf 100644
--- a/stdlib/public/runtime/SwiftObject.mm
+++ b/stdlib/public/runtime/SwiftObject.mm
@@ -82,6 +82,24 @@
 #endif
 }
 
+bool isObjCPinned(HeapObject *obj) {
+  #if SWIFT_OBJC_INTEROP
+    /* future: implement checking the relevant objc runtime bits */
+    return true;
+  #else
+    return false;
+  #endif
+}
+
+// returns non-null if realloc was successful
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
+HeapObject *swift::_swift_reallocObject(HeapObject *obj, size_t size) {
+ if (isObjCPinned(obj) || obj->refCounts.hasSideTable()) {
+   return nullptr;
+ }
+ return (HeapObject *)realloc(obj, size);
+}
+
 #if SWIFT_OBJC_INTEROP
 
 /// \brief Replacement for ObjC object_isClass(), which is unavailable on
@@ -583,13 +601,14 @@
   return (uintptr_t(object) & objectPointerIsObjCBit) != 0
       && (uintptr_t(object) & heap_object_abi::BridgeObjectTagBitsMask) == 0;
 }
-#endif
 
 /// Return true iff the given BridgeObject is a tagged value.
 static bool isBridgeObjectTaggedPointer(void *object) {
-	return (uintptr_t(object) & heap_object_abi::BridgeObjectTagBitsMask) != 0;
+  return (uintptr_t(object) & heap_object_abi::BridgeObjectTagBitsMask) != 0;
 }
 
+#endif
+
 // Mask out the spare bits in a bridgeObject, returning the object it
 // encodes.
 ///
diff --git a/stdlib/public/runtime/SwiftRT-COFF.cpp b/stdlib/public/runtime/SwiftRT-COFF.cpp
index af3451f..0b7fe91 100644
--- a/stdlib/public/runtime/SwiftRT-COFF.cpp
+++ b/stdlib/public/runtime/SwiftRT-COFF.cpp
@@ -42,6 +42,7 @@
 DECLARE_SWIFT_SECTION(sw5rfst)
 DECLARE_SWIFT_SECTION(sw5flmd)
 DECLARE_SWIFT_SECTION(sw5asty)
+DECLARE_SWIFT_SECTION(sw5repl)
 }
 
 namespace {
@@ -68,6 +69,7 @@
       SWIFT_SECTION_RANGE(sw5rfst),
       SWIFT_SECTION_RANGE(sw5flmd),
       SWIFT_SECTION_RANGE(sw5asty),
+      SWIFT_SECTION_RANGE(sw5repl),
   };
 
 #undef SWIFT_SECTION_RANGE
diff --git a/stdlib/public/runtime/SwiftRT-ELF.cpp b/stdlib/public/runtime/SwiftRT-ELF.cpp
index 9848a90..1ae4f4d 100644
--- a/stdlib/public/runtime/SwiftRT-ELF.cpp
+++ b/stdlib/public/runtime/SwiftRT-ELF.cpp
@@ -32,6 +32,7 @@
 DECLARE_SWIFT_SECTION(swift5_reflstr)
 DECLARE_SWIFT_SECTION(swift5_fieldmd)
 DECLARE_SWIFT_SECTION(swift5_assocty)
+DECLARE_SWIFT_SECTION(swift5_replace)
 }
 
 #undef DECLARE_SWIFT_SECTION
@@ -61,6 +62,7 @@
       SWIFT_SECTION_RANGE(swift5_reflstr),
       SWIFT_SECTION_RANGE(swift5_fieldmd),
       SWIFT_SECTION_RANGE(swift5_assocty),
+      SWIFT_SECTION_RANGE(swift5_replace),
   };
 
 #undef SWIFT_SECTION_RANGE
diff --git a/stdlib/public/runtime/WeakReference.h b/stdlib/public/runtime/WeakReference.h
index a2c2954..ca8c67c 100644
--- a/stdlib/public/runtime/WeakReference.h
+++ b/stdlib/public/runtime/WeakReference.h
@@ -189,7 +189,7 @@
 
  public:
   
-  WeakReference() = default;
+  WeakReference() : nativeValue() {}
 
   WeakReference(std::nullptr_t)
     : nativeValue(WeakReferenceBits(nullptr)) { }
diff --git a/stdlib/public/stubs/CMakeLists.txt b/stdlib/public/stubs/CMakeLists.txt
index 16b662b..2196d45 100644
--- a/stdlib/public/stubs/CMakeLists.txt
+++ b/stdlib/public/stubs/CMakeLists.txt
@@ -2,7 +2,6 @@
     Assert.cpp
     CommandLine.cpp
     GlobalObjects.cpp
-    KeyPaths.cpp
     LibcShims.cpp
     Random.cpp
     Stubs.cpp
diff --git a/stdlib/public/stubs/FoundationHelpers.mm b/stdlib/public/stubs/FoundationHelpers.mm
index 0668862..6979355 100644
--- a/stdlib/public/stubs/FoundationHelpers.mm
+++ b/stdlib/public/stubs/FoundationHelpers.mm
@@ -82,6 +82,24 @@
   return cast(CFStringCreateWithSubstring(cast(alloc), cast(str), cast(range)));
 }
 
+_swift_shims_CFComparisonResult
+swift::_swift_stdlib_CFStringCompare(
+                              _swift_shims_CFStringRef string,
+                              _swift_shims_CFStringRef string2) {
+  return cast(CFStringCompareWithOptionsAndLocale(cast(string),
+                                                  cast(string2),
+                                                  { 0, CFStringGetLength(cast(string)) },
+                                                  0,
+                                                  NULL));
+}
+
+__swift_uint8_t
+swift::_swift_stdlib_isNSString(id obj) {
+  //TODO: we can likely get a small perf win by using _NSIsNSString on
+  //sufficiently new OSs
+  return CFGetTypeID((CFTypeRef)obj) == CFStringGetTypeID() ? 1 : 0;
+}
+
 _swift_shims_UniChar
 swift::_swift_stdlib_CFStringGetCharacterAtIndex(_swift_shims_CFStringRef theString,
                                                  _swift_shims_CFIndex idx) {
@@ -114,5 +132,22 @@
 swift::_swift_stdlib_objcDebugDescription(id _Nonnull nsObject) {
   return [nsObject debugDescription];
 }
+
+extern "C" CFHashCode CFStringHashCString(const uint8_t *bytes, CFIndex len);
+extern "C" CFHashCode CFStringHashNSString(id str);
+
+
+_swift_shims_CFHashCode
+swift::_swift_stdlib_CFStringHashNSString(id _Nonnull obj) {
+  return CFStringHashNSString(obj);
+}
+
+_swift_shims_CFHashCode
+swift::_swift_stdlib_CFStringHashCString(const _swift_shims_UInt8 * _Nonnull bytes,
+                                  _swift_shims_CFIndex length) {
+  return CFStringHashCString(bytes, length);
+}
+
+
 #endif
 
diff --git a/stdlib/public/stubs/KeyPaths.cpp b/stdlib/public/stubs/KeyPaths.cpp
deleted file mode 100644
index 053dc20..0000000
--- a/stdlib/public/stubs/KeyPaths.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//===--- KeyPaths.cpp - Key path helper symbols ---------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "../SwiftShims/Visibility.h"
-#include "swift/Runtime/Config.h"
-#include <cstdint>
-#include <cstring>
-
-SWIFT_RUNTIME_EXPORT SWIFT_CC(swift)
-void swift_copyKeyPathTrivialIndices(const void *src, void *dest, size_t bytes) {
-  memcpy(dest, src, bytes);
-}
-
-SWIFT_CC(swift)
-static bool equateGenericArguments(const void *a, const void *b, size_t bytes) {
-  // Generic arguments can't affect equality, since an equivalent key path may
-  // have been formed in a fully concrete context without capturing generic
-  // arguments.
-  return true;
-}
-
-SWIFT_CC(swift)
-static intptr_t hashGenericArguments(const void *src, size_t bytes) {
-  // Generic arguments can't affect equality, since an equivalent key path may
-  // have been formed in a fully concrete context without capturing generic
-  // arguments. The implementation recognizes a hash value return of '0' as
-  // "no effect on the hash".
-  return 0;
-}
-
-/// A prefab witness table for computed key path components that only include
-/// captured generic arguments.
-SWIFT_RUNTIME_EXPORT
-void *(swift_keyPathGenericWitnessTable[]) = {
-  nullptr, // no destructor necessary
-  (void*)(uintptr_t)swift_copyKeyPathTrivialIndices,
-  (void*)(uintptr_t)equateGenericArguments,
-  (void*)(uintptr_t)hashGenericArguments,
-};
diff --git a/stdlib/public/stubs/LibcShims.cpp b/stdlib/public/stubs/LibcShims.cpp
index 3f817ec..083deaa 100644
--- a/stdlib/public/stubs/LibcShims.cpp
+++ b/stdlib/public/stubs/LibcShims.cpp
@@ -23,6 +23,9 @@
 
 #include <stdio.h>
 #include <sys/types.h>
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
+#include <unistd.h>
+#endif
 
 #include <type_traits>
 
@@ -50,3 +53,32 @@
                                                   __swift_size_t nitems) {
     return fwrite(ptr, size, nitems, stdout);
 }
+
+SWIFT_RUNTIME_STDLIB_SPI
+__swift_ssize_t
+swift::_swift_stdlib_read(int fd, void *buf, __swift_size_t nbyte) {
+#if defined(_WIN32)
+  return _read(fd, buf, nbyte);
+#else
+  return read(fd, buf, nbyte);
+#endif
+}
+
+SWIFT_RUNTIME_STDLIB_SPI
+__swift_ssize_t
+swift::_swift_stdlib_write(int fd, const void *buf, __swift_size_t nbyte) {
+#if defined(_WIN32)
+  return _write(fd, buf, nbyte);
+#else
+  return write(fd, buf, nbyte);
+#endif
+}
+
+SWIFT_RUNTIME_STDLIB_SPI
+int swift::_swift_stdlib_close(int fd) {
+#if defined(_WIN32)
+  return _close(fd);
+#else
+  return close(fd);
+#endif
+}
diff --git a/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb b/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb
index 875b9d2..ac35b02 100644
--- a/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb
+++ b/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb
@@ -45,8 +45,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-extern "C" CFHashCode CFStringHashCString(const uint8_t *bytes, CFIndex len);
-
 using namespace swift;
 
 // NOTE: older runtimes called these _SwiftNativeNSXXXBase. The two must
@@ -133,14 +131,6 @@
   return Result;
 }
 
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
-size_t
-swift_stdlib_CFStringHashCString(const uint8_t *bytes, CFIndex len) {
-  CFHashCode Result = CFStringHashCString(bytes, len);
-
-  return Result;
-}
-
 SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
 void swift_stdlib_CFSetGetValues(NSSet *set,
                                  const void **values) {
diff --git a/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Redeclared.h b/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Redeclared.h
index 94f733a..ae66a21 100644
--- a/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Redeclared.h
+++ b/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Redeclared.h
@@ -1,7 +1,16 @@
 @import Foundation;
+#ifndef NO_IMPORT_BASE_FROM_REDECLARED
 @import Base;
+#endif
 
 extern NSString * const SomeErrorDomain;
 // typedef NS_ERROR_ENUM(SomeErrorDomain, SomeErrorCode);
 typedef enum SomeErrorCode : long SomeErrorCode;
-enum __attribute__((ns_error_domain(SomeErrorDomain))) SomeErrorCode : long;
\ No newline at end of file
+enum __attribute__((ns_error_domain(SomeErrorDomain))) SomeErrorCode : long
+#ifdef NO_IMPORT_BASE_FROM_REDECLARED
+{
+  SomeErrorX,
+  SomeErrorY
+}
+#endif
+;
\ No newline at end of file
diff --git a/test/ClangImporter/enum-error-redeclared.swift b/test/ClangImporter/enum-error-redeclared.swift
index 6833908..582a836 100644
--- a/test/ClangImporter/enum-error-redeclared.swift
+++ b/test/ClangImporter/enum-error-redeclared.swift
@@ -1,4 +1,10 @@
 // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -verify -enable-objc-interop -I %S/Inputs/custom-modules/RedeclaredErrorEnum
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -verify -enable-objc-interop -I %S/Inputs/custom-modules/RedeclaredErrorEnum -DIMPORT_BASE
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -verify -enable-objc-interop -I %S/Inputs/custom-modules/RedeclaredErrorEnum -DIMPORT_BASE -Xcc -DNO_IMPORT_BASE_FROM_REDECLARED
+
+#if IMPORT_BASE
+import Base
+#endif
 
 import Redeclared
 
diff --git a/test/Compatibility/attr_autoclosure.swift b/test/Compatibility/attr_autoclosure.swift
new file mode 100644
index 0000000..a9698c2
--- /dev/null
+++ b/test/Compatibility/attr_autoclosure.swift
@@ -0,0 +1,39 @@
+// RUN: %target-swift-frontend -emit-sil -verify %s | %FileCheck %s
+// REQUIRES: SWIFT_VERSION=4
+
+do {
+  func a(_ x: @autoclosure () -> Int) {}
+  func b(_ x: Int, _ f: @autoclosure () -> Int = #line) {}
+
+  func c(_ y: @autoclosure () -> Int, _ z: Int) {
+    // CHECK: function_ref @$s16attr_autoclosure1aL_yySiyXKF
+    a(y)
+
+    // CHECK: function_ref @$s16attr_autoclosure1cL_yySiyXK_SitFSiyXEfu_
+    b(z + 42) // ok
+    b(z, y) // ok to pass `@autoclosure` function type as an argument
+    b(z, y()) // ok
+  }
+}
+
+func foo(_ f: @autoclosure () -> Int) {}
+func foo(_ f: () -> Int) {}
+
+do {
+  func bar(_ a: @autoclosure () -> Int,
+           _ b: () -> Int,
+           _ c: Int) {
+    // CHECK: function_ref @$s16attr_autoclosure3fooyySiyXEF
+    foo(a)
+    // CHECK: function_ref @$s16attr_autoclosure3fooyySiyXEF
+    foo(b)
+
+    // CHECK: function_ref @$s16attr_autoclosure3fooyySiyXKF
+    foo(a())
+    // CHECK: function_ref @$s16attr_autoclosure3fooyySiyXKF
+    foo(b())
+
+    // CHECK: function_ref @$s16attr_autoclosure3fooyySiyXKF
+    foo(c)
+  }
+}
diff --git a/test/Compatibility/attr_usableFromInline_protocol.swift b/test/Compatibility/attr_usableFromInline_protocol.swift
new file mode 100644
index 0000000..9f6ce14
--- /dev/null
+++ b/test/Compatibility/attr_usableFromInline_protocol.swift
@@ -0,0 +1,42 @@
+// RUN: %target-typecheck-verify-swift -swift-version 4
+// RUN: %target-typecheck-verify-swift -swift-version 4.2
+
+public protocol PublicProtoWithReqs {
+  associatedtype Assoc
+  func foo()
+}
+
+@usableFromInline struct UFIAdopter<T> : PublicProtoWithReqs {}
+// expected-warning@-1 {{type alias 'Assoc' should be declared '@usableFromInline' because because it matches a requirement in protocol 'PublicProtoWithReqs'}} {{none}}
+extension UFIAdopter {
+  typealias Assoc = Int
+  // expected-note@-1 {{'Assoc' declared here}}
+  func foo() {}
+}
+
+@usableFromInline struct UFIAdopterAllInOne<T> : PublicProtoWithReqs {
+  typealias Assoc = Int
+  // expected-warning@-1 {{type alias 'Assoc' should be declared '@usableFromInline' because because it matches a requirement in protocol 'PublicProtoWithReqs'}} {{none}}
+  func foo() {}
+}
+
+internal struct InternalAdopter<T> : PublicProtoWithReqs {}
+extension InternalAdopter {
+  typealias Assoc = Int // okay
+  func foo() {} // okay
+}
+
+
+@usableFromInline protocol UFIProtoWithReqs {
+  associatedtype Assoc
+  func foo()
+}
+
+public struct PublicAdopter<T> : UFIProtoWithReqs {}
+// expected-warning@-1 {{type alias 'Assoc' should be declared '@usableFromInline' because because it matches a requirement in protocol 'UFIProtoWithReqs'}} {{none}}
+extension PublicAdopter {
+  typealias Assoc = Int
+  // expected-note@-1 {{'Assoc' declared here}}
+  func foo() {}
+}
+extension InternalAdopter: UFIProtoWithReqs {} // okay
diff --git a/test/Constraints/add_with_nil.swift b/test/Constraints/add_with_nil.swift
new file mode 100644
index 0000000..144dc7b
--- /dev/null
+++ b/test/Constraints/add_with_nil.swift
@@ -0,0 +1,6 @@
+// RUN: %target-typecheck-verify-swift -swift-version 5 -solver-enable-operator-designated-types -solver-disable-shrink -disable-constraint-solver-performance-hacks
+
+func test(_ x: Int) -> Int {
+  return x + nil
+  // expected-error@-1 {{cannot convert value of type 'Int' to expected argument type '_.Stride'}}
+}
diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift
index 5c7da2e..0eaff39 100644
--- a/test/Constraints/closures.swift
+++ b/test/Constraints/closures.swift
@@ -798,10 +798,54 @@
 
 test([1]) { _, _ in fatalError(); () }
 
+// rdar://problem/40537960 - Misleading diagnostic when using closure with wrong type
+
+protocol P_40537960 {}
+func rdar_40537960() {
+  struct S {
+    var v: String
+  }
+
+  struct L : P_40537960 {
+    init(_: String) {}
+  }
+
+  struct R<T : P_40537960> {
+    init(_: P_40537960) {}
+  }
+
+  struct A<T: Collection, P: P_40537960> {
+    typealias Data = T.Element
+    init(_: T, fn: (Data) -> R<P>) {}
+  }
+
+  var arr: [S] = []
+  _ = A(arr, fn: { L($0.v) }) // expected-error {{cannot convert value of type 'L' to closure result type 'R<T>'}}
+}
+
 // rdar://problem/45659733
 func rdar_45659733() {
   func foo<T : BinaryInteger>(_: AnyHashable, _: T) {}
   func bar(_ a: Int, _ b: Int) {
     _ = (a ..< b).map { i in foo(i, i) } // Ok
   }
+
+  struct S<V> {
+    func map<T>(
+      get: @escaping (V) -> T,
+      set: @escaping (inout V, T) -> Void
+    ) -> S<T> {
+      fatalError()
+    }
+
+    subscript<T>(
+      keyPath: WritableKeyPath<V, T?>,
+      default defaultValue: T
+    ) -> S<T> {
+      return map(
+        get: { $0[keyPath: keyPath] ?? defaultValue },
+        set: { $0[keyPath: keyPath] = $1 }
+      ) // Ok, make sure that we deduce result to be S<T>
+    }
+  }
 }
diff --git a/test/Constraints/rdar37160679.swift b/test/Constraints/rdar37160679.swift
index d241320..f4cdd64 100644
--- a/test/Constraints/rdar37160679.swift
+++ b/test/Constraints/rdar37160679.swift
@@ -10,7 +10,7 @@
          a2: () -> Int,
          b1: () throws -> Int,
          b2: () -> Int) {
-  // CHECK: function_ref @$s12rdar371606793fooyySiyXKF
+  // CHECK: function_ref @$s12rdar371606793fooyySiyXEF
   foo(a1)
   // CHECK: function_ref @$s12rdar371606793fooyySiyXEF
   foo(a2)
diff --git a/test/Constraints/subscript.swift b/test/Constraints/subscript.swift
index 74aeaf9..ea6dfc2 100644
--- a/test/Constraints/subscript.swift
+++ b/test/Constraints/subscript.swift
@@ -116,3 +116,31 @@
 func r31977679_2(_ properties: [String: String]) -> Any? {
   return properties["foo"] // Ok
 }
+
+// rdar://problem/45819956 - inout-to-pointer in a subscript arg could use a better diagnostic
+func rdar_45819956() {
+  struct S {
+    subscript(takesPtr ptr: UnsafeMutablePointer<Int>) -> Int {
+      get { return 0 }
+    }
+  }
+
+  let s = S()
+  var i = 0
+
+  // TODO: It should be possible to suggest `withUnsafe[Mutable]Pointer` as a fix-it
+  _ = s[takesPtr: &i]
+  // expected-error@-1 {{cannot pass an inout argument to a subscript; use 'withUnsafeMutablePointer' to explicitly convert argument to a pointer}}
+}
+
+// rdar://problem/45825806 - [SR-7190] Array-to-pointer in subscript arg crashes compiler
+func rdar_45825806() {
+  struct S {
+    subscript(takesPtr ptr: UnsafePointer<Int>) -> Int {
+      get { return 0 }
+    }
+  }
+
+  let s = S()
+  _ = s[takesPtr: [1, 2, 3]] // Ok
+}
diff --git a/test/DebugInfo/LoadableByAddress-allockstack.swift b/test/DebugInfo/LoadableByAddress-allockstack.swift
index 90f534a..a4028d7 100644
--- a/test/DebugInfo/LoadableByAddress-allockstack.swift
+++ b/test/DebugInfo/LoadableByAddress-allockstack.swift
@@ -46,4 +46,4 @@
   }
 }
 
-// CHECK: define linkonce_odr hidden %swift.opaque* @"$s4main1mVwCP"
+// CHECK: define internal %swift.opaque* @"$s4main1mVwCP"
diff --git a/test/DebugInfo/autoclosure.swift b/test/DebugInfo/autoclosure.swift
index 6ea5ba3..a0c0b27 100644
--- a/test/DebugInfo/autoclosure.swift
+++ b/test/DebugInfo/autoclosure.swift
@@ -21,7 +21,7 @@
 func call_me(_ input: Int64) -> Void {
 // rdar://problem/14627460
 // An autoclosure should have a line number in the debug info and a scope line of 0.
-// CHECK-DAG: !DISubprogram({{.*}}linkageName: "$s11autoclosure7call_meyys5Int64VFSbyXKfu_",{{.*}} isLocal: true, isDefinition: true
+// CHECK-DAG: !DISubprogram({{.*}}linkageName: "$s11autoclosure7call_meyys5Int64VFSbyXEfu_",{{.*}} isLocal: true, isDefinition: true
 // But not in the line table.
 // CHECK-DAG: ![[DBG]] = !DILocation(line: [[@LINE+1]],
   if input != 0 &&&&& ( get_truth (input * 2 + 1) > 0 ) {
diff --git a/test/DebugInfo/typealias.swift b/test/DebugInfo/typealias.swift
index 3974227..f4a5c51 100644
--- a/test/DebugInfo/typealias.swift
+++ b/test/DebugInfo/typealias.swift
@@ -12,6 +12,27 @@
   fileprivate static func usePrivateType() -> PrivateType { return () }
 }
 
+struct Generic<T> {
+  enum Inner {
+    case value
+  }
+}
+
+typealias Specific = Generic<Int>
+typealias NotSpecific<T> = Generic<T>.Inner
+
+struct Outer : P {
+  enum Inner {
+    case x
+  }
+}
+
+protocol P {
+  typealias T = Outer
+}
+
+// CHECK-DAG: [[INNER_TYPE:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type{{.*}} identifier: "$s9typealias5OuterV5InnerOD"
+
 func main () {
   // CHECK-DAG: !DILocalVariable(name: "a",{{.*}} type: ![[DIEOFFSET]]
   let a : DWARF.DIEOffset = 123
@@ -23,6 +44,25 @@
   // CHECK-DAG: !DILocalVariable(name: "c",{{.*}} type: ![[PRIVATETYPE]]
   let c = DWARF.usePrivateType()
   markUsed(c);
+
+  // CHECK-DAG: !DILocalVariable(name: "d", {{.*}} type: [[NONGENERIC_TYPE:![0-9]+]])
+  // CHECK: [[NONGENERIC_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type{{.*}} identifier: "$s9typealias7GenericV5InnerOySi_GD"
+  let d: Specific.Inner = .value
+  markUsed(d)
+
+  // CHECK-DAG: !DILocalVariable(name: "e", {{.*}} type: [[INNER_TYPE]])
+  let e: Outer.T.Inner = .x
+  markUsed(e)
+
+  // CHECK-DAG: !DILocalVariable(name: "f", {{.*}} type: [[OUTER_T_TYPE:![0-9]+]])
+  // CHECK: [[OUTER_T_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$s9typealias1PP1TayAA5OuterV_GD"
+  let f: Outer.T = Outer()
+  markUsed(f)
+
+  // CHECK-DAG: !DILocalVariable(name: "g", {{.*}} type: [[GENERIC_TYPE:![0-9]+]])
+  // CHECK: [[GENERIC_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$s9typealias11NotSpecificaySiGD"
+  let g: NotSpecific<Int> = .value
+  markUsed(g)
 }
 
-main();
+main()
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.ubsan-x86_64.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.ubsan-x86_64.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.ubsan-x86_64.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/windows/clang_rt.ubsan-x86_64.lib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/windows/clang_rt.ubsan-x86_64.lib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/windows/clang_rt.ubsan-x86_64.lib
diff --git a/test/Driver/actions-dsym.swift b/test/Driver/actions-dsym.swift
new file mode 100644
index 0000000..fc4970d
--- /dev/null
+++ b/test/Driver/actions-dsym.swift
@@ -0,0 +1,116 @@
+// RUN: %empty-directory(%t)
+
+// RUN: touch %t/a.swiftmodule
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g -emit-module -module-name foo %s %t/a.swiftmodule 2>&1 | %FileCheck %s -check-prefix=SWIFTMODULE-DEBUG-INPUT
+// SWIFTMODULE-DEBUG-INPUT: 0: input, "{{.*}}actions-dsym.swift", swift
+// SWIFTMODULE-DEBUG-INPUT: 1: compile, {0}, swiftmodule
+// SWIFTMODULE-DEBUG-INPUT: 2: input, "{{.*}}a.swiftmodule", swift
+// SWIFTMODULE-DEBUG-INPUT: 3: merge-module, {1, 2}, swiftmodule
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g %s 2>&1 | %FileCheck %s -check-prefix=DEBUG
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -gnone -g %s 2>&1 | %FileCheck %s -check-prefix=DEBUG
+// DEBUG: 0: input, "{{.*}}actions-dsym.swift", swift
+// DEBUG: 1: compile, {0}, object
+// DEBUG: 2: merge-module, {1}, swiftmodule
+// DEBUG: 3: link, {1, 2}, image
+// DEBUG: 4: generate-dSYM, {3}, dSYM
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -gnone %s 2>&1 | %FileCheck %s -check-prefix=BASIC
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g -gnone %s 2>&1 | %FileCheck %s -check-prefix=BASIC
+// BASIC: 0: input, "{{.*}}actions-dsym.swift", swift
+// BASIC: 1: compile, {0}, object
+// BASIC: 2: link, {1}, image
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=DEBUG,VERIFY-DEBUG-INFO
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -gnone -g -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=DEBUG,VERIFY-DEBUG-INFO
+// VERIFY-DEBUG-INFO: 5: verify-debug-info, {4}, none
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -gdwarf-types -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=EXEC-AND-MODULE,VERIFY-DEBUG-DWARF
+// EXEC-AND-MODULE: 0: input, "{{.*}}actions-dsym.swift", swift
+// EXEC-AND-MODULE: 1: compile, {0}, object
+// EXEC-AND-MODULE: 2: merge-module, {1}, swiftmodule
+// EXEC-AND-MODULE: 3: link, {1}, image
+// VERIFY-DEBUG-DWARF-TYPES: 4: generate-dSYM, {3}, dSYM
+// VERIFY-DEBUG-DWARF-TYPES: 5: verify-debug-info, {4}, none
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -gline-tables-only -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=BASIC,VERIFY-DEBUG-LINE-TABLES
+// VERIFY-DEBUG-LINE-TABLES-ONLY: 3: generate-dSYM, {2}, dSYM
+// VERIFY-DEBUG-LINE-TABLES-ONLY: 4: verify-debug-info, {3}, none
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -gnone -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=MISSING-DEBUG-OPTION
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g -gnone -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=MISSING-DEBUG-OPTION
+// MISSING-DEBUG-OPTION: warning: ignoring '-verify-debug-info'; no debug info is being generated
+// MISSING-DEBUG-OPTION: 0: input, "{{.*}}actions-dsym.swift", swift
+// MISSING-DEBUG-OPTION: 1: compile, {0}, object
+// MISSING-DEBUG-OPTION: 2: link, {1}, image
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g -c %s 2>&1 | %FileCheck %s -check-prefix=DEBUG-OBJECT
+// DEBUG-OBJECT: 0: input, "{{.*}}actions-dsym.swift", swift
+// DEBUG-OBJECT: 1: compile, {0}, object
+// DEBUG-OBJECT-NOT: merge-module
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g -emit-executable -emit-module %s 2>&1 | %FileCheck %s -check-prefix=DEBUG-MODULE
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -gnone -g -emit-executable -emit-module %s 2>&1 | %FileCheck %s -check-prefix=DEBUG-MODULE
+// DEBUG-MODULE: 0: input, "{{.*}}actions-dsym.swift", swift
+// DEBUG-MODULE: 1: compile, {0}, object
+// DEBUG-MODULE: 2: merge-module, {1}, swiftmodule
+// DEBUG-MODULE: 3: link, {1, 2}, image
+// DEBUG-MODULE: 4: generate-dSYM, {3}, dSYM
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -gnone -emit-executable -emit-module %s 2>&1 | %FileCheck %s -check-prefix=EXEC-AND-MODULE
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g -gnone -emit-executable -emit-module %s 2>&1 | %FileCheck %s -check-prefix=EXEC-AND-MODULE
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g %S/Inputs/main.swift %S/../Inputs/empty.swift %s -module-name actions 2>&1 | %FileCheck %s -check-prefix=DEBUG-MULTI
+// DEBUG-MULTI: 0: input, "{{.*}}Inputs/main.swift", swift
+// DEBUG-MULTI: 1: compile, {0}, object
+// DEBUG-MULTI: 2: input, "{{.*}}Inputs/empty.swift", swift
+// DEBUG-MULTI: 3: compile, {2}, object
+// DEBUG-MULTI: 4: input, "{{.*}}actions-dsym.swift", swift
+// DEBUG-MULTI: 5: compile, {4}, object
+// DEBUG-MULTI: 6: merge-module, {1, 3, 5}, swiftmodule
+// DEBUG-MULTI: 7: link, {1, 3, 5, 6}, image
+// DEBUG-MULTI: 8: generate-dSYM, {7}, dSYM
+
+
+// RUN: touch %t/a.o %t/b.o
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g %t/a.o %t/b.o -o main 2>&1 | %FileCheck %s -check-prefix=LINK-ONLY
+// LINK-ONLY: 0: input, "{{.*}}/a.o", object
+// LINK-ONLY: 1: input, "{{.*}}/b.o", object
+// LINK-ONLY: 2: link, {0, 1}, image
+
+// RUN: touch %t/a.swiftmodule %t/b.swiftmodule
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g %t/a.o %t/b.o %t/a.swiftmodule %t/b.swiftmodule -o main 2>&1 | %FileCheck %s -check-prefix=DEBUG-LINK-ONLY
+// DEBUG-LINK-ONLY: 0: input, "{{.*}}/a.o", object
+// DEBUG-LINK-ONLY: 1: input, "{{.*}}/b.o", object
+// DEBUG-LINK-ONLY: 2: input, "{{.*}}/a.swiftmodule", swiftmodule
+// DEBUG-LINK-ONLY: 3: input, "{{.*}}/b.swiftmodule", swiftmodule
+// DEBUG-LINK-ONLY: 4: link, {0, 1, 2, 3}, image
+// DEBUG-LINK-ONLY: 5: generate-dSYM, {4}, dSYM
+
+// RUN: touch %t/c.swift
+// LINK-SWIFTMODULES: 0: input, "{{.*}}/c.swift", swift
+// LINK-SWIFTMODULES: 1: compile, {0}, object
+// LINK-SWIFTMODULES: 2: input, "{{.*}}/a.o", object
+// LINK-SWIFTMODULES: 3: input, "{{.*}}/b.o", object
+// LINK-SWIFTMODULES: 4: input, "{{.*}}/a.swiftmodule", swiftmodule
+// LINK-SWIFTMODULES: 5: input, "{{.*}}/b.swiftmodule", swiftmodule
+// LINK-SWIFTMODULES: 6: link, {1, 2, 3, 4, 5}, image
+
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g %t/c.swift %t/a.o %t/b.o %t/a.swiftmodule %t/b.swiftmodule -o main 2>&1 | %FileCheck %s -check-prefix=LINK-DEBUG-SWIFTMODULES
+// LINK-DEBUG-SWIFTMODULES: 0: input, "{{.*}}/c.swift", swift
+// LINK-DEBUG-SWIFTMODULES: 1: compile, {0}, object
+// LINK-DEBUG-SWIFTMODULES: 2: input, "{{.*}}/a.o", object
+// LINK-DEBUG-SWIFTMODULES: 3: input, "{{.*}}/b.o", object
+// LINK-DEBUG-SWIFTMODULES: 4: input, "{{.*}}/a.swiftmodule", swiftmodule
+// LINK-DEBUG-SWIFTMODULES: 5: input, "{{.*}}/b.swiftmodule", swiftmodule
+// LINK-DEBUG-SWIFTMODULES: 6: merge-module, {1}, swiftmodule
+// LINK-DEBUG-SWIFTMODULES: 7: link, {1, 2, 3, 4, 5, 6}, image
+
+// RUN: touch %t/a.o %t/b.o
+// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g %S/Inputs/main.swift %S/../Inputs/empty.swift %s -module-name actions -force-single-frontend-invocation 2>&1 | %FileCheck %s -check-prefix=WHOLE-MODULE
+// WHOLE-MODULE: 0: input, "{{.*}}Inputs/main.swift", swift
+// WHOLE-MODULE: 1: input, "{{.*}}Inputs/empty.swift", swift
+// WHOLE-MODULE: 2: input, "{{.*}}actions-dsym.swift", swift
+// WHOLE-MODULE: 3: compile, {0, 1, 2}, object
+// WHOLE-MODULE: 4: link, {3}, image
+// WHOLE-MODULE: 5: generate-dSYM, {4}, dSYM
diff --git a/test/Driver/actions.swift b/test/Driver/actions.swift
index 3e21f12..4d0fb4c 100644
--- a/test/Driver/actions.swift
+++ b/test/Driver/actions.swift
@@ -53,22 +53,18 @@
 // DEBUG: 1: compile, {0}, object
 // DEBUG: 2: merge-module, {1}, swiftmodule
 // DEBUG: 3: link, {1, 2}, image
-// DEBUG: 4: generate-dSYM, {3}, dSYM
 
 // RUN: %swiftc_driver -driver-print-actions -gnone %s 2>&1 | %FileCheck %s -check-prefix=BASIC
 // RUN: %swiftc_driver -driver-print-actions -g -gnone %s 2>&1 | %FileCheck %s -check-prefix=BASIC
 
-// RUN: %swiftc_driver -driver-print-actions -g -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=DEBUG,VERIFY-DEBUG-INFO
-// RUN: %swiftc_driver -driver-print-actions -gnone -g -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=DEBUG,VERIFY-DEBUG-INFO
-// VERIFY-DEBUG-INFO: 5: verify-debug-info, {4}, none
+// RUN: %swiftc_driver -driver-print-actions -g -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=DEBUG
+// RUN: %swiftc_driver -driver-print-actions -gnone -g -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=DEBUG
 
 // RUN: %swiftc_driver -driver-print-actions -gdwarf-types -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=EXEC-AND-MODULE,VERIFY-DEBUG-DWARF
-// VERIFY-DEBUG-DWARF-TYPES: 4: generate-dSYM, {3}, dSYM
-// VERIFY-DEBUG-DWARF-TYPES: 5: verify-debug-info, {4}, none
+// VERIFY-DEBUG-DWARF-TYPES: 0: verify-debug-info, {4}, none
 
 // RUN: %swiftc_driver -driver-print-actions -gline-tables-only -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=BASIC,VERIFY-DEBUG-LINE-TABLES
-// VERIFY-DEBUG-LINE-TABLES-ONLY: 3: generate-dSYM, {2}, dSYM
-// VERIFY-DEBUG-LINE-TABLES-ONLY: 4: verify-debug-info, {3}, none
+// VERIFY-DEBUG-LINE-TABLES-ONLY: 0: verify-debug-info, {3}, none
 
 // RUN: %swiftc_driver -driver-print-actions -gnone -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=MISSING-DEBUG-OPTION
 // RUN: %swiftc_driver -driver-print-actions -g -gnone -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefixes=MISSING-DEBUG-OPTION
@@ -88,7 +84,6 @@
 // DEBUG-MODULE: 1: compile, {0}, object
 // DEBUG-MODULE: 2: merge-module, {1}, swiftmodule
 // DEBUG-MODULE: 3: link, {1, 2}, image
-// DEBUG-MODULE: 4: generate-dSYM, {3}, dSYM
 
 // RUN: %swiftc_driver -driver-print-actions -gnone -emit-executable -emit-module %s 2>&1 | %FileCheck %s -check-prefix=EXEC-AND-MODULE
 // RUN: %swiftc_driver -driver-print-actions -g -gnone -emit-executable -emit-module %s 2>&1 | %FileCheck %s -check-prefix=EXEC-AND-MODULE
@@ -111,7 +106,6 @@
 // DEBUG-MULTI: 5: compile, {4}, object
 // DEBUG-MULTI: 6: merge-module, {1, 3, 5}, swiftmodule
 // DEBUG-MULTI: 7: link, {1, 3, 5, 6}, image
-// DEBUG-MULTI: 8: generate-dSYM, {7}, dSYM
 
 
 // RUN: touch %t/a.o %t/b.o
@@ -128,7 +122,6 @@
 // DEBUG-LINK-ONLY: 2: input, "{{.*}}/a.swiftmodule", swiftmodule
 // DEBUG-LINK-ONLY: 3: input, "{{.*}}/b.swiftmodule", swiftmodule
 // DEBUG-LINK-ONLY: 4: link, {0, 1, 2, 3}, image
-// DEBUG-LINK-ONLY: 5: generate-dSYM, {4}, dSYM
 
 // RUN: touch %t/c.swift
 // RUN: %swiftc_driver -driver-print-actions %t/c.swift %t/a.o %t/b.o %t/a.swiftmodule %t/b.swiftmodule -o main 2>&1 | %FileCheck %s -check-prefix=LINK-SWIFTMODULES
@@ -164,6 +157,3 @@
 // WHOLE-MODULE: 2: input, "{{.*}}actions.swift", swift
 // WHOLE-MODULE: 3: compile, {0, 1, 2}, object
 // WHOLE-MODULE: 4: link, {3}, image
-
-// RUN: %swiftc_driver -driver-print-actions -g %S/Inputs/main.swift %S/../Inputs/empty.swift %s -module-name actions -force-single-frontend-invocation 2>&1 | %FileCheck %s -check-prefix=WHOLE-MODULE -check-prefix=WHOLE-MODULE-DEBUG
-// WHOLE-MODULE-DEBUG: 5: generate-dSYM, {4}, dSYM
diff --git a/test/Driver/bridging-pch.swift b/test/Driver/bridging-pch.swift
index 528b5b1..275f4eb 100644
--- a/test/Driver/bridging-pch.swift
+++ b/test/Driver/bridging-pch.swift
@@ -17,6 +17,9 @@
 // RUN: %target-build-swift -typecheck -disable-bridging-pch  -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=NOPCHJOB
 // NOPCHJOB: {{.*}}swift -frontend {{.*}} -import-objc-header {{.*}}Inputs/bridging-header.h
 
+// RUN: %target-build-swift -typecheck -driver-print-jobs -index-store-path %t/idx -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=INDEXSTORE
+// INDEXSTORE: {{.*}}swift -frontend {{.*}} -index-store-path {{.*}}/idx -emit-pch -o {{.*}}bridging-header-{{.*}}.pch
+
 // RUN: echo "{\"\": {\"swift-dependencies\": \"%t/master.swiftdeps\"}, \"%s\": {\"swift-dependencies\": \"%t/bridging-header.swiftdeps\"}}" > %t.json
 // RUN: %target-build-swift -typecheck -incremental -enable-bridging-pch -output-file-map %t.json -import-objc-header %S/Inputs/bridging-header.h %s
 
diff --git a/test/Driver/sanitizers.swift b/test/Driver/sanitizers.swift
index 894c5d6..987e9e8 100644
--- a/test/Driver/sanitizers.swift
+++ b/test/Driver/sanitizers.swift
@@ -1,3 +1,6 @@
+/*
+ * Address Sanitizer Tests  (asan)
+ */
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_OSX %s
 // RUN: not %swiftc_driver -driver-print-jobs -sanitize=fuzzer -target x86_64-apple-macosx10.9 -resource-dir %S/Inputs/nonexistent-resource-dir %s 2>&1 | %FileCheck -check-prefix=FUZZER_NONEXISTENT %s
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-apple-ios7.1 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_IOSSIM %s
@@ -9,6 +12,9 @@
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=ASAN_LINUX %s
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-unknown-windows-msvc %s 2>&1 | %FileCheck -check-prefix=ASAN_WINDOWS %s
 
+/*
+ * Thread Sanitizer Tests  (tsan)
+ */
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=TSAN -check-prefix=TSAN_OSX %s
 // RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86-apple-macosx10.9 %s 2>&1 | %FileCheck -check-prefix=TSAN_OSX_32 %s
 // RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-apple-ios7.1 %s 2>&1 | %FileCheck -check-prefix=TSAN_IOSSIM %s
@@ -20,6 +26,23 @@
 // RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-unknown-windows-msvc %s 2>&1 | %FileCheck -check-prefix=TSAN_WINDOWS %s
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=TSAN_LINUX %s
 
+/*
+ * Undefined Behavior Sanitizer Tests  (ubsan)
+ */
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_OSX %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-apple-ios7.1 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_IOSSIM %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target arm64-apple-ios7.1 %s  | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_IOS %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-apple-tvos9.0 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_tvOS_SIM %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target arm64-apple-tvos9.0 %s  | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_tvOS %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target i386-apple-watchos2.0 %s   | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_watchOS_SIM %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target armv7k-apple-watchos2.0 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_watchOS %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=UBSAN_LINUX %s
+// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-unknown-windows-msvc %s 2>&1 | %FileCheck -check-prefix=UBSAN_WINDOWS %s
+
+
+/*
+ * Bad Argument Tests
+ */
 // RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address,unknown %s 2>&1 | %FileCheck -check-prefix=BADARG %s
 // RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -sanitize=unknown %s 2>&1 | %FileCheck -check-prefix=BADARG %s
 // RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address,thread %s 2>&1 | %FileCheck -check-prefix=INCOMPATIBLESANITIZERS %s
@@ -64,5 +87,20 @@
 
 // TSAN: -rpath @executable_path
 
+// UBSAN: swift
+// UBSAN: -sanitize=undefined
+
+// UBSAN_OSX: lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx_dynamic.dylib
+// UBSAN_IOSSIM: lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim_dynamic.dylib
+// UBSAN_IOS: lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios_dynamic.dylib
+// UBSAN_tvOS_SIM: lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim_dynamic.dylib
+// UBSAN_tvOS: lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos_dynamic.dylib
+// UBSAN_watchOS_SIM: lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim_dynamic.dylib
+// UBSAN_watchOS: lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos_dynamic.dylib
+// UBSAN_LINUX: lib/swift/clang/lib/linux/libclang_rt.ubsan-x86_64.a
+// UBSAN_WINDOWS: lib/swift/clang/lib/windows/clang_rt.ubsan-x86_64.lib
+
+// UBSAN: -rpath @executable_path
+
 // BADARG: unsupported argument 'unknown' to option '-sanitize='
 // INCOMPATIBLESANITIZERS: argument '-sanitize=address' is not allowed with '-sanitize=thread'
diff --git a/test/Driver/verify-debug-info.swift b/test/Driver/verify-debug-info.swift
index cb92103..f718ab8 100644
--- a/test/Driver/verify-debug-info.swift
+++ b/test/Driver/verify-debug-info.swift
@@ -4,5 +4,5 @@
 
 // RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.10 -gline-tables-only -verify-debug-info %s 2>&1 | %FileCheck %s -check-prefix=VERIFY-DEBUG-INFO
 
-// VERIFY-DEBUG-INFO: dsymutil verify-debug-info -o verify-debug-info.dSYM
+// VERIFY-DEBUG-INFO: dsymutil{{(\.exe)?}}{{"?}} verify-debug-info -o verify-debug-info.dSYM
 // VERIFY-DEBUG-INFO: dwarfdump --verify --debug-info --eh-frame --quiet verify-debug-info.dSYM
diff --git a/test/IDE/complete_decl_attribute.swift b/test/IDE/complete_decl_attribute.swift
index eb0e55b..b8e093f 100644
--- a/test/IDE/complete_decl_attribute.swift
+++ b/test/IDE/complete_decl_attribute.swift
@@ -50,9 +50,10 @@
 @#^KEYWORD3^#
 class C {}
 
-// KEYWORD3:                  Begin completions, 9 items
+// KEYWORD3:                  Begin completions, 10 items
 // KEYWORD3-NEXT:             Keyword/None:                       available[#Class Attribute#]; name=available{{$}}
 // KEYWORD3-NEXT:             Keyword/None:                       objc[#Class Attribute#]; name=objc{{$}}
+// KEYWORD3-NEXT:             Keyword/None:                       dynamicCallable[#Class Attribute#]; name=dynamicCallable{{$}}
 // KEYWORD3-NEXT:             Keyword/None:                       dynamicMemberLookup[#Class Attribute#]; name=dynamicMemberLookup{{$}}
 // KEYWORD3-NEXT:             Keyword/None:                       IBDesignable[#Class Attribute#]; name=IBDesignable{{$}}
 // KEYWORD3-NEXT:             Keyword/None:                       UIApplicationMain[#Class Attribute#]; name=UIApplicationMain{{$}}
@@ -64,9 +65,10 @@
 
 @#^KEYWORD4^#
 enum E {}
-// KEYWORD4:                  Begin completions, 4 items
+// KEYWORD4:                  Begin completions, 5 items
 // KEYWORD4-NEXT:             Keyword/None:                       available[#Enum Attribute#]; name=available{{$}}
 // KEYWORD4-NEXT:             Keyword/None:                       objc[#Enum Attribute#]; name=objc{{$}}
+// KEYWORD4-NEXT:             Keyword/None:                       dynamicCallable[#Enum Attribute#]; name=dynamicCallable
 // KEYWORD4-NEXT:             Keyword/None:                       dynamicMemberLookup[#Enum Attribute#]; name=dynamicMemberLookup
 // KEYWORD4-NEXT:             Keyword/None:                       usableFromInline[#Enum Attribute#]; name=usableFromInline
 // KEYWORD4-NEXT:             End completions
@@ -74,8 +76,9 @@
 
 @#^KEYWORD5^#
 struct S{}
-// KEYWORD5:                  Begin completions, 3 items
+// KEYWORD5:                  Begin completions, 4 items
 // KEYWORD5-NEXT:             Keyword/None:                       available[#Struct Attribute#]; name=available{{$}}
+// KEYWORD5-NEXT:             Keyword/None:                       dynamicCallable[#Struct Attribute#]; name=dynamicCallable
 // KEYWORD5-NEXT:             Keyword/None:                       dynamicMemberLookup[#Struct Attribute#]; name=dynamicMemberLookup
 // KEYWORD5-NEXT:             Keyword/None:                       usableFromInline[#Struct Attribute#]; name=usableFromInline
 // KEYWORD5-NEXT:             End completions
@@ -83,9 +86,10 @@
 
 @#^KEYWORD_LAST^#
 
-// KEYWORD_LAST:                  Begin completions, 21 items
+// KEYWORD_LAST:                  Begin completions, 22 items
 // KEYWORD_LAST-NEXT:             Keyword/None:                       available[#Declaration Attribute#]; name=available{{$}}
 // KEYWORD_LAST-NEXT:             Keyword/None:                       objc[#Declaration Attribute#]; name=objc{{$}}
+// KEYWORD_LAST-NEXT:             Keyword/None:                       dynamicCallable[#Declaration Attribute#]; name=dynamicCallable
 // KEYWORD_LAST-NEXT:             Keyword/None:                       noreturn[#Declaration Attribute#]; name=noreturn{{$}}
 // KEYWORD_LAST-NEXT:             Keyword/None:                       dynamicMemberLookup[#Declaration Attribute#]; name=dynamicMemberLookup
 // KEYWORD_LAST-NEXT:             Keyword/None:                       NSCopying[#Declaration Attribute#]; name=NSCopying{{$}}
diff --git a/test/IRGen/Inputs/multithread_keypaths_other.swift b/test/IRGen/Inputs/multithread_keypaths_other.swift
new file mode 100644
index 0000000..a9cb8e9
--- /dev/null
+++ b/test/IRGen/Inputs/multithread_keypaths_other.swift
@@ -0,0 +1,4 @@
+public struct A {
+  // note: not public
+  var foo: Int { get { return 0 } set { } }
+}
diff --git a/test/IRGen/access_markers.sil b/test/IRGen/access_markers.sil
index 765bbbd..2178e01 100644
--- a/test/IRGen/access_markers.sil
+++ b/test/IRGen/access_markers.sil
@@ -4,8 +4,8 @@
 import Swift
 
 class A {
-  @sil_stored var property: Int { get set }
-  @sil_stored var exProperty: Any { get set }
+  @_hasStorage var property: Int { get set }
+  @_hasStorage var exProperty: Any { get set }
   deinit
   init()
 }
diff --git a/test/IRGen/associated_type_witness.swift b/test/IRGen/associated_type_witness.swift
index 5bb99b7..0fb403d 100644
--- a/test/IRGen/associated_type_witness.swift
+++ b/test/IRGen/associated_type_witness.swift
@@ -36,17 +36,11 @@
   associatedtype ThreeAssoc
 }
 
-//   Witness table access functions for Universal : P and Universal : Q.
-// CHECK-LABEL: define linkonce_odr hidden i8** @"$s23associated_type_witness9UniversalVAcA1PAAWl"
-// CHECK:         call i8** @swift_getWitnessTable(%swift.protocol_conformance_descriptor* @"$s23associated_type_witness9UniversalVAA1PAAMc"
-// CHECK-LABEL: define linkonce_odr hidden i8** @"$s23associated_type_witness9UniversalVAcA1QAAWl"()
-// CHECK:         call i8** @swift_getWitnessTable(%swift.protocol_conformance_descriptor* @"$s23associated_type_witness9UniversalVAA1QAAMc"
-
 //   Witness table for WithUniversal : Assocked.
 // GLOBAL-LABEL: @"$s23associated_type_witness13WithUniversalVAA8AssockedAAWP" = hidden global [4 x i8*] [
 // GLOBAL-SAME:    @"$s23associated_type_witness13WithUniversalVAA8AssockedAAMc"
-// GLOBAL-SAME:    i8* bitcast (i8** ()* @"$s23associated_type_witness9UniversalVAcA1PAAWl" to i8*) 
-// GLOBAL-SAME:    i8* bitcast (i8** ()* @"$s23associated_type_witness9UniversalVAcA1QAAWl" to i8*)  
+// GLOBAL-SAME:    @"associated conformance 23associated_type_witness13WithUniversalVAA8AssockedAA5AssocAaDP_AA1P",
+// GLOBAL-SAME:    @"associated conformance 23associated_type_witness13WithUniversalVAA8AssockedAA5AssocAaDP_AA1Q"
 // GLOBAL-SAME:    i64 add (i64 ptrtoint (<{ [36 x i8], i8 }>* @"symbolic 23associated_type_witness9UniversalV" to i64), i64 1) to i8*)
 // GLOBAL-SAME:  ]
 struct WithUniversal : Assocked {
@@ -56,8 +50,8 @@
 //   Witness table for GenericWithUniversal : Assocked.
 // GLOBAL-LABEL: @"$s23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAAWP" = hidden global [4 x i8*] [
 // GLOBAL-SAME:    @"$s23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAAMc"
-// GLOBAL-SAME:    i8* bitcast (i8** ()* @"$s23associated_type_witness9UniversalVAcA1PAAWl" to i8*)
-// GLOBAL-SAME:    i8* bitcast (i8** ()* @"$s23associated_type_witness9UniversalVAcA1QAAWl" to i8*)  
+// GLOBAL-SAME:    @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5Assoc_AA1P"
+// GLOBAL-SAME:    @"associated conformance 23associated_type_witness20GenericWithUniversalVyxGAA8AssockedAA5Assoc_AA1Q"
 // GLOBAL-SAME:    @"symbolic 23associated_type_witness9UniversalV"
 // GLOBAL-SAME:  ]
 struct GenericWithUniversal<T> : Assocked {
@@ -65,10 +59,10 @@
 }
 
 //   Witness table for Fulfilled : Assocked.
-// GLOBAL-LABEL: @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAAWp" = internal constant [4 x i8*] [
+// GLOBAL-LABEL: @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAAWp" = internal global [4 x i8*] [
 // GLOBAL-SAME:    @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAAMc"
-// GLOBAL-SAME:    i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1PPWT" to i8*)
-// GLOBAL-SAME:    i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1QPWT" to i8*)
+// GLOBAL-SAME:    @"associated conformance 23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1P"
+// GLOBAL-SAME:    @"associated conformance 23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1Q"
 // GLOBAL-SAME:    @"symbolic x"
 // GLOBAL-SAME:  ]
 struct Fulfilled<T : P & Q> : Assocked {
@@ -92,10 +86,10 @@
 struct Pair<T, U> : P, Q {}
 
 //   Generic witness table pattern for Computed : Assocked.
-// GLOBAL-LABEL: @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAAWp" = internal constant [4 x i8*] [
+// GLOBAL-LABEL: @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAAWp" = internal global [4 x i8*] [
 // GLOBAL-SAME:    @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAAMc"
-// GLOBAL-SAME:    i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1PPWT" to i8*)
-// GLOBAL-SAME:    i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1QPWT" to i8*)
+// GLOBAL-SAME:    @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1P"
+// GLOBAL-SAME:    @"associated conformance 23associated_type_witness8ComputedVyxq_GAA8AssockedAA5Assoc_AA1Q"
 // GLOBAL-SAME:    @"symbolic 23associated_type_witness4PairVyxq_G"
 // GLOBAL-SAME:  ]
 
diff --git a/test/IRGen/associated_types.swift b/test/IRGen/associated_types.swift
index 6811108..68372ae 100644
--- a/test/IRGen/associated_types.swift
+++ b/test/IRGen/associated_types.swift
@@ -75,24 +75,18 @@
 //   1. Get the type metadata for U.RuncerType.Runcee.
 //     1a. Get the type metadata for U.RuncerType.
 //         Note that we actually look things up in T, which is going to prove unfortunate.
-// CHECK: [[T2:%.*]] = call %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 0, i8** %T.Runcible, %swift.type* %T, %swift.protocol_requirement* getelementptr{{.*}}i32 12), i32 -1), %swift.protocol_requirement* getelementptr inbounds (<{{.*}}>, <{{.*}}>* @"$s16associated_types8RuncibleMp", i32 0, i32 14)) [[NOUNWIND_READNONE:#.*]]
+// CHECK: [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 0, i8** %T.Runcible, %swift.type* %T, %swift.protocol_requirement* getelementptr{{.*}}i32 12), i32 -1), %swift.protocol_requirement* getelementptr inbounds (<{{.*}}>, <{{.*}}>* @"$s16associated_types8RuncibleMp", i32 0, i32 14)) [[NOUNWIND_READNONE:#.*]]
 // CHECK-NEXT: %T.RuncerType = extractvalue %swift.metadata_response [[T2]], 0
 // CHECK-NEXT: store %swift.type*
 //   2. Get the witness table for U.RuncerType.Runcee : Speedy
 //     2a. Get the protocol witness table for U.RuncerType : FastRuncer.
-// CHECK:      [[T0:%.*]] = getelementptr inbounds i8*, i8** %U.FastRuncible, i32 1
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]],
-// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8** (%swift.type*, %swift.type*, i8**)*
-// CHECK-NEXT: %T.RuncerType.FastRuncer = call swiftcc i8** [[T2]](%swift.type* %T.RuncerType, %swift.type* %U, i8** %U.FastRuncible)
+// CHECK-NEXT: %T.RuncerType.FastRuncer = call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** %U.FastRuncible, %swift.type* %U, %swift.type* %T.RuncerType
 //     1c. Get the type metadata for U.RuncerType.Runcee.
-// CHECK-NEXT: [[T2:%.*]] = call %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 0, i8** %T.RuncerType.FastRuncer, %swift.type* %T.RuncerType, {{.*}}, %swift.protocol_requirement* getelementptr inbounds (<{{.*}}>, <{{.*}}>* @"$s16associated_types10FastRuncerMp", i32 0, i32 10))
+// CHECK-NEXT: [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 0, i8** %T.RuncerType.FastRuncer, %swift.type* %T.RuncerType, {{.*}}, %swift.protocol_requirement* getelementptr inbounds (<{{.*}}>, <{{.*}}>* @"$s16associated_types10FastRuncerMp", i32 0, i32 10))
 // CHECK-NEXT: %T.RuncerType.Runcee = extractvalue %swift.metadata_response [[T2]], 0
 // CHECK-NEXT: store %swift.type*
 //     2b. Get the witness table for U.RuncerType.Runcee : Speedy.
-// CHECK:      [[T0:%.*]] = getelementptr inbounds i8*, i8** %T.RuncerType.FastRuncer, i32 1
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]],
-// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i8** (%swift.type*, %swift.type*, i8**)*
-// CHECK-NEXT: %T.RuncerType.Runcee.Speedy = call swiftcc i8** [[T2]](%swift.type* %T.RuncerType.Runcee, %swift.type* %T.RuncerType, i8** %T.RuncerType.FastRuncer)
+// CHECK-NEXT: %T.RuncerType.Runcee.Speedy = call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** %T.RuncerType.FastRuncer, %swift.type* %T.RuncerType, %swift.type* %T.RuncerType.Runcee
 //   3. Perform the actual call.
 // CHECK-NEXT: [[T0_GEP:%.*]] = getelementptr inbounds i8*, i8** %T.RuncerType.Runcee.Speedy, i32 1
 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[T0_GEP]]
diff --git a/test/IRGen/big_types_corner_cases_as_library.swift b/test/IRGen/big_types_corner_cases_as_library.swift
index a53aa9b..7cbd836 100644
--- a/test/IRGen/big_types_corner_cases_as_library.swift
+++ b/test/IRGen/big_types_corner_cases_as_library.swift
@@ -12,7 +12,7 @@
   var i8 : Int32 = 8
 }
 
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} linkonce_odr hidden %swift.opaque* @"$s33big_types_corner_cases_as_library9BigStructVwCP"
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.opaque* @"$s33big_types_corner_cases_as_library9BigStructVwCP"
 // CHECK: [[RETVAL:%.*]] = bitcast %T33big_types_corner_cases_as_library9BigStructV* {{.*}} to %swift.opaque*
 // CHECK: ret %swift.opaque* [[RETVAL]]
 let bigStructGlobalArray : [BigStruct] = [
diff --git a/test/IRGen/big_types_coroutine.sil b/test/IRGen/big_types_coroutine.sil
new file mode 100644
index 0000000..642c90b
--- /dev/null
+++ b/test/IRGen/big_types_coroutine.sil
@@ -0,0 +1,78 @@
+// RUN: %target-sil-opt -loadable-address -enable-sil-verify-all %s | %FileCheck %s
+
+// REQUIRES: CPU=x86_64
+// REQUIRES: OS=macosx
+
+sil_stage canonical
+import Builtin
+import Swift
+
+public struct BigStruct {
+  var i0 : Int32 = 0
+  var i1 : Int32 = 1
+  var i2 : Int32 = 2
+  var i3 : Int32 = 3
+  var i4 : Int32 = 4
+  var i5 : Int32 = 5
+  var i6 : Int32 = 6
+  var i7 : Int32 = 7
+  var i8 : Int32 = 8
+}
+
+sil @make_big_struct : $@convention(thin) () -> BigStruct
+sil @use_big_struct : $@convention(thin) (BigStruct) -> ()
+
+// CHECK-LABEL: sil @test_yield_big : $@yield_once @convention(thin) () -> @yields @in_constant BigStruct {
+// CHECK:       bb0:
+// CHECK-NEXT:    [[TEMP:%.*]] = alloc_stack $BigStruct
+// CHECK-NEXT:    // function_ref
+// CHECK-NEXT:    [[MAKE:%.*]] = function_ref @make_big_struct : $@convention(thin) () -> @out BigStruct
+// CHECK-NEXT:    apply [[MAKE]]([[TEMP]])
+// CHECK-NEXT:    yield [[TEMP]] : $*BigStruct, resume bb1, unwind bb2
+// CHECK:       bb1:
+// CHECK-NEXT:    [[RET:%.*]] = tuple ()
+// CHECK-NEXT:    dealloc_stack [[TEMP]] : $*BigStruct
+// CHECK-NEXT:    return [[RET]] : $()
+// CHECK:       bb2:
+// CHECK-NEXT:    dealloc_stack [[TEMP]] : $*BigStruct
+// CHECK-NEXT:    unwind
+sil @test_yield_big : $@convention(thin) @yield_once() -> (@yields BigStruct) {
+entry:
+  %make = function_ref @make_big_struct : $@convention(thin) () -> BigStruct
+  %big = apply %make() : $@convention(thin) () -> BigStruct
+  yield %big : $BigStruct, resume resume, unwind unwind
+
+resume:
+  %ret = tuple ()
+  return %ret : $()
+
+unwind:
+  unwind
+}
+
+// CHECK-LABEL: sil @use_yield_big : $@convention(thin) () -> () {
+// CHECK:       bb0:
+// CHECK-NEXT:    [[TEMP:%.*]] = alloc_stack $BigStruct
+// CHECK-NEXT:    // function_ref
+// CHECK-NEXT:    [[CORO:%.*]] = function_ref @test_yield_big : $@yield_once @convention(thin) () -> @yields @in_constant BigStruct
+// CHECK-NEXT:    ([[ADDR:%.*]], [[TOKEN:%.*]]) = begin_apply [[CORO]]()
+//   TODO: this isn't very efficient
+// CHECK-NEXT:    [[T0:%.*]] = load [trivial] [[ADDR]] : $*BigStruct
+// CHECK-NEXT:    store [[T0]] to [trivial] [[TEMP]] : $*BigStruct
+// CHECK-NEXT:    // function_ref
+// CHECK-NEXT:    [[USE:%.*]] = function_ref @use_big_struct : $@convention(thin) (@in_constant BigStruct) -> ()
+// CHECK-NEXT:    apply [[USE]]([[TEMP]])
+// CHECK-NEXT:    end_apply [[TOKEN]]
+// CHECK-NEXT:    [[RET:%.*]] = tuple ()
+// CHECK-NEXT:    dealloc_stack [[TEMP]] : $*BigStruct
+// CHECK-NEXT:    return [[RET]] : $()
+sil @use_yield_big : $@convention(thin) () -> () {
+entry:
+  %yield_big = function_ref @test_yield_big : $@convention(thin) @yield_once() -> (@yields BigStruct)
+  (%big, %token) = begin_apply %yield_big() : $@convention(thin) @yield_once() -> (@yields BigStruct)
+  %use_big = function_ref @use_big_struct : $@convention(thin) (BigStruct) -> ()
+  apply %use_big(%big) : $@convention(thin) (BigStruct) -> ()
+  end_apply %token
+  %ret = tuple ()
+  return %ret : $()
+}
diff --git a/test/IRGen/class_field_other_module.swift b/test/IRGen/class_field_other_module.swift
index b6ef44e..8c2f037 100644
--- a/test/IRGen/class_field_other_module.swift
+++ b/test/IRGen/class_field_other_module.swift
@@ -1,7 +1,7 @@
 // RUN: %empty-directory(%t)
 
 // RUN: %target-swift-frontend -emit-module -emit-module-path=%t/other_class.swiftmodule %S/Inputs/other_class.swift
-// RUN: %target-swift-frontend -I %t -emit-ir -O %s | %FileCheck %s -DINT=i%target-ptrsize
+// RUN: %target-swift-frontend -I %t -emit-ir -O -enforce-exclusivity=unchecked %s | %FileCheck %s -DINT=i%target-ptrsize
 
 import other_class
 
diff --git a/test/IRGen/class_stack_alloc.sil b/test/IRGen/class_stack_alloc.sil
index 648efac..9596023 100644
--- a/test/IRGen/class_stack_alloc.sil
+++ b/test/IRGen/class_stack_alloc.sil
@@ -4,24 +4,24 @@
 import Swift
 
 class TestClass {
-  @sil_stored var a : Int64
+  @_hasStorage var a : Int64
   init()
 }
 
 struct TestStruct {
-  @sil_stored var a : Int64
-  @sil_stored var b : Int64
-  @sil_stored var c : Int64
+  @_hasStorage var a : Int64
+  @_hasStorage var b : Int64
+  @_hasStorage var c : Int64
 }
 
 class BigClass {
-  @sil_stored var a : Int64
-  @sil_stored var b : Int64
-  @sil_stored var c : Int64
-  @sil_stored var d : Int64
-  @sil_stored var e : Int64
-  @sil_stored var f : Int64
-  @sil_stored var g : Int64
+  @_hasStorage var a : Int64
+  @_hasStorage var b : Int64
+  @_hasStorage var c : Int64
+  @_hasStorage var d : Int64
+  @_hasStorage var e : Int64
+  @_hasStorage var f : Int64
+  @_hasStorage var g : Int64
   init()
 }
 
diff --git a/test/IRGen/conformance_access_path.swift b/test/IRGen/conformance_access_path.swift
index 395c312..9cd4357 100644
--- a/test/IRGen/conformance_access_path.swift
+++ b/test/IRGen/conformance_access_path.swift
@@ -18,10 +18,7 @@
       // CHECK:   [[S_AS_VALIDATION_SUITE_GEP:%[0-9]+]] = getelementptr inbounds i8*, i8** %S.ValidationSuite, i32 1
       // CHECK:   [[S_AS_VALIDATION_SUITE:%[0-9]+]] = load i8*, i8** [[S_AS_VALIDATION_SUITE_GEP]]
       // CHECK-NEXT:   [[S_VALIDATOR_BASE:%.*]] = bitcast i8* [[S_AS_VALIDATION_SUITE]] to i8**
-      // CHECK-NEXT: [[S_VALIDATABLE_ADDR:%[0-9]+]] = getelementptr inbounds i8*, i8** [[S_VALIDATOR_BASE]], i32 1
-      // CHECK-NEXT: [[S_VALIDATABLE_FN_RAW:%[0-9]+]] = load i8*, i8** [[S_VALIDATABLE_ADDR]]
-      // CHECK-NEXT: [[S_VALIDATABLE_FN:%[0-9]+]] = bitcast i8* [[S_VALIDATABLE_FN_RAW]] to i8** (%swift.type*, %swift.type*, i8**)*
-      // CHECK-NEXT: call swiftcc i8** [[S_VALIDATABLE_FN]](%swift.type* %Self, %swift.type* %S, i8** %S.Validator)
+      // CHECK-NEXT: call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** %S.Validator, %swift.type* %S, %swift.type* %Self, 
       tested()
     }
 }
diff --git a/test/IRGen/constant_struct_with_padding.sil b/test/IRGen/constant_struct_with_padding.sil
index c38fecb..b189570 100644
--- a/test/IRGen/constant_struct_with_padding.sil
+++ b/test/IRGen/constant_struct_with_padding.sil
@@ -6,8 +6,8 @@
 import Swift
 
 struct T {
-  @sil_stored var a: Builtin.Int1 { get set }
-  @sil_stored var b: Builtin.Int32 { get set }
+  @_hasStorage var a: Builtin.Int1 { get set }
+  @_hasStorage var b: Builtin.Int32 { get set }
 }
 
 // CHECK: @global = hidden global %T4main1TV <{ i1 false, [3 x i8] undef, i32 0 }>, align 4
diff --git a/test/IRGen/dynamic_replaceable.sil b/test/IRGen/dynamic_replaceable.sil
new file mode 100644
index 0000000..a36a50d
--- /dev/null
+++ b/test/IRGen/dynamic_replaceable.sil
@@ -0,0 +1,76 @@
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil %s -emit-ir -disable-objc-interop | %FileCheck %s
+
+// REQUIRES: objc_interop
+
+// CHECK: @test_dynamically_replaceableTX = global %swift.dyn_repl_link_entry { i8* bitcast (void ()* @test_dynamically_replaceableTI to i8*), %swift.dyn_repl_link_entry* null }
+// CHECK: @test_dynamically_replaceableTx = constant %swift.dyn_repl_key { i32{{.*}}%swift.dyn_repl_link_entry* @test_dynamically_replaceableTX{{.*}}, i32 0 }, section "__TEXT,__const"
+// CHECK: @test_replacementTX = global %swift.dyn_repl_link_entry zeroinitializer
+
+// CHECK: @"\01l_unnamed_dynamic_replacements" = private constant { i32, i32, [1 x { i32, i32, i32, i32 }] }
+// CHECK: { i32 0,
+// CHECK:   i32 1,
+// CHECK:  [1 x { i32, i32, i32, i32 }]
+// CHECK:  [{ i32, i32, i32, i32 }
+// CHECK:  %swift.dyn_repl_key* @test_dynamically_replaceableTx
+// CHECK:  @test_replacement
+// CHECK:  %swift.dyn_repl_link_entry* @test_replacementTX
+// CHECK:  i32 0 }] }, section "__TEXT,__const"
+
+// CHECK: @"\01l_auto_dynamic_replacements" = private constant { i32, i32, [1 x i32] }
+// CHECK: { i32 0, i32 1,
+// CHECK: [1 x i32] [{{.*}}@"\01l_unnamed_dynamic_replacements"{{.*}}]
+// CHECK: }, section "__TEXT, __swift5_replace, regular, no_dead_strip"
+
+// CHECK-LABEL: define swiftcc void @test_dynamically_replaceable()
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   [[FUN_PTR:%.*]] = load i8*, i8** getelementptr inbounds (%swift.dyn_repl_link_entry, %swift.dyn_repl_link_entry* @test_dynamically_replaceableTX, i32 0, i32 0)
+// CHECK-NEXT:   [[TYPED_PTR:%.*]] = bitcast i8* [[FUN_PTR]] to void ()*
+// CHECK-NEXT:   call swiftcc void [[TYPED_PTR]]()
+// CHECK-NEXT:   ret void
+// CHECK-NEXT: }
+
+// CHECK-LABEL: define swiftcc void @test_dynamically_replaceableTI()
+// CHECK: entry:
+// CHECK:   ret void
+// CHECK: }
+
+sil [dynamically_replacable] @test_dynamically_replaceable : $@convention(thin) () -> () {
+bb0:
+  %0 = tuple ()
+  return %0 : $()
+}
+
+// CHECK-LABEL: define swiftcc void @test_replacement()
+// CHECK: entry:
+// CHECK:   call swiftcc void @test_replacementTI()
+// CHECK:   ret void
+// CHECK: }
+
+// The thunk that implement the prev_dynamic_function_ref lookup.
+// CHECK-LABEL: define swiftcc void @test_replacementTI()
+// CHECK: entry:
+// CHECK:   [[FUN_PTR:%.*]] = load i8*, i8** getelementptr inbounds (%swift.dyn_repl_link_entry, %swift.dyn_repl_link_entry* @test_replacementTX, i32 0, i32 0)
+// CHECK:   [[TYPED_PTR:%.*]] = bitcast i8* [[FUN_PTR]] to void ()*
+// CHECK:   call swiftcc void [[TYPED_PTR]]()
+// CHECK:   ret void
+// CHECK: }
+sil [dynamic_replacement_for "test_dynamically_replaceable"] @test_replacement : $@convention(thin) () -> () {
+bb0:
+  %0 = prev_dynamic_function_ref @test_replacement : $@convention(thin) () -> ()
+  %1 = apply %0() : $@convention(thin) () -> ()
+  %2 = tuple ()
+  return %2 : $()
+}
+
+// CHECK-LABEL: define swiftcc void @test_dynamic_call()
+// CHECK: entry:
+// CHECK:   call swiftcc void @test_dynamically_replaceable()
+// CHECK:   ret void
+// CHECK: }
+sil @test_dynamic_call : $@convention(thin) () -> () {
+bb0:
+  %0 = dynamic_function_ref @test_dynamically_replaceable : $@convention(thin) () -> ()
+  %1 = apply %0() : $@convention(thin) () -> ()
+  %2 = tuple ()
+  return %2 : $()
+}
diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil
index 1953e08..29eee07 100644
--- a/test/IRGen/enum.sil
+++ b/test/IRGen/enum.sil
@@ -181,9 +181,9 @@
 // CHECK-32-SAME:   i8* inttoptr ([[WORD]] 5 to i8*),
 // CHECK-64-SAME:   i8* inttoptr ([[WORD]] 9 to i8*),
 // -- flags                 0x250003 - alignment 4
-// CHECK-32-SAME:   i8* inttoptr ([[WORD]] {{2424835|2097155}} to i8*)
-// -- flags                 0x200007 - alignment 8
-// CHECK-64-SAME:   i8* inttoptr ([[WORD]] 2097159 to i8*)
+// CHECK-32-SAME:   i8* inttoptr ([[WORD]] {{2686979|2359299}} to i8*)
+// -- flags                 0x240007 - alignment 8, extra inhabitants
+// CHECK-64-SAME:   i8* inttoptr ([[WORD]] 2359303 to i8*)
 // CHECK-SAME: ]
 
 enum Empty {}
@@ -2688,7 +2688,7 @@
 // CHECK:   [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 8
 // CHECK:   call void @swift_initEnumMetadataSinglePayload(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]], i32 3)
 
-// CHECK-64-LABEL: define linkonce_odr hidden void @"$s4enum17StructWithWeakVarVwxs"(%swift.opaque* noalias %dest, i32 %index, %swift.type* %StructWithWeakVar)
+// CHECK-64-LABEL: define internal void @"$s4enum17StructWithWeakVarVwxs"(%swift.opaque* noalias %dest, i32 %index, %swift.type* %StructWithWeakVar)
 // -- TODO: some pointless masking here.
 // -- TODO: should use EnumPayload word-chunking.
 // CHECK-64:         %1 = zext i32 %index to i128
@@ -2701,7 +2701,7 @@
 // --                             0x1__0000_0000_0000_0000
 // CHECK-64:         %6 = or i128 %5, 18446744073709551616
 
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s4enum40MultiPayloadLessThan32BitsWithEmptyCasesOwug"(%swift.opaque* noalias %value
+// CHECK-LABEL: define internal i32 @"$s4enum40MultiPayloadLessThan32BitsWithEmptyCasesOwug"(%swift.opaque* noalias %value
 // CHECK:  [[VAL00:%.*]] = bitcast %swift.opaque* %value to %T4enum40MultiPayloadLessThan32BitsWithEmptyCasesO*
 // CHECK:  [[VAL01:%.*]] = bitcast %T4enum40MultiPayloadLessThan32BitsWithEmptyCasesO* [[VAL00]] to i8*
 // CHECK:  [[VAL02:%.*]] = load {{.*}} [[VAL01]]
@@ -2716,7 +2716,7 @@
 // CHECK:  [[VAL11:%.*]] = select i1 [[VAL10]], i32 [[VAL09]], i32 [[VAL06]]
 // CHECK:  ret i32 [[VAL11]]
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s4enum40MultiPayloadLessThan32BitsWithEmptyCasesOwui"(%swift.opaque* noalias %value, i32 %tag
+// CHECK-LABEL: define internal void @"$s4enum40MultiPayloadLessThan32BitsWithEmptyCasesOwui"(%swift.opaque* noalias %value, i32 %tag
 // CHECK: entry:
 // CHECK:  [[VAL00:%.*]] = bitcast %swift.opaque* %value
 // CHECK:  [[VAL01:%.*]] = icmp uge i32 %tag, 2
diff --git a/test/IRGen/enum_objc.sil b/test/IRGen/enum_objc.sil
index 4dcf274..c2d044e 100644
--- a/test/IRGen/enum_objc.sil
+++ b/test/IRGen/enum_objc.sil
@@ -129,4 +129,4 @@
 }
 
 // Weak existentials allow extra inhabitants if not @objc, therefore StructWithWeakVar must emit:
-// CHECK: define linkonce_odr hidden void @"$s9enum_objc17StructWithWeakVarVwxs"
+// CHECK: define internal void @"$s9enum_objc17StructWithWeakVarVwxs"
diff --git a/test/IRGen/enum_value_semantics.sil b/test/IRGen/enum_value_semantics.sil
index c9901fc..23bb584 100644
--- a/test/IRGen/enum_value_semantics.sil
+++ b/test/IRGen/enum_value_semantics.sil
@@ -198,7 +198,7 @@
 
 
 // -- NoPayload getExtraInhabitants
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics9NoPayloadOwxg"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics9NoPayloadOwxg"
 // CHECK:      [[VALUE:%.*]] = load i8, i8* {{%.*}}, align 1
 // CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[VALUE]] to i32
 // CHECK-NEXT: [[SUB:%.*]] = sub i32 [[ZEXT]], 3
@@ -208,7 +208,7 @@
 
 
 // -- NoPayload getEnumTag
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics9NoPayloadOwug"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics9NoPayloadOwug"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics9NoPayloadO*
 // CHECK-NEXT: [[TAG_ADDR:%.*]] = getelementptr inbounds %T20enum_value_semantics9NoPayloadO, %T20enum_value_semantics9NoPayloadO* [[SELF]], i32 0, i32 0
 // CHECK-NEXT: [[TAG:%.*]] = load i8, i8* [[TAG_ADDR]], align 1
@@ -217,12 +217,12 @@
 
 
 // -- NoPayload destructiveProjectEnumData
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics9NoPayloadOwup"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics9NoPayloadOwup"
 // CHECK:      ret void
 
 
 // -- NoPayload destructiveInjectEnumTag
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics9NoPayloadOwui"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics9NoPayloadOwui"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics9NoPayloadO*
 // CHECK-NEXT: [[TAG:%.*]] = trunc i32 %tag to i8
 // CHECK-NEXT: [[TAG_ADDR:%.*]] = getelementptr inbounds %T20enum_value_semantics9NoPayloadO, %T20enum_value_semantics9NoPayloadO* [[SELF]], i32 0, i32 0
@@ -236,24 +236,24 @@
 
 
 // -- SingletonPayload getEnumTag
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics16SingletonPayloadOwug"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics16SingletonPayloadOwug"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics16SingletonPayloadO*
 // CHECK-NEXT: ret i32 0
 
 
 // -- SingletonPayload destructiveProjectEnumData
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics16SingletonPayloadOwup"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics16SingletonPayloadOwup"
 // CHECK:      ret void
 
 
 // -- SingletonPayload destructiveInjectEnumTag
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics16SingletonPayloadOwui"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics16SingletonPayloadOwui"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics16SingletonPayloadO*
 // CHECK-NEXT: ret void
 
 
 // -- SinglePayloadTrivial getEnumTag
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics20SinglePayloadTrivialOwug"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics20SinglePayloadTrivialOwug"
 // CHECK:  [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics20SinglePayloadTrivialO*
 // CHECK:  [[OPAQUE:%.*]] = bitcast %T20enum_value_semantics20SinglePayloadTrivialO* [[SELF]] to %swift.opaque*
 // CHECK:  [[TAG:%.*]] = call i32 %getEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE]], i32 3, %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* @"$sBi64_N", i32 0, i32 1))
@@ -261,7 +261,7 @@
 
 
 // -- SinglePayloadTrivial destructiveProjectEnumData
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics20SinglePayloadTrivialOwup"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics20SinglePayloadTrivialOwup"
 // CHECK:      ret void
 
 
@@ -271,7 +271,7 @@
 
 
 // -- SinglePayloadTrivial destructiveInjectEnumTag
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics20SinglePayloadTrivialOwui"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics20SinglePayloadTrivialOwui"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics20SinglePayloadTrivialO*
 // CHECK-NEXT: [[OPAQUE:%.*]] = bitcast %T20enum_value_semantics20SinglePayloadTrivialO* [[SELF]] to %swift.opaque*
 // CHECK: call void %storeEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE]], i32 %tag, i32 3, %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* @"$sBi64_N", i32 0, i32 1))
@@ -279,7 +279,7 @@
 
 
 // -- SinglePayloadNontrivial destroyBuffer
-// CHECK: define linkonce_odr hidden void @"$s20enum_value_semantics23SinglePayloadNontrivialOwxx"(%swift.opaque* noalias [[OBJ:%.*]], %swift.type* %SinglePayloadNontrivial) {{.*}} {
+// CHECK: define internal void @"$s20enum_value_semantics23SinglePayloadNontrivialOwxx"(%swift.opaque* noalias [[OBJ:%.*]], %swift.type* %SinglePayloadNontrivial) {{.*}} {
 // CHECK:      [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %T20enum_value_semantics23SinglePayloadNontrivialO*
 // CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %T20enum_value_semantics23SinglePayloadNontrivialO* [[ADDR]] to i64*
 // CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
@@ -309,7 +309,7 @@
 
 
 // -- MultiPayloadTrivial getEnumTag
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics19MultiPayloadTrivialOwug"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics19MultiPayloadTrivialOwug"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics19MultiPayloadTrivialO*
 // CHECK-NEXT: [[PAYLOAD:%.*]] = bitcast %T20enum_value_semantics19MultiPayloadTrivialO* [[SELF]] to i64*
 
@@ -334,12 +334,12 @@
 // CHECK-NEXT: ret i32 [[TAG]]
 
 // -- MultiPayloadTrivial destructiveProjectEnumData
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics19MultiPayloadTrivialOwup"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics19MultiPayloadTrivialOwup"
 // CHECK:      ret void
 
 
 // -- MultiPayloadTrivial destructiveInjectEnumTag
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics19MultiPayloadTrivialOwui"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics19MultiPayloadTrivialOwui"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics19MultiPayloadTrivialO*
 // CHECK-NEXT: [[IS_PAYLOAD:%.*]] = icmp uge i32 %tag, 2
 // CHECK-NEXT: br i1 [[IS_PAYLOAD]], label %[[HAS_NO_PAYLOAD:.*]], label %[[HAS_PAYLOAD:.*]]
@@ -379,7 +379,7 @@
 
 
 // -- MultiPayloadNoEmptyCases getEnumTag
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics24MultiPayloadNoEmptyCasesOwug"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics24MultiPayloadNoEmptyCasesOwug"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics24MultiPayloadNoEmptyCasesO*
 // CHECK-NEXT: [[PAYLOAD:%.*]] = bitcast %T20enum_value_semantics24MultiPayloadNoEmptyCasesO* [[SELF]] to i64*
 // CHECK-NEXT: [[NO_PAYLOAD_TAG_TMP:%.*]] = load i64, i64* [[PAYLOAD]], align 8
@@ -393,12 +393,12 @@
 // CHECK-NEXT: ret i32 [[EXTRA_TAG]]
 
 // -- MultiPayloadNoEmptyCases destructiveProjectEnumData
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics24MultiPayloadNoEmptyCasesOwup"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics24MultiPayloadNoEmptyCasesOwup"
 // CHECK:      ret void
 
 
 // -- MultiPayloadNoEmptyCases destructiveInjectEnumTag
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics24MultiPayloadNoEmptyCasesOwui"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics24MultiPayloadNoEmptyCasesOwui"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics24MultiPayloadNoEmptyCasesO*
 // CHECK-NEXT: [[TAG:%.*]] = trunc i32 %tag to i1
 
@@ -415,7 +415,7 @@
 
 
 // -- MultiPayloadEmptyPayload getEnumTag
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics017MultiPayloadEmptyE0Owug"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics017MultiPayloadEmptyE0Owug"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics017MultiPayloadEmptyE0O*
 
 //   -- Load the tag from the extra tag area
@@ -426,12 +426,12 @@
 
 
 // -- MultiPayloadEmptyPayload destructiveProjectEnumData
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics017MultiPayloadEmptyE0Owup"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics017MultiPayloadEmptyE0Owup"
 // CHECK:      ret void
 
 
 // -- MultiPayloadEmptyPayload destructiveInjectEnumTag
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics017MultiPayloadEmptyE0Owui"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics017MultiPayloadEmptyE0Owui"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics017MultiPayloadEmptyE0O*
 
 //   -- Store the tag in the extra tag area
@@ -447,7 +447,7 @@
 
 
 // -- MultiPayloadNontrivial destroyBuffer
-// CHECK: define linkonce_odr hidden void @"$s20enum_value_semantics22MultiPayloadNontrivialOwxx"(%swift.opaque* noalias [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivial)
+// CHECK: define internal void @"$s20enum_value_semantics22MultiPayloadNontrivialOwxx"(%swift.opaque* noalias [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivial)
 // CHECK:      [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %T20enum_value_semantics22MultiPayloadNontrivialO*
 // CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %T20enum_value_semantics22MultiPayloadNontrivialO* [[ADDR]] to { i64, i64 }*
 // CHECK-NEXT: [[PAYLOAD_0_ADDR:%.*]] = getelementptr
@@ -466,18 +466,18 @@
 //
 
 
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics19MultiPayloadGenericOwug"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics19MultiPayloadGenericOwug"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics19MultiPayloadGenericO*
 // CHECK-NEXT: [[OPAQUE:%.*]] = bitcast %T20enum_value_semantics19MultiPayloadGenericO* [[SELF]] to %swift.opaque*
 // CHECK-NEXT: [[TAG:%.*]] = call i32 @swift_getEnumCaseMultiPayload(%swift.opaque* [[OPAQUE]], %swift.type* %"MultiPayloadGeneric<T>")
 // CHECK-NEXT: ret i32 [[TAG]]
 
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics19MultiPayloadGenericOwup"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics19MultiPayloadGenericOwup"
 // CHECK:      ret void
 
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics19MultiPayloadGenericOwui"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics19MultiPayloadGenericOwui"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics19MultiPayloadGenericO*
 // CHECK:      [[OPAQUE:%.*]] = bitcast %T20enum_value_semantics19MultiPayloadGenericO* [[SELF]] to %swift.opaque*
 // CHECK-NEXT: call void @swift_storeEnumTagMultiPayload(%swift.opaque* [[OPAQUE]], %swift.type* %"MultiPayloadGeneric<T>", i32 %tag)
@@ -490,7 +490,7 @@
 
 
 // -- MultiPayloadNontrivialSpareBits destroyBuffer
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics31MultiPayloadNontrivialSpareBitsOwxx"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics31MultiPayloadNontrivialSpareBitsOwxx"
 // CHECK-SAME: (%swift.opaque* noalias [[OBJ:%.*]], %swift.type* %MultiPayloadNontrivialSpareBits) {{.*}} {
 // CHECK:      [[ADDR:%.*]] = bitcast %swift.opaque* [[OBJ]] to %T20enum_value_semantics31MultiPayloadNontrivialSpareBitsO*
 // CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = bitcast %T20enum_value_semantics31MultiPayloadNontrivialSpareBitsO* [[ADDR]] to { i64, i64 }*
@@ -502,7 +502,7 @@
 // CHECK-NEXT: ret void
 
 
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics31MultiPayloadNontrivialSpareBitsOwug"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics31MultiPayloadNontrivialSpareBitsOwug"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics31MultiPayloadNontrivialSpareBitsO*
 
 //   -- Load the payload
@@ -529,7 +529,7 @@
 // CHECK-NEXT: [[TAG:%.*]] = select i1 [[IS_PAYLOAD]], i32 [[NO_PAYLOAD_TAG2]], i32 [[SPARE_TAG]]
 // CHECK-NEXT: ret i32 [[TAG]]
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics31MultiPayloadNontrivialSpareBitsOwup"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics31MultiPayloadNontrivialSpareBitsOwup"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to { i64, i64 }*
 
 //   -- Load the payload
@@ -550,7 +550,7 @@
 // CHECK-NEXT: ret void
 
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics31MultiPayloadNontrivialSpareBitsOwui"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics31MultiPayloadNontrivialSpareBitsOwui"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics31MultiPayloadNontrivialSpareBitsO*
 // CHECK-NEXT: [[IS_PAYLOAD:%.*]] = icmp uge i32 %tag, 3
 // CHECK-NEXT: br i1 [[IS_PAYLOAD]], label %[[HAS_NO_PAYLOAD:.*]], label %[[HAS_PAYLOAD:.*]]
@@ -609,7 +609,7 @@
 // CHECK-NEXT: ret void
 
 
-// CHECK-LABEL: define linkonce_odr hidden i32 @"$s20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0Owug"
+// CHECK-LABEL: define internal i32 @"$s20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0Owug"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0O*
 
 //   -- Load the payload
@@ -634,7 +634,7 @@
 // CHECK-NEXT: ret i32 [[RESULT]]
 
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0Owup"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0Owup"
 // CHECK:      [[PAYLOAD_ADDR:%.*]] = bitcast %swift.opaque* %value to i64*
 // CHECK-NEXT: [[PAYLOAD:%.*]] = load i64, i64* [[PAYLOAD_ADDR]], align 8
 //                                                         -- 0x7fffffffffffffff
@@ -644,7 +644,7 @@
 // CHECK-NEXT: ret void
 
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0Owui"
+// CHECK-LABEL: define internal void @"$s20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0Owui"
 // CHECK:      [[SELF:%.*]] = bitcast %swift.opaque* %value to %T20enum_value_semantics029MultiPayloadSpareBitsAndExtraG0O*
 // CHECK-NEXT: [[SPARE_TAG_TMP3:%.*]] = and i32 %tag, 1
 
diff --git a/test/IRGen/enum_value_semantics_special_cases.sil b/test/IRGen/enum_value_semantics_special_cases.sil
index 2c70968..985d484 100644
--- a/test/IRGen/enum_value_semantics_special_cases.sil
+++ b/test/IRGen/enum_value_semantics_special_cases.sil
@@ -11,7 +11,7 @@
   case None
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s34enum_value_semantics_special_cases18NullableRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %NullableRefcounted) {{.*}} {
+// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases18NullableRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %NullableRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T34enum_value_semantics_special_cases18NullableRefcountedO*
 // CHECK:   %1 = bitcast %T34enum_value_semantics_special_cases18NullableRefcountedO* %0 to %swift.refcounted**
@@ -20,7 +20,7 @@
 // CHECK:   ret void
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s34enum_value_semantics_special_cases18NullableRefcountedOwcp"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableRefcounted) {{.*}} {
+// CHECK-LABEL: define internal %swift.opaque* @"$s34enum_value_semantics_special_cases18NullableRefcountedOwcp"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases18NullableRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases18NullableRefcountedO*
@@ -33,7 +33,7 @@
 // CHECK:   ret %swift.opaque* %6
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s34enum_value_semantics_special_cases18NullableRefcountedOwca"(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableRefcounted) {{.*}} {
+// CHECK-LABEL: define internal %swift.opaque* @"$s34enum_value_semantics_special_cases18NullableRefcountedOwca"(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases18NullableRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases18NullableRefcountedO*
@@ -48,7 +48,7 @@
 // CHECK:   ret %swift.opaque* %7
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s34enum_value_semantics_special_cases18NullableRefcountedOwta"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableRefcounted) {{.*}} {
+// CHECK-LABEL: define internal %swift.opaque* @"$s34enum_value_semantics_special_cases18NullableRefcountedOwta"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases18NullableRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases18NullableRefcountedO*
@@ -69,7 +69,7 @@
   case None
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %NullableBlockRefcounted) {{.*}} {
+// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %NullableBlockRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
 // CHECK:   %1 = bitcast %T34enum_value_semantics_special_cases23NullableBlockRefcountedO* %0 to %objc_block**
@@ -78,7 +78,7 @@
 // CHECK:   ret void
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwcp"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
+// CHECK-LABEL: define internal %swift.opaque* @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwcp"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
@@ -91,7 +91,7 @@
 // CHECK:   ret %swift.opaque* %6
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwca"(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
+// CHECK-LABEL: define internal %swift.opaque* @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwca"(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
@@ -106,7 +106,7 @@
 // CHECK:   ret %swift.opaque* %7
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwta"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
+// CHECK-LABEL: define internal %swift.opaque* @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwta"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %NullableBlockRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %dest to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
 // CHECK:   %1 = bitcast %swift.opaque* %src to %T34enum_value_semantics_special_cases23NullableBlockRefcountedO*
@@ -127,7 +127,7 @@
   case B
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s34enum_value_semantics_special_cases23MultipleEmptyRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %MultipleEmptyRefcounted) {{.*}} {
+// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases23MultipleEmptyRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %MultipleEmptyRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T34enum_value_semantics_special_cases23MultipleEmptyRefcountedO*
 // CHECK:   %1 = bitcast %T34enum_value_semantics_special_cases23MultipleEmptyRefcountedO* %0 to i64*
@@ -166,7 +166,7 @@
   case None
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s34enum_value_semantics_special_cases13AllRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %AllRefcounted) {{.*}} {
+// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases13AllRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %AllRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T34enum_value_semantics_special_cases13AllRefcountedO*
 // CHECK:   %1 = bitcast %T34enum_value_semantics_special_cases13AllRefcountedO* %0 to i64*
@@ -178,7 +178,7 @@
 // CHECK:   ret void
 // CHECK: }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s34enum_value_semantics_special_cases13AllRefcountedOwcp"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %AllRefcounted)
+// CHECK-LABEL: define internal %swift.opaque* @"$s34enum_value_semantics_special_cases13AllRefcountedOwcp"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %AllRefcounted)
 // --                              0x3fffffffffffffff
 // CHECK:         %4 = and i64 %3, 4611686018427387903
 // CHECK:         %5 = inttoptr i64 %4 to %swift.refcounted*
@@ -196,5 +196,5 @@
   case Nothing
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s34enum_value_semantics_special_cases22AllRefcountedTwoSimpleOwxx"
+// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases22AllRefcountedTwoSimpleOwxx"
 // CHECK:   call void @"$s34enum_value_semantics_special_cases22AllRefcountedTwoSimpleOWOy"
diff --git a/test/IRGen/enum_value_semantics_special_cases_objc.sil b/test/IRGen/enum_value_semantics_special_cases_objc.sil
index 62dde4d..ce6b6ff 100644
--- a/test/IRGen/enum_value_semantics_special_cases_objc.sil
+++ b/test/IRGen/enum_value_semantics_special_cases_objc.sil
@@ -9,7 +9,7 @@
   case Ref(Builtin.UnknownObject)
   case None
 }
-// CHECK-LABEL: define linkonce_odr hidden void @"$s39enum_value_semantics_special_cases_objc22NullableObjCRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %NullableObjCRefcounted) {{.*}} {
+// CHECK-LABEL: define internal void @"$s39enum_value_semantics_special_cases_objc22NullableObjCRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %NullableObjCRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T39enum_value_semantics_special_cases_objc22NullableObjCRefcountedO*
 // CHECK:   %1 = bitcast %T39enum_value_semantics_special_cases_objc22NullableObjCRefcountedO* %0 to %objc_object**
@@ -30,7 +30,7 @@
   case None
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s39enum_value_semantics_special_cases_objc18AllMixedRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %AllMixedRefcounted) {{.*}} {
+// CHECK-LABEL: define internal void @"$s39enum_value_semantics_special_cases_objc18AllMixedRefcountedOwxx"(%swift.opaque* noalias %object, %swift.type* %AllMixedRefcounted) {{.*}} {
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T39enum_value_semantics_special_cases_objc18AllMixedRefcountedO*
 // CHECK:   %1 = bitcast %T39enum_value_semantics_special_cases_objc18AllMixedRefcountedO* %0 to i64*
@@ -50,7 +50,7 @@
   case Nothing
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s39enum_value_semantics_special_cases_objc27AllMixedRefcountedTwoSimpleOwxx"
+// CHECK-LABEL: define internal void @"$s39enum_value_semantics_special_cases_objc27AllMixedRefcountedTwoSimpleOwxx"
 // CHECK:   call void @"$s39enum_value_semantics_special_cases_objc27AllMixedRefcountedTwoSimpleOWOy"
 
 struct Val {
@@ -64,7 +64,7 @@
   case None
 }
 
-// CHECK-LABEL: define linkonce_odr hidden void @"$s39enum_value_semantics_special_cases_objc27MixedRefcountedWithIndirectOwxx"(%swift.opaque* noalias %object, %swift.type* %MixedRefcountedWithIndirect)
+// CHECK-LABEL: define internal void @"$s39enum_value_semantics_special_cases_objc27MixedRefcountedWithIndirectOwxx"(%swift.opaque* noalias %object, %swift.type* %MixedRefcountedWithIndirect)
 // CHECK: entry:
 // CHECK:   %0 = bitcast %swift.opaque* %object to %T39enum_value_semantics_special_cases_objc27MixedRefcountedWithIndirectO*
 // CHECK:   %1 = bitcast %T39enum_value_semantics_special_cases_objc27MixedRefcountedWithIndirectO* %0 to i64*
diff --git a/test/IRGen/exactcast.sil b/test/IRGen/exactcast.sil
index 835829a..805e95a 100644
--- a/test/IRGen/exactcast.sil
+++ b/test/IRGen/exactcast.sil
@@ -9,7 +9,7 @@
 import SwiftShims
 
 class Node {
-  @sil_stored var index: Int { get set }
+  @_hasStorage var index: Int { get set }
   init(index: Int)
   func check() -> Int
   @objc deinit
diff --git a/test/IRGen/exclusivity.sil b/test/IRGen/exclusivity.sil
index b9156c8..4d226ff 100644
--- a/test/IRGen/exclusivity.sil
+++ b/test/IRGen/exclusivity.sil
@@ -5,7 +5,7 @@
 import Swift
 
 class A {
-   @sil_stored final var x: Int { get set }
+   @_hasStorage final var x: Int { get set }
    init(x: Int)
 }
 sil_vtable A {}
diff --git a/test/IRGen/existentials_objc.sil b/test/IRGen/existentials_objc.sil
index 2371b6f..d31aec0 100644
--- a/test/IRGen/existentials_objc.sil
+++ b/test/IRGen/existentials_objc.sil
@@ -186,7 +186,7 @@
 class NSObject {}
 
 class TestC {
-  @sil_stored unowned final let t: @sil_unowned NSObject & TestP
+  @_hasStorage unowned final let t: @sil_unowned NSObject & TestP
   init(t: NSObject & TestP)
 }
 
diff --git a/test/IRGen/generic_enums.swift b/test/IRGen/generic_enums.swift
index 31286b3..c475aa0 100644
--- a/test/IRGen/generic_enums.swift
+++ b/test/IRGen/generic_enums.swift
@@ -5,6 +5,4 @@
   var b: Foo<A1>
 }
 
-enum Foo<A>{
-  case bar
-}
+enum Foo<A> {}
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index aa33202..1ce6ed2 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -215,7 +215,7 @@
 // Check that we directly delegate buffer witnesses to a single dynamic field:
 
 //   initializeBufferWithCopyOfBuffer
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s15generic_structs13SingleDynamicVwCP"([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %"SingleDynamic<T>") {{.*}} {
+// CHECK-LABEL: define internal %swift.opaque* @"$s15generic_structs13SingleDynamicVwCP"([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %"SingleDynamic<T>") {{.*}} {
 // CHECK:      %T = load %swift.type*,
 // CHECK:      [[T0:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
@@ -256,14 +256,10 @@
 // CHECK: [[T0_GEP:%.*]] = getelementptr inbounds i8*, i8** %T.ParentHasAssociatedType, i32 1
 // CHECK: [[T0:%.*]] = load i8*, i8** [[T0_GEP]]
 // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i8**
-// CHECK: [[T4:%.*]] = call %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, i8** %T.HasAssociatedType, %swift.type* %T, %swift.protocol_requirement* @"$s15generic_structs17HasAssociatedTypeTL", %swift.protocol_requirement* @"$s5Assoc15generic_structs17HasAssociatedTypePTl")
+// CHECK: [[T4:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, i8** %T.HasAssociatedType, %swift.type* %T, %swift.protocol_requirement* @"$s15generic_structs17HasAssociatedTypeTL", %swift.protocol_requirement* @"$s5Assoc15generic_structs17HasAssociatedTypePTl")
 
 // CHECK: %T.Assoc = extractvalue %swift.metadata_response [[T4]], 0
+// CHECK:   %T.Assoc.HasAssociatedType = call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** %T.ParentHasAssociatedType, %swift.type* %T, %swift.type* %T.Assoc,
 
-// CHECK:   [[T0:%.*]] = getelementptr inbounds i8*, i8** %T.ParentHasAssociatedType, i32 2
-// CHECK:   [[T1:%.*]] = load i8*, i8** [[T0]],
-// CHECK:   [[T2:%.*]] = bitcast i8* [[T1]] to i8** (%swift.type*, %swift.type*, i8**)*
-// CHECK:   %T.Assoc.HasAssociatedType = call swiftcc i8** [[T2]](%swift.type* %T.Assoc, %swift.type* %T, i8** %T.ParentHasAssociatedType)
-
-// CHECK:   [[T2:%.*]] = call %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, i8** %T.Assoc.HasAssociatedType, %swift.type* %T.Assoc, %swift.protocol_requirement* @"$s15generic_structs17HasAssociatedTypeTL", %swift.protocol_requirement* @"$s5Assoc15generic_structs17HasAssociatedTypePTl")
+// CHECK:   [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, i8** %T.Assoc.HasAssociatedType, %swift.type* %T.Assoc, %swift.protocol_requirement* @"$s15generic_structs17HasAssociatedTypeTL", %swift.protocol_requirement* @"$s5Assoc15generic_structs17HasAssociatedTypePTl")
 // CHECK:   %T.Assoc.Assoc = extractvalue %swift.metadata_response [[T2]], 0
diff --git a/test/IRGen/generic_types.swift b/test/IRGen/generic_types.swift
index 4b3cc2d..31c1cfa 100644
--- a/test/IRGen/generic_types.swift
+++ b/test/IRGen/generic_types.swift
@@ -147,14 +147,15 @@
   typealias A = X1
 }
 
-// Check for correct root generic parameters in the generic requirements of X3.
-// CHECK-LABEL: @"$sq_1A13generic_types2P2P_MXA" = linkonce_odr hidden constant
+// Check for correct generic parameters in the nominal type descriptor
+// CHECK-LABEL: @"$s13generic_types2X3VMn" =
 
 // Root: generic parameter 1
-// CHECK-SAME: i32 1
+// CHECK-SAME: @"symbolic q_"
 
-// Protocol P2
-// CHECK-SAME: $s13generic_types2P2Mp
+// U.A (via P2)
+// CHECK-SAME: @"symbolic 1A_____Qy_ 13generic_types2P2P
+
 struct X3<T, U> where U: P2, U.A: P1 { }
 
 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} internal %swift.type* @"$s13generic_types1ACMi"(%swift.type_descriptor*, i8**, i8*) {{.*}} {
diff --git a/test/IRGen/indirect_enum.sil b/test/IRGen/indirect_enum.sil
index c02ca2e..9ecc1cf 100644
--- a/test/IRGen/indirect_enum.sil
+++ b/test/IRGen/indirect_enum.sil
@@ -2,8 +2,8 @@
 
 import Swift
 
-// CHECK-64: @"$s13indirect_enum5TreeAOWV" = internal constant {{.*}} i8* inttoptr ([[WORD:i64]] 8 to i8*), i8* inttoptr (i64 2162695 to i8*), i8* inttoptr (i64 8 to i8*)
-// CHECK-32: @"$s13indirect_enum5TreeAOWV" = internal constant {{.*}} i8* inttoptr ([[WORD:i32]] 4 to i8*), i8* inttoptr (i32 2162691 to i8*), i8* inttoptr (i32 4 to i8*)
+// CHECK-64: @"$s13indirect_enum5TreeAOWV" = internal constant {{.*}} i8* inttoptr ([[WORD:i64]] 8 to i8*), i8* inttoptr (i64 2424839 to i8*), i8* inttoptr (i64 8 to i8*)
+// CHECK-32: @"$s13indirect_enum5TreeAOWV" = internal constant {{.*}} i8* inttoptr ([[WORD:i32]] 4 to i8*), i8* inttoptr (i32 2424835 to i8*), i8* inttoptr (i32 4 to i8*)
 
 // CHECK-NOT: define{{( protected)?}} private %swift.type** @get_field_types_TreeA
 indirect enum TreeA<T> {
diff --git a/test/IRGen/keypath_witness_overrides.swift b/test/IRGen/keypath_witness_overrides.swift
index 687601f..6649ee1 100644
--- a/test/IRGen/keypath_witness_overrides.swift
+++ b/test/IRGen/keypath_witness_overrides.swift
@@ -5,7 +5,7 @@
 import protocol_overrides
 
 // CHECK: @keypath = private global
-// CHECK-SAME: %swift.method_descriptor* @"$s18protocol_overrides14OriginalGetterPy7ElementQz5IndexQzcigTq"
+// CHECK-SAME: %swift.method_descriptor** @"got.$s18protocol_overrides14OriginalGetterPy7ElementQz5IndexQzcigTq"
 public func getWritableKeyPath<OS: OverridesSetter>(_ c: OS, index: OS.Index) -> AnyKeyPath
 where OS.Index: Hashable {
   let keypath = \OS.[index]
diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil
index 38b39c8..6c1bb5d 100644
--- a/test/IRGen/keypaths.sil
+++ b/test/IRGen/keypaths.sil
@@ -33,208 +33,190 @@
   subscript<U: Hashable>(x: U) -> T { get set }
 }
 
+class C1: C { }
+class C2: C1 {
+  var reabstracted: () -> ()
+}
+
 sil_vtable C {}
+sil_vtable C1 {}
+sil_vtable C2 {}
 
 // CHECK: %TSi = type <{ [[WORD:i.*]] }>
 
 // -- %a: S.x
-// CHECK: [[KP_A:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
+// CHECK: [[KP_A:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic 8keypaths1SV"
+// CHECK-SAME: @"symbolic Si
 //               -- instantiable in-line, size 4
 // CHECK-SAME: <i32 0x8000_0004>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- offset of S.x, mutable
 // CHECK-SAME: <i32 0x0180_0000> }>
 
 // -- %b: S.y
-// CHECK: [[KP_B:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
+// CHECK: [[KP_B:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic 8keypaths1SV
+// CHECK-SAME: @"symbolic SS
 //               -- instantiable in-line, size 4
 // CHECK-SAME: <i32 0x8000_0004>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- offset of S.y, immutable
 // CHECK-32-SAME: <i32 0x0100_0004> }>
 // CHECK-64-SAME: <i32 0x0100_0008> }>
 
 // -- %c: S.z
-// CHECK: [[KP_C:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
+// CHECK: [[KP_C:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic 8keypaths1SV
+// CHECK-SAME: @"symbolic 8keypaths1CC
 //               -- instantiable in-line, size 4
 // CHECK-SAME: <i32 0x8000_0004>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- offset of S.z, mutable
 // CHECK-32-SAME: <i32 0x0180_0010> }>
 // CHECK-64-SAME: <i32 0x0180_0018> }>
 
 // -- %d: C.x
-// CHECK: [[KP_D:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
+// CHECK: [[KP_D:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
 //               -- instantiable in-line, size 4
 // CHECK-SAME: <i32 0x8000_0004>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- 0x0300_0000 (class) + mutable + offset of C.x
 // CHECK-32-SAME: <i32 0x0380_0008> }>
 // CHECK-64-SAME: <i32 0x0380_0010> }>
 
 // -- %e: C.y
-// CHECK: [[KP_E:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
+// CHECK: [[KP_E:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
 //               -- instantiable in-line, size 4
 // CHECK-SAME: <i32 0x8000_0004>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- 0x0300_0000 (class) + immutable + offset of C.y
 // CHECK-32-SAME: <i32 0x0300_000c> }>
 // CHECK-64-SAME: <i32 0x0300_0018> }>
 
 // -- %f: C.z
-// CHECK: [[KP_F:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
+// CHECK: [[KP_F:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
 //               -- instantiable in-line, size 4
 // CHECK-SAME: <i32 0x8000_0004>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
 // -- 0x0300_0000 (class) + mutable offset of C.z
 // CHECK-32-SAME: <i32 0x0380_0018> }>
 // CHECK-64-SAME: <i32 0x0380_0028> }>
 
 // -- %g: S.z.x
-// CHECK: [[KP_G:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
+// CHECK: [[KP_G:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
 //                  -- instantiable in-line, size 12
-// CHECK-32-SAME: <i32 0x8000_000c>,
-//                  -- instantiable in-line, size 20
-// CHECK-64-SAME: <i32 0x8000_0014>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
+// CHECK-SAME: <i32 0x8000_000c>,
 // -- offset of S.z
 // CHECK-32-SAME: <i32 0x0180_0010>,
 // CHECK-64-SAME: <i32 0x0180_0018>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
-// CHECK: %swift.type* (i8*)*
+// CHECK: @"symbolic
 // -- 0x0300_0000 (class) + offset of C.x
 // CHECK-32-SAME: <i32 0x0380_0008> }>
 // CHECK-64-SAME: <i32 0x0380_0010> }>
 
 // -- %h: C.z.x
-// CHECK: [[KP_H:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
-//                  -- instantiable in-line, size 12
-// CHECK-32-SAME: <i32 0x8000_000c>,
-//                  -- instantiable in-line, size 20
-// CHECK-64-SAME: <i32 0x8000_0014>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
+// CHECK: [[KP_H:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: <i32 0x8000_000c>,
 // -- 0x0300_0000 (class) + offset of C.z
 // CHECK-32-SAME: <i32 0x0380_0018>,
 // CHECK-64-SAME: <i32 0x0380_0028>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
-// CHECK: %swift.type* (i8*)*
+// CHECK: @"symbolic
 // -- offset of S.x
 // CHECK-SAME: <i32 0x0180_0000> }>
 
 // -- %k: computed
-// CHECK: [[KP_K:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
-//              -- instantiable in-line, size 24
-// CHECK-64-SAME: <i32 0x8000_0018>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
+// CHECK: [[KP_K:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
 //              -- instantiable in-line, size 12
-// CHECK-32-SAME: <i32 0x8000_000c>,
-// -- computed, get-only, identified by function pointer, no args
-// CHECK-SAME: <i32 0x0200_0000>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
-// CHECK-SAME: void ()* @k_id,
-// CHECK-SAME: void (%TSi*, %T8keypaths1SV*)* @k_get }>
+// CHECK-SAME: <i32 0x8000_000c>,
+// -- computed, get-only, identified by (indirected) function pointer, no args
+// CHECK-SAME: <i32 0x0200_0002>,
+// CHECK-SAME: @got.k_id
+// CHECK-SAME: void (%TSi*, %T8keypaths1SV*)* @k_get
 
 // -- %l: computed
-// CHECK: [[KP_L:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
-//              -- instantiable in-line, size 32
-// CHECK-64-SAME: <i32 0x8000_0020>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
+// CHECK: [[KP_L:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
 //              -- instantiable in-line, size 16
-// CHECK-32-SAME: <i32 0x8000_0010>,
-// -- computed, settable, nonmutating, identified by pointer, no args
-// CHECK-SAME: <i32 0x0240_0000>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
-// CHECK-SAME: %swift.method_descriptor* getelementptr inbounds (<{{.*}}>, <{{.*}}>* @"$s8keypaths1CCMn", i32 0, i32 13),
-// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_get,
-// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_set }>
+// CHECK-SAME: <i32 0x8000_0010>,
+// -- computed, settable, nonmutating, identified by indirect pointer, no args
+// CHECK-SAME: <i32 0x0240_0002>,
+// CHECK-SAME: @"got.$s8keypaths1CC1wSivgTq"
+// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_get
+// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_set
 
 // -- %m: computed
-// CHECK: [[KP_M:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)*
-// CHECK-SAME: %swift.type* (i8*)*
-//              -- instantiable in-line, size 32
-// CHECK-64-SAME: <i32 0x8000_0020>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
+// CHECK: [[KP_M:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: [[WORD]]* @keypath_once
+// CHECK-SAME: @"symbolic
+// CHECK-SAME: @"symbolic
 //              -- instantiable in-line, size 16
-// CHECK-32-SAME: <i32 0x8000_0010>,
+// CHECK-SAME: <i32 0x8000_0010>,
 // -- computed, settable, nonmutating, identified by property offset, no args
 // CHECK-SAME: <i32 0x02e0_0000>,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
 // CHECK-SAME: [[WORD]]
-// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_get,
-// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_set }>
+// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_get
+// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* @m_set
 
+// -- %m2: reabstracted
+// Note: the contents here aren't interesting. The test triggered infinite
+// looping in the compiler at one point.
+// CHECK: [[KP_M:@keypath.*]] = private global <{ {{.*}} }> <{
 
 // -- %i: Gen<A>.x
-// CHECK: [[KP_I:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)* [[I_GET_GEN_A_A:@[a-z_.0-9]+]],
-// CHECK-SAME: %swift.type* (i8*)* [[I_GET_A:@[a-z_.0-9]+]],
+// CHECK: [[KP_I:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: i32 0
+// CHECK-SAME: @"keypath_get_type
+// CHECK-SAME: @"keypath_get_type
 //             -- size 8
 // CHECK-SAME: i32 8,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
 //             -- struct with runtime-resolved offset, mutable
 // CHECK-SAME: <i32 0x01fffffe>,
 // CHECK-32-SAME: i32 16 }>
 // CHECK-64-SAME: i32 32 }>
 
 // -- %j: Gen<A>.y
-// CHECK: [[KP_J:@keypath.*]] = private global <{ {{.*}} }> <{
-// CHECK-SAME: [[WORD]] 0,
-// CHECK-SAME: %swift.type* (i8*)* [[J_GET_GEN_A_A:@[a-z_.0-9]+]],
-// CHECK-SAME: %swift.type* (i8*)* [[J_GET_A:@[a-z_.0-9]+]],
+// CHECK: [[KP_J:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
+// CHECK-SAME: i32 0
+// CHECK-SAME: @"keypath_get_type
+// CHECK-SAME: @"keypath_get_type
 //             -- size 8
 // CHECK-SAME: i32 8,
-// CHECK-64-SAME: [4 x i8] zeroinitializer,
 //             -- struct with runtime-resolved offset
 // CHECK-SAME: <i32 0x01fffffe>,
 // CHECK-32-SAME: i32 20 }>
 // CHECK-64-SAME: i32 36 }>
 
 // -- %t
-// CHECK: [[KP_T:@keypath.*]] = private global <{ {{.*}} }> <{ {{.*}} i32 1, {{.*}} @"$s8keypaths1GV1xxvpMV",
-// CHECK-SAME:   %swift.type* (i8*)* [[T_GET_TYPE_A:@[A-Za-z0-9._]*]],
-//            -- computed get-only property
-// CHECK-SAME:   <i32 0x0208_0000>
+// CHECK: [[KP_T:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ {{.*}} i32 1, {{.*}} @"got.$s8keypaths1GV1xxvpMV"
+// CHECK-SAME:   @"keypath_get_type
+//            -- computed get-only property, identified by indirect pointer
+// CHECK-SAME:   <i32 0x0208_0002>
 
 // -- %u
-// CHECK: [[KP_U:@keypath.*]] = private global <{ {{.*}} }> <{ {{.*}} i32 3, {{.*}} @"$s8keypaths1GVyxqd__cSHRd__luipMV",
-// CHECK-SAME:   %swift.type* (i8*)* [[U_GET_TYPE_A:@[A-Za-z0-9._]*]],
-// CHECK-SAME:   %swift.type* (i8*)* [[U_GET_TYPE_B:@[A-Za-z0-9._]*]],
-// CHECK-SAME:   i8** (i8*)* [[U_GET_WITNESS_HASHABLE:@[A-Za-z0-9._]*]],
-//            -- computed get-only property
-// CHECK-SAME:   <i32 0x0208_0000>
+// CHECK: [[KP_U:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ {{.*}} i32 3, {{.*}} @"got.$s8keypaths1GVyxqd__cSHRd__luipMV"
+// CHECK-SAME:   @"keypath_get_type
+// CHECK-SAME:   @"keypath_get_type
+// CHECK-SAME:   @"keypath_get_witness_table
+//            -- computed get-only property, identified by indirect pointer
+// CHECK-SAME:   <i32 0x0208_0002>
 
 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @stored_property_fixed_offsets()
 sil @stored_property_fixed_offsets : $@convention(thin) () -> () {
@@ -261,18 +243,39 @@
   %k = keypath $KeyPath<S, Int>, (root $S; gettable_property $Int, id @k_id : $@convention(thin) () -> (), getter @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int)
   %l = keypath $KeyPath<C, Int>, (root $C; settable_property $Int, id #C.w!getter.1, getter @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ())
   %m = keypath $KeyPath<S, () -> ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed () -> @out (), setter @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout S) -> ())
+  %m2 = keypath $KeyPath<C2, () -> ()>, (root $C2; settable_property $() -> (), id ##C2.reabstracted, getter @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed () -> @out (), setter @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout C2) -> ())
 
   return undef : $()
 }
 
 sil @k_id : $@convention(thin) () -> ()
-sil @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int
+sil @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int {
+bb0(%0 : @trivial $*Int, %1 : @trivial $*S):
+  unreachable
+}
 
-sil @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int
-sil @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()
+sil @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int {
+bb0(%0 : @trivial $*Int, %1 : @trivial $*C):
+  unreachable
+}
 
-sil @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed () -> @out ()
-sil @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout S) -> ()
+sil @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () {
+bb0(%0 : @trivial $*Int, %1 : @trivial $*C):
+  unreachable
+}
+
+sil @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed () -> @out () {
+bb0(%0 : @trivial $*@callee_guaranteed () -> @out (), %1 : @trivial $*S):
+  unreachable
+}
+
+sil @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout S) -> () {
+bb0(%0 : @trivial $*@callee_guaranteed () -> @out (), %1 : @trivial $*S):
+  unreachable
+}
+
+sil @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed () -> @out ()
+sil @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed () -> @out (), @inout C2) -> ()
 
 struct Gen<T, U> {
   var x: T
@@ -306,19 +309,6 @@
   return undef : $()
 }
 
-// CHECK: define private %swift.type* [[I_GET_GEN_A_A]](i8*)
-// CHECK:   [[BUF:%.*]] = bitcast i8* %0
-// CHECK:   [[A:%.*]] = load %swift.type*, %swift.type** [[BUF]]
-// CHECK:   [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s8keypaths3GenVMa"([[WORD]] 0, %swift.type* [[A]], %swift.type* [[A]])
-// CHECK:   [[GEN:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
-// CHECK:   ret %swift.type* [[GEN]]
-
-
-// CHECK: define private %swift.type* [[I_GET_A]](i8*)
-// CHECK:   [[BUF:%.*]] = bitcast i8* %0
-// CHECK:   [[A:%.*]] = load %swift.type*, %swift.type** [[BUF]]
-// CHECK:   ret %swift.type* [[A]]
-
 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @computed_property_generics
 sil @computed_property_generics : $@convention(thin) <T, U> () -> () {
 entry:
diff --git a/test/IRGen/keypaths_objc.sil b/test/IRGen/keypaths_objc.sil
index aa6b2ad..27d5da5 100644
--- a/test/IRGen/keypaths_objc.sil
+++ b/test/IRGen/keypaths_objc.sil
@@ -9,7 +9,7 @@
 
 class C: NSObject {
   @objc dynamic var x: NSString { get }
-  @sil_stored final var stored: Int
+  @_hasStorage final var stored: Int
   override init()
 }
 
@@ -17,15 +17,15 @@
 
 sil @x_get : $@convention(thin) (@in_guaranteed C) -> @out NSString
 
-// CHECK: [[KEYPATH_A:@keypath.*]] = private global
+// CHECK: [[KEYPATH_A:@keypath(\..*)?]] = private global
 // --             computed, get-only, indirect identifier
 // CHECK-SAME: <i32 0x0200_0002>,
 // CHECK-SAME: i8** @"\01L_selector(x)"
 
-// CHECK: [[KEYPATH_B:@keypath.*]] = private global
+// CHECK: [[KEYPATH_B:@keypath(\..*)?]] = private global
 // --             class mutable stored property with indirect offset
 // CHECK-SAME: <i32 0x03fffffd>,
-// CHECK-SAME: @"$s13keypaths_objc1CC6storedSivpWvd"
+// CHECK-SAME: @"got.$s13keypaths_objc1CC6storedSivpWvd"
 
 // CHECK-LABEL: define swiftcc void @objc_only_property()
 sil @objc_only_property : $@convention(thin) () -> () {
diff --git a/test/IRGen/method_linkage.swift b/test/IRGen/method_linkage.swift
index 34afd55..5e27e98 100644
--- a/test/IRGen/method_linkage.swift
+++ b/test/IRGen/method_linkage.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend -primary-file %s -emit-ir | %FileCheck %s
+// RUN: %target-swift-frontend -primary-file %s -emit-ir -enable-resilience | %FileCheck %s --check-prefix=RESILIENT
 
 // Test if all methods which go into a vtable have at least the visibility of its class.
 // Reason: Derived classes from "outside" still have to put the less visible base members
@@ -17,22 +18,26 @@
 
 class Base {
   // CHECK: define hidden swiftcc void @"$s14method_linkage4Base{{.*}}3foo0
+  // RESILIENT: define hidden swiftcc void @"$s14method_linkage4Base{{.*}}3foo0
   @inline(never)
   fileprivate func foo() {
   }
 
   // CHECK: define internal swiftcc void @"$s14method_linkage4Base{{.*}}3bar0
+  // RESILIENT: define internal swiftcc void @"$s14method_linkage4Base{{.*}}3bar0
   @inline(never)
   fileprivate final func bar() {
   }
 
   // CHECK: define hidden swiftcc void @"$s14method_linkage4Base{{.*}}5other0
+  // RESILIENT: define hidden swiftcc void @"$s14method_linkage4Base{{.*}}5other0
   @inline(never)
   fileprivate func other() {
   }
 }
 class Derived : Base {
   // CHECK: define internal swiftcc void @"$s14method_linkage7Derived{{.*}}3foo0
+  // RESILIENT: define internal swiftcc void @"$s14method_linkage7Derived{{.*}}3foo0
   @inline(never)
   fileprivate final override func foo() {
   }
@@ -40,6 +45,7 @@
 
 extension Base {
   // CHECK: define internal swiftcc void @"$s14method_linkage4Base{{.*}}7extfunc0
+  // RESILIENT: define internal swiftcc void @"$s14method_linkage4Base{{.*}}7extfunc0
   @inline(never)
   fileprivate func extfunc() {
   }
@@ -49,11 +55,13 @@
   internal init() {}
 
   // CHECK: define hidden swiftcc void @"$s14method_linkage11PublicClass{{.*}}4pfoo0
+  // RESILIENT: define hidden swiftcc void @"$s14method_linkage11PublicClass{{.*}}4pfoo0
   @inline(never)
   fileprivate func pfoo() {
   }
 
   // CHECK: define hidden swiftcc void @"$s14method_linkage11PublicClassC4pbaryyF
+  // RESILIENT: define hidden swiftcc void @"$s14method_linkage11PublicClassC4pbaryyF
   @inline(never)
   internal func pbar() {
   }
@@ -63,11 +71,13 @@
   internal init() {}
 
   // CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s14method_linkage9OpenClassC4pfoo0
+  // RESILIENT: define hidden swiftcc void @"$s14method_linkage9OpenClassC4pfoo0
   @inline(never)
   fileprivate func pfoo() {
   }
 
   // CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s14method_linkage9OpenClassC4pbaryyF
+  // RESILIENT: define hidden swiftcc void @"$s14method_linkage9OpenClassC4pbaryyF
   @inline(never)
   internal func pbar() {
   }
diff --git a/test/IRGen/multithread_keypaths.swift b/test/IRGen/multithread_keypaths.swift
new file mode 100644
index 0000000..5dcf87e
--- /dev/null
+++ b/test/IRGen/multithread_keypaths.swift
@@ -0,0 +1,11 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -c %S/Inputs/multithread_keypaths_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_keypaths
+// RUN: %target-swift-frontend -c %S/Inputs/multithread_keypaths_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_keypaths -enable-testing
+// RUN: %target-swift-frontend -c %S/Inputs/multithread_keypaths_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_keypaths -enable-resilience
+// RUN: %target-swift-frontend -c %S/Inputs/multithread_keypaths_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_keypaths -enable-testing -enable-resilience
+
+func f(_ k: WritableKeyPath<A, Int>) {}
+
+func g() {
+  f(\A.foo)
+}
diff --git a/test/IRGen/property_descriptor.sil b/test/IRGen/property_descriptor.sil
index 1649cd5..96da26f 100644
--- a/test/IRGen/property_descriptor.sil
+++ b/test/IRGen/property_descriptor.sil
@@ -7,8 +7,8 @@
 import Swift
 
 public struct ExternalGeneric<T: Comparable> {
-  @sil_stored public var ro: T { get }
-  @sil_stored public var rw: T { get set }
+  @_hasStorage public var ro: T { get }
+  @_hasStorage public var rw: T { get set }
 
   public var computedRO: T { get }
   public var computedRW: T { get set }
@@ -21,8 +21,8 @@
 }
 
 public struct External {
-  @sil_stored public var ro: Int { get }
-  @sil_stored public var rw: Int { get set }
+  @_hasStorage public var ro: Int { get }
+  @_hasStorage public var rw: Int { get set }
 
   public var computedRO: Int { get }
   public var computedRW: Int { get set }
@@ -35,8 +35,8 @@
 }
 
 public struct ExternalReabstractions<T> {
-  @sil_stored public var ro: T { get }
-  @sil_stored public var reabstracted: () -> () { get set }
+  @_hasStorage public var ro: T { get }
+  @_hasStorage public var reabstracted: () -> () { get set }
 }
 
 // -- struct property, offset resolved from field offset vector in metadata
@@ -52,27 +52,28 @@
   stored_property #ExternalGeneric.rw : $T)
 
 // CHECK: @"$s19property_descriptor15ExternalGenericV10computedROxvpMV" =
-// -- 0x0108_0000 - computed, readonly, has arguments
-// CHECK-SAME:  <{ <i32 0x0208_0000>,
-// CHECK-SAME:     @id_computed, 
-// CHECK-SAME:     [[GET_COMPUTEDRO:@keypath_get[.0-9]*]],
-// CHECK-SAME:     [[GET_ARG_LAYOUT_COMPUTEDRO:@keypath_get_arg_layout[.0-9]*]],
-// CHECK-SAME:     @swift_keyPathGenericWitnessTable,
-// CHECK-SAME:     [[ARG_INIT_COMPUTEDRO:@keypath_arg_init[.0-9]*]] }>
+// -- 0x0108_0000 - computed, readonly, has arguments, identified by indirect
+// CHECK-SAME:  <{ <i32 0x0208_0002>,
+// CHECK-SAME:     @got.id_computed
+// CHECK-SAME:     [[GET_COMPUTEDRO:@keypath_get[.0-9]*]]
+// CHECK-SAME:     [[GET_ARG_LAYOUT_COMPUTEDRO:@keypath_get_arg_layout[.0-9]*]]
+// -- default witness table
+// CHECK-SAME:     i32 0
+// CHECK-SAME:     [[ARG_INIT_COMPUTEDRO:@keypath_arg_init[.0-9]*]]
 sil_property #ExternalGeneric.computedRO <T: Comparable> (
   gettable_property $T,
     id @id_computed : $@convention(thin) () -> (),
     getter @get_computed_generic : $@convention(thin) <T: Comparable> (@in_guaranteed ExternalGeneric<T>) -> @out T)
 
 // CHECK: @"$s19property_descriptor15ExternalGenericV10computedRWxvpMV" =
-// -- 0x01c8_0000 - computed, settable, mutating, has arguments
-// CHECK-SAME:  <{ <i32 0x02c8_0000>, 
-// CHECK-SAME:     @id_computed,
-// CHECK-SAME:     [[GET_COMPUTEDRW:@keypath_get[.0-9]*]],
-// CHECK-SAME:     [[SET_COMPUTEDRW:@keypath_set[.0-9]*]],
-// CHECK-SAME:     [[GET_ARG_LAYOUT_COMPUTEDRW:@keypath_get_arg_layout[.0-9]*]],
-// CHECK-SAME:     @swift_keyPathGenericWitnessTable,
-// CHECK-SAME:     [[ARG_INIT_COMPUTEDRW:@keypath_arg_init[.0-9]*]] }>
+// -- 0x01c8_0000 - computed, settable, mutating, has arguments, indirect id
+// CHECK-SAME:  <{ <i32 0x02c8_0002>, 
+// CHECK-SAME:     @got.id_computed
+// CHECK-SAME:     [[GET_COMPUTEDRW:@keypath_get[.0-9]*]]
+// CHECK-SAME:     [[SET_COMPUTEDRW:@keypath_set[.0-9]*]]
+// CHECK-SAME:     [[GET_ARG_LAYOUT_COMPUTEDRW:@keypath_get_arg_layout[.0-9]*]]
+// CHECK-SAME:     i32 0
+// CHECK-SAME:     [[ARG_INIT_COMPUTEDRW:@keypath_arg_init[.0-9]*]]
 sil_property #ExternalGeneric.computedRW <T: Comparable> (
   settable_property $T,
     id @id_computed : $@convention(thin) () -> (),
@@ -80,14 +81,14 @@
     setter @set_computed_generic : $@convention(thin) <T: Comparable> (@in_guaranteed T, @inout ExternalGeneric<T>) -> ())
 
 // CHECK: @"$s19property_descriptor15ExternalGenericVyxqd__cSHRd__luipMV" =
-// -- 0x01c8_0000 - computed, settable, mutating, has arguments
-// CHECK-SAME:  <{ <i32 0x02c8_0000>, 
-// CHECK-SAME:     @id_computed,
-// CHECK-SAME:     [[GET_SUBSCRIPT:@keypath_get[.0-9]*]],
-// CHECK-SAME:     [[SET_SUBSCRIPT:@keypath_set[.0-9]*]],
-// CHECK-SAME:     [[GET_ARG_LAYOUT_SUBSCRIPT:@keypath_get_arg_layout[.0-9]*]],
-// CHECK-SAME:     @swift_keyPathGenericWitnessTable,
-// CHECK-SAME:     [[ARG_INIT_SUBSCRIPT:@keypath_arg_init[.0-9]*]] }>
+// -- 0x01c8_0000 - computed, settable, mutating, has arguments, indirect id
+// CHECK-SAME:  <{ <i32 0x02c8_0002>, 
+// CHECK-SAME:     @got.id_computed
+// CHECK-SAME:     [[GET_SUBSCRIPT:@keypath_get[.0-9]*]]
+// CHECK-SAME:     [[SET_SUBSCRIPT:@keypath_set[.0-9]*]]
+// CHECK-SAME:     [[GET_ARG_LAYOUT_SUBSCRIPT:@keypath_get_arg_layout[.0-9]*]]
+// CHECK-SAME:     i32 0
+// CHECK-SAME:     [[ARG_INIT_SUBSCRIPT:@keypath_arg_init[.0-9]*]]
 sil_property #ExternalGeneric.subscript <T: Comparable><U: Hashable> (
   settable_property $T,
     id @id_computed : $@convention(thin) () -> (),
diff --git a/test/IRGen/protocol_metadata.swift b/test/IRGen/protocol_metadata.swift
index 28ef7fb..90039af 100644
--- a/test/IRGen/protocol_metadata.swift
+++ b/test/IRGen/protocol_metadata.swift
@@ -54,7 +54,9 @@
 // CHECK-SAME:   i32 1,
 // CHECK-SAME:   i32 0,
 // AnyObject layout constraint
-// CHECK-SAME:   i32 31, i32 0, i32 0
+// CHECK-SAME:   i32 31,
+// CHECK-SAME:   @"symbolic x"
+// CHECK-SAME:   i32 0
 // CHECK-SAME: }
 
 // -- @objc protocol OPT uses ObjC symbol mangling and layout
@@ -76,11 +78,13 @@
 // CHECK-SAME:   i32 2, i32 3, i32 0
 
 // Inheritance from A
-// CHECK-SAME:   i32 128, i32 0
+// CHECK-SAME:   i32 128,
+// CHECK-SAME:   @"symbolic x"
 // CHECK-SAME: @"$s17protocol_metadata1AMp"
 
 // Inheritance from B
-// CHECK-SAME:   i32 128, i32 0
+// CHECK-SAME:   i32 128,
+// CHECK-SAME:   @"symbolic x"
 // CHECK-SAME:   @"$s17protocol_metadata1BMp"
 // CHECK: }
 
diff --git a/test/IRGen/protocol_resilience.sil b/test/IRGen/protocol_resilience.sil
index f3670aa..0f00109 100644
--- a/test/IRGen/protocol_resilience.sil
+++ b/test/IRGen/protocol_resilience.sil
@@ -25,7 +25,7 @@
 
 // Requirement signature
 // CHECK-SAME:   i32 128,
-// CHECK-SAME:   @"$sx1T19protocol_resilience17ResilientProtocolP_MXA"
+// CHECK-SAME:   @"symbolic 1T_____Qz 19protocol_resilience17ResilientProtocolP"
 // CHECK-SAME:   @"$s19protocol_resilience17ResilientProtocolMp"
 
 // Protocol requirements
@@ -82,7 +82,7 @@
 
 // CHECK: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWp" =
 
-// CHECK-SAME: internal constant [1 x i8*] [
+// CHECK-SAME: internal global [1 x i8*] [
 
 // -- conformance descriptor
 // CHECK-SAME: "$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAMc"
@@ -90,10 +90,10 @@
 // CHECK-SAME: ]
 
 
-// Witness table for conformance with resilient associated type
+// Witness table pattern for conformance with resilient associated type
 
-// CHECK: @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWP" = {{(protected )?}}hidden global [3 x i8*] [
-// CHECK-SAME:   i8* bitcast (i8** ()* @"$s19protocol_resilience23ResilientConformingTypeVAC010resilient_A005OtherC8ProtocolAAWl"
+// CHECK: @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWp" = {{(protected )?}}internal global [3 x i8*] [
+// CHECK-SAME:   @"associated conformance 19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AA1TAaDP_010resilient_A005OtherE8Protocol"
 // CHECK-SAME:   @"symbolic 19protocol_resilience23ResilientConformingTypeV"
 // CHECK-SAME: ]
 
@@ -449,7 +449,8 @@
 
   // CHECK-NEXT: entry:
   // CHECK-NEXT: [[ARG:%.*]] = bitcast %T19protocol_resilience26ConformsWithResilientAssocV* %0 to %swift.opaque*
-  // CHECK-NEXT: call swiftcc void @doSomethingAssoc(%swift.opaque* noalias nocapture [[ARG]], %swift.type* bitcast ({{i32|i64}}* getelementptr inbounds ({{.*}} @"$s19protocol_resilience26ConformsWithResilientAssocVMf", i32 0, i32 1) to %swift.type*), i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWP", i32 0, i32 0))
+  // CHECK-NEXT: [[WTABLE:%.*]] = call i8** @"$s19protocol_resilience26ConformsWithResilientAssocVAcA03HaseF0AAWl
+  // CHECK-NEXT: call swiftcc void @doSomethingAssoc(%swift.opaque* noalias nocapture [[ARG]], %swift.type* bitcast ({{i32|i64}}* getelementptr inbounds ({{.*}} @"$s19protocol_resilience26ConformsWithResilientAssocVMf", i32 0, i32 1) to %swift.type*), i8** [[WTABLE]])
 
   %fn = function_ref @doSomethingAssoc : $@convention(thin) <T : HasResilientAssoc> (@in T) -> ()
   %ignore = apply %fn<ConformsWithResilientAssoc>(%0) : $@convention(thin) <T : HasResilientAssoc> (@in T) -> ()
diff --git a/test/IRGen/protocol_resilience_descriptors.swift b/test/IRGen/protocol_resilience_descriptors.swift
index 0ed781a..883f374 100644
--- a/test/IRGen/protocol_resilience_descriptors.swift
+++ b/test/IRGen/protocol_resilience_descriptors.swift
@@ -19,7 +19,7 @@
 
 // Protocol descriptor
 // CHECK-DEFINITION-LABEL: @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsMp" ={{( protected)?}} constant
-// CHECK-DEFINITION-SAME: @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2AC_AA014OtherResilientC0TN"
+// CHECK-DEFINITION-SAME: @"default associated conformance2T218resilient_protocol29ProtocolWithAssocTypeDefaultsP_AB014OtherResilientD0"
 
 // Associated type default + flags
 // CHECK-DEFINITION-SAME: [[INT]] add
@@ -64,16 +64,10 @@
 
 // CHECK-USAGE: @"$s31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAAMc" =
 // CHECK-USAGE-SAME: $s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2AC_AA014OtherResilientC0Tn
-// CHECK-USAGE-SAME: $s31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAA2T2AdEP_AD014OtherResilientI0PWT
+// CHECK-USAGE-SAME: @"associated conformance 31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAA2T2AdEP_AD014OtherResilientI0"
 public struct ConformsWithAssocRequirements : ProtocolWithAssocTypeDefaults {
 }
 
-// CHECK-USAGE: @"$sx1T18resilient_protocol24ProtocolWithRequirementsP_MXA" =
-// CHECK-USAGE-SAME: i32 0
-// CHECK-USAGE-SAME: @"{{got.|__imp_}}$s18resilient_protocol24ProtocolWithRequirementsMp"
-// CHECK-USAGE-SAME: @"$sx1T18resilient_protocol24ProtocolWithRequirementsP_MXA"
-// CHECK-USAGE-SAME: %swift.protocol_requirement** @"{{got.|__imp_}}$s1T18resilient_protocol24ProtocolWithRequirementsPTl"
-
 // CHECK-USAGE: @"$s31protocol_resilience_descriptors21ConditionallyConformsVyxG010resilient_A024ProtocolWithRequirementsAaeFRzAA1YV1TRtzlMc"
 extension ConditionallyConforms: ProtocolWithRequirements
 where Element: ProtocolWithRequirements, Element.T == Y {
@@ -88,7 +82,7 @@
 
 // CHECK-USAGE: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.type* @"$s31protocol_resilience_descriptors17assocTypeMetadatay1TQzmxm010resilient_A024ProtocolWithRequirementsRzlF"(%swift.type*, %swift.type* [[PWD:%.*]], i8** [[WTABLE:%.*]])
 public func assocTypeMetadata<PWR: ProtocolWithRequirements>(_: PWR.Type) -> PWR.T.Type {
-  // CHECK-USAGE: call %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 0, i8** %PWR.ProtocolWithRequirements, %swift.type* %PWR, %swift.protocol_requirement* @"$s18resilient_protocol24ProtocolWithRequirementsTL", %swift.protocol_requirement* @"$s1T18resilient_protocol24ProtocolWithRequirementsPTl")
+  // CHECK-USAGE: call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 0, i8** %PWR.ProtocolWithRequirements, %swift.type* %PWR, %swift.protocol_requirement* @"$s18resilient_protocol24ProtocolWithRequirementsTL", %swift.protocol_requirement* @"$s1T18resilient_protocol24ProtocolWithRequirementsPTl")
   return PWR.T.self
 }
 
@@ -96,7 +90,6 @@
 
 // CHECK-USAGE: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s31protocol_resilience_descriptors23extractAssocConformanceyyx010resilient_A0012ProtocolWithE12TypeDefaultsRzlF"
 public func extractAssocConformance<T: ProtocolWithAssocTypeDefaults>(_: T) {
-  // CHECK-USAGE: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %T.ProtocolWithAssocTypeDefaults, [[INT]] udiv ([[INT]] sub ([[INT]] ptrtoint (%swift.protocol_requirement* @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2AC_AA014OtherResilientC0Tn" to [[INT]]), [[INT]] ptrtoint (%swift.protocol_requirement* @"$s18resilient_protocol29ProtocolWithAssocTypeDefaultsTL" to [[INT]])), [[INT]] 8)
-  // CHECK-USAGE: load i8*, i8** [[WITNESS_ADDR]]
+  // CHECK-USAGE: swift_getAssociatedConformanceWitness
   useOtherResilientProtocol(T.T2.self)
 }
diff --git a/test/IRGen/reference_storage_extra_inhabitants.sil b/test/IRGen/reference_storage_extra_inhabitants.sil
index 7ee79eb..b094e11 100644
--- a/test/IRGen/reference_storage_extra_inhabitants.sil
+++ b/test/IRGen/reference_storage_extra_inhabitants.sil
@@ -9,7 +9,7 @@
 sil_vtable C { }
 
 struct S {
-  @sil_stored unowned(unsafe) var uu: @sil_unmanaged C? { get set }
+  @_hasStorage unowned(unsafe) var uu: @sil_unmanaged C? { get set }
 }
 
 func example(_ os: S?)
diff --git a/test/IRGen/sil_witness_tables.swift b/test/IRGen/sil_witness_tables.swift
index 68cbc16..e88498b 100644
--- a/test/IRGen/sil_witness_tables.swift
+++ b/test/IRGen/sil_witness_tables.swift
@@ -42,7 +42,7 @@
 // CHECK:   i8* bitcast (void (%T18sil_witness_tables9ConformerV*, %swift.type*, i8**)* @"$s18sil_witness_tables9ConformerVAA1QA2aDP7qMethod{{[_0-9a-zA-Z]*}}FTW" to i8*)
 // CHECK: ]
 // CHECK: [[CONFORMER_P_WITNESS_TABLE]] = hidden global [5 x i8*] [
-// CHECK:   i8* bitcast (i8** ()* @"$s18sil_witness_tables14AssocConformerVAcA1AAAWl" to i8*)
+// CHECK:   @"associated conformance 18sil_witness_tables9ConformerVAA1PAA5AssocAaDP_AA1A"
 // CHECK:   "symbolic 18sil_witness_tables14AssocConformerV"
 // CHECK:   i8* bitcast (void (%swift.type*, %swift.type*, i8**)* @"$s18sil_witness_tables9ConformerVAA1PA2aDP12staticMethod{{[_0-9a-zA-Z]*}}FZTW" to i8*),
 // CHECK:   i8* bitcast (void (%T18sil_witness_tables9ConformerV*, %swift.type*, i8**)* @"$s18sil_witness_tables9ConformerVAA1PA2aDP14instanceMethod{{[_0-9a-zA-Z]*}}FTW" to i8*)
diff --git a/test/IRGen/static_initializer.sil b/test/IRGen/static_initializer.sil
index 2e79e58..9e6369e 100644
--- a/test/IRGen/static_initializer.sil
+++ b/test/IRGen/static_initializer.sil
@@ -47,7 +47,7 @@
 // CHECK: @"$s6nested1xAA2S2Vv" = {{(protected )?}}global %T18static_initializer2S2V <{ %Ts5Int32V <{ i32 2 }>, %Ts5Int32V <{ i32 3 }>, %T18static_initializer1SV <{ %Ts5Int32V <{ i32 4 }> }> }>, align 4
 
 final class TestArrayStorage {
-  @sil_stored var count: Int32
+  @_hasStorage var count: Int32
   init()
 }
 
@@ -78,8 +78,8 @@
 // CHECK: @static_aligned_array = {{(protected )?}}global %T18static_initializer16TestArrayStorageC_tailelems1c { [2 x i64] zeroinitializer, %T18static_initializer16TestArrayStorageC_tailelems1 <{ %swift.refcounted zeroinitializer, %Ts5Int32V <{ i32 2 }>, [12 x i8] undef, %Ts7Float80V <{ x86_fp80 0xK3FFE8000000000000000 }> }> }, align 16
 
 final class ClassWithEmptyField {
-  @sil_stored var x: Int32
-  @sil_stored var y: ()
+  @_hasStorage var x: Int32
+  @_hasStorage var y: ()
   init()
 }
 
diff --git a/test/IRGen/tail_alloc.sil b/test/IRGen/tail_alloc.sil
index dbd078a..18e1947 100644
--- a/test/IRGen/tail_alloc.sil
+++ b/test/IRGen/tail_alloc.sil
@@ -9,7 +9,7 @@
 
 // sizeof(TestClass) = 16 bytes header + 1 byte = 17 bytes
 class TestClass {
-  @sil_stored var a : Int8
+  @_hasStorage var a : Int8
   init()
 }
 
diff --git a/test/IRGen/type_layout.swift b/test/IRGen/type_layout.swift
index c9f92d4..c0e4535 100644
--- a/test/IRGen/type_layout.swift
+++ b/test/IRGen/type_layout.swift
@@ -60,7 +60,7 @@
   // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$sBi64_WV", i32 8)
   var g: ESing
   // -- Multi-case enum, open-coded layout
-  // CHECK:    store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
+  // CHECK:    store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_9_8_fe_pod, i32 0, i32 0)
   var h: EMult
   // -- Single-element generic struct, shares layout of its field (T)
   // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
diff --git a/test/IRGen/type_layout_dumper_all.swift b/test/IRGen/type_layout_dumper_all.swift
index 1e3ce82..529c64d 100644
--- a/test/IRGen/type_layout_dumper_all.swift
+++ b/test/IRGen/type_layout_dumper_all.swift
@@ -23,7 +23,7 @@
 // CHECK-NEXT:   - Name:            24type_layout_dumper_other21ConcreteResilientEnumO
 // CHECK-NEXT:     Size:            9
 // CHECK-NEXT:     Alignment:       8
-// CHECK-NEXT:     ExtraInhabitants: 0
+// CHECK-NEXT:     ExtraInhabitants: 254
 // CHECK-NEXT:   - Name:            24type_layout_dumper_other22DependentResilientEnumO09NestedNonefG0O
 // CHECK-NEXT:     Size:            8
 // CHECK-NEXT:     Alignment:       8
diff --git a/test/IRGen/type_layout_dumper_resilient.swift b/test/IRGen/type_layout_dumper_resilient.swift
index 5a86e86..df80e93 100644
--- a/test/IRGen/type_layout_dumper_resilient.swift
+++ b/test/IRGen/type_layout_dumper_resilient.swift
@@ -19,7 +19,7 @@
 // CHECK-NEXT:   - Name:            24type_layout_dumper_other21ConcreteResilientEnumO
 // CHECK-NEXT:     Size:            9
 // CHECK-NEXT:     Alignment:       8
-// CHECK-NEXT:     ExtraInhabitants: 0
+// CHECK-NEXT:     ExtraInhabitants: 254
 // CHECK-NEXT:   - Name:            24type_layout_dumper_other22DependentResilientEnumO09NestedNonefG0O
 // CHECK-NEXT:     Size:            8
 // CHECK-NEXT:     Alignment:       8
diff --git a/test/IRGen/type_layout_objc.swift b/test/IRGen/type_layout_objc.swift
index 1693e55..636a4d6 100644
--- a/test/IRGen/type_layout_objc.swift
+++ b/test/IRGen/type_layout_objc.swift
@@ -58,7 +58,7 @@
   // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$sBi64_WV", i32 8)
   var g: ESing
   // -- Multi-case enum, open-coded layout
-  // CHECK:    store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
+  // CHECK:    store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_9_8_fe_pod, i32 0, i32 0)
   var h: EMult
   // -- Single-element generic struct, shares layout of its field (T)
   // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
diff --git a/test/IRGen/unowned.sil b/test/IRGen/unowned.sil
index f0edc00..67c5806 100644
--- a/test/IRGen/unowned.sil
+++ b/test/IRGen/unowned.sil
@@ -50,7 +50,7 @@
 // Value witnesses for A:
 
 //   initializeBufferWithCopyOfBuffer
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s7unowned1AVwCP"([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s7unowned1AVwCP"([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -64,7 +64,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   destroy
-// CHECK:    define linkonce_odr hidden void @"$s7unowned1AVwxx"([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
+// CHECK:    define internal void @"$s7unowned1AVwxx"([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
 // CHECK:      [[T0:%.*]] = bitcast [[OPAQUE]]* [[ARG]] to [[A]]*
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0
 // CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]*
@@ -73,7 +73,7 @@
 // CHECK-NEXT: ret void
 
 //   initializeWithCopy
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s7unowned1AVwcp"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s7unowned1AVwcp"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -87,7 +87,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   assignWithCopy
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s7unowned1AVwca"([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s7unowned1AVwca"([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -103,7 +103,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   assignWithTake
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s7unowned1AVwta"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s7unowned1AVwta"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
diff --git a/test/IRGen/unowned_objc.sil b/test/IRGen/unowned_objc.sil
index 983f0b8..5a51874 100644
--- a/test/IRGen/unowned_objc.sil
+++ b/test/IRGen/unowned_objc.sil
@@ -126,7 +126,7 @@
 // Value witnesses for A:
 
 //   initializeBufferWithCopyOfBuffer
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s12unowned_objc1AVwCP"([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s12unowned_objc1AVwCP"([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -140,7 +140,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   destroy
-// CHECK:    define linkonce_odr hidden void @"$s12unowned_objc1AVwxx"([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
+// CHECK:    define internal void @"$s12unowned_objc1AVwxx"([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
 // CHECK:      [[T0:%.*]] = bitcast [[OPAQUE]]* [[ARG]] to [[A]]*
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0
 // CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]*
@@ -149,7 +149,7 @@
 // CHECK-NEXT: ret void
 
 //   initializeWithCopy
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s12unowned_objc1AVwcp"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s12unowned_objc1AVwcp"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -163,7 +163,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   assignWithCopy
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s12unowned_objc1AVwca"([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s12unowned_objc1AVwca"([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -179,7 +179,7 @@
 // CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
 
 //   assignWithTake
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s12unowned_objc1AVwta"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s12unowned_objc1AVwta"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
diff --git a/test/IRGen/vtable_symbol_linkage.swift b/test/IRGen/vtable_symbol_linkage.swift
index 0800347..cb77e13 100644
--- a/test/IRGen/vtable_symbol_linkage.swift
+++ b/test/IRGen/vtable_symbol_linkage.swift
@@ -1,7 +1,11 @@
 // RUN: %empty-directory(%t)
+
 // RUN: %target-build-swift %S/Inputs/vtable_symbol_linkage_base.swift -emit-module -emit-module-path=%t/BaseModule.swiftmodule -emit-library -module-name BaseModule -o %t/BaseModule.%target-dylib-extension
 // RUN: %target-build-swift -I %t %s %t/BaseModule.%target-dylib-extension -o %t/a.out
 
+// RUN: %target-build-swift %S/Inputs/vtable_symbol_linkage_base.swift -emit-module -emit-module-path=%t/BaseModule.swiftmodule -emit-library -module-name BaseModule -o %t/BaseModule.%target-dylib-extension -Xfrontend -enable-resilience -Xfrontend -enable-class-resilience
+// RUN: %target-build-swift -I %t %s %t/BaseModule.%target-dylib-extension -o %t/a.out -Xfrontend -enable-class-resilience
+
 // Check if the program can be linked without undefined symbol errors.
 
 import BaseModule
diff --git a/test/IRGen/weak.sil b/test/IRGen/weak.sil
index 155b214..a8a21c9 100644
--- a/test/IRGen/weak.sil
+++ b/test/IRGen/weak.sil
@@ -103,7 +103,7 @@
 // Value witnesses for A:
 
 //   initializeBufferWithCopyOfBuffer
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s4weak1AVwCP"([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s4weak1AVwCP"([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
 // CHECK:  [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to %swift.refcounted**
 // CHECK:  [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to %swift.refcounted**
 // CHECK:  [[REF:%.*]] = load %swift.refcounted*, %swift.refcounted** [[SRC]]
@@ -119,7 +119,7 @@
 // CHECK:  ret %swift.opaque* [[CAST3]]
 
 //   destroy
-// CHECK:    define linkonce_odr hidden void @"$s4weak1AVwxx"([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
+// CHECK:    define internal void @"$s4weak1AVwxx"([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
 // CHECK:      [[T0:%.*]] = bitcast [[OPAQUE]]* [[ARG]] to [[A]]*
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0
 // CHECK-NEXT: call void @swift_weakDestroy([[WEAK]]* [[T1]])
@@ -129,7 +129,7 @@
 // TAILCALL:  jmp{{q?}} {{(\*__imp_)?_?}}swift_weakDestroy
 
 //   initializeWithCopy
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s4weak1AVwcp"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s4weak1AVwcp"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -142,7 +142,7 @@
 // TAILCALL:  jmp{{q?}} {{(\*__imp_)?_?}}swift_weakCopyInit
 
 //   assignWithCopy
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s4weak1AVwca"([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s4weak1AVwca"([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
@@ -155,7 +155,7 @@
 // TAILCALL:  jmp{{q?}} {{(\*__imp_)?_?}}swift_weakCopyAssign
 
 //   assignWithTake
-// CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$s4weak1AVwta"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
+// CHECK:    define internal [[OPAQUE]]* @"$s4weak1AVwta"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]*
 // CHECK:      [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]*
 // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]*
 // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
diff --git a/test/IRGen/weak_value_witnesses.sil b/test/IRGen/weak_value_witnesses.sil
index fd87ef1..30bedb1 100644
--- a/test/IRGen/weak_value_witnesses.sil
+++ b/test/IRGen/weak_value_witnesses.sil
@@ -25,14 +25,14 @@
   var y: T
 }
 
-// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$s20weak_value_witnesses8JustWeakVwTK"(
+// CHECK-NOT: define internal %swift.opaque* @"$s20weak_value_witnesses8JustWeakVwTK"(
 
 // The default memcpy-ing witness is good enough for NoWeak.
-// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$s20weak_value_witnesses6NoWeakVwtk"(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self)
+// CHECK-NOT: define internal %swift.opaque* @"$s20weak_value_witnesses6NoWeakVwtk"(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self)
 
 // CHECK-NOT: @"$s20weak_value_witnesses6NoWeakVwTK"
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s20weak_value_witnesses8JustWeakVwCP"
+// CHECK-LABEL: define internal %swift.opaque* @"$s20weak_value_witnesses8JustWeakVwCP"
 // CHECK: entry:
 // CHECK:  load %swift.refcounted*, %swift.refcounted**
 // CHECK:  call %swift.refcounted* @swift_retain
@@ -42,7 +42,7 @@
 // CHECK:  ret %swift.opaque
 // CHECK:}
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s20weak_value_witnesses8SomeWeakVwCP"
+// CHECK-LABEL: define internal %swift.opaque* @"$s20weak_value_witnesses8SomeWeakVwCP"
 // CHECK:entry:
 // CHECK:  load %swift.refcounted*, %swift.refcounted**
 // CHECK:  call %swift.refcounted* @swift_retain
@@ -53,11 +53,11 @@
 // CHECK:}
 
 // Weak references must be taken by swift_weakTakeInit.
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s20weak_value_witnesses8SomeWeakVwtk"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %SomeWeak)
+// CHECK-LABEL: define internal %swift.opaque* @"$s20weak_value_witnesses8SomeWeakVwtk"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %SomeWeak)
 // CHECK:         call %swift.weak* @swift_weakTakeInit
 
-// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$s20weak_value_witnesses8SomeWeakVwTK"(
+// CHECK-NOT: define internal %swift.opaque* @"$s20weak_value_witnesses8SomeWeakVwTK"(
 
 // Generic types must be taken using their value witness.
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$s20weak_value_witnesses3GenVwtk"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %"Gen<T>")
+// CHECK-LABEL: define internal %swift.opaque* @"$s20weak_value_witnesses3GenVwtk"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %"Gen<T>")
 // CHECK:         call %swift.opaque* %initializeWithTake
diff --git a/test/IRGen/witness_table_indirect_conformances.swift b/test/IRGen/witness_table_indirect_conformances.swift
index 0684468..399a922 100644
--- a/test/IRGen/witness_table_indirect_conformances.swift
+++ b/test/IRGen/witness_table_indirect_conformances.swift
@@ -32,7 +32,7 @@
 
 // CHECK: @"$s35witness_table_indirect_conformances1WVAA2P3AAWP" = hidden global [5 x i8*] [
 // CHECK-SAME: @"$s35witness_table_indirect_conformances1WVAA2P3AAMc"
-// CHECK-SAME: i8* bitcast (i8** ()* @"$s35witness_table_indirect_conformances1ZVAcA2P2AAWl
+// CHECK-SAME: @"associated conformance 35witness_table_indirect_conformances1WVAA2P3AA05AssocE0AaDP_AA2P2"
 // CHECK-SAME: @"symbolic 35witness_table_indirect_conformances1ZV"
 // CHECK-SAME: i8* bitcast (void (%T35witness_table_indirect_conformances1ZV*, %T35witness_table_indirect_conformances1WV*, %swift.type*, i8**)* @"$s35witness_table_indirect_conformances1WVAA2P3A2aDP08getAssocE00gE0QzyFTW" to i8*)]
 struct W: P3 {
diff --git a/test/IRGen/witness_table_objc_associated_type.swift b/test/IRGen/witness_table_objc_associated_type.swift
index 42cdac6..1da6e75 100644
--- a/test/IRGen/witness_table_objc_associated_type.swift
+++ b/test/IRGen/witness_table_objc_associated_type.swift
@@ -20,7 +20,7 @@
   func foo() {}
 }
 // CHECK-LABEL: @"$s34witness_table_objc_associated_type2SBVAA1BAAWP" = hidden global [4 x i8*] [
-// CHECK:         i8* bitcast (i8** ()* @"$s34witness_table_objc_associated_type2SAVAcA1AAAWl
+// CHECK:         @"associated conformance 34witness_table_objc_associated_type2SBVAA1BAA2AAAaDP_AA1A"
 // CHECK:         @"symbolic 34witness_table_objc_associated_type2SAV"
 // CHECK:         i8* bitcast {{.*}} @"$s34witness_table_objc_associated_type2SBVAA1BA2aDP3fooyyFTW"
 // CHECK:       ]
diff --git a/test/IRGen/yield_once.sil b/test/IRGen/yield_once.sil
index c3e05e4..b0b0b50 100644
--- a/test/IRGen/yield_once.sil
+++ b/test/IRGen/yield_once.sil
@@ -90,5 +90,45 @@
   return %ret : $()
 }
 
+sil @yields_pair : $@yield_once @convention(thin) () -> (@yields Builtin.Int32, @yields Builtin.Int32)
+
+// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_yields_pair()
+sil @test_yields_pair : $() -> () {
+entry:
+  %marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
+
+  //   Allocate the buffer.
+  // CHECK:         [[T0:%.*]] = alloca {{\[}}[[BUFFER_SIZE]] x i8], align [[BUFFER_ALIGN]]
+  // CHECK-NEXT:    [[BUFFER:%.*]] = getelementptr inbounds {{\[}}[[BUFFER_SIZE]] x i8], {{\[}}[[BUFFER_SIZE]] x i8]* [[T0]], i32 0, i32 0
+  // CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]])
+
+  //   Prepare the continuation function pointer to block analysis.
+  // CHECK-NEXT:    [[T0:%.*]] = call i8* @llvm.coro.prepare.retcon(i8* bitcast ({ i8*, i32, i32 } (i8*)* @yields_pair to i8*))
+  // CHECK-NEXT:    [[PREPARE:%.*]] = bitcast i8* [[T0]] to { i8*, i32, i32 } (i8*)*
+  //   Call the function pointer.
+  // CHECK-NEXT:    [[PACKED:%.*]] = call swiftcc { i8*, i32, i32 } [[PREPARE]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]])
+  // CHECK-NEXT:    [[CONTINUATION:%.*]] = extractvalue { i8*, i32, i32 } [[PACKED]], 0
+  // CHECK-NEXT:    [[FIRST:%.*]] = extractvalue { i8*, i32, i32 } [[PACKED]], 1
+  // CHECK-NEXT:    [[SECOND:%.*]] = extractvalue { i8*, i32, i32 } [[PACKED]], 2
+  %coro = function_ref @yields_pair : $@yield_once @convention(thin) () -> (@yields Builtin.Int32, @yields Builtin.Int32)
+  (%first, %second, %token) = begin_apply %coro() : $@yield_once @convention(thin) () -> (@yields Builtin.Int32, @yields Builtin.Int32)
+
+  // CHECK-NEXT:    call swiftcc void @marker(i32 [[FIRST]])
+  apply %marker(%first) : $@convention(thin) (Builtin.Int32) -> ()
+
+  // CHECK-NEXT:    [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)*
+  // CHECK-NEXT:    call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false)
+  // CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]])
+  end_apply %token
+
+  // CHECK-NEXT:    call swiftcc void @marker(i32 [[SECOND]])
+  apply %marker(%second) : $@convention(thin) (Builtin.Int32) -> ()
+
+  // CHECK-NEXT:    ret void
+  %ret = tuple ()
+  return %ret : $()
+}
+
+
 // CHECK:       attributes [[CORO_ATTRIBUTES]] =
 // CHECK-SAME:    noinline
diff --git a/test/Index/patterns.swift b/test/Index/patterns.swift
new file mode 100644
index 0000000..20ccaf9
--- /dev/null
+++ b/test/Index/patterns.swift
@@ -0,0 +1,28 @@
+// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s
+
+struct Foo {
+  enum Inner {
+    case bar
+  }
+}
+
+let a: Foo.Inner = .bar
+
+if case .bar = a {}
+// CHECK: [[@LINE-1]]:10 | {{.*}} | bar
+if case Foo.Inner.bar = a {}
+// CHECK: [[@LINE-1]]:19 | {{.*}} | bar
+// CHECK: [[@LINE-2]]:9 | {{.*}} | Foo
+// CHECK: [[@LINE-3]]:13 | {{.*}} | Inner
+switch a {
+case .bar:
+// CHECK: [[@LINE-1]]:7 | {{.*}} | bar
+    break
+case Foo.Inner.bar:
+// CHECK: [[@LINE-1]]:16 | {{.*}} | bar
+// CHECK: [[@LINE-2]]:6 | {{.*}} | Foo
+// CHECK: [[@LINE-3]]:10 | {{.*}} | Inner
+    break
+default:
+    break
+}
diff --git a/test/Inputs/conditional_conformance_with_assoc.swift b/test/Inputs/conditional_conformance_with_assoc.swift
index 5ca3151..7ec5f6c 100644
--- a/test/Inputs/conditional_conformance_with_assoc.swift
+++ b/test/Inputs/conditional_conformance_with_assoc.swift
@@ -268,6 +268,6 @@
 // CHECK:   [[XT_TYPE:%.*]] = bitcast %swift.type* %"X<T>" to %swift.type**
 // CHECK:   [[ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[XT_TYPE]], i64 2
 // CHECK:   [[T:%.*]] = load %swift.type*, %swift.type** [[ADDR]]
-// CHECK:   %T.Base = call swiftcc i8** {{.*}}(%swift.type* %T, %swift.type* %T, i8** {{.*}})
+// CHECK:   %T.Base = call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** {{.*}}, %swift.type* %T, %swift.type* %T
 // CHECK:   ret void
 // CHECK: }
diff --git a/test/Inputs/resilient_struct.swift b/test/Inputs/resilient_struct.swift
index 37b52da..ddd07dc 100644
--- a/test/Inputs/resilient_struct.swift
+++ b/test/Inputs/resilient_struct.swift
@@ -91,3 +91,7 @@
 public struct ResilientRef {
   public var r: Referent
 }
+
+public struct ResilientWithInternalField {
+  var x: Int
+}
diff --git a/test/Interpreter/Inputs/dynamic_replacement_chaining_A.swift b/test/Interpreter/Inputs/dynamic_replacement_chaining_A.swift
new file mode 100644
index 0000000..41a5ff7
--- /dev/null
+++ b/test/Interpreter/Inputs/dynamic_replacement_chaining_A.swift
@@ -0,0 +1,6 @@
+public struct Impl {
+  public init() {}
+  dynamic public func foo() -> Int {
+     return 1
+  }
+}
diff --git a/test/Interpreter/Inputs/dynamic_replacement_chaining_B.swift b/test/Interpreter/Inputs/dynamic_replacement_chaining_B.swift
new file mode 100644
index 0000000..6a9aae0
--- /dev/null
+++ b/test/Interpreter/Inputs/dynamic_replacement_chaining_B.swift
@@ -0,0 +1,8 @@
+import A
+
+extension Impl {
+  @_dynamicReplacement(for: foo())
+  func repl() -> Int {
+    return foo() + 1
+  }
+}
diff --git a/test/Interpreter/Inputs/dynamic_replacement_module.swift b/test/Interpreter/Inputs/dynamic_replacement_module.swift
new file mode 100644
index 0000000..2fd74b5
--- /dev/null
+++ b/test/Interpreter/Inputs/dynamic_replacement_module.swift
@@ -0,0 +1,215 @@
+#if MODULE
+public dynamic func public_global_func() -> String {
+  return "public_global_func"
+}
+
+public dynamic func public_global_generic_func<T>(_ t: T.Type) -> String {
+  return "public_global_generic_func"
+}
+
+public class PublicClass {
+  public var str : String = ""
+  public init() {}
+  public dynamic init(x: Int) { str = "public_class_init" }
+
+  public dynamic func function() -> String {
+    return "public_class_func"
+  }
+  public dynamic func genericFunction<T>(_ t: T.Type) -> String {
+    return "public_class_generic_func"
+  }
+}
+
+public struct PublicStruct {
+  public var str = ""
+  public init() {}
+
+  public dynamic init(x: Int) { str = "public_struct_init" }
+
+  public dynamic func function() -> String {
+    return "public_struct_func"
+  }
+  public dynamic func genericFunction<T>(_ t: T.Type) -> String {
+    return "public_struct_generic_func"
+  }
+  public dynamic var public_stored_property : String = "public_stored_property"
+
+  public dynamic subscript(_ x: Int) -> String {
+    get {
+      return "public_subscript_get"
+    }
+    set {
+      str = newValue
+    }
+  }
+  public dynamic subscript(y x: Int) -> String {
+    _read {
+      yield "public_subscript_get_modify_read"
+    }
+    _modify {
+      yield &str
+    }
+  }
+}
+
+public enum PublicEnumeration<Q> {
+  case A
+  case B
+
+  public dynamic func function() -> String {
+    return "public_enum_func"
+  }
+  public dynamic func genericFunction<T>(_ t: T.Type) -> String {
+    return "public_enum_generic_func"
+  }
+}
+#elseif MODULENODYNAMIC
+public func public_global_func() -> String {
+  return "public_global_func"
+}
+
+public func public_global_generic_func<T>(_ t: T.Type) -> String {
+  return "public_global_generic_func"
+}
+
+public class PublicClass {
+  public var str : String = ""
+  public init() {}
+  public init(x: Int) { str = "public_class_init" }
+
+  public func function() -> String {
+    return "public_class_func"
+  }
+  public func genericFunction<T>(_ t: T.Type) -> String {
+    return "public_class_generic_func"
+  }
+}
+
+public struct PublicStruct {
+  public var str = ""
+  public init() {}
+
+  public init(x: Int) { str = "public_struct_init" }
+
+  public func function() -> String {
+    return "public_struct_func"
+  }
+  public func genericFunction<T>(_ t: T.Type) -> String {
+    return "public_struct_generic_func"
+  }
+  public var public_stored_property : String = "public_stored_property"
+
+  public subscript(_ x: Int) -> String {
+    get {
+      return "public_subscript_get"
+    }
+    set {
+      str = newValue
+    }
+  }
+  public subscript(y x: Int) -> String {
+    _read {
+      yield "public_subscript_get_modify_read"
+    }
+    _modify {
+      yield &str
+    }
+  }
+}
+
+public enum PublicEnumeration<Q> {
+  case A
+  case B
+
+  public func function() -> String {
+    return "public_enum_func"
+  }
+  public func genericFunction<T>(_ t: T.Type) -> String {
+    return "public_enum_generic_func"
+  }
+}
+#elseif MODULE2
+
+import Module1
+
+/// Public global functions, struct, class, and enum.
+
+@_dynamicReplacement(for: public_global_func())
+public func replacement_for_public_global_func() -> String {
+  return "replacement of " + public_global_func()
+}
+
+@_dynamicReplacement(for: public_global_generic_func(_:))
+public func replacement_for_public_global_generic_func<T>(_ t: T.Type) -> String {
+  return "replacement of " + public_global_generic_func(t)
+}
+
+extension PublicClass {
+  @_dynamicReplacement(for: init(x:))
+  convenience public init(y: Int) {
+    self.init(x: y)
+    str = "replacement of public_class_init"
+  }
+
+  @_dynamicReplacement(for: function())
+  public func replacement_function() -> String {
+    return "replacement of " + function()
+  }
+  @_dynamicReplacement(for: genericFunction(_:))
+  public func replacement_genericFunction<T>(_ t: T.Type) -> String {
+    return "replacement of " + genericFunction(t)
+  }
+}
+
+extension PublicStruct {
+  @_dynamicReplacement(for: init(x:))
+  public init(y: Int) {
+    self.init(x: y)
+    str = "replacement of public_struct_init"
+  }
+
+  @_dynamicReplacement(for: function())
+  public func replacement_function() -> String {
+    return "replacement of " + function()
+  }
+  @_dynamicReplacement(for: genericFunction(_:))
+  public func replacement_genericFunction<T>(_ t: T.Type) -> String {
+    return "replacement of " + genericFunction(t)
+  }
+  @_dynamicReplacement(for: public_stored_property)
+  var replacement_public_stored_property : String {
+    return "replacement of " + public_stored_property
+  }
+  @_dynamicReplacement(for: subscript(_:))
+  subscript(x x: Int) -> String {
+    get {
+      return "replacement of " + self[x]
+    }
+    set {
+      str = "replacement of " + newValue
+    }
+  }
+
+  @_dynamicReplacement(for: subscript(y:))
+  public subscript(z x: Int) -> String {
+    _read {
+      yield "replacement of " + self[y: x]
+    }
+    _modify {
+      yield &str
+      str = "replacement of " + str
+    }
+  }
+}
+
+extension PublicEnumeration {
+  @_dynamicReplacement(for: function())
+  public func replacement_function() -> String {
+    return "replacement of " + function()
+  }
+  @_dynamicReplacement(for: genericFunction(_:))
+  public func replacement_genericFunction<T>(_ t: T.Type) -> String {
+    return "replacement of " + genericFunction(t)
+  }
+}
+#endif
diff --git a/test/Interpreter/dynamic_replacement.swift b/test/Interpreter/dynamic_replacement.swift
new file mode 100644
index 0000000..4e23a0a
--- /dev/null
+++ b/test/Interpreter/dynamic_replacement.swift
@@ -0,0 +1,126 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift-dylib(%t/libModule1.%target-dylib-extension) -DMODULE -module-name Module1 -emit-module -emit-module-path %t/Module1.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift-dylib(%t/libModule2.%target-dylib-extension) -I%t -L%t -lModule1 -Xlinker -rpath -Xlinker %t -DMODULE2 -module-name Module2 -emit-module -emit-module-path %t/Module2.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift -I%t -L%t -lModule1 -DMAIN -o %t/main -Xlinker -rpath -Xlinker %t %s -swift-version 5
+// RUN: %target-codesign %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+// RUN: %target-run %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+
+// Now the same in optimized mode.
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift-dylib(%t/libModule1.%target-dylib-extension) -O -DMODULE -module-name Module1 -emit-module -emit-module-path %t/Module1.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift-dylib(%t/libModule2.%target-dylib-extension) -O -I%t -L%t -lModule1 -Xlinker -rpath -Xlinker %t -DMODULE2 -module-name Module2 -emit-module -emit-module-path %t/Module2.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift -O -I%t -L%t -lModule1 -DMAIN -o %t/main -Xlinker -rpath -Xlinker %t %s -swift-version 5
+// RUN: %target-codesign %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+// RUN: %target-run %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+
+// Now the same in size mode.
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift-dylib(%t/libModule1.%target-dylib-extension) -Osize -DMODULE -module-name Module1 -emit-module -emit-module-path %t/Module1.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift-dylib(%t/libModule2.%target-dylib-extension) -Osize -I%t -L%t -lModule1 -Xlinker -rpath -Xlinker %t -DMODULE2 -module-name Module2 -emit-module -emit-module-path %t/Module2.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift -Osize -I%t -L%t -lModule1 -DMAIN -o %t/main -Xlinker -rpath -Xlinker %t %s -swift-version 5
+// RUN: %target-codesign %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+// RUN: %target-run %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+
+// Now the same in optimized wholemodule mode.
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift-dylib(%t/libModule1.%target-dylib-extension) -O -wmo -DMODULE -module-name Module1 -emit-module -emit-module-path %t/Module1.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift-dylib(%t/libModule2.%target-dylib-extension) -O -wmo -I%t -L%t -lModule1 -Xlinker -rpath -Xlinker %t -DMODULE2 -module-name Module2 -emit-module -emit-module-path %t/Module2.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift -O -wmo -I%t -L%t -lModule1 -DMAIN -o %t/main -Xlinker -rpath -Xlinker %t %s -swift-version 5
+// RUN: %target-codesign %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+// RUN: %target-run %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+
+// Test the -enable-implicit-dynamic flag.
+
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift-dylib(%t/libModule1.%target-dylib-extension) -DMODULENODYNAMIC -module-name Module1 -emit-module -emit-module-path %t/Module1.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift -Xfrontend -enable-implicit-dynamic
+// RUN: %target-build-swift-dylib(%t/libModule2.%target-dylib-extension) -I%t -L%t -lModule1 -Xlinker -rpath -Xlinker %t -DMODULE2 -module-name Module2 -emit-module -emit-module-path %t/Module2.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift -I%t -L%t -lModule1 -DMAIN -o %t/main -Xlinker -rpath -Xlinker %t %s -swift-version 5
+// RUN: %target-codesign %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+// RUN: %target-run %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+
+// Test the -enable-implicit-dynamic flag in optimized wholemodule mode.
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift-dylib(%t/libModule1.%target-dylib-extension) -O -wmo -DMODULENODYNAMIC -module-name Module1 -emit-module -emit-module-path %t/Module1.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift -Xfrontend -enable-implicit-dynamic
+// RUN: %target-build-swift-dylib(%t/libModule2.%target-dylib-extension) -O -wmo -I%t -L%t -lModule1 -Xlinker -rpath -Xlinker %t -DMODULE2 -module-name Module2 -emit-module -emit-module-path %t/Module2.swiftmodule -swift-version 5 %S/Inputs/dynamic_replacement_module.swift
+// RUN: %target-build-swift -O -wmo -I%t -L%t -lModule1 -DMAIN -o %t/main -Xlinker -rpath -Xlinker %t %s -swift-version 5
+// RUN: %target-codesign %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+// RUN: %target-run %t/main %t/libModule1.%target-dylib-extension %t/libModule2.%target-dylib-extension
+
+
+// REQUIRES: executable_test
+
+import Module1
+
+import StdlibUnittest
+
+#if os(Linux)
+  import Glibc
+  let dylibSuffix = "so"
+#else
+  import Darwin
+  let dylibSuffix = "dylib"
+#endif
+
+var DynamicallyReplaceable = TestSuite("DynamicallyReplaceable")
+
+func expectedResult(_ forOriginalLibrary: Bool,  _ expectedOriginalString: String) -> String {
+  if forOriginalLibrary {
+    return expectedOriginalString
+  } else {
+    return "replacement of \(expectedOriginalString)"
+	}
+}
+
+func checkExpectedResults(forOriginalLibrary useOrig: Bool) {
+ expectTrue(public_global_func() ==
+            expectedResult(useOrig, "public_global_func"))
+ expectTrue(public_global_generic_func(Int.self) ==
+            expectedResult(useOrig, "public_global_generic_func"))
+
+ expectTrue(PublicClass().function() ==
+            expectedResult(useOrig, "public_class_func"))
+ expectTrue(PublicClass().genericFunction(Int.self) ==
+            expectedResult(useOrig, "public_class_generic_func"))
+
+ expectTrue(PublicStruct().function() ==
+            expectedResult(useOrig, "public_struct_func"))
+ expectTrue(PublicStruct().genericFunction(Int.self) ==
+            expectedResult(useOrig, "public_struct_generic_func"))
+ expectTrue(PublicStruct().public_stored_property ==
+            expectedResult(useOrig, "public_stored_property"))
+ expectTrue(PublicStruct()[0] ==
+            expectedResult(useOrig, "public_subscript_get"))
+ expectTrue(PublicStruct()[y:0] ==
+            expectedResult(useOrig, "public_subscript_get_modify_read"))
+ var testSetter = PublicStruct()
+ testSetter[0] = "public_subscript_set"
+ expectTrue(testSetter.str ==
+            expectedResult(useOrig, "public_subscript_set"))
+ testSetter[y:0] = "public_subscript_set_modify_read"
+ expectTrue(testSetter.str ==
+            expectedResult(useOrig, "public_subscript_set_modify_read"))
+
+ expectTrue(PublicEnumeration<Int>.A.function() ==
+            expectedResult(useOrig, "public_enum_func"))
+ expectTrue(PublicEnumeration<Int>.B.genericFunction(Int.self) ==
+            expectedResult(useOrig, "public_enum_generic_func"))
+}
+
+DynamicallyReplaceable.test("DynamicallyReplaceable") {
+  var executablePath = CommandLine.arguments[0]
+  executablePath.removeLast(4)
+
+  // First, test with only the original module.
+	checkExpectedResults(forOriginalLibrary: true)
+
+  // Now, test with the module containing the replacements.
+
+#if os(Linux)
+	_ = dlopen("libModule2."+dylibSuffix, RTLD_NOW)
+#else
+	_ = dlopen(executablePath+"libModule2."+dylibSuffix, RTLD_NOW)
+#endif
+	checkExpectedResults(forOriginalLibrary: false)
+}
+
+runAllTests()
diff --git a/test/Interpreter/dynamic_replacement_chaining.swift b/test/Interpreter/dynamic_replacement_chaining.swift
new file mode 100644
index 0000000..b15ac9b
--- /dev/null
+++ b/test/Interpreter/dynamic_replacement_chaining.swift
@@ -0,0 +1,54 @@
+// First build without chaining.
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift-dylib(%t/libA.%target-dylib-extension) -module-name A -emit-module -emit-module-path %t -swift-version 5 %S/Inputs/dynamic_replacement_chaining_A.swift
+// RUN: %target-build-swift-dylib(%t/libB.%target-dylib-extension) -I%t -L%t -lA -Xlinker -rpath -Xlinker %t -module-name B -emit-module -emit-module-path %t -swift-version 5 %S/Inputs/dynamic_replacement_chaining_B.swift
+// RUN: %target-build-swift-dylib(%t/libC.%target-dylib-extension) -I%t -L%t -lA -Xlinker -rpath -Xlinker %t -module-name C -emit-module -emit-module-path %t -swift-version 5 %S/Inputs/dynamic_replacement_chaining_B.swift
+// RUN: %target-build-swift -I%t -L%t -lA -o %t/main -Xlinker -rpath -Xlinker %t %s -swift-version 5
+// RUN: %target-codesign %t/main %t/libA.%target-dylib-extension %t/libB.%target-dylib-extension %t/libC.%target-dylib-extension
+// RUN: %target-run %t/main %t/libA.%target-dylib-extension %t/libB.%target-dylib-extension %t/libC.%target-dylib-extension
+
+// Now build with chaining enabled.
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift-dylib(%t/libA.%target-dylib-extension) -module-name A -emit-module -emit-module-path %t -swift-version 5 %S/Inputs/dynamic_replacement_chaining_A.swift
+// RUN: %target-build-swift-dylib(%t/libB.%target-dylib-extension) -I%t -L%t -lA -Xlinker -rpath -Xlinker %t -module-name B -emit-module -emit-module-path %t -swift-version 5 %S/Inputs/dynamic_replacement_chaining_B.swift -Xfrontend -enable-dynamic-replacement-chaining
+// RUN: %target-build-swift-dylib(%t/libC.%target-dylib-extension) -I%t -L%t -lA -Xlinker -rpath -Xlinker %t -module-name C -emit-module -emit-module-path %t -swift-version 5 %S/Inputs/dynamic_replacement_chaining_B.swift -Xfrontend -enable-dynamic-replacement-chaining
+// RUN: %target-build-swift -I%t -L%t -lA -DCHAINING -o %t/main -Xlinker -rpath -Xlinker %t %s -swift-version 5
+// RUN: %target-codesign %t/main %t/libA.%target-dylib-extension %t/libB.%target-dylib-extension %t/libC.%target-dylib-extension
+// RUN: %target-run %t/main %t/libA.%target-dylib-extension %t/libB.%target-dylib-extension %t/libC.%target-dylib-extension
+
+
+import A
+
+import StdlibUnittest
+
+#if os(Linux)
+  import Glibc
+  let dylibSuffix = "so"
+#else
+  import Darwin
+  let dylibSuffix = "dylib"
+#endif
+
+var DynamicallyReplaceable = TestSuite("DynamicallyReplaceableChaining")
+
+
+DynamicallyReplaceable.test("DynamicallyReplaceable") {
+  var executablePath = CommandLine.arguments[0]
+  executablePath.removeLast(4)
+
+#if os(Linux)
+	_ = dlopen("libB."+dylibSuffix, RTLD_NOW)
+	_ = dlopen("libC."+dylibSuffix, RTLD_NOW)
+#else
+	_ = dlopen(executablePath+"libB."+dylibSuffix, RTLD_NOW)
+	_ = dlopen(executablePath+"libC."+dylibSuffix, RTLD_NOW)
+#endif
+
+#if CHAINING
+  expectEqual(3, Impl().foo())
+#else
+  expectEqual(2, Impl().foo())
+#endif
+}
+
+runAllTests()
diff --git a/test/Interpreter/multi_payload_extra_inhabitant.swift b/test/Interpreter/multi_payload_extra_inhabitant.swift
new file mode 100644
index 0000000..7cd7cad
--- /dev/null
+++ b/test/Interpreter/multi_payload_extra_inhabitant.swift
@@ -0,0 +1,198 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-build-swift -parse-stdlib -Xfrontend -verify-type-layout -Xfrontend SpareBitExtraInhabitants -Xfrontend -verify-type-layout -Xfrontend SpareBitSingleExtraInhabitant -Xfrontend -verify-type-layout -Xfrontend SpareBitNoExtraInhabitant -Xfrontend -verify-type-layout -Xfrontend SpareBitNoExtraInhabitant2 -Xfrontend -verify-type-layout -Xfrontend TwoTagExtraInhabitants -Xfrontend -verify-type-layout -Xfrontend ThreeTagExtraInhabitants -Xfrontend -verify-type-layout -Xfrontend NoTagExtraInhabitants -Xfrontend -verify-type-layout -Xfrontend DynamicExtraInhabitantsOneByte -Xfrontend -verify-type-layout -Xfrontend DynamicExtraInhabitantsTwoBytes -O -o %t/a.out %s
+// RUN: %target-run %t/a.out 2>&1
+
+// Type layout verifier is only compiled into the runtime in asserts builds.
+// REQUIRES: swift_stdlib_asserts
+
+// REQUIRES: executable_test
+
+// CHECK-NOT: Type verification
+
+
+import Swift
+import StdlibUnittest
+
+enum SpareBitExtraInhabitants {
+  case a(Builtin.Int30)
+  case b(Builtin.Int30)
+}
+
+enum SpareBitSingleExtraInhabitant {
+  case a(Builtin.Int30)
+  case b(Builtin.Int30)
+  case c(Builtin.Int30)
+}
+
+enum SpareBitNoExtraInhabitant {
+  case a(Builtin.Int30)
+  case b(Builtin.Int30)
+  case c(Builtin.Int30)
+  case d(Builtin.Int30)
+}
+
+enum SpareBitNoExtraInhabitant2 {
+  case a(Builtin.Int30)
+  case b(Builtin.Int30)
+  case c(Builtin.Int30)
+  case d
+}
+
+enum TwoTagExtraInhabitants {
+  case a(Builtin.Int32)
+  case b(Builtin.Int32)
+}
+
+enum ThreeTagExtraInhabitants {
+  case a(Builtin.Int32)
+  case b(Builtin.Int32)
+  case c(Builtin.Int32)
+}
+
+enum NoTagExtraInhabitants {
+  case aaa(Builtin.Int32), aab(Builtin.Int32), aac(Builtin.Int32), aad(Builtin.Int32), aae(Builtin.Int32), aaf(Builtin.Int32), aag(Builtin.Int32), aah(Builtin.Int32)
+  case aba(Builtin.Int32), abb(Builtin.Int32), abc(Builtin.Int32), abd(Builtin.Int32), abe(Builtin.Int32), abf(Builtin.Int32), abg(Builtin.Int32), abh(Builtin.Int32)
+  case aca(Builtin.Int32), acb(Builtin.Int32), acc(Builtin.Int32), acd(Builtin.Int32), ace(Builtin.Int32), acf(Builtin.Int32), acg(Builtin.Int32), ach(Builtin.Int32)
+  case ada(Builtin.Int32), adb(Builtin.Int32), adc(Builtin.Int32), add(Builtin.Int32), ade(Builtin.Int32), adf(Builtin.Int32), adg(Builtin.Int32), adh(Builtin.Int32)
+  case aea(Builtin.Int32), aeb(Builtin.Int32), aec(Builtin.Int32), aed(Builtin.Int32), aee(Builtin.Int32), aef(Builtin.Int32), aeg(Builtin.Int32), aeh(Builtin.Int32)
+  case afa(Builtin.Int32), afb(Builtin.Int32), afc(Builtin.Int32), afd(Builtin.Int32), afe(Builtin.Int32), aff(Builtin.Int32), afg(Builtin.Int32), afh(Builtin.Int32)
+  case aga(Builtin.Int32), agb(Builtin.Int32), agc(Builtin.Int32), agd(Builtin.Int32), age(Builtin.Int32), agf(Builtin.Int32), agg(Builtin.Int32), agh(Builtin.Int32)
+  case aha(Builtin.Int32), ahb(Builtin.Int32), ahc(Builtin.Int32), ahd(Builtin.Int32), ahe(Builtin.Int32), ahf(Builtin.Int32), ahg(Builtin.Int32), ahh(Builtin.Int32)
+
+  case baa(Builtin.Int32), bab(Builtin.Int32), bac(Builtin.Int32), bad(Builtin.Int32), bae(Builtin.Int32), baf(Builtin.Int32), bag(Builtin.Int32), bah(Builtin.Int32)
+  case bba(Builtin.Int32), bbb(Builtin.Int32), bbc(Builtin.Int32), bbd(Builtin.Int32), bbe(Builtin.Int32), bbf(Builtin.Int32), bbg(Builtin.Int32), bbh(Builtin.Int32)
+  case bca(Builtin.Int32), bcb(Builtin.Int32), bcc(Builtin.Int32), bcd(Builtin.Int32), bce(Builtin.Int32), bcf(Builtin.Int32), bcg(Builtin.Int32), bch(Builtin.Int32)
+  case bda(Builtin.Int32), bdb(Builtin.Int32), bdc(Builtin.Int32), bdd(Builtin.Int32), bde(Builtin.Int32), bdf(Builtin.Int32), bdg(Builtin.Int32), bdh(Builtin.Int32)
+  case bea(Builtin.Int32), beb(Builtin.Int32), bec(Builtin.Int32), bed(Builtin.Int32), bee(Builtin.Int32), bef(Builtin.Int32), beg(Builtin.Int32), beh(Builtin.Int32)
+  case bfa(Builtin.Int32), bfb(Builtin.Int32), bfc(Builtin.Int32), bfd(Builtin.Int32), bfe(Builtin.Int32), bff(Builtin.Int32), bfg(Builtin.Int32), bfh(Builtin.Int32)
+  case bga(Builtin.Int32), bgb(Builtin.Int32), bgc(Builtin.Int32), bgd(Builtin.Int32), bge(Builtin.Int32), bgf(Builtin.Int32), bgg(Builtin.Int32), bgh(Builtin.Int32)
+  case bha(Builtin.Int32), bhb(Builtin.Int32), bhc(Builtin.Int32), bhd(Builtin.Int32), bhe(Builtin.Int32), bhf(Builtin.Int32), bhg(Builtin.Int32), bhh(Builtin.Int32)
+
+  case caa(Builtin.Int32), cab(Builtin.Int32), cac(Builtin.Int32), cad(Builtin.Int32), cae(Builtin.Int32), caf(Builtin.Int32), cag(Builtin.Int32), cah(Builtin.Int32)
+  case cba(Builtin.Int32), cbb(Builtin.Int32), cbc(Builtin.Int32), cbd(Builtin.Int32), cbe(Builtin.Int32), cbf(Builtin.Int32), cbg(Builtin.Int32), cbh(Builtin.Int32)
+  case cca(Builtin.Int32), ccb(Builtin.Int32), ccc(Builtin.Int32), ccd(Builtin.Int32), cce(Builtin.Int32), ccf(Builtin.Int32), ccg(Builtin.Int32), cch(Builtin.Int32)
+  case cda(Builtin.Int32), cdb(Builtin.Int32), cdc(Builtin.Int32), cdd(Builtin.Int32), cde(Builtin.Int32), cdf(Builtin.Int32), cdg(Builtin.Int32), cdh(Builtin.Int32)
+  case cea(Builtin.Int32), ceb(Builtin.Int32), cec(Builtin.Int32), ced(Builtin.Int32), cee(Builtin.Int32), cef(Builtin.Int32), ceg(Builtin.Int32), ceh(Builtin.Int32)
+  case cfa(Builtin.Int32), cfb(Builtin.Int32), cfc(Builtin.Int32), cfd(Builtin.Int32), cfe(Builtin.Int32), cff(Builtin.Int32), cfg(Builtin.Int32), cfh(Builtin.Int32)
+  case cga(Builtin.Int32), cgb(Builtin.Int32), cgc(Builtin.Int32), cgd(Builtin.Int32), cge(Builtin.Int32), cgf(Builtin.Int32), cgg(Builtin.Int32), cgh(Builtin.Int32)
+  case cha(Builtin.Int32), chb(Builtin.Int32), chc(Builtin.Int32), chd(Builtin.Int32), che(Builtin.Int32), chf(Builtin.Int32), chg(Builtin.Int32), chh(Builtin.Int32)
+
+  case daa(Builtin.Int32), dab(Builtin.Int32), dac(Builtin.Int32), dad(Builtin.Int32), dae(Builtin.Int32), daf(Builtin.Int32), dag(Builtin.Int32), dah(Builtin.Int32)
+  case dba(Builtin.Int32), dbb(Builtin.Int32), dbc(Builtin.Int32), dbd(Builtin.Int32), dbe(Builtin.Int32), dbf(Builtin.Int32), dbg(Builtin.Int32), dbh(Builtin.Int32)
+  case dca(Builtin.Int32), dcb(Builtin.Int32), dcc(Builtin.Int32), dcd(Builtin.Int32), dce(Builtin.Int32), dcf(Builtin.Int32), dcg(Builtin.Int32), dch(Builtin.Int32)
+  case dda(Builtin.Int32), ddb(Builtin.Int32), ddc(Builtin.Int32), ddd(Builtin.Int32), dde(Builtin.Int32), ddf(Builtin.Int32), ddg(Builtin.Int32), ddh(Builtin.Int32)
+  case dea(Builtin.Int32), deb(Builtin.Int32), dec(Builtin.Int32), ded(Builtin.Int32), dee(Builtin.Int32), def(Builtin.Int32), deg(Builtin.Int32), deh(Builtin.Int32)
+  case dfa(Builtin.Int32), dfb(Builtin.Int32), dfc(Builtin.Int32), dfd(Builtin.Int32), dfe(Builtin.Int32), dff(Builtin.Int32), dfg(Builtin.Int32), dfh(Builtin.Int32)
+  case dga(Builtin.Int32), dgb(Builtin.Int32), dgc(Builtin.Int32), dgd(Builtin.Int32), dge(Builtin.Int32), dgf(Builtin.Int32), dgg(Builtin.Int32), dgh(Builtin.Int32)
+  case dha(Builtin.Int32), dhb(Builtin.Int32), dhc(Builtin.Int32), dhd(Builtin.Int32), dhe(Builtin.Int32), dhf(Builtin.Int32), dhg(Builtin.Int32), dhh(Builtin.Int32)
+}
+
+enum DynamicExtraInhabitants<T> {
+  case payloadA(T)
+  case payloadB(T)
+
+  case tagAAA, tagAAB, tagAAC, tagAAD, tagAAE, tagAAF, tagAAG, tagAAH
+  case tagABA, tagABB, tagABC, tagABD, tagABE, tagABF, tagABG, tagABH
+  case tagACA, tagACB, tagACC, tagACD, tagACE, tagACF, tagACG, tagACH
+  case tagADA, tagADB, tagADC, tagADD, tagADE, tagADF, tagADG, tagADH
+  case tagAEA, tagAEB, tagAEC, tagAED, tagAEE, tagAEF, tagAEG, tagAEH
+  case tagAFA, tagAFB, tagAFC, tagAFD, tagAFE, tagAFF, tagAFG, tagAFH
+  case tagAGA, tagAGB, tagAGC, tagAGD, tagAGE, tagAGF, tagAGG, tagAGH
+  case tagAHA, tagAHB, tagAHC, tagAHD, tagAHE, tagAHF, tagAHG, tagAHH
+  case tagAIA, tagAIB, tagAIC, tagAID, tagAIE, tagAIF, tagAIG, tagAIH
+
+  case tagBAA, tagBAB, tagBAC, tagBAD, tagBAE, tagBAF, tagBAG, tagBAH
+  case tagBBA, tagBBB, tagBBC, tagBBD, tagBBE, tagBBF, tagBBG, tagBBH
+  case tagBCA, tagBCB, tagBCC, tagBCD, tagBCE, tagBCF, tagBCG, tagBCH
+  case tagBDA, tagBDB, tagBDC, tagBDD, tagBDE, tagBDF, tagBDG, tagBDH
+  case tagBEA, tagBEB, tagBEC, tagBED, tagBEE, tagBEF, tagBEG, tagBEH
+  case tagBFA, tagBFB, tagBFC, tagBFD, tagBFE, tagBFF, tagBFG, tagBFH
+  case tagBGA, tagBGB, tagBGC, tagBGD, tagBGE, tagBGF, tagBGG, tagBGH
+  case tagBHA, tagBHB, tagBHC, tagBHD, tagBHE, tagBHF, tagBHG, tagBHH
+  case tagBIA, tagBIB, tagBIC, tagBID, tagBIE, tagBIF, tagBIG, tagBIH
+
+  case tagCAA, tagCAB, tagCAC, tagCAD, tagCAE, tagCAF, tagCAG, tagCAH
+  case tagCBA, tagCBB, tagCBC, tagCBD, tagCBE, tagCBF, tagCBG, tagCBH
+  case tagCCA, tagCCB, tagCCC, tagCCD, tagCCE, tagCCF, tagCCG, tagCCH
+  case tagCDA, tagCDB, tagCDC, tagCDD, tagCDE, tagCDF, tagCDG, tagCDH
+  case tagCEA, tagCEB, tagCEC, tagCED, tagCEE, tagCEF, tagCEG, tagCEH
+  case tagCFA, tagCFB, tagCFC, tagCFD, tagCFE, tagCFF, tagCFG, tagCFH
+  case tagCGA, tagCGB, tagCGC, tagCGD, tagCGE, tagCGF, tagCGG, tagCGH
+  case tagCHA, tagCHB, tagCHC, tagCHD, tagCHE, tagCHF, tagCHG, tagCHH
+  case tagCIA, tagCIB, tagCIC, tagCID, tagCIE, tagCIF, tagCIG, tagCIH
+
+  case tagDAA, tagDAB, tagDAC, tagDAD, tagDAE, tagDAF, tagDAG, tagDAH
+  case tagDBA, tagDBB, tagDBC, tagDBD, tagDBE, tagDBF, tagDBG, tagDBH
+  case tagDCA, tagDCB, tagDCC, tagDCD, tagDCE, tagDCF, tagDCG, tagDCH
+  case tagDDA, tagDDB, tagDDC, tagDDD, tagDDE, tagDDF, tagDDG, tagDDH
+  case tagDEA, tagDEB, tagDEC, tagDED, tagDEE, tagDEF, tagDEG, tagDEH
+  case tagDFA, tagDFB, tagDFC, tagDFD, tagDFE, tagDFF, tagDFG, tagDFH
+  case tagDGA, tagDGB, tagDGC, tagDGD, tagDGE, tagDGF, tagDGG, tagDGH
+  case tagDHA, tagDHB, tagDHC, tagDHD, tagDHE, tagDHF, tagDHG, tagDHH
+  case tagDIA, tagDIB, tagDIC, tagDID, tagDIE, tagDIF, tagDIG, tagDIH
+}
+
+typealias DynamicExtraInhabitantsOneByte = DynamicExtraInhabitants<UInt8>
+typealias DynamicExtraInhabitantsTwoBytes = DynamicExtraInhabitants<UInt16>
+
+var tests = TestSuite("extra inhabitants of structs")
+
+@inline(never)
+func expectHasAtLeastTwoExtraInhabitants<T>(_: T.Type,
+                                            nil theNil: T??,
+                                            someNil: T??,
+                                 file: String = #file, line: UInt = #line) {
+  expectEqual(MemoryLayout<T>.size, MemoryLayout<T??>.size,
+              "\(T.self) has at least two extra inhabitants",
+              file: file, line: line)
+
+  expectNil(theNil,
+            "\(T.self) extra inhabitant should agree in generic and concrete " +
+            "context")
+
+  expectNil(someNil!,
+            "\(T.self) extra inhabitant should agree in generic and concrete " +
+            "context")
+}
+
+@inline(never)
+func expectHasExtraInhabitant<T>(_: T.Type, nil theNil: T?,
+                                 file: String = #file, line: UInt = #line) {
+  expectEqual(MemoryLayout<T>.size, MemoryLayout<T?>.size,
+              "\(T.self) has extra inhabitant",
+              file: file, line: line)
+
+  expectNil(theNil,
+            "\(T.self) extra inhabitant should agree in generic and concrete " +
+            "context")
+}
+
+func expectHasNoExtraInhabitant<T>(_: T.Type,
+                                   file: String = #file, line: UInt = #line) {
+  expectNotEqual(MemoryLayout<T>.size, MemoryLayout<T?>.size,
+                 "\(T.self) does not have extra inhabitant",
+                 file: file, line: line)
+}
+
+tests.test("types that have no extra inhabitant") {
+  expectHasNoExtraInhabitant(SpareBitNoExtraInhabitant.self)
+  expectHasNoExtraInhabitant(SpareBitNoExtraInhabitant2.self)
+  expectHasNoExtraInhabitant(NoTagExtraInhabitants.self)
+}
+tests.test("types that have at least one extra inhabitant") {
+  expectHasExtraInhabitant(SpareBitExtraInhabitants.self, nil: nil)
+  expectHasExtraInhabitant(SpareBitSingleExtraInhabitant.self, nil: nil)
+  expectHasExtraInhabitant(TwoTagExtraInhabitants.self, nil: nil)
+  expectHasExtraInhabitant(ThreeTagExtraInhabitants.self, nil: nil)
+  expectHasExtraInhabitant(DynamicExtraInhabitantsOneByte.self, nil: nil)
+  expectHasExtraInhabitant(DynamicExtraInhabitantsTwoBytes.self, nil: nil)
+}
+tests.test("types that have at least two extra inhabitants") {
+  expectHasExtraInhabitant(SpareBitExtraInhabitants.self, nil: nil)
+  expectHasExtraInhabitant(TwoTagExtraInhabitants.self, nil: nil)
+  expectHasExtraInhabitant(ThreeTagExtraInhabitants.self, nil: nil)
+  expectHasExtraInhabitant(DynamicExtraInhabitantsOneByte.self, nil: nil)
+  expectHasExtraInhabitant(DynamicExtraInhabitantsTwoBytes.self, nil: nil)
+}
+runAllTests()
diff --git a/test/Interpreter/struct_extra_inhabitants.swift b/test/Interpreter/struct_extra_inhabitants.swift
index f7ebb5e..352c7a6 100644
--- a/test/Interpreter/struct_extra_inhabitants.swift
+++ b/test/Interpreter/struct_extra_inhabitants.swift
@@ -113,13 +113,36 @@
 var tests = TestSuite("extra inhabitants of structs")
 
 @inline(never)
-func expectHasExtraInhabitant<T>(_: T.Type, nil: T?,
+func expectHasAtLeastThreeExtraInhabitants<T>(_: T.Type,
+                                              nil theNil: T???,
+                                              someNil: T???,
+                                              someSomeNil: T???,
+                                 file: String = #file, line: UInt = #line) {
+  expectEqual(MemoryLayout<T>.size, MemoryLayout<T???>.size,
+              "\(T.self) has at least three extra inhabitants",
+              file: file, line: line)
+
+  expectNil(theNil,
+            "\(T.self) extra inhabitant should agree in generic and concrete " +
+            "context")
+
+  expectNil(someNil!,
+            "\(T.self) extra inhabitant should agree in generic and concrete " +
+            "context")
+
+  expectNil(someSomeNil!!,
+            "\(T.self) extra inhabitant should agree in generic and concrete " +
+            "context")
+}
+
+@inline(never)
+func expectHasExtraInhabitant<T>(_: T.Type, nil theNil: T?,
                                  file: String = #file, line: UInt = #line) {
   expectEqual(MemoryLayout<T>.size, MemoryLayout<T?>.size,
               "\(T.self) has extra inhabitant",
               file: file, line: line)
 
-  expectNil(Optional<T>.none,
+  expectNil(theNil,
             "\(T.self) extra inhabitant should agree in generic and concrete " +
             "context")
 }
@@ -167,5 +190,10 @@
   expectHasExtraInhabitant(GenericFullHouse<UnsafeRawPointer, UnsafeRawPointer>.self, nil: nil)
 }
 
+tests.test("types that have more than one extra inhabitant") {
+  expectHasAtLeastThreeExtraInhabitants(StringAlike64.self, nil: nil, someNil: .some(nil), someSomeNil: .some(.some(nil)))
+  expectHasAtLeastThreeExtraInhabitants(StringAlike32.self, nil: nil, someNil: .some(nil), someSomeNil: .some(.some(nil)))
+}
+
 runAllTests()
 
diff --git a/test/Parse/diagnose_dynamicReplacement.swift b/test/Parse/diagnose_dynamicReplacement.swift
new file mode 100644
index 0000000..07ab5d1
--- /dev/null
+++ b/test/Parse/diagnose_dynamicReplacement.swift
@@ -0,0 +1,20 @@
+// RUN: %target-typecheck-verify-swift -swift-version 5
+
+dynamic func dynamic_replaceable() {
+
+}
+
+@_dynamicReplacement
+// expected-error@-1 {{expected '(' in '_dynamicReplacement' attribute}}
+func test_dynamic_replacement_for() {
+}
+
+@_dynamicReplacement(
+// expected-error@-1 {{expected 'for' in '_dynamicReplacement' attribute}}
+func test_dynamic_replacement_for2() {
+}
+
+@_dynamicReplacement(for: dynamically_replaceable() // expected-note {{to match this opening '('}}
+func test_dynamic_replacement_for3() {
+// expected-error@-1 {{expected ')' after function name for @_dynamicReplacement}}
+}
diff --git a/test/Parse/pound_assert.swift b/test/Parse/pound_assert.swift
new file mode 100644
index 0000000..dcbd88b
--- /dev/null
+++ b/test/Parse/pound_assert.swift
@@ -0,0 +1,19 @@
+// RUN: %target-typecheck-verify-swift -enable-experimental-static-assert
+
+#assert(true, 123) // expected-error{{expected a string literal}}
+
+#assert(true, "error \(1) message") // expected-error{{'#assert' message cannot be an interpolated string literal}}
+
+#assert true, "error message") // expected-error{{expected '(' in #assert directive}}
+
+#assert(, "error message") // expected-error{{expected a condition expression}}
+
+func unbalanced1() {
+  #assert(true // expected-error{{expected ')' in #assert directive}}
+  // expected-note @-1 {{to match this opening '('}}
+}
+
+func unbalanced2() {
+  #assert(true, "hello world" // expected-error{{expected ')' in #assert directive}}
+  // expected-note @-1 {{to match this opening '('}}
+}
diff --git a/test/Parse/recovery.swift b/test/Parse/recovery.swift
index f29323b..c7210a0 100644
--- a/test/Parse/recovery.swift
+++ b/test/Parse/recovery.swift
@@ -33,7 +33,9 @@
   func exists() -> Bool { return true }
 }
 
-func test(a: BadAttributes) -> () { // expected-note * {{did you mean 'test'?}}
+// expected-note @+2 {{did you mean 'test'?}}
+// expected-note @+1 {{'test' declared here}}
+func test(a: BadAttributes) -> () {
   _ = a.exists() // no-warning
 }
 
@@ -617,7 +619,7 @@
 func foo2(bar! = baz) {}// expected-note {{did you mean 'foo2'?}}
 
 // rdar://19605567
-// expected-error@+1{{use of unresolved identifier 'esp'}}
+// expected-error@+1{{use of unresolved identifier 'esp'; did you mean 'test'?}}
 switch esp {
 case let (jeb):
   // expected-error@+5{{operator with postfix spacing cannot start a subexpression}}
diff --git a/test/ParseableInterface/Conformances.swiftinterface b/test/ParseableInterface/Conformances.swiftinterface
index c549692..e59fa69 100644
--- a/test/ParseableInterface/Conformances.swiftinterface
+++ b/test/ParseableInterface/Conformances.swiftinterface
@@ -2,8 +2,10 @@
 // swift-module-flags: 
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -enable-resilience -o %t/Conformances.swiftmodule %s
-// RUN: %target-swift-frontend -emit-sil -I %t %S/Inputs/ConformancesUser.swift -O | %FileCheck %s
+// RUN: %target-swift-frontend -emit-module-path %t/Conformances.swiftmodule -enable-resilience -emit-sil -o %t/Conformances.sil -enable-objc-interop -disable-objc-attr-requires-foundation-module %s
+// RUN: %FileCheck -check-prefix CHECK-MODULE %s < %t/Conformances.sil
+// RUN: %FileCheck -check-prefix NEGATIVE-MODULE %s < %t/Conformances.sil
+// RUN: %target-swift-frontend -enable-objc-interop -emit-sil -I %t %S/Inputs/ConformancesUser.swift -O | %FileCheck %s
 
 public protocol MyProto {
   init()
@@ -11,6 +13,15 @@
   var prop: Int { get set }
   subscript(index: Int) -> Int { get set }
 }
+extension MyProto {
+  public func method() {}
+}
+
+// Make sure there's no default witness table. (But also make sure we printed at
+// least some regular witness tables, or we'll have to change the test.)
+// CHECK-MODULE: sil_witness_table{{.+}}: MyProto module Conformances
+// NEGATIVE-MODULE-NOT: sil_default_witness_table{{.+}}MyProto
+
 
 @_fixed_layout // allow conformance devirtualization
 public struct FullStructImpl: MyProto {
@@ -31,7 +42,41 @@
 
 // CHECK-LABEL: sil @$s16ConformancesUser10testOpaqueSiyF
 // CHECK: function_ref @$s12Conformances7MyProtoPxycfC
-// CHECK: function_ref @$s12Conformances7MyProtoP6methodyyF
+// Note the default implementation is filled in here.
+// CHECK: function_ref @$s12Conformances7MyProtoPAAE6methodyyF
 // CHECK: function_ref @$s12Conformances7MyProtoP4propSivs
 // CHECK: function_ref @$s12Conformances7MyProtoPyS2icig
 // CHECK: end sil function '$s16ConformancesUser10testOpaqueSiyF'
+
+public struct ResilientStructImpl: MyProto {
+  @available(*, unavailable) // Ignore this, because the conformance is resilient.
+  public init()
+}
+
+// CHECK-LABEL: sil @$s16ConformancesUser13testResilientSiyF
+// CHECK: witness_method $ResilientStructImpl, #MyProto.init!allocator.1
+// CHECK: witness_method $ResilientStructImpl, #MyProto.method!1
+// CHECK: witness_method $ResilientStructImpl, #MyProto.prop!setter.1
+// CHECK: witness_method $ResilientStructImpl, #MyProto.subscript!getter.1
+// CHECK: end sil function '$s16ConformancesUser13testResilientSiyF'
+
+
+@objc public protocol OptionalReqs {
+  @objc optional func method()
+}
+@_fixed_layout
+public final class OptionalReqsPresent: OptionalReqs {
+  public func method () {}
+}
+@_fixed_layout
+public final class OptionalReqsAbsent: OptionalReqs {}
+
+// It would be okay if this one got optimized...
+// CHECK-LABEL: sil @$s16ConformancesUser19testOptionalPresentySb0A00d4ReqsE0CF
+// CHECK: dynamic_method_br %0 : $OptionalReqsPresent, #OptionalReqs.method!1.foreign
+// CHECK: end sil function '$s16ConformancesUser19testOptionalPresentySb0A00d4ReqsE0CF'
+
+// ...but not this one, because the method that's currently absent might get added.
+// CHECK-LABEL: sil @$s16ConformancesUser18testOptionalAbsentySb0A00d4ReqsE0CF
+// CHECK: dynamic_method_br %0 : $OptionalReqsAbsent, #OptionalReqs.method!1.foreign
+// CHECK: end sil function '$s16ConformancesUser18testOptionalAbsentySb0A00d4ReqsE0CF'
diff --git a/test/ParseableInterface/Inputs/ConformancesUser.swift b/test/ParseableInterface/Inputs/ConformancesUser.swift
index b7a7b64..c3f4599 100644
--- a/test/ParseableInterface/Inputs/ConformancesUser.swift
+++ b/test/ParseableInterface/Inputs/ConformancesUser.swift
@@ -14,3 +14,20 @@
 public func testOpaque() -> Int {
   return testGeneric(OpaqueStructImpl.self)
 }
+
+public func testResilient() -> Int {
+  return testGeneric(ResilientStructImpl.self)
+}
+
+
+func testOptionalGeneric<T: OptionalReqs>(_ obj: T) -> Bool {
+  return obj.method?() != nil
+}
+
+public func testOptionalPresent(_ obj: OptionalReqsPresent) -> Bool {
+  return testOptionalGeneric(obj)
+}
+
+public func testOptionalAbsent(_ obj: OptionalReqsAbsent) -> Bool {
+  return testOptionalGeneric(obj)
+}
diff --git a/test/ParseableInterface/Inputs/check-is-new.py b/test/ParseableInterface/Inputs/check-is-new.py
new file mode 100755
index 0000000..61f7931
--- /dev/null
+++ b/test/ParseableInterface/Inputs/check-is-new.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# check-is-new.py - a more-legible way to read a timestamp test than test(1)
+#
+# This source file is part of the Swift.org open source project
+#
+# Copyright (c) 2014 - 2018 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
+#
+# ----------------------------------------------------------------------------
+#
+# Compares the mtime of the provided files to a constant "old" reference time.
+# Fails if any file is as-old-or-older than old.
+#
+# ----------------------------------------------------------------------------
+
+import os
+import sys
+
+OLD = 1390550700  # 2014-01-24T08:05:00+00:00
+for f in sys.argv[1:]:
+    if os.stat(f).st_mtime <= OLD:
+        print("%s is not new!" % f)
+        exit(1)
diff --git a/test/ParseableInterface/Inputs/check-is-old.py b/test/ParseableInterface/Inputs/check-is-old.py
new file mode 100755
index 0000000..23fa01d
--- /dev/null
+++ b/test/ParseableInterface/Inputs/check-is-old.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+#
+# check-is-old.py - a more-legible way to read a timestamp test than test(1)
+#
+# This source file is part of the Swift.org open source project
+#
+# Copyright (c) 2014 - 2018 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
+#
+# ----------------------------------------------------------------------------
+#
+# Compares the mtime of the provided files to a constant "old" reference time.
+# Fails if any file has mtime not-equal to old.
+#
+# ----------------------------------------------------------------------------
+
+import os
+import sys
+
+OLD = 1390550700  # 2014-01-24T08:05:00+00:00
+for f in sys.argv[1:]:
+    if os.stat(f).st_mtime != OLD:
+        print("%s is not old!" % f)
+        exit(1)
diff --git a/test/ParseableInterface/Inputs/make-old.py b/test/ParseableInterface/Inputs/make-old.py
new file mode 100755
index 0000000..a97c6c4
--- /dev/null
+++ b/test/ParseableInterface/Inputs/make-old.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+#
+# make-old.py - /bin/touch that writes a constant "old" timestamp.
+#
+# This source file is part of the Swift.org open source project
+#
+# Copyright (c) 2014 - 2018 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
+#
+# ----------------------------------------------------------------------------
+#
+# Like /bin/touch, but writes a constant "old" timestamp.
+#
+# ----------------------------------------------------------------------------
+
+import os
+import sys
+
+OLD = 1390550700  # 2014-01-24T08:05:00+00:00
+for f in sys.argv[1:]:
+    os.utime(f, (OLD, OLD))
diff --git a/test/ParseableInterface/access-filter.swift b/test/ParseableInterface/access-filter.swift
index a3851da..64e2a75 100644
--- a/test/ParseableInterface/access-filter.swift
+++ b/test/ParseableInterface/access-filter.swift
@@ -149,3 +149,139 @@
   // CHECK-NEXT: case y(Int)
   case y(Int)
 } // CHECK-NEXT: {{^[}]$}}
+
+// CHECK: public class PublicClass {{[{]$}}
+public class PublicClass {
+} // CHECK: {{^[}]$}}
+
+class InternalClass_BAD {
+}
+
+// CHECK: @usableFromInline
+// CHECK-NEXT: internal class UFIClass {{[{]$}}
+@usableFromInline class UFIClass {
+} // CHECK: {{^[}]$}}
+
+// CHECK: public struct GenericStruct<T>
+public struct GenericStruct<T> {}
+
+// CHECK: extension GenericStruct where T == main.PublicStruct {{[{]$}}
+extension GenericStruct where T == PublicStruct {
+  // CHECK-NEXT: public func constrainedToPublicStruct(){{$}}
+  public func constrainedToPublicStruct() {}
+} // CHECK-NEXT: {{^[}]$}}
+// CHECK: extension GenericStruct where T == main.UFIStruct {{[{]$}}
+extension GenericStruct where T == UFIStruct {
+  // CHECK-NEXT: @usableFromInline{{$}}
+  // CHECK-NEXT: internal func constrainedToUFIStruct(){{$}}
+  @usableFromInline internal func constrainedToUFIStruct() {}
+} // CHECK-NEXT: {{^[}]$}}
+extension GenericStruct where T == InternalStruct_BAD {
+  @usableFromInline internal func constrainedToInternalStruct_BAD() {}
+}
+
+// CHECK: extension GenericStruct where T == main.PublicStruct {{[{]$}}
+extension GenericStruct where PublicStruct == T {
+  // CHECK-NEXT: public func constrainedToPublicStruct2(){{$}}
+  public func constrainedToPublicStruct2() {}
+} // CHECK-NEXT: {{^[}]$}}
+// CHECK: extension GenericStruct where T == main.UFIStruct {{[{]$}}
+extension GenericStruct where UFIStruct == T {
+  // CHECK-NEXT: @usableFromInline{{$}}
+  // CHECK-NEXT: internal func constrainedToUFIStruct2(){{$}}
+  @usableFromInline internal func constrainedToUFIStruct2() {}
+} // CHECK-NEXT: {{^[}]$}}
+extension GenericStruct where InternalStruct_BAD == T {
+  @usableFromInline internal func constrainedToInternalStruct2_BAD() {}
+}
+
+// CHECK: extension GenericStruct where T : PublicProto {{[{]$}}
+extension GenericStruct where T: PublicProto {
+  // CHECK-NEXT: public func constrainedToPublicProto(){{$}}
+  public func constrainedToPublicProto() {}
+} // CHECK-NEXT: {{^[}]$}}
+// CHECK: extension GenericStruct where T : UFIProto {{[{]$}}
+extension GenericStruct where T: UFIProto {
+  // CHECK-NEXT: @usableFromInline{{$}}
+  // CHECK-NEXT: internal func constrainedToUFIProto(){{$}}
+  @usableFromInline internal func constrainedToUFIProto() {}
+} // CHECK-NEXT: {{^[}]$}}
+extension GenericStruct where T: InternalProto_BAD {
+  @usableFromInline internal func constrainedToInternalProto_BAD() {}
+}
+
+// CHECK: extension GenericStruct where T : main.PublicClass {{[{]$}}
+extension GenericStruct where T: PublicClass {
+  // CHECK-NEXT: public func constrainedToPublicClass(){{$}}
+  public func constrainedToPublicClass() {}
+} // CHECK-NEXT: {{^[}]$}}
+// CHECK: extension GenericStruct where T : main.UFIClass {{[{]$}}
+extension GenericStruct where T: UFIClass {
+  // CHECK-NEXT: @usableFromInline{{$}}
+  // CHECK-NEXT: internal func constrainedToUFIClass(){{$}}
+  @usableFromInline internal func constrainedToUFIClass() {}
+} // CHECK-NEXT: {{^[}]$}}
+extension GenericStruct where T: InternalClass_BAD {
+  @usableFromInline internal func constrainedToInternalClass_BAD() {}
+}
+
+// CHECK: extension GenericStruct where T : AnyObject {{[{]$}}
+extension GenericStruct where T: AnyObject {
+  // CHECK-NEXT: public func constrainedToAnyObject(){{$}}
+  public func constrainedToAnyObject() {}
+} // CHECK-NEXT: {{^[}]$}}
+
+public struct PublicAliasBase {}
+internal struct ReallyInternalAliasBase_BAD {}
+
+// CHECK: public typealias PublicAlias = PublicAliasBase
+public typealias PublicAlias = PublicAliasBase
+internal typealias InternalAlias_BAD = PublicAliasBase
+// CHECK: @usableFromInline
+// CHECK-NEXT: internal typealias UFIAlias = PublicAliasBase
+@usableFromInline internal typealias UFIAlias = PublicAliasBase
+
+internal typealias ReallyInternalAlias_BAD = ReallyInternalAliasBase_BAD
+
+// CHECK: extension GenericStruct where T == PublicAlias {{[{]$}}
+extension GenericStruct where T == PublicAlias {
+  // CHECK-NEXT: public func constrainedToPublicAlias(){{$}}
+  public func constrainedToPublicAlias() {}
+} // CHECK-NEXT: {{^[}]$}}
+// CHECK: extension GenericStruct where T == UFIAlias {{[{]$}}
+extension GenericStruct where T == UFIAlias {
+  // CHECK-NEXT: @usableFromInline{{$}}
+  // CHECK-NEXT: internal func constrainedToUFIAlias(){{$}}
+  @usableFromInline internal func constrainedToUFIAlias() {}
+} // CHECK-NEXT: {{^[}]$}}
+extension GenericStruct where T == InternalAlias_BAD {
+  // FIXME: We could print this one by desugaring; it is indeed public.
+  @usableFromInline internal func constrainedToInternalAlias() {}
+}
+extension GenericStruct where T == ReallyInternalAlias_BAD {
+  @usableFromInline internal func constrainedToPrivateAlias() {}
+}
+
+extension GenericStruct {
+  // For the next extension's test.
+  public func requirement() {}
+}
+extension GenericStruct: PublicProto where T: InternalProto_BAD {
+  @usableFromInline internal func conformance_BAD() {}
+}
+
+
+public struct MultiGenericStruct<First, Second> {}
+
+// CHECK: extension MultiGenericStruct where First == main.PublicStruct, Second == main.PublicStruct {{[{]$}}
+extension MultiGenericStruct where First == PublicStruct, Second == PublicStruct {
+  // CHECK-NEXT: public func publicPublic(){{$}}
+  public func publicPublic() {}
+} // CHECK-NEXT: {{^[}]$}}
+
+extension MultiGenericStruct where First == PublicStruct, Second == InternalStruct_BAD {
+  @usableFromInline internal func publicInternal_BAD() {}
+}
+extension MultiGenericStruct where First == InternalStruct_BAD, Second == PublicStruct {
+  @usableFromInline internal func internalPublic_BAD() {}
+}
diff --git a/test/ParseableInterface/client.swift b/test/ParseableInterface/client.swift
deleted file mode 100644
index 43ee525..0000000
--- a/test/ParseableInterface/client.swift
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: %empty-directory(%t)
-// RUN: %empty-directory(%t/modulecache)
-// RUN: %target-swift-frontend -enable-resilience -emit-parseable-module-interface-path %t/TestModule.swiftinterface -module-name TestModule %S/Inputs/other.swift -emit-module -o /dev/null
-// RUN: test -f %t/TestModule.swiftinterface
-// RUN: %target-swift-frontend -typecheck -enable-parseable-module-interface -module-cache-path %t/modulecache -I %t %s
-
-// RUN: test ! %t/modulecache/TestModule-*.swiftmodule -ot %t/TestModule.swiftinterface
-// RUN: llvm-bcanalyzer -dump %t/modulecache/TestModule-*.swiftmodule | %FileCheck %s -check-prefix=CHECK-SWIFTMODULE
-// RUN: %FileCheck %s -check-prefix=CHECK-SID <%t/modulecache/TestModule-*.sid
-
-// Now add a "dependency" to the .sid file but set it to be quite old
-// RUN: echo %t/fake-dep >>%t/modulecache/TestModule-*.sid
-// RUN: touch -t 201401240005 %t/fake-dep
-// RUN: %FileCheck %s -check-prefix=CHECK-SID2 <%t/modulecache/TestModule-*.sid
-
-// Check that the cache does not rebuild
-// RUN: %target-swift-frontend -typecheck -enable-parseable-module-interface -module-cache-path %t/modulecache -I %t %s
-// RUN: %FileCheck %s -check-prefix=CHECK-SID2 <%t/modulecache/TestModule-*.sid
-
-// Now touch the dependency a ways into the future, and check that the cache _does_ rebuild
-// (Sorry, this test will need refreshing in the year 2035)
-// RUN: touch -t 203501240005 %t/fake-dep
-// RUN: %target-swift-frontend -typecheck -enable-parseable-module-interface -module-cache-path %t/modulecache -I %t %s
-// RUN: %FileCheck %s -check-prefix=CHECK-SID3 <%t/modulecache/TestModule-*.sid
-
-// CHECK-SWIFTMODULE: {{MODULE_NAME.*blob data = 'TestModule'}}
-// CHECK-SWIFTMODULE: FUNC_DECL
-// CHECK-SWIFTMODULE: RESILIENCE_STRATEGY
-// CHECK-SID: Swift.swiftmodule
-// CHECK-SID2: fake-dep
-// CHECK-SID3-NOT: fake-dep
-
-import TestModule
-func foo() {
-    otherFileFunction()
-}
diff --git a/test/ParseableInterface/conformances.swift b/test/ParseableInterface/conformances.swift
index d58e89a..80d6181 100644
--- a/test/ParseableInterface/conformances.swift
+++ b/test/ParseableInterface/conformances.swift
@@ -1,5 +1,6 @@
 // RUN: %target-swift-frontend-typecheck -emit-parseable-module-interface-path %t.swiftinterface %s
 // RUN: %FileCheck %s < %t.swiftinterface
+// RUN: %FileCheck -check-prefix CHECK-END %s < %t.swiftinterface
 // RUN: %FileCheck -check-prefix NEGATIVE %s < %t.swiftinterface
 
 // CHECK-LABEL: public protocol SimpleProto {
@@ -11,10 +12,159 @@
   func inference(_: Inferred)
 } // CHECK: {{^}$}}
 
-// CHECK-LABEL: public struct SimplImpl<Element> : SimpleProto {
-public struct SimplImpl<Element>: SimpleProto {
+// CHECK-LABEL: public struct SimpleImpl<Element> : SimpleProto {
+public struct SimpleImpl<Element>: SimpleProto {
   // NEGATIVE-NOT: typealias Element =
   // CHECK: public func inference(_: Int){{$}}
   public func inference(_: Int) {}
   // CHECK: public typealias Inferred = Swift.Int
 } // CHECK: {{^}$}}
+
+
+public protocol PublicProto {}
+private protocol PrivateProto {}
+
+// CHECK: public struct A1 : PublicProto {
+// NEGATIVE-NOT: extension conformances.A1
+public struct A1: PublicProto, PrivateProto {}
+// CHECK: public struct A2 : PublicProto {
+// NEGATIVE-NOT: extension conformances.A2
+public struct A2: PrivateProto, PublicProto {}
+// CHECK: public struct A3 {
+// CHECK-END: extension conformances.A3 : PublicProto {}
+public struct A3: PublicProto & PrivateProto {}
+// CHECK: public struct A4 {
+// CHECK-END: extension conformances.A4 : PublicProto {}
+public struct A4: PrivateProto & PublicProto {}
+
+public protocol PublicBaseProto {}
+private protocol PrivateSubProto: PublicBaseProto {}
+
+// CHECK: public struct B1 {
+// CHECK-END: extension conformances.B1 : PublicBaseProto {}
+public struct B1: PrivateSubProto {}
+// CHECK: public struct B2 : PublicBaseProto {
+// NEGATIVE-NOT: extension conformances.B2
+public struct B2: PublicBaseProto, PrivateSubProto {}
+// CHECK: public struct B3 {
+// CHECK-END: extension conformances.B3 : PublicBaseProto {}
+public struct B3: PublicBaseProto & PrivateSubProto {}
+// CHECK: public struct B4 : PublicBaseProto {
+// CHECK: extension B4 {
+// NEGATIVE-NOT: extension conformances.B4
+public struct B4: PublicBaseProto {}
+extension B4: PrivateSubProto {}
+// CHECK: public struct B5 {
+// CHECK: extension B5 : PublicBaseProto {
+// NEGATIVE-NOT: extension conformances.B5
+public struct B5: PrivateSubProto {}
+extension B5: PublicBaseProto {}
+// CHECK: public struct B6 {
+// CHECK: extension B6 {
+// CHECK: extension B6 : PublicBaseProto {
+// NEGATIVE-NOT: extension conformances.B6
+public struct B6 {}
+extension B6: PrivateSubProto {}
+extension B6: PublicBaseProto {}
+// CHECK: public struct B7 {
+// CHECK: extension B7 : PublicBaseProto {
+// CHECK: extension B7 {
+// NEGATIVE-NOT: extension conformances.B7
+public struct B7 {}
+extension B7: PublicBaseProto {}
+extension B7: PrivateSubProto {}
+
+// CHECK-LABEL: public struct OuterGeneric<T> {
+public struct OuterGeneric<T> {
+  // CHECK-NEXT: public struct Inner {
+  public struct Inner: PrivateSubProto {}
+  // CHECK-NEXT: {{^  }$}}
+}
+// CHECK-NEXT: {{^}$}}
+
+public protocol ConditionallyConformed {}
+public protocol ConditionallyConformedAgain {}
+
+// CHECK-END: extension conformances.OuterGeneric : ConditionallyConformed, ConditionallyConformedAgain where T : _ConstraintThatIsNotPartOfTheAPIOfThisLibrary {}
+extension OuterGeneric: ConditionallyConformed where T: PrivateProto {}
+extension OuterGeneric: ConditionallyConformedAgain where T == PrivateProto {}
+
+// CHECK-END: extension conformances.OuterGeneric.Inner : PublicBaseProto {}
+// CHECK-END: extension conformances.OuterGeneric.Inner : ConditionallyConformed, ConditionallyConformedAgain where T : _ConstraintThatIsNotPartOfTheAPIOfThisLibrary {}
+extension OuterGeneric.Inner: ConditionallyConformed where T: PrivateProto {}
+extension OuterGeneric.Inner: ConditionallyConformedAgain where T == PrivateProto {}
+
+private protocol AnotherPrivateSubProto: PublicBaseProto {}
+
+// CHECK: public struct C1 {
+// CHECK-END: extension conformances.C1 : PublicBaseProto {}
+public struct C1: PrivateSubProto, AnotherPrivateSubProto {}
+// CHECK: public struct C2 {
+// CHECK-END: extension conformances.C2 : PublicBaseProto {}
+public struct C2: PrivateSubProto & AnotherPrivateSubProto {}
+// CHECK: public struct C3 {
+// CHECK: extension C3 {
+// CHECK-END: extension conformances.C3 : PublicBaseProto {}
+public struct C3: PrivateSubProto {}
+extension C3: AnotherPrivateSubProto {}
+
+public protocol PublicSubProto: PublicBaseProto {}
+public protocol APublicSubProto: PublicBaseProto {}
+
+// CHECK: public struct D1 : PublicSubProto {
+// NEGATIVE-NOT: extension conformances.D1
+public struct D1: PublicSubProto, PrivateSubProto {}
+// CHECK: public struct D2 : PublicSubProto {
+// NEGATIVE-NOT: extension conformances.D2
+public struct D2: PrivateSubProto, PublicSubProto {}
+// CHECK: public struct D3 {
+// CHECK-END: extension conformances.D3 : PublicBaseProto, PublicSubProto {}
+public struct D3: PrivateSubProto & PublicSubProto {}
+// CHECK: public struct D4 {
+// CHECK-END: extension conformances.D4 : APublicSubProto, PublicBaseProto {}
+public struct D4: APublicSubProto & PrivateSubProto {}
+// CHECK: public struct D5 {
+// CHECK: extension D5 : PublicSubProto {
+// NEGATIVE-NOT: extension conformances.D5
+public struct D5: PrivateSubProto {}
+extension D5: PublicSubProto {}
+// CHECK: public struct D6 : PublicSubProto {
+// CHECK: extension D6 {
+// NEGATIVE-NOT: extension conformances.D6
+public struct D6: PublicSubProto {}
+extension D6: PrivateSubProto {}
+
+private typealias PrivateProtoAlias = PublicProto
+
+// CHECK: public struct E1 {
+// CHECK-END: extension conformances.E1 : PublicProto {}
+public struct E1: PrivateProtoAlias {}
+
+private typealias PrivateSubProtoAlias = PrivateSubProto
+
+// CHECK: public struct F1 {
+// CHECK-END: extension conformances.F1 : PublicBaseProto {}
+public struct F1: PrivateSubProtoAlias {}
+
+private protocol ClassConstrainedProto: PublicProto, AnyObject {}
+
+public class G1: ClassConstrainedProto {}
+// CHECK: public class G1 {
+// CHECK-END: extension conformances.G1 : PublicProto {}
+
+public class Base {}
+private protocol BaseConstrainedProto: Base, PublicProto {}
+
+public class H1: Base, ClassConstrainedProto {}
+// CHECK: public class H1 : Base {
+// CHECK-END: extension conformances.H1 : PublicProto {}
+
+public struct MultiGeneric<T, U, V> {}
+extension MultiGeneric: PublicProto where U: PrivateProto {}
+
+// CHECK: public struct MultiGeneric<T, U, V> {
+// CHECK-END: extension conformances.MultiGeneric : PublicProto where T : _ConstraintThatIsNotPartOfTheAPIOfThisLibrary {}
+
+
+// CHECK-END: @usableFromInline
+// CHECK-END-NEXT: internal protocol _ConstraintThatIsNotPartOfTheAPIOfThisLibrary {}
diff --git a/test/ParseableInterface/inlinable-function.swift b/test/ParseableInterface/inlinable-function.swift
index e94bd6a..3bb0589 100644
--- a/test/ParseableInterface/inlinable-function.swift
+++ b/test/ParseableInterface/inlinable-function.swift
@@ -199,14 +199,6 @@
     inlinableProperty = 4
   }
 
-  // CHECK: @inline(__always) [[ATTRS]] func inlineAlwaysMethod() {
-  // CHECK-NEXT: inlinableProperty = 4
-  // CHECK-NEXT: }
-  @inline(__always)
-  mutating public func inlineAlwaysMethod() {
-    inlinableProperty = 4
-  }
-
   // CHECK: public func nonInlinableMethod(){{$}}
   // CHECK-NOT: print("Not inlinable")
   public func nonInlinableMethod() {
diff --git a/test/ParseableInterface/modifiers.swift b/test/ParseableInterface/modifiers.swift
index 3a11bb8..d63a46a 100644
--- a/test/ParseableInterface/modifiers.swift
+++ b/test/ParseableInterface/modifiers.swift
@@ -3,7 +3,7 @@
 // RUN: %FileCheck %s < %t/Test.swiftinterface
 // RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-parseable-module-interface-path - -module-name Test -enable-objc-interop | %FileCheck %s
 
-// CHECK: final public class FinalClass {
+// CHECK-LABEL: final public class FinalClass {
 public final class FinalClass {
   // CHECK: @inlinable final public class var a: [[INT:(Swift.)?Int]] {
   // CHECK-NEXT: {{^}} get {
@@ -53,7 +53,35 @@
   }
 }
 
-// CHECK: public struct MyStruct {
+// CHECK-LABEL: public class Base {
+public class Base {
+  // CHECK-NEXT: @objc public init(){{$}}
+  @objc public init() {}
+  // CHECK-NEXT: @objc required public init(x: [[INT]]){{$}}
+  @objc public required init(x: Int) {}
+  // CHECK-NEXT: @objc deinit{{$}}
+} // CHECK-NEXT: {{^}$}}
+
+
+// CHECK-LABEL: public class SubImplicit : {{(Test[.])?Base}} {
+public class SubImplicit: Base {
+  // CHECK-NEXT: @objc override public init(){{$}}
+  // CHECK-NEXT: @objc required public init(x: [[INT]]){{$}}
+  // CHECK-NEXT: @objc deinit{{$}}
+} // CHECK-NEXT: {{^}$}}
+
+
+// CHECK-LABEL: public class SubExplicit : {{(Test[.])?Base}} {
+public class SubExplicit: Base {
+  // Make sure adding "required" preserves both "required" and "override".
+  // CHECK-NEXT: @objc override required public init(){{$}}
+  public override required init() { super.init() }
+  // CHECK-NEXT: @objc required public init(x: [[INT]]){{$}}
+  public required init(x: Int) { super.init() }
+  // CHECK-NEXT: @objc deinit{{$}}
+} // CHECK-NEXT: {{^}$}}
+
+// CHECK-LABEL: public struct MyStruct {
 public struct MyStruct {
   // CHECK: public var e: [[INT]] {
   // CHECK-NEXT: {{^}} mutating get{{$}}
diff --git a/test/ParseableInterface/module-cache-init.swift b/test/ParseableInterface/module-cache-init.swift
new file mode 100644
index 0000000..72bc18f
--- /dev/null
+++ b/test/ParseableInterface/module-cache-init.swift
@@ -0,0 +1,51 @@
+// RUN: %empty-directory(%t)
+// RUN: %empty-directory(%t/modulecache)
+//
+// Test will build a module TestModule that depends on OtherModule and LeafModule (built from other.swift and leaf.swift).
+//
+// RUN: echo 'public func LeafFunc() -> Int { return 10; }' >%t/leaf.swift
+//
+// RUN: echo 'import LeafModule' >%t/other.swift
+// RUN: echo 'public func OtherFunc() -> Int { return LeafFunc(); }' >>%t/other.swift
+//
+// Phase 1: build LeafModule into a .swiftinterface file:
+//
+// RUN: %target-swift-frontend -I %t -emit-parseable-module-interface-path %t/LeafModule.swiftinterface -module-name LeafModule %t/leaf.swift -emit-module -o /dev/null
+// RUN: test -f %t/LeafModule.swiftinterface
+// RUN: %FileCheck %s -check-prefix=CHECK-LEAFINTERFACE <%t/LeafModule.swiftinterface
+// CHECK-LEAFINTERFACE: LeafFunc
+//
+//
+// Phase 2: build OtherModule into a .swiftinterface _using_ LeafModule via LeafModule.swiftinterface, creating LeafModule-*.swiftmodule along the way.
+//
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-parseable-module-interface-path %t/OtherModule.swiftinterface -module-name OtherModule %t/other.swift -emit-module -o /dev/null
+// RUN: test -f %t/OtherModule.swiftinterface
+// RUN: %FileCheck %s -check-prefix=CHECK-OTHERINTERFACE <%t/OtherModule.swiftinterface
+// CHECK-OTHERINTERFACE: OtherFunc
+// RUN: test -f %t/modulecache/LeafModule-*.swiftmodule
+// RUN: llvm-bcanalyzer -dump %t/modulecache/LeafModule-*.swiftmodule | %FileCheck %s -check-prefix=CHECK-LEAFMODULE
+// CHECK-LEAFMODULE: {{MODULE_NAME.*blob data = 'LeafModule'}}
+// CHECK-LEAFMODULE: {{FILE_DEPENDENCY.*Swift.swiftmodule'}}
+// CHECK-LEAFMODULE: {{FILE_DEPENDENCY.*SwiftOnoneSupport.swiftmodule'}}
+// CHECK-LEAFMODULE: {{FILE_DEPENDENCY.*LeafModule.swiftinterface'}}
+// CHECK-LEAFMODULE: FUNC_DECL
+//
+//
+// Phase 3: build TestModule into a .swiftmodule explicitly us OtherModule via OtherModule.swiftinterface, creating OtherModule-*.swiftmodule along the way.
+//
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: test -f %t/TestModule.swiftmodule
+// RUN: test -f %t/modulecache/OtherModule-*.swiftmodule
+// RUN: llvm-bcanalyzer -dump %t/modulecache/OtherModule-*.swiftmodule | %FileCheck %s -check-prefix=CHECK-OTHERMODULE
+// CHECK-OTHERMODULE: {{MODULE_NAME.*blob data = 'OtherModule'}}
+// CHECK-OTHERMODULE: {{FILE_DEPENDENCY.*Swift.swiftmodule'}}
+// CHECK-OTHERMODULE: {{FILE_DEPENDENCY.*SwiftOnoneSupport.swiftmodule'}}
+// CHECK-OTHERMODULE: {{FILE_DEPENDENCY.*LeafModule-.*.swiftmodule'}}
+// CHECK-OTHERMODULE: {{FILE_DEPENDENCY.*OtherModule.swiftinterface'}}
+// CHECK-OTHERMODULE: FUNC_DECL
+
+import OtherModule
+
+public func TestFunc() {
+    print(OtherFunc())
+}
diff --git a/test/ParseableInterface/module-cache-intermediate-mtime-change-rebuilds-only-intermediate.swift b/test/ParseableInterface/module-cache-intermediate-mtime-change-rebuilds-only-intermediate.swift
new file mode 100644
index 0000000..fe7396e
--- /dev/null
+++ b/test/ParseableInterface/module-cache-intermediate-mtime-change-rebuilds-only-intermediate.swift
@@ -0,0 +1,44 @@
+// RUN: %empty-directory(%t)
+// RUN: %empty-directory(%t/modulecache)
+//
+// Setup builds a module TestModule that depends on OtherModule and LeafModule (built from other.swift and leaf.swift).
+// During setup, input and intermediate mtimes are all set to a constant 'old' time (long in the past).
+//
+// We then modify OtherModule.swiftinterface, and check only OtherModule-*.swiftmodule has a new mtime, LeafModule is unchanged.
+//
+//
+// Setup phase 1: Write input files.
+//
+// RUN: echo 'public func LeafFunc() -> Int { return 10; }' >%t/leaf.swift
+//
+// RUN: echo 'import LeafModule' >%t/other.swift
+// RUN: echo 'public func OtherFunc() -> Int { return LeafFunc(); }' >>%t/other.swift
+//
+//
+// Setup phase 2: build modules, pushing timestamps of inputs and intermediates into the past as we go.
+//
+// RUN: %S/Inputs/make-old.py %t/leaf.swift %t/other.swift
+// RUN: %target-swift-frontend -I %t -emit-parseable-module-interface-path %t/LeafModule.swiftinterface -module-name LeafModule %t/leaf.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/LeafModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-parseable-module-interface-path %t/OtherModule.swiftinterface -module-name OtherModule %t/other.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/modulecache/LeafModule-*.swiftmodule %t/OtherModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/make-old.py %t/modulecache/OtherModule-*.swiftmodule
+//
+//
+// Actual test: make OtherModule.swiftinterface newer, check we only rebuild its cached module.
+//
+// RUN: %S/Inputs/check-is-old.py %t/OtherModule.swiftinterface %t/LeafModule.swiftinterface
+// RUN: %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
+// RUN: touch %t/OtherModule.swiftinterface
+// RUN: %S/Inputs/check-is-new.py %t/OtherModule.swiftinterface
+// RUN: rm %t/TestModule.swiftmodule
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/check-is-new.py %t/modulecache/OtherModule-*.swiftmodule
+// RUN: %S/Inputs/check-is-old.py %t/modulecache/LeafModule-*.swiftmodule
+
+import OtherModule
+
+public func TestFunc() {
+    print(OtherFunc())
+}
diff --git a/test/ParseableInterface/module-cache-intermediate-size-change-rebuilds-only-intermediate.swift b/test/ParseableInterface/module-cache-intermediate-size-change-rebuilds-only-intermediate.swift
new file mode 100644
index 0000000..437c572
--- /dev/null
+++ b/test/ParseableInterface/module-cache-intermediate-size-change-rebuilds-only-intermediate.swift
@@ -0,0 +1,45 @@
+// RUN: %empty-directory(%t)
+// RUN: %empty-directory(%t/modulecache)
+//
+// Setup builds a module TestModule that depends on OtherModule and LeafModule (built from other.swift and leaf.swift).
+// During setup, input and intermediate mtimes are all set to a constant 'old' time (long in the past).
+//
+// We then modify OtherModule.swiftinterface's size (but not mtime), and check only OtherModule-*.swiftmodule has a new mtime, LeafModule is unchanged.
+//
+//
+// Setup phase 1: Write input files.
+//
+// RUN: echo 'public func LeafFunc() -> Int { return 10; }' >%t/leaf.swift
+//
+// RUN: echo 'import LeafModule' >%t/other.swift
+// RUN: echo 'public func OtherFunc() -> Int { return LeafFunc(); }' >>%t/other.swift
+//
+//
+// Setup phase 2: build modules, pushing timestamps of inputs and intermediates into the past as we go.
+//
+// RUN: %S/Inputs/make-old.py %t/leaf.swift %t/other.swift
+// RUN: %target-swift-frontend -I %t -emit-parseable-module-interface-path %t/LeafModule.swiftinterface -module-name LeafModule %t/leaf.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/LeafModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-parseable-module-interface-path %t/OtherModule.swiftinterface -module-name OtherModule %t/other.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/modulecache/LeafModule-*.swiftmodule %t/OtherModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/make-old.py %t/modulecache/OtherModule-*.swiftmodule
+//
+//
+// Actual test: make OtherModule.swiftinterface change size without changing mtime, check we only rebuild its cached module.
+//
+// RUN: %S/Inputs/check-is-old.py %t/OtherModule.swiftinterface %t/LeafModule.swiftinterface
+// RUN: %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
+// RUN: echo "// size change" >>%t/OtherModule.swiftinterface
+// RUN: %S/Inputs/make-old.py %t/OtherModule.swiftinterface
+// RUN: %S/Inputs/check-is-old.py %t/OtherModule.swiftinterface
+// RUN: rm %t/TestModule.swiftmodule
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/check-is-new.py %t/modulecache/OtherModule-*.swiftmodule
+// RUN: %S/Inputs/check-is-old.py %t/modulecache/LeafModule-*.swiftmodule
+
+import OtherModule
+
+public func TestFunc() {
+    print(OtherFunc())
+}
diff --git a/test/ParseableInterface/module-cache-leaf-mtime-change-rebuilds-all.swift b/test/ParseableInterface/module-cache-leaf-mtime-change-rebuilds-all.swift
new file mode 100644
index 0000000..001e34d
--- /dev/null
+++ b/test/ParseableInterface/module-cache-leaf-mtime-change-rebuilds-all.swift
@@ -0,0 +1,43 @@
+// RUN: %empty-directory(%t)
+// RUN: %empty-directory(%t/modulecache)
+//
+// Setup builds a module TestModule that depends on OtherModule and LeafModule (built from other.swift and leaf.swift).
+// During setup, input and intermediate mtimes are all set to a constant 'old' time (long in the past).
+//
+// We then modify LeafModule.swiftinterface, and check both cached modules have new mtimes.
+//
+//
+// Setup phase 1: Write input files.
+//
+// RUN: echo 'public func LeafFunc() -> Int { return 10; }' >%t/leaf.swift
+//
+// RUN: echo 'import LeafModule' >%t/other.swift
+// RUN: echo 'public func OtherFunc() -> Int { return LeafFunc(); }' >>%t/other.swift
+//
+//
+// Setup phase 2: build modules, pushing timestamps of inputs and intermediates into the past as we go.
+//
+// RUN: %S/Inputs/make-old.py %t/leaf.swift %t/other.swift
+// RUN: %target-swift-frontend -I %t -emit-parseable-module-interface-path %t/LeafModule.swiftinterface -module-name LeafModule %t/leaf.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/LeafModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-parseable-module-interface-path %t/OtherModule.swiftinterface -module-name OtherModule %t/other.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/modulecache/LeafModule-*.swiftmodule %t/OtherModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/make-old.py %t/modulecache/OtherModule-*.swiftmodule
+//
+//
+// Actual test: make LeafModule.swiftinterface newer, check both cached modules get rebuilt.
+//
+// RUN: %S/Inputs/check-is-old.py %t/OtherModule.swiftinterface %t/LeafModule.swiftinterface
+// RUN: %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
+// RUN: touch %t/LeafModule.swiftinterface
+// RUN: %S/Inputs/check-is-new.py %t/LeafModule.swiftinterface
+// RUN: rm %t/TestModule.swiftmodule
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/check-is-new.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
+
+import OtherModule
+
+public func TestFunc() {
+    print(OtherFunc())
+}
diff --git a/test/ParseableInterface/module-cache-leaf-size-change-rebuilds-all.swift b/test/ParseableInterface/module-cache-leaf-size-change-rebuilds-all.swift
new file mode 100644
index 0000000..5512171
--- /dev/null
+++ b/test/ParseableInterface/module-cache-leaf-size-change-rebuilds-all.swift
@@ -0,0 +1,44 @@
+// RUN: %empty-directory(%t)
+// RUN: %empty-directory(%t/modulecache)
+//
+// Setup builds a module TestModule that depends on OtherModule and LeafModule (built from other.swift and leaf.swift).
+// During setup, input and intermediate mtimes are all set to a constant 'old' time (long in the past).
+//
+// We then modify LeafModule.swiftinterface's size (but not mtime), and check both cached modules have new mtimes.
+//
+//
+// Setup phase 1: Write input files.
+//
+// RUN: echo 'public func LeafFunc() -> Int { return 10; }' >%t/leaf.swift
+//
+// RUN: echo 'import LeafModule' >%t/other.swift
+// RUN: echo 'public func OtherFunc() -> Int { return LeafFunc(); }' >>%t/other.swift
+//
+//
+// Setup phase 2: build modules, pushing timestamps of inputs and intermediates into the past as we go.
+//
+// RUN: %S/Inputs/make-old.py %t/leaf.swift %t/other.swift
+// RUN: %target-swift-frontend -I %t -emit-parseable-module-interface-path %t/LeafModule.swiftinterface -module-name LeafModule %t/leaf.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/LeafModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-parseable-module-interface-path %t/OtherModule.swiftinterface -module-name OtherModule %t/other.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/modulecache/LeafModule-*.swiftmodule %t/OtherModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/make-old.py %t/modulecache/OtherModule-*.swiftmodule
+//
+//
+// Actual test: make LeafModule.swiftinterface change size without changing mtime, check both cached modules get rebuilt.
+//
+// RUN: %S/Inputs/check-is-old.py %t/OtherModule.swiftinterface %t/LeafModule.swiftinterface
+// RUN: %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
+// RUN: echo "// size change" >>%t/LeafModule.swiftinterface
+// RUN: %S/Inputs/make-old.py %t/LeafModule.swiftinterface
+// RUN: %S/Inputs/check-is-old.py %t/LeafModule.swiftinterface
+// RUN: rm %t/TestModule.swiftmodule
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/check-is-new.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
+
+import OtherModule
+
+public func TestFunc() {
+    print(OtherFunc())
+}
diff --git a/test/ParseableInterface/module-cache-no-rebuild.swift b/test/ParseableInterface/module-cache-no-rebuild.swift
new file mode 100644
index 0000000..4a18a16
--- /dev/null
+++ b/test/ParseableInterface/module-cache-no-rebuild.swift
@@ -0,0 +1,42 @@
+// RUN: %empty-directory(%t)
+// RUN: %empty-directory(%t/modulecache)
+//
+// Setup builds a module TestModule that depends on OtherModule and LeafModule (built from other.swift and leaf.swift).
+// During setup, input and intermediate mtimes are all set to a constant 'old' time (long in the past).
+//
+// We then rebuild TestModule a second time, without changing any inputs, and confirm none of the files has a new mtime.
+//
+//
+// Setup phase 1: Write input files.
+//
+// RUN: echo 'public func LeafFunc() -> Int { return 10; }' >%t/leaf.swift
+//
+// RUN: echo 'import LeafModule' >%t/other.swift
+// RUN: echo 'public func OtherFunc() -> Int { return LeafFunc(); }' >>%t/other.swift
+//
+//
+// Setup phase 2: build modules, pushing timestamps of inputs and intermediates into the past as we go.
+//
+// RUN: %S/Inputs/make-old.py %t/leaf.swift %t/other.swift
+// RUN: %target-swift-frontend -I %t -emit-parseable-module-interface-path %t/LeafModule.swiftinterface -module-name LeafModule %t/leaf.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/LeafModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-parseable-module-interface-path %t/OtherModule.swiftinterface -module-name OtherModule %t/other.swift -emit-module -o /dev/null
+// RUN: %S/Inputs/make-old.py %t/modulecache/LeafModule-*.swiftmodule %t/OtherModule.swiftinterface
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/make-old.py %t/modulecache/OtherModule-*.swiftmodule
+//
+//
+// Actual test: rebuild output, check no intermediates gets rebuilt.
+//
+// RUN: %S/Inputs/check-is-old.py %t/OtherModule.swiftinterface %t/LeafModule.swiftinterface
+// RUN: %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
+// RUN: rm %t/TestModule.swiftmodule
+// RUN: %target-swift-frontend -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface -emit-module -o %t/TestModule.swiftmodule -module-name TestModule %s
+// RUN: %S/Inputs/check-is-old.py %t/OtherModule.swiftinterface %t/LeafModule.swiftinterface
+// RUN: %S/Inputs/check-is-old.py %t/modulecache/OtherModule-*.swiftmodule %t/modulecache/LeafModule-*.swiftmodule
+
+import OtherModule
+
+public func TestFunc() {
+    print(OtherFunc())
+}
diff --git a/test/ParseableInterface/synthesized.swift b/test/ParseableInterface/synthesized.swift
new file mode 100644
index 0000000..6a1f148
--- /dev/null
+++ b/test/ParseableInterface/synthesized.swift
@@ -0,0 +1,31 @@
+// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path - %s -disable-objc-attr-requires-foundation-module -enable-objc-interop | %FileCheck %s
+
+// CHECK-LABEL: public enum HasRawValue : Int {
+public enum HasRawValue: Int {
+  // CHECK-NEXT: case a, b, c
+  case a, b = 5, c
+  // CHECK-NEXT: public typealias RawValue = Swift.Int
+  // CHECK-NEXT: public var hashValue: Swift.Int {
+  // CHECK-NEXT:   get{{$}}
+  // CHECK-NEXT: }
+  // CHECK-NEXT: public func hash(into hasher: inout Swift.Hasher)
+  // CHECK-NEXT: @inlinable public init?(rawValue: Swift.Int)
+  // CHECK-NEXT: public var rawValue: Swift.Int {
+  // CHECK-NEXT:   @inlinable get{{$}}
+  // CHECK-NEXT: }
+} // CHECK-NEXT: {{^}$}}
+
+// CHECK-LABEL: @objc public enum ObjCEnum : Int {
+@objc public enum ObjCEnum: Int {
+  // CHECK-NEXT: case a, b, c
+  case a, b = 5, c
+  // CHECK-NEXT: public typealias RawValue = Swift.Int
+  // CHECK-NEXT: public var hashValue: Swift.Int {
+  // CHECK-NEXT:   get{{$}}
+  // CHECK-NEXT: }
+  // CHECK-NEXT: public func hash(into hasher: inout Swift.Hasher)
+  // CHECK-NEXT: @inlinable public init?(rawValue: Swift.Int)
+  // CHECK-NEXT: public var rawValue: Swift.Int {
+  // CHECK-NEXT:   @inlinable get{{$}}
+  // CHECK-NEXT: }
+} // CHECK-NEXT: {{^}$}}
diff --git a/test/Profiler/coverage_closures.swift b/test/Profiler/coverage_closures.swift
index 255767d..c87e940 100644
--- a/test/Profiler/coverage_closures.swift
+++ b/test/Profiler/coverage_closures.swift
@@ -16,7 +16,7 @@
 // CHECK-LABEL: sil_coverage_map {{.*}}// f1 #1 ((Swift.Int32, Swift.Int32) -> Swift.Bool) -> Swift.Bool in coverage_closures.foo()
 // CHECK-NEXT: [[@LINE+1]]:55 -> {{.*}}:4 : 0
   func f1(_ closure : (Int32, Int32) -> Bool) -> Bool {
-// CHECK-LABEL: sil_coverage_map {{.*}}// implicit closure #1 : @autoclosure () throws -> Swift.Bool in f1
+// CHECK-LABEL: sil_coverage_map {{.*}}// implicit closure #1 () throws -> Swift.Bool in f1
 // CHECK-NEXT: [[@LINE+1]]:29 -> [[@LINE+1]]:42 : 0
     return closure(0, 1) && closure(1, 0)
   }
@@ -29,7 +29,7 @@
 
 // CHECK-LABEL: sil_coverage_map {{.*}}// closure #3 (Swift.Int32, Swift.Int32) -> Swift.Bool in coverage_closures.foo()
 // CHECK-NEXT: [[@LINE+3]]:6 -> [[@LINE+3]]:48 : 0
-// CHECK-LABEL: sil_coverage_map {{.*}}// implicit closure #1 : @autoclosure () throws -> {{.*}} in coverage_closures.foo
+// CHECK-LABEL: sil_coverage_map {{.*}}// implicit closure #1 () throws -> {{.*}} in coverage_closures.foo
 // CHECK-NEXT: [[@LINE+1]]:36 -> [[@LINE+1]]:46 : 0
   f1 { left, right in left == 0 || right == 1 }
 }
diff --git a/test/Profiler/instrprof_operators.swift b/test/Profiler/instrprof_operators.swift
index e7c6328..313a100 100644
--- a/test/Profiler/instrprof_operators.swift
+++ b/test/Profiler/instrprof_operators.swift
@@ -21,7 +21,7 @@
 }
 
 // CHECK: implicit closure
-// CHECK: %[[NAME:.*]] = string_literal utf8 "{{.*}}:$s19instrprof_operators0B01a1bySb_SbtFSbyKXKfu_"
+// CHECK: %[[NAME:.*]] = string_literal utf8 "{{.*}}:$s19instrprof_operators0B01a1bySb_SbtFSbyKXEfu_"
 // CHECK: %[[HASH:.*]] = integer_literal $Builtin.Int64,
 // CHECK: %[[NCOUNTS:.*]] = integer_literal $Builtin.Int32, 1
 // CHECK: %[[INDEX:.*]] = integer_literal $Builtin.Int32, 0
@@ -29,7 +29,7 @@
 // CHECK-NOT: builtin "int_instrprof_increment"
 
 // CHECK: implicit closure
-// CHECK: %[[NAME:.*]] = string_literal utf8 "{{.*}}:$s19instrprof_operators0B01a1bySb_SbtFSbyKXKfu0_"
+// CHECK: %[[NAME:.*]] = string_literal utf8 "{{.*}}:$s19instrprof_operators0B01a1bySb_SbtFSbyKXEfu0_"
 // CHECK: %[[HASH:.*]] = integer_literal $Builtin.Int64,
 // CHECK: %[[NCOUNTS:.*]] = integer_literal $Builtin.Int32, 1
 // CHECK: %[[INDEX:.*]] = integer_literal $Builtin.Int32, 0
diff --git a/test/Prototypes/CollectionTransformers.swift b/test/Prototypes/CollectionTransformers.swift
index 3c93110..83ef091 100644
--- a/test/Prototypes/CollectionTransformers.swift
+++ b/test/Prototypes/CollectionTransformers.swift
@@ -15,6 +15,8 @@
 // FIXME: This test runs very slowly on watchOS.
 // UNSUPPORTED: OS=watchos
 
+import SwiftPrivate
+
 public enum ApproximateCount {
   case Unknown
   case Precise(Int64)
diff --git a/test/Prototypes/IntroSort.swift b/test/Prototypes/IntroSort.swift
new file mode 100644
index 0000000..64c7d24
--- /dev/null
+++ b/test/Prototypes/IntroSort.swift
@@ -0,0 +1,397 @@
+//===--- IntroSort.swift --------------------------------------*- swift -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 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
+//
+//===----------------------------------------------------------------------===//
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -g -Onone -DUSE_STDLIBUNITTEST %s -o %t/a.out
+// RUN: %target-codesign %t/a.out
+// RUN: %target-run %t/a.out
+// REQUIRES: executable_test
+
+// Note: This introsort was the standard library's sort algorithm until Swift 5.
+
+import Swift
+import StdlibUnittest
+
+extension MutableCollection {
+  /// Sorts the elements at `elements[a]`, `elements[b]`, and `elements[c]`.
+  /// Stable.
+  ///
+  /// The indices passed as `a`, `b`, and `c` do not need to be consecutive, but
+  /// must be in strict increasing order.
+  ///
+  /// - Precondition: `a < b && b < c`
+  /// - Postcondition: `self[a] <= self[b] && self[b] <= self[c]`
+  @inlinable
+  public // @testable
+  mutating func _sort3(
+    _ a: Index, _ b: Index, _ c: Index,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool
+  ) rethrows {
+    // There are thirteen possible permutations for the original ordering of
+    // the elements at indices `a`, `b`, and `c`. The comments in the code below
+    // show the relative ordering of the three elements using a three-digit
+    // number as shorthand for the position and comparative relationship of
+    // each element. For example, "312" indicates that the element at `a` is the
+    // largest of the three, the element at `b` is the smallest, and the element
+    // at `c` is the median. This hypothetical input array has a 312 ordering for
+    // `a`, `b`, and `c`:
+    //
+    //      [ 7, 4, 3, 9, 2, 0, 3, 7, 6, 5 ]
+    //        ^              ^           ^
+    //        a              b           c
+    //
+    // - If each of the three elements is distinct, they could be ordered as any
+    //   of the permutations of 1, 2, and 3: 123, 132, 213, 231, 312, or 321.
+    // - If two elements are equivalent and one is distinct, they could be
+    //   ordered as any permutation of 1, 1, and 2 or 1, 2, and 2: 112, 121, 211,
+    //   122, 212, or 221.
+    // - If all three elements are equivalent, they are already in order: 111.
+    
+    switch try (areInIncreasingOrder(self[b], self[a]),
+                areInIncreasingOrder(self[c], self[b])) {
+    case (false, false):
+      // 0 swaps: 123, 112, 122, 111
+      break
+      
+    case (true, true):
+      // 1 swap: 321
+      // swap(a, c): 312->123
+      swapAt(a, c)
+      
+    case (true, false):
+      // 1 swap: 213, 212 --- 2 swaps: 312, 211
+      // swap(a, b): 213->123, 212->122, 312->132, 211->121
+      swapAt(a, b)
+      
+      if try areInIncreasingOrder(self[c], self[b]) {
+        // 132 (started as 312), 121 (started as 211)
+        // swap(b, c): 132->123, 121->112
+        swapAt(b, c)
+      }
+      
+    case (false, true):
+      // 1 swap: 132, 121 --- 2 swaps: 231, 221
+      // swap(b, c): 132->123, 121->112, 231->213, 221->212
+      swapAt(b, c)
+      
+      if try areInIncreasingOrder(self[b], self[a]) {
+        // 213 (started as 231), 212 (started as 221)
+        // swap(a, b): 213->123, 212->122
+        swapAt(a, b)
+      }
+    }
+  }
+}
+
+extension MutableCollection where Self: RandomAccessCollection {
+  /// Reorders the collection and returns an index `p` such that every element
+  /// in `range.lowerBound..<p` is less than every element in
+  /// `p..<range.upperBound`.
+  ///
+  /// - Precondition: The count of `range` must be >= 3 i.e.
+  ///   `distance(from: range.lowerBound, to: range.upperBound) >= 3`
+  @inlinable
+  internal mutating func _partition(
+    within range: Range<Index>,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool
+  ) rethrows -> Index {
+    var lo = range.lowerBound
+    var hi = index(before: range.upperBound)
+    
+    // Sort the first, middle, and last elements, then use the middle value
+    // as the pivot for the partition.
+    let half = distance(from: lo, to: hi) / 2
+    let mid = index(lo, offsetBy: half)
+    try _sort3(lo, mid, hi, by: areInIncreasingOrder)
+    
+    // FIXME: Stashing the pivot element instead of using the index won't work
+    // for move-only types.
+    let pivot = self[mid]
+    
+    // Loop invariants:
+    // * lo < hi
+    // * self[i] < pivot, for i in range.lowerBound..<lo
+    // * pivot <= self[i] for i in hi..<range.upperBound
+    Loop: while true {
+      FindLo: do {
+        formIndex(after: &lo)
+        while lo != hi {
+          if try !areInIncreasingOrder(self[lo], pivot) { break FindLo }
+          formIndex(after: &lo)
+        }
+        break Loop
+      }
+      
+      FindHi: do {
+        formIndex(before: &hi)
+        while hi != lo {
+          if try areInIncreasingOrder(self[hi], pivot) { break FindHi }
+          formIndex(before: &hi)
+        }
+        break Loop
+      }
+      
+      swapAt(lo, hi)
+    }
+    
+    return lo
+  }
+  
+  @inlinable
+  public // @testable
+  mutating func _introSort(
+    within range: Range<Index>,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool
+  ) rethrows {
+    
+    let n = distance(from: range.lowerBound, to: range.upperBound)
+    guard n > 1 else { return }
+    
+    // Set max recursion depth to 2*floor(log(N)), as suggested in the introsort
+    // paper: http://www.cs.rpi.edu/~musser/gp/introsort.ps
+    let depthLimit = 2 * n._binaryLogarithm()
+    try _introSortImpl(
+      within: range,
+      by: areInIncreasingOrder,
+      depthLimit: depthLimit)
+  }
+  
+  @inlinable
+  internal mutating func _introSortImpl(
+    within range: Range<Index>,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool,
+    depthLimit: Int
+  ) rethrows {
+    
+    // Insertion sort is better at handling smaller regions.
+    if distance(from: range.lowerBound, to: range.upperBound) < 20 {
+      try _insertionSort(within: range, by: areInIncreasingOrder)
+    } else if depthLimit == 0 {
+      try _heapSort(within: range, by: areInIncreasingOrder)
+    } else {
+      // Partition and sort.
+      // We don't check the depthLimit variable for underflow because this
+      // variable is always greater than zero (see check above).
+      let partIdx = try _partition(within: range, by: areInIncreasingOrder)
+      try _introSortImpl(
+        within: range.lowerBound..<partIdx,
+        by: areInIncreasingOrder,
+        depthLimit: depthLimit &- 1)
+      try _introSortImpl(
+        within: partIdx..<range.upperBound,
+        by: areInIncreasingOrder,
+        depthLimit: depthLimit &- 1)
+    }
+  }
+  
+  @inlinable
+  internal mutating func _siftDown(
+    _ idx: Index,
+    within range: Range<Index>,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool
+  ) rethrows {
+    var idx = idx
+    var countToIndex = distance(from: range.lowerBound, to: idx)
+    var countFromIndex = distance(from: idx, to: range.upperBound)
+    // Check if left child is within bounds. If not, stop iterating, because
+    // there are no children of the given node in the heap.
+    while countToIndex + 1 < countFromIndex {
+      let left = index(idx, offsetBy: countToIndex + 1)
+      var largest = idx
+      if try areInIncreasingOrder(self[largest], self[left]) {
+        largest = left
+      }
+      // Check if right child is also within bounds before trying to examine it.
+      if countToIndex + 2 < countFromIndex {
+        let right = index(after: left)
+        if try areInIncreasingOrder(self[largest], self[right]) {
+          largest = right
+        }
+      }
+      // If a child is bigger than the current node, swap them and continue
+      // sifting down.
+      if largest != idx {
+        swapAt(idx, largest)
+        idx = largest
+        countToIndex = distance(from: range.lowerBound, to: idx)
+        countFromIndex = distance(from: idx, to: range.upperBound)
+      } else {
+        break
+      }
+    }
+  }
+  
+  @inlinable
+  internal mutating func _heapify(
+    within range: Range<Index>,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool
+  ) rethrows {
+    // Here we build a heap starting from the lowest nodes and moving to the
+    // root. On every step we sift down the current node to obey the max-heap
+    // property:
+    //   parent >= max(leftChild, rightChild)
+    //
+    // We skip the rightmost half of the array, because these nodes don't have
+    // any children.
+    let root = range.lowerBound
+    let half = distance(from: range.lowerBound, to: range.upperBound) / 2
+    var node = index(root, offsetBy: half)
+    
+    while node != root {
+      formIndex(before: &node)
+      try _siftDown(node, within: range, by: areInIncreasingOrder)
+    }
+  }
+  
+  @inlinable
+  public // @testable
+  mutating func _heapSort(
+    within range: Range<Index>,
+    by areInIncreasingOrder: (Element, Element) throws -> Bool
+  ) rethrows {
+    var hi = range.upperBound
+    let lo = range.lowerBound
+    try _heapify(within: range, by: areInIncreasingOrder)
+    formIndex(before: &hi)
+    while hi != lo {
+      swapAt(lo, hi)
+      try _siftDown(lo, within: lo..<hi, by: areInIncreasingOrder)
+      formIndex(before: &hi)
+    }
+  }
+}
+
+//===--- Tests ------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+
+var suite = TestSuite("IntroSort")
+
+// The routine is based on http://www.cs.dartmouth.edu/~doug/mdmspe.pdf
+func makeQSortKiller(_ len: Int) -> [Int] {
+  var candidate: Int = 0
+  var keys = [Int: Int]()
+  func Compare(_ x: Int, y : Int) -> Bool {
+    if keys[x] == nil && keys[y] == nil {
+      if (x == candidate) {
+        keys[x] = keys.count
+      } else {
+        keys[y] = keys.count
+      }
+    }
+    if keys[x] == nil {
+      candidate = x
+      return true
+    }
+    if keys[y] == nil {
+      candidate = y
+      return false
+    }
+    return keys[x]! > keys[y]!
+  }
+  
+  var ary = [Int](repeating: 0, count: len)
+  var ret = [Int](repeating: 0, count: len)
+  for i in 0..<len { ary[i] = i }
+  ary = ary.sorted(by: Compare)
+  for i in 0..<len {
+    ret[ary[i]] = i
+  }
+  return ret
+}
+
+suite.test("sorted/complexity") {
+  var ary: [Int] = []
+  
+  // Check performance of sorting an array of repeating values.
+  var comparisons_100 = 0
+  ary = Array(repeating: 0, count: 100)
+  ary._introSort(within: 0..<ary.count) { comparisons_100 += 1; return $0 < $1 }
+  var comparisons_1000 = 0
+  ary = Array(repeating: 0, count: 1000)
+  ary._introSort(within: 0..<ary.count) { comparisons_1000 += 1; return $0 < $1 }
+  expectTrue(comparisons_1000/comparisons_100 < 20)
+  
+  // Try to construct 'bad' case for quicksort, on which the algorithm
+  // goes quadratic.
+  comparisons_100 = 0
+  ary = makeQSortKiller(100)
+  ary._introSort(within: 0..<ary.count) { comparisons_100 += 1; return $0 < $1 }
+  comparisons_1000 = 0
+  ary = makeQSortKiller(1000)
+  ary._introSort(within: 0..<ary.count) { comparisons_1000 += 1; return $0 < $1 }
+  expectTrue(comparisons_1000/comparisons_100 < 20)
+}
+
+suite.test("sort3/simple")
+  .forEach(in: [
+    [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]
+  ]) {
+    var input = $0
+    input._sort3(0, 1, 2, by: <)
+    expectEqual([1, 2, 3], input)
+}
+
+func isSorted<T>(_ a: [T], by areInIncreasingOrder: (T, T) -> Bool) -> Bool {
+  return !zip(a.dropFirst(), a).contains(where: areInIncreasingOrder)
+}
+
+suite.test("sort3/stable")
+  .forEach(in: [
+    [1, 1, 2], [1, 2, 1], [2, 1, 1], [1, 2, 2], [2, 1, 2], [2, 2, 1], [1, 1, 1]
+  ]) {
+    // decorate with offset, but sort by value
+    var input = Array($0.enumerated())
+    input._sort3(0, 1, 2) { $0.element < $1.element }
+    // offsets should still be ordered for equal values
+    expectTrue(isSorted(input) {
+      if $0.element == $1.element {
+        return $0.offset < $1.offset
+      }
+      return $0.element < $1.element
+    })
+}
+
+suite.test("heapSort") {
+  // Generates the next permutation of `num` as a binary integer, using long
+  // arithmetics approach.
+  //
+  // - Precondition: All values in `num` are either 0 or 1.
+  func addOne(to num: [Int]) -> [Int] {
+    // `num` represents a binary integer. To add one, we toggle any bits until
+    // we've set a clear bit.
+    var num = num
+    for i in num.indices {
+      if num[i] == 1 {
+        num[i] = 0
+      } else {
+        num[i] = 1
+        break
+      }
+    }
+    return num
+  }
+  
+  // Test binary number size.
+  let numberLength = 11
+  var binaryNumber = Array(repeating: 0, count: numberLength)
+  
+  // We are testing sort on all permutations off 0-1s of size `numberLength`
+  // except the all 1's case (its equals to all 0's case).
+  while !binaryNumber.allSatisfy({ $0 == 1 }) {
+    var buffer = binaryNumber
+    buffer._heapSort(within: buffer.startIndex..<buffer.endIndex, by: <)
+    expectTrue(isSorted(buffer, by: <))
+    binaryNumber = addOne(to: binaryNumber)
+  }
+}
+
+runAllTests()
+
diff --git a/test/Prototypes/UnicodeDecoders.swift b/test/Prototypes/UnicodeDecoders.swift
index 443d0c5..e19b285 100644
--- a/test/Prototypes/UnicodeDecoders.swift
+++ b/test/Prototypes/UnicodeDecoders.swift
@@ -37,6 +37,79 @@
 //===----------------------------------------------------------------------===//
 
 extension Unicode {
+  @_fixed_layout
+  public // @testable
+  struct _ParsingIterator<
+    CodeUnitIterator : IteratorProtocol, 
+    Parser: Unicode.Parser
+  > where Parser.Encoding.CodeUnit == CodeUnitIterator.Element {
+    @inline(__always)
+    @inlinable
+    public init(codeUnits: CodeUnitIterator, parser: Parser) {
+      self.codeUnits = codeUnits
+      self.parser = parser
+    }
+    public var codeUnits: CodeUnitIterator
+    public var parser: Parser
+  }
+}
+
+extension Unicode._ParsingIterator : IteratorProtocol, Sequence {
+  @inline(__always)
+  @inlinable
+  public mutating func next() -> Parser.Encoding.EncodedScalar? {
+    switch parser.parseScalar(from: &codeUnits) {
+    case let .valid(scalarContent): return scalarContent
+    case .error: return Parser.Encoding.encodedReplacementCharacter
+    case .emptyInput: return nil
+    }
+  }
+}
+
+extension _UnicodeParser {
+  @inlinable // FIXME(sil-serialize-all)
+  @inline(__always)
+  @discardableResult
+  internal static func _parse<I: IteratorProtocol>(
+    _ input: inout I,
+    repairingIllFormedSequences makeRepairs: Bool = true,
+    into output: (Encoding.EncodedScalar)->Void
+  ) -> Int
+  where I.Element == Encoding.CodeUnit
+  {
+    var errorCount = 0
+    var d = Self()
+    while true {
+      switch d.parseScalar(from: &input) {
+      case let .valid(scalarContent):
+        output(scalarContent)
+      case .error:
+        if _slowPath(!makeRepairs) { return 1 }
+        errorCount += 1
+        output(Encoding.encodedReplacementCharacter)
+      case .emptyInput:
+        return errorCount
+      }
+    }
+  }
+
+  @inlinable // FIXME(sil-serialize-all)
+  @inline(__always)
+  @discardableResult
+  public static func _decode<I: IteratorProtocol>(
+    _ input: inout I,
+    repairingIllFormedSequences makeRepairs: Bool,
+    into output: (Unicode.Scalar)->Void
+  ) -> Int
+  where I.Element == Encoding.CodeUnit
+  {
+    return _parse(&input, repairingIllFormedSequences: makeRepairs) {
+      output(Encoding.decode($0))
+    }
+  }
+}
+
+extension Unicode {
   struct DefaultScalarView<
     CodeUnits: BidirectionalCollection,
     Encoding: Unicode.Encoding
diff --git a/test/Reflection/Inputs/TypeLowering.swift b/test/Reflection/Inputs/TypeLowering.swift
index 7c86839..aa3cfb2 100644
--- a/test/Reflection/Inputs/TypeLowering.swift
+++ b/test/Reflection/Inputs/TypeLowering.swift
@@ -60,11 +60,17 @@
 
   public let strongRefTuple: (C, C)
   public let optionalStrongRefTuple: (C, C)?
+}
 
+public struct UnownedReferenceStruct {
   public unowned let unownedRef: C
+}
 
+public struct WeakReferenceStruct {
   public weak var weakRef: C?
+}
 
+public struct UnmanagedReferenceStruct {
   public unowned(unsafe) let unmanagedRef: C
 }
 
@@ -85,6 +91,8 @@
 
 public protocol CP1 : class {}
 public protocol CP2 : CP1 {}
+public protocol CP3 : C {}
+public protocol CP4 where Self : C {}
 
 public struct ExistentialStruct {
   public let any: Any
@@ -111,10 +119,26 @@
   public let anyClassBoundProtoComposition2: P1 & CP2
   public let optionalAnyClassBoundProtoComposition2: (P1 & CP2)?
   
+  public let classConstrainedP1: C & P1
+}
+
+public struct UnownedExistentialStruct {
+  public unowned var unownedRef: CP1
+}
+
+public struct UnownedNativeExistentialStruct {
+  public unowned var unownedRef1: C & CP1
+  public unowned var unownedRef2: CP3
+  public unowned var unownedRef3: CP4
+}
+
+public struct WeakExistentialStruct {
   public weak var weakAnyObject: AnyObject?
   public weak var weakAnyClassBoundProto: CP1?
+}
 
-  public let classConstrainedP1: C & P1
+public struct UnmanagedExistentialStruct {
+  public unowned(unsafe) var unmanagedRef: CP1
 }
 
 public struct MetadataHolder<T, U> {
@@ -144,14 +168,8 @@
   public let abstractMetatype: MetadataHolder<BasicStruct.Type, BasicStruct>
 }
 
-// We don't allow stored properties to have uninhabited types now, but make a
-// wrapper over one to continue testing this 
 public enum EmptyEnum {}
 
-public struct EmptyEnumWrapper<T> {
-  public var value: T
-}
-
 public enum NoPayloadEnum {
   case A
   case B
@@ -200,7 +218,7 @@
 }
 
 public struct EnumStruct {
-  public let empty: EmptyEnumWrapper<EmptyEnum>
+  public let empty: EmptyEnum
   public let noPayload: NoPayloadEnum
   public let sillyNoPayload: SillyNoPayloadEnum
   public let singleton: SingletonEnum
@@ -218,3 +236,18 @@
   // tag byte
   public let optionalOptionalPtr: UnsafePointer<Int>??
 }
+
+public enum MultiPayloadConcreteNotBitwiseTakable {
+  case Left(WeakReferenceStruct)
+  case Right(WeakReferenceStruct)
+}
+
+public enum MultiPayloadGenericNotBitwiseTakable<T> {
+  case Left(WeakReferenceStruct)
+  case Right(T)
+}
+
+public struct EnumStructWithOwnership {
+  public let multiPayloadConcrete: MultiPayloadConcreteNotBitwiseTakable
+  public let multiPayloadGeneric: MultiPayloadGenericNotBitwiseTakable<Int8>
+}
diff --git a/test/Reflection/Inputs/TypeLoweringObjectiveC.swift b/test/Reflection/Inputs/TypeLoweringObjectiveC.swift
index c754a6e..7bd0c3c 100644
--- a/test/Reflection/Inputs/TypeLoweringObjectiveC.swift
+++ b/test/Reflection/Inputs/TypeLoweringObjectiveC.swift
@@ -21,3 +21,6 @@
   let reference: AnyObject
 }
 
+public struct UnownedReferenceStruct {
+  unowned var unownedRef: NSObjectSubclass
+}
diff --git a/test/Reflection/typeref_decoding_imported.swift b/test/Reflection/typeref_decoding_imported.swift
index 546f88a..c3a2c42 100644
--- a/test/Reflection/typeref_decoding_imported.swift
+++ b/test/Reflection/typeref_decoding_imported.swift
@@ -53,30 +53,35 @@
 // CHECK-32: Alignment: 4
 // CHECK-32: Stride: 12
 // CHECK-32: NumExtraInhabitants: 0
+// CHECK-32: BitwiseTakable: 1
 
 // CHECK-32-LABEL: - __C.MyCEnum:
 // CHECK-32: Size: 4
 // CHECK-32: Alignment: 4
 // CHECK-32: Stride: 4
 // CHECK-32: NumExtraInhabitants: 0
+// CHECK-32: BitwiseTakable: 1
 
 // CHECK-32-LABEL: - __C.MyCUnion:
 // CHECK-32: Size: 4
 // CHECK-32: Alignment: 4
 // CHECK-32: Stride: 4
 // CHECK-32: NumExtraInhabitants: 0
+// CHECK-32: BitwiseTakable: 1
 
 // CHECK-i386-LABEL: - __C.MyCStructWithBitfields:
 // CHECK-i386: Size: 4
 // CHECK-i386: Alignment: 4
 // CHECK-i386: Stride: 4
 // CHECK-i386: NumExtraInhabitants: 0
+// CHECK-i386: BitwiseTakable: 1
 
 // CHECK-arm-LABEL: - __C.MyCStructWithBitfields:
 // CHECK-arm: Size: 2
 // CHECK-arm: Alignment: 1
 // CHECK-arm: Stride: 2
 // CHECK-arm: NumExtraInhabitants: 0
+// CHECK-arm: BitwiseTakable: 1
 
 // CHECK-32: CAPTURE DESCRIPTORS:
 // CHECK-32: ====================
@@ -128,24 +133,28 @@
 // CHECK-64: Alignment: 8
 // CHECK-64: Stride: 24
 // CHECK-64: NumExtraInhabitants: 0
+// CHECK-64: BitwiseTakable: 1
 
 // CHECK-64-LABEL: - __C.MyCEnum:
 // CHECK-64: Size: 4
 // CHECK-64: Alignment: 4
 // CHECK-64: Stride: 4
 // CHECK-64: NumExtraInhabitants: 0
+// CHECK-64: BitwiseTakable: 1
 
 // CHECK-64-LABEL: - __C.MyCUnion:
 // CHECK-64: Size: 8
 // CHECK-64: Alignment: 8
 // CHECK-64: Stride: 8
 // CHECK-64: NumExtraInhabitants: 0
+// CHECK-64: BitwiseTakable: 1
 
 // CHECK-64-LABEL: - __C.MyCStructWithBitfields:
 // CHECK-64: Size: 4
 // CHECK-64: Alignment: 4
 // CHECK-64: Stride: 4
 // CHECK-64: NumExtraInhabitants: 0
+// CHECK-64: BitwiseTakable: 1
 
 // CHECK-64: CAPTURE DESCRIPTORS:
 // CHECK-64: ====================
diff --git a/test/Reflection/typeref_decoding_objc.swift b/test/Reflection/typeref_decoding_objc.swift
index 57280fb..bf1217c 100644
--- a/test/Reflection/typeref_decoding_objc.swift
+++ b/test/Reflection/typeref_decoding_objc.swift
@@ -59,12 +59,14 @@
 // CHECK-32: Alignment: 4
 // CHECK-32: Stride: 16
 // CHECK-32: NumExtraInhabitants: 0
+// CHECK-32: BitwiseTakable: 1
 
 // CHECK-64: - __C.CGRect:
 // CHECK-64: Size: 32
 // CHECK-64: Alignment: 8
 // CHECK-64: Stride: 32
 // CHECK-64: NumExtraInhabitants: 0
+// CHECK-64: BitwiseTakable: 1
 
 // CHECK:      CAPTURE DESCRIPTORS:
 // CHECK-NEXT: ====================
diff --git a/test/Reflection/typeref_lowering.swift b/test/Reflection/typeref_lowering.swift
index b150744..674f0af 100644
--- a/test/Reflection/typeref_lowering.swift
+++ b/test/Reflection/typeref_lowering.swift
@@ -6,357 +6,357 @@
 12TypeLowering11BasicStructV
 // CHECK-64:      (struct TypeLowering.BasicStruct)
 
-// CHECK-64-NEXT: (struct size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-64-NEXT: (struct size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=i1 offset=0
-// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=i2 offset=2
-// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=i3 offset=4
-// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=bi1 offset=8
-// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=value offset=0
-// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:             (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=bi2 offset=10
-// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=value offset=0
-// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:             (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=bi3 offset=12
-// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=value offset=0
-// CHECK-64-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))))
+// CHECK-64-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))))
 
 // CHECK-32:      (struct TypeLowering.BasicStruct)
-// CHECK-32-NEXT: (struct size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32-NEXT: (struct size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=i1 offset=0
-// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=i2 offset=2
-// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=i3 offset=4
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=bi1 offset=8
-// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=value offset=0
-// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:             (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=bi2 offset=10
-// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=value offset=0
-// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:             (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=bi3 offset=12
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=value offset=0
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))))
 
 12TypeLowering05AssocA6StructV
 // CHECK-64:      (struct TypeLowering.AssocTypeStruct)
-// CHECK-64-NEXT: (struct size=36 alignment=2 stride=36 num_extra_inhabitants=0
+// CHECK-64-NEXT: (struct size=36 alignment=2 stride=36 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=t1 offset=0
-// CHECK-64-NEXT:     (struct size=7 alignment=2 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=7 alignment=2 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=a offset=0
-// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=b offset=2
-// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=c offset=4
-// CHECK-64-NEXT:         (tuple size=3 alignment=2 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (tuple size=3 alignment=2 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field offset=0
-// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:           (field offset=2
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))))))
+// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))))))
 // CHECK-64-NEXT:   (field name=t2 offset=8
-// CHECK-64-NEXT:     (struct size=7 alignment=2 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=7 alignment=2 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=a offset=0
-// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=b offset=2
-// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=c offset=4
-// CHECK-64-NEXT:         (tuple size=3 alignment=2 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (tuple size=3 alignment=2 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field offset=0
-// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:           (field offset=2
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))))))
+// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))))))
 // CHECK-64-NEXT:   (field name=t3 offset=16
-// CHECK-64-NEXT:     (struct size=8 alignment=2 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=2 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=a offset=0
-// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=b offset=2
-// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=c offset=4
-// CHECK-64-NEXT:         (tuple size=4 alignment=2 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (tuple size=4 alignment=2 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field offset=0
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:           (field offset=2
-// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))))))
+// CHECK-64-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))))))
 // CHECK-64-NEXT:   (field name=t4 offset=24
-// CHECK-64-NEXT:     (struct size=8 alignment=2 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=2 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=a offset=0
-// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=b offset=2
-// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=c offset=4
-// CHECK-64-NEXT:         (tuple size=4 alignment=2 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (tuple size=4 alignment=2 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field offset=0
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:           (field offset=2
-// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))))))
+// CHECK-64-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))))))
 // CHECK-64-NEXT:   (field name=t5 offset=32
-// CHECK-64-NEXT:     (struct size=4 alignment=1 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=4 alignment=1 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=a offset=0
-// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=b offset=1
-// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=value offset=0
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_value offset=0
-// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:       (field name=c offset=2
-// CHECK-64-NEXT:         (tuple size=2 alignment=1 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (tuple size=2 alignment=1 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field offset=0
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:           (field offset=1
-// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=value offset=0
-// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_value offset=0
-// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))))))))
+// CHECK-64-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))))))))
 
 // CHECK-32:      (struct TypeLowering.AssocTypeStruct)
-// CHECK-32-NEXT: (struct size=36 alignment=2 stride=36 num_extra_inhabitants=0
+// CHECK-32-NEXT: (struct size=36 alignment=2 stride=36 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=t1 offset=0
-// CHECK-32-NEXT:     (struct size=7 alignment=2 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=7 alignment=2 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=a offset=0
-// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=b offset=2
-// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=c offset=4
-// CHECK-32-NEXT:         (tuple size=3 alignment=2 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (tuple size=3 alignment=2 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field offset=0
-// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:           (field offset=2
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))))))
+// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))))))
 // CHECK-32-NEXT:   (field name=t2 offset=8
-// CHECK-32-NEXT:     (struct size=7 alignment=2 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=7 alignment=2 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=a offset=0
-// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=b offset=2
-// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=c offset=4
-// CHECK-32-NEXT:         (tuple size=3 alignment=2 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (tuple size=3 alignment=2 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field offset=0
-// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:           (field offset=2
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))))))
+// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))))))
 // CHECK-32-NEXT:   (field name=t3 offset=16
-// CHECK-32-NEXT:     (struct size=8 alignment=2 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=8 alignment=2 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=a offset=0
-// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=b offset=2
-// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=c offset=4
-// CHECK-32-NEXT:         (tuple size=4 alignment=2 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (tuple size=4 alignment=2 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field offset=0
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:           (field offset=2
-// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))))))
+// CHECK-32-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))))))
 // CHECK-32-NEXT:   (field name=t4 offset=24
-// CHECK-32-NEXT:     (struct size=8 alignment=2 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=8 alignment=2 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=a offset=0
-// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=b offset=2
-// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=c offset=4
-// CHECK-32-NEXT:         (tuple size=4 alignment=2 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (tuple size=4 alignment=2 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field offset=0
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:           (field offset=2
-// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))))))
+// CHECK-32-NEXT:                     (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))))))
 // CHECK-32-NEXT:   (field name=t5 offset=32
-// CHECK-32-NEXT:     (struct size=4 alignment=1 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=1 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=a offset=0
-// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=b offset=1
-// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=value offset=0
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=_value offset=0
-// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:       (field name=c offset=2
-// CHECK-32-NEXT:         (tuple size=2 alignment=1 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (tuple size=2 alignment=1 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field offset=0
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:           (field offset=1
-// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:             (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:               (field name=value offset=0
-// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:                   (field name=_value offset=0
-// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))))))))
+// CHECK-32-NEXT:                     (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))))))))
 
 12TypeLowering3BoxVys5Int16VG_s5Int32Vt
 // CHECK-64-NEXT: (tuple
@@ -369,612 +369,763 @@
 // CHECK-32-NEXT:     (struct Swift.Int16))
 // CHECK-32-NEXT:   (struct Swift.Int32))
 
-// CHECK-64-NEXT: (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT: (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field offset=0
-// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=value offset=0
-// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:             (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field offset=4
-// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
-// CHECK-32-NEXT: (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT: (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field offset=0
-// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=value offset=0
-// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:             (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field offset=4
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
-
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 12TypeLowering15ReferenceStructV
 // CHECK-64:      (struct TypeLowering.ReferenceStruct)
-// CHECK-64-NEXT: (struct size=72 alignment=8 stride=72 num_extra_inhabitants=[[PTR_XI:2048|4096|2147483647]]
+// CHECK-64-NEXT: (struct size=48 alignment=8 stride=48 num_extra_inhabitants=[[PTR_XI:2048|4096|2147483647]] bitwise_takable=1
 // CHECK-64-NEXT:   (field name=strongRef offset=0
 // CHECK-64-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-64-NEXT:   (field name=optionalStrongRef offset=8
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1:2047|4095|2147483646]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1:2047|4095|2147483646]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-64-NEXT:   (field name=strongRefTuple offset=16
-// CHECK-64-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))
 // CHECK-64-NEXT:       (field offset=8
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-64-NEXT:   (field name=optionalStrongRefTuple offset=32
-// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field offset=0
 // CHECK-64-NEXT:             (reference kind=strong refcounting=native))
 // CHECK-64-NEXT:           (field offset=8
-// CHECK-64-NEXT:             (reference kind=strong refcounting=native))))))
-// CHECK-64-NEXT:   (field name=unownedRef offset=48
-// CHECK-64-NEXT:     (reference kind=unowned refcounting=native))
-// CHECK-64-NEXT:   (field name=weakRef offset=56
-// CHECK-64-NEXT:     (reference kind=weak refcounting=native))
-// CHECK-64-NEXT:   (field name=unmanagedRef offset=64
-// CHECK-64-NEXT:     (reference kind=unmanaged refcounting=native)))
+// CHECK-64-NEXT:             (reference kind=strong refcounting=native)))))))
 
 // CHECK-32: (struct TypeLowering.ReferenceStruct)
-// CHECK-32-NEXT: (struct size=36 alignment=4 stride=36 num_extra_inhabitants=4096
+// CHECK-32-NEXT: (struct size=24 alignment=4 stride=24 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=strongRef offset=0
 // CHECK-32-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:   (field name=optionalStrongRef offset=4
-// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
 // CHECK-32-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-32-NEXT:   (field name=strongRefTuple offset=8
-// CHECK-32-NEXT:     (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field offset=0
 // CHECK-32-NEXT:         (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:       (field offset=4
 // CHECK-32-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-32-NEXT:   (field name=optionalStrongRefTuple offset=16
-// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field offset=0
 // CHECK-32-NEXT:             (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:           (field offset=4
-// CHECK-32-NEXT:             (reference kind=strong refcounting=native))))))
-// CHECK-32-NEXT:   (field name=unownedRef offset=24
-// CHECK-32-NEXT:     (reference kind=unowned refcounting=native))
-// CHECK-32-NEXT:   (field name=weakRef offset=28
-// CHECK-32-NEXT:     (reference kind=weak refcounting=native))
-// CHECK-32-NEXT:   (field name=unmanagedRef offset=32
+// CHECK-32-NEXT:             (reference kind=strong refcounting=native)))))))
+
+12TypeLowering22UnownedReferenceStructV
+// CHECK-64:      (struct TypeLowering.UnownedReferenceStruct)
+// CHECK-64-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
+// CHECK-64-NEXT:   (field name=unownedRef offset=0
+// CHECK-64-NEXT:     (reference kind=unowned refcounting=native)))
+
+// CHECK-32:      (struct TypeLowering.UnownedReferenceStruct)
+// CHECK-32-NEXT: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
+// CHECK-32-NEXT:   (field name=unownedRef offset=0
+// CHECK-32-NEXT:     (reference kind=unowned refcounting=native)))
+
+12TypeLowering19WeakReferenceStructV
+// CHECK-64:      (struct TypeLowering.WeakReferenceStruct)
+// CHECK-64-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=0
+// CHECK-64-NEXT:   (field name=weakRef offset=0
+// CHECK-64-NEXT:     (reference kind=weak refcounting=native)))
+
+// CHECK-32:      (struct TypeLowering.WeakReferenceStruct)
+// CHECK-32-NEXT: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=0
+// CHECK-32-NEXT:   (field name=weakRef offset=0
+// CHECK-32-NEXT:     (reference kind=weak refcounting=native)))
+
+12TypeLowering24UnmanagedReferenceStructV
+// CHECK-64:      (struct TypeLowering.UnmanagedReferenceStruct)
+// CHECK-64-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
+// CHECK-64-NEXT:   (field name=unmanagedRef offset=0
+// CHECK-64-NEXT:     (reference kind=unmanaged refcounting=native)))
+
+// CHECK-32:      (struct TypeLowering.UnmanagedReferenceStruct)
+// CHECK-32-NEXT: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
+// CHECK-32-NEXT:   (field name=unmanagedRef offset=0
 // CHECK-32-NEXT:     (reference kind=unmanaged refcounting=native)))
 
 12TypeLowering14FunctionStructV
 // CHECK-64:      (struct TypeLowering.FunctionStruct)
-// CHECK-64-NEXT: (struct size=64 alignment=8 stride=64 num_extra_inhabitants=[[PTR_XI_2:4096|2147483647]]
+// CHECK-64-NEXT: (struct size=64 alignment=8 stride=64 num_extra_inhabitants=[[PTR_XI_2:4096|2147483647]] bitwise_takable=1
 // CHECK-64-NEXT:   (field name=thickFunction offset=0
-// CHECK-64-NEXT:     (thick_function size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_2]]
+// CHECK-64-NEXT:     (thick_function size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_2]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=function offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]]))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]] bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=context offset=8
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-64-NEXT:   (field name=optionalThickFunction offset=16
-// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_2_SUB_1:4095|2147483646]]
+// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_2_SUB_1:4095|2147483646]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (thick_function size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_2]]
+// CHECK-64-NEXT:         (thick_function size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_2]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=function offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]]))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]] bitwise_takable=1))
 // CHECK-64-NEXT:           (field name=context offset=8
 // CHECK-64-NEXT:             (reference kind=strong refcounting=native))))))
 // CHECK-64-NEXT:   (field name=thinFunction offset=32
-// CHECK-64-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]]))
+// CHECK-64-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]] bitwise_takable=1))
 // CHECK-64-NEXT:   (field name=optionalThinFunction offset=40
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]]))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]] bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=cFunction offset=48
-// CHECK-64-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]]))
+// CHECK-64-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]] bitwise_takable=1))
 // CHECK-64-NEXT:   (field name=optionalCFunction offset=56
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]])))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_2]] bitwise_takable=1)))))
 
 // CHECK-32: (struct TypeLowering.FunctionStruct)
-// CHECK-32-NEXT: (struct size=32 alignment=4 stride=32 num_extra_inhabitants=4096
+// CHECK-32-NEXT: (struct size=32 alignment=4 stride=32 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=thickFunction offset=0
-// CHECK-32-NEXT:     (thick_function size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (thick_function size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=function offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=context offset=4
 // CHECK-32-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-32-NEXT:   (field name=optionalThickFunction offset=8
-// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (thick_function size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (thick_function size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=function offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:           (field name=context offset=4
 // CHECK-32-NEXT:             (reference kind=strong refcounting=native))))))
 // CHECK-32-NEXT:   (field name=thinFunction offset=16
-// CHECK-32-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:   (field name=optionalThinFunction offset=20
-// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=cFunction offset=24
-// CHECK-32-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:   (field name=optionalCFunction offset=28
-// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1)))))
 
 12TypeLowering17ExistentialStructV
 // CHECK-64:      (struct TypeLowering.ExistentialStruct)
-// CHECK-64-NEXT: (struct size=440 alignment=8 stride=440 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT: (struct size=416 alignment=8 stride=416 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:   (field name=any offset=0
-// CHECK-64-NEXT:     (opaque_existential size=32 alignment=8 stride=32 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (opaque_existential size=32 alignment=8 stride=32 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=24
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAny offset=32
-// CHECK-64-NEXT:     (single_payload_enum size=32 alignment=8 stride=32 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=32 alignment=8 stride=32 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (opaque_existential size=32 alignment=8 stride=32 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (opaque_existential size=32 alignment=8 stride=32 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=metadata offset=24
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=anyObject offset=64
 // CHECK-64-NEXT:     (class_existential size=8 alignment=8 stride=8
 // CHECK-64-NEXT:       (field name=object offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=unknown))))
 // CHECK-64-NEXT:   (field name=optionalAnyObject offset=72
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (class_existential size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (class_existential size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=object offset=0
 // CHECK-64-NEXT:             (reference kind=strong refcounting=unknown))))))
 // CHECK-64-NEXT:   (field name=anyProto offset=80
-// CHECK-64-NEXT:     (opaque_existential size=40 alignment=8 stride=40 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (opaque_existential size=40 alignment=8 stride=40 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=24
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=32
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAnyProto offset=120
-// CHECK-64-NEXT:     (single_payload_enum size=40 alignment=8 stride=40 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=40 alignment=8 stride=40 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (opaque_existential size=40 alignment=8 stride=40 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (opaque_existential size=40 alignment=8 stride=40 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=metadata offset=24
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:           (field name=wtable offset=32
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=anyProtoComposition offset=160
-// CHECK-64-NEXT:     (opaque_existential size=48 alignment=8 stride=48 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (opaque_existential size=48 alignment=8 stride=48 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=24
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=32
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=40
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAnyProtoComposition offset=208
-// CHECK-64-NEXT:     (single_payload_enum size=48 alignment=8 stride=48 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=48 alignment=8 stride=48 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (opaque_existential size=48 alignment=8 stride=48 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (opaque_existential size=48 alignment=8 stride=48 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=metadata offset=24
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:           (field name=wtable offset=32
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-64-NEXT:           (field name=wtable offset=40
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=anyClassBoundProto1 offset=256
-// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=object offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:       (field name=wtable offset=8
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAnyClassBoundProto1 offset=272
-// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=object offset=0
 // CHECK-64-NEXT:             (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:           (field name=wtable offset=8
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=anyClassBoundProto2 offset=288
-// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=object offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:       (field name=wtable offset=8
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAnyClassBoundProto2 offset=304
-// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=object offset=0
 // CHECK-64-NEXT:             (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:           (field name=wtable offset=8
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=anyClassBoundProtoComposition1 offset=320
-// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=object offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:       (field name=wtable offset=8
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAnyClassBoundProtoComposition1 offset=336
-// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=object offset=0
 // CHECK-64-NEXT:             (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:           (field name=wtable offset=8
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=anyClassBoundProtoComposition2 offset=352
-// CHECK-64-NEXT:     (class_existential size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (class_existential size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=object offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:       (field name=wtable offset=8
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=16
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAnyClassBoundProtoComposition2 offset=376
-// CHECK-64-NEXT:     (single_payload_enum size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (class_existential size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (class_existential size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=object offset=0
 // CHECK-64-NEXT:             (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:           (field name=wtable offset=8
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-64-NEXT:           (field name=wtable offset=16
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))))
-// CHECK-64-NEXT:   (field name=weakAnyObject offset=400
-// CHECK-64-NEXT:     (class_existential size=8 alignment=8 stride=8
-// CHECK-64-NEXT:       (field name=object offset=0
-// CHECK-64-NEXT:         (reference kind=weak refcounting=unknown))))
-// CHECK-64-NEXT:   (field name=weakAnyClassBoundProto offset=408
-// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
-// CHECK-64-NEXT:       (field name=object offset=0
-// CHECK-64-NEXT:         (reference kind=weak refcounting=unknown))
-// CHECK-64-NEXT:       (field name=wtable offset=8
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
-// CHECK-64-NEXT:   (field name=classConstrainedP1 offset=424
-// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))))
+// CHECK-64-NEXT:   (field name=classConstrainedP1 offset=400
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=object offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))
 // CHECK-64-NEXT:       (field name=wtable offset=8
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1)))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 // CHECK-32: (struct TypeLowering.ExistentialStruct)
-// CHECK-32-NEXT: (struct size=220 alignment=4 stride=220 num_extra_inhabitants=4096
+// CHECK-32-NEXT: (struct size=208 alignment=4 stride=208 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=any offset=0
-// CHECK-32-NEXT:     (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=12
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAny offset=16
-// CHECK-32-NEXT:     (single_payload_enum size=16 alignment=4 stride=16 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=16 alignment=4 stride=16 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=metadata offset=12
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=anyObject offset=32
-// CHECK-32-NEXT:     (class_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (class_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=object offset=0
 // CHECK-32-NEXT:         (reference kind=strong refcounting=unknown))))
 // CHECK-32-NEXT:   (field name=optionalAnyObject offset=36
-// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (class_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (class_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=object offset=0
 // CHECK-32-NEXT:             (reference kind=strong refcounting=unknown))))))
 // CHECK-32-NEXT:   (field name=anyProto offset=40
-// CHECK-32-NEXT:     (opaque_existential size=20 alignment=4 stride=20 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (opaque_existential size=20 alignment=4 stride=20 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=12
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=16
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAnyProto offset=60
-// CHECK-32-NEXT:     (single_payload_enum size=20 alignment=4 stride=20 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=20 alignment=4 stride=20 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (opaque_existential size=20 alignment=4 stride=20 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (opaque_existential size=20 alignment=4 stride=20 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=metadata offset=12
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:           (field name=wtable offset=16
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=anyProtoComposition offset=80
-// CHECK-32-NEXT:     (opaque_existential size=24 alignment=4 stride=24 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (opaque_existential size=24 alignment=4 stride=24 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=12
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=16
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=20
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAnyProtoComposition offset=104
-// CHECK-32-NEXT:     (single_payload_enum size=24 alignment=4 stride=24 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=24 alignment=4 stride=24 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (opaque_existential size=24 alignment=4 stride=24 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (opaque_existential size=24 alignment=4 stride=24 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=metadata offset=12
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:           (field name=wtable offset=16
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-32-NEXT:           (field name=wtable offset=20
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=anyClassBoundProto1 offset=128
-// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=object offset=0
 // CHECK-32-NEXT:         (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:       (field name=wtable offset=4
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAnyClassBoundProto1 offset=136
-// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=object offset=0
 // CHECK-32-NEXT:             (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:           (field name=wtable offset=4
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=anyClassBoundProto2 offset=144
-// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=object offset=0
 // CHECK-32-NEXT:         (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:       (field name=wtable offset=4
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAnyClassBoundProto2 offset=152
-// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=object offset=0
 // CHECK-32-NEXT:             (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:           (field name=wtable offset=4
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=anyClassBoundProtoComposition1 offset=160
-// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=object offset=0
 // CHECK-32-NEXT:         (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:       (field name=wtable offset=4
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAnyClassBoundProtoComposition1 offset=168
-// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=object offset=0
 // CHECK-32-NEXT:             (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:           (field name=wtable offset=4
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=anyClassBoundProtoComposition2 offset=176
-// CHECK-32-NEXT:     (class_existential size=12 alignment=4 stride=12 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (class_existential size=12 alignment=4 stride=12 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=object offset=0
 // CHECK-32-NEXT:         (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:       (field name=wtable offset=4
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=8
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAnyClassBoundProtoComposition2 offset=188
-// CHECK-32-NEXT:     (single_payload_enum size=12 alignment=4 stride=12 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=12 alignment=4 stride=12 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (class_existential size=12 alignment=4 stride=12 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (class_existential size=12 alignment=4 stride=12 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=object offset=0
 // CHECK-32-NEXT:             (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:           (field name=wtable offset=4
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-32-NEXT:           (field name=wtable offset=8
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))))
-// CHECK-32-NEXT:   (field name=weakAnyObject offset=200
-// CHECK-32-NEXT:     (class_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096
-// CHECK-32-NEXT:       (field name=object offset=0
-// CHECK-32-NEXT:         (reference kind=weak refcounting=unknown))))
-// CHECK-32-NEXT:   (field name=weakAnyClassBoundProto offset=204
-// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
-// CHECK-32-NEXT:       (field name=object offset=0
-// CHECK-32-NEXT:         (reference kind=weak refcounting=unknown))
-// CHECK-32-NEXT:       (field name=wtable offset=4
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
-// CHECK-32-NEXT:   (field name=classConstrainedP1 offset=212
-// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))))
+// CHECK-32-NEXT:   (field name=classConstrainedP1 offset=200
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=object offset=0
 // CHECK-32-NEXT:         (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:       (field name=wtable offset=4
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
+
+12TypeLowering24UnownedExistentialStructV
+// CHECK-64:      (struct size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=0
+// CHECK-64-NEXT:   (field name=unownedRef offset=0
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=0
+// CHECK-64-NEXT:       (field name=object offset=0
+// CHECK-64-NEXT:         (reference kind=unowned refcounting=unknown))
+// CHECK-64-NEXT:       (field name=wtable offset=8
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
+
+// CHECK-32:      (struct size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=0
+// CHECK-32-NEXT:   (field name=unownedRef offset=0
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=0
+// CHECK-32-NEXT:       (field name=object offset=0
+// CHECK-32-NEXT:         (reference kind=unowned refcounting=unknown))
+// CHECK-32-NEXT:       (field name=wtable offset=4
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
+
+12TypeLowering30UnownedNativeExistentialStructV
+// CHECK-64:      (struct TypeLowering.UnownedNativeExistentialStruct)
+// CHECK-64-NEXT: (struct size=48 alignment=8 stride=48 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
+// CHECK-64-NEXT:   (field name=unownedRef1 offset=0
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
+// CHECK-64-NEXT:       (field name=object offset=0
+// CHECK-64-NEXT:         (reference kind=unowned refcounting=native))
+// CHECK-64-NEXT:       (field name=wtable offset=8
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
+// CHECK-64-NEXT:   (field name=unownedRef2 offset=16
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
+// CHECK-64-NEXT:       (field name=object offset=0
+// CHECK-64-NEXT:         (reference kind=unowned refcounting=native))
+// CHECK-64-NEXT:       (field name=wtable offset=8
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
+// CHECK-64-NEXT:   (field name=unownedRef3 offset=32
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
+// CHECK-64-NEXT:       (field name=object offset=0
+// CHECK-64-NEXT:         (reference kind=unowned refcounting=native))
+// CHECK-64-NEXT:       (field name=wtable offset=8
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
+
+// CHECK-32:      (struct TypeLowering.UnownedNativeExistentialStruct)
+// CHECK-32-NEXT: (struct size=24 alignment=4 stride=24 num_extra_inhabitants=4096 bitwise_takable=1
+// CHECK-32-NEXT:   (field name=unownedRef1 offset=0
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
+// CHECK-32-NEXT:       (field name=object offset=0
+// CHECK-32-NEXT:         (reference kind=unowned refcounting=native))
+// CHECK-32-NEXT:       (field name=wtable offset=4
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
+// CHECK-32-NEXT:   (field name=unownedRef2 offset=8
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
+// CHECK-32-NEXT:       (field name=object offset=0
+// CHECK-32-NEXT:         (reference kind=unowned refcounting=native))
+// CHECK-32-NEXT:       (field name=wtable offset=4
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
+// CHECK-32-NEXT:   (field name=unownedRef3 offset=16
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
+// CHECK-32-NEXT:       (field name=object offset=0
+// CHECK-32-NEXT:         (reference kind=unowned refcounting=native))
+// CHECK-32-NEXT:       (field name=wtable offset=4
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
+
+12TypeLowering21WeakExistentialStructV
+// CHECK-64-NEXT: (struct TypeLowering.WeakExistentialStruct)
+// CHECK-64-NEXT: (struct size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=0
+// CHECK-64-NEXT:   (field name=weakAnyObject offset=0
+// CHECK-64-NEXT:     (class_existential size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=0
+// CHECK-64-NEXT:       (field name=object offset=0
+// CHECK-64-NEXT:         (reference kind=weak refcounting=unknown))))
+// CHECK-64-NEXT:   (field name=weakAnyClassBoundProto offset=8
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=0
+// CHECK-64-NEXT:       (field name=object offset=0
+// CHECK-64-NEXT:         (reference kind=weak refcounting=unknown))
+// CHECK-64-NEXT:       (field name=wtable offset=8
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
+
+// CHECK-32-NEXT: (struct TypeLowering.WeakExistentialStruct)
+// CHECK-32-NEXT: (struct size=12 alignment=4 stride=12 num_extra_inhabitants=4096 bitwise_takable=0
+// CHECK-32-NEXT:   (field name=weakAnyObject offset=0
+// CHECK-32-NEXT:     (class_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=0
+// CHECK-32-NEXT:       (field name=object offset=0
+// CHECK-32-NEXT:         (reference kind=weak refcounting=unknown))))
+// CHECK-32-NEXT:   (field name=weakAnyClassBoundProto offset=4
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=0
+// CHECK-32-NEXT:       (field name=object offset=0
+// CHECK-32-NEXT:         (reference kind=weak refcounting=unknown))
+// CHECK-32-NEXT:       (field name=wtable offset=4
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
+
+12TypeLowering26UnmanagedExistentialStructV
+// CHECK-64:      (struct TypeLowering.UnmanagedExistentialStruct)
+// CHECK-64-NEXT: (struct size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
+// CHECK-64-NEXT:   (field name=unmanagedRef offset=0
+// CHECK-64-NEXT:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
+// CHECK-64-NEXT:       (field name=object offset=0
+// CHECK-64-NEXT:         (reference kind=unmanaged refcounting=unknown))
+// CHECK-64-NEXT:       (field name=wtable offset=8
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
+
+// CHECK-32:      (struct TypeLowering.UnmanagedExistentialStruct)
+// CHECK-32-NEXT: (struct size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
+// CHECK-32-NEXT:   (field name=unmanagedRef offset=0
+// CHECK-32-NEXT:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
+// CHECK-32-NEXT:       (field name=object offset=0
+// CHECK-32-NEXT:         (reference kind=unmanaged refcounting=unknown))
+// CHECK-32-NEXT:       (field name=wtable offset=4
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 12TypeLowering14MetatypeStructV
 // CHECK-64:      (struct TypeLowering.MetatypeStruct)
-// CHECK-64-NEXT: (struct size=152 alignment=8 stride=152 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT: (struct size=152 alignment=8 stride=152 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:   (field name=any offset=0
-// CHECK-64-NEXT:     (existential_metatype size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (existential_metatype size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAny offset=8
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (existential_metatype size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (existential_metatype size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=metadata offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=anyObject offset=16
-// CHECK-64-NEXT:     (existential_metatype size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (existential_metatype size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAnyObject offset=24
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (existential_metatype size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (existential_metatype size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=metadata offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=anyProto offset=32
-// CHECK-64-NEXT:     (existential_metatype size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (existential_metatype size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=8
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAnyProto offset=48
-// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (existential_metatype size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (existential_metatype size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=metadata offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:           (field name=wtable offset=8
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=anyProtoComposition offset=64
-// CHECK-64-NEXT:     (existential_metatype size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (existential_metatype size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=8
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=16
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=optionalAnyProtoComposition offset=88
-// CHECK-64-NEXT:     (single_payload_enum size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (existential_metatype size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:         (existential_metatype size=24 alignment=8 stride=24 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=metadata offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:           (field name=wtable offset=8
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-64-NEXT:           (field name=wtable offset=16
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=structMetatype offset=112
-// CHECK-64-NEXT:     (builtin size=0 alignment=1 stride=1 num_extra_inhabitants=0))
+// CHECK-64-NEXT:     (builtin size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-64-NEXT:   (field name=optionalStructMetatype offset=112
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=classMetatype offset=120
-// CHECK-64-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:   (field name=optionalClassMetatype offset=128
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=abstractMetatype offset=136
-// CHECK-64-NEXT:     (struct size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT:     (struct size=16 alignment=8 stride=16 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=t offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]]))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=u offset=8
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]])))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1)))))
 
 // CHECK-32: (struct TypeLowering.MetatypeStruct)
 // CHECK-32-NEXT: (struct size=76 alignment=4 stride=76 num_extra_inhabitants=4096
 // CHECK-32-NEXT:   (field name=any offset=0
-// CHECK-32-NEXT:     (existential_metatype size=4 alignment=4 stride=4 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (existential_metatype size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAny offset=4
-// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (existential_metatype size=4 alignment=4 stride=4 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (existential_metatype size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=metadata offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=anyObject offset=8
-// CHECK-32-NEXT:     (existential_metatype size=4 alignment=4 stride=4 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (existential_metatype size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAnyObject offset=12
-// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (existential_metatype size=4 alignment=4 stride=4 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (existential_metatype size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=metadata offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=anyProto offset=16
-// CHECK-32-NEXT:     (existential_metatype size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (existential_metatype size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=4
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAnyProto offset=24
-// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=8 alignment=4 stride=8 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (existential_metatype size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (existential_metatype size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=metadata offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:           (field name=wtable offset=4
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=anyProtoComposition offset=32
-// CHECK-32-NEXT:     (existential_metatype size=12 alignment=4 stride=12 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (existential_metatype size=12 alignment=4 stride=12 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=4
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=8
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=optionalAnyProtoComposition offset=44
-// CHECK-32-NEXT:     (single_payload_enum size=12 alignment=4 stride=12 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=12 alignment=4 stride=12 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (existential_metatype size=12 alignment=4 stride=12 num_extra_inhabitants=4096
+// CHECK-32-NEXT:         (existential_metatype size=12 alignment=4 stride=12 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=metadata offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:           (field name=wtable offset=4
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-32-NEXT:           (field name=wtable offset=8
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=structMetatype offset=56
-// CHECK-32-NEXT:     (builtin size=0 alignment=1 stride=1 num_extra_inhabitants=0))
+// CHECK-32-NEXT:     (builtin size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-32-NEXT:   (field name=optionalStructMetatype offset=56
-// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=classMetatype offset=60
-// CHECK-32-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:   (field name=optionalClassMetatype offset=64
-// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
+// CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=some offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=abstractMetatype offset=68
-// CHECK-32-NEXT:     (struct size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (struct size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=t offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=u offset=4
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1)))))
 
 12TypeLowering10EnumStructV
 // CHECK-64: (struct TypeLowering.EnumStruct)
-// CHECK-64-NEXT: (struct size=81 alignment=8 stride=88 num_extra_inhabitants=[[PTR_XI]]
+// CHECK-64-NEXT: (struct size=81 alignment=8 stride=88 num_extra_inhabitants=[[PTR_XI]] bitwise_takable=1
 // CHECK-64-NEXT:   (field name=empty offset=0
-// CHECK-64-NEXT:     (struct size=0 alignment=1 stride=1 num_extra_inhabitants=0
-// CHECK-64-NEXT:       (field name=value offset=0
-// CHECK-64-NEXT:         (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:     (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-64-NEXT:   (field name=noPayload offset=0
-// CHECK-64-NEXT:     (no_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0))
+// CHECK-64-NEXT:     (no_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-64-NEXT:   (field name=sillyNoPayload offset=1
-// CHECK-64-NEXT:     (no_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0))
+// CHECK-64-NEXT:     (no_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-64-NEXT:   (field name=singleton offset=8
 // CHECK-64-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-64-NEXT:   (field name=singlePayload offset=16
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=Indirect offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-64-NEXT:   (field name=multiPayloadConcrete offset=24
-// CHECK-64-NEXT:     (multi_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (multi_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=2045 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=Left offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))
 // CHECK-64-NEXT:       (field name=Right offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-64-NEXT:   (field name=multiPayloadGenericFixed offset=32
-// CHECK-64-NEXT:     (multi_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (multi_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=253 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=Left offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))
 // CHECK-64-NEXT:       (field name=Right offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=native))))
 // CHECK-64-NEXT:   (field name=multiPayloadGenericDynamic offset=48
-// CHECK-64-NEXT:     (multi_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (multi_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=253 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=Left offset=0
-// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:             (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:       (field name=Right offset=0
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=optionalOptionalRef offset=64
-// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_2:2147483645|2046|4094]]
+// CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_2:2147483645|2046|4094]] bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]]
+// CHECK-64-NEXT:         (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=[[PTR_XI_SUB_1]] bitwise_takable=1
 // CHECK-64-NEXT:           (field name=some offset=0
 // CHECK-64-NEXT:             (reference kind=strong refcounting=native))))))
 // CHECK-64-NEXT:   (field name=optionalOptionalPtr offset=72
-// CHECK-64-NEXT:     (single_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (single_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=some offset=0
-// CHECK-64-NEXT:         (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=some offset=0
-// CHECK-64-NEXT:             (struct size=8 alignment=8 stride=8 num_extra_inhabitants=1
+// CHECK-64-NEXT:             (struct size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_rawValue offset=0
-// CHECK-64-NEXT:                 (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1)))))))))
+// CHECK-64-NEXT:                 (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))))))
+
+12TypeLowering23EnumStructWithOwnershipV
+// CHECK-64:      (struct TypeLowering.EnumStructWithOwnership)
+// CHECK-64-NEXT: (struct size=25 alignment=8 stride=32 num_extra_inhabitants=254 bitwise_takable=0
+// CHECK-64-NEXT:   (field name=multiPayloadConcrete offset=0
+// CHECK-64-NEXT:     (multi_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=254 bitwise_takable=0
+// CHECK-64-NEXT:       (field name=Left offset=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=0
+// CHECK-64-NEXT:           (field name=weakRef offset=0
+// CHECK-64-NEXT:             (reference kind=weak refcounting=native))))
+// CHECK-64-NEXT:       (field name=Right offset=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=0
+// CHECK-64-NEXT:           (field name=weakRef offset=0
+// CHECK-64-NEXT:             (reference kind=weak refcounting=native))))))
+// CHECK-64-NEXT:   (field name=multiPayloadGeneric offset=16
+// CHECK-64-NEXT:     (multi_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=254 bitwise_takable=0
+// CHECK-64-NEXT:       (field name=Left offset=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=0
+// CHECK-64-NEXT:           (field name=weakRef offset=0
+// CHECK-64-NEXT:             (reference kind=weak refcounting=native))))
+// CHECK-64-NEXT:       (field name=Right offset=0
+// CHECK-64-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
+// CHECK-64-NEXT:           (field name=_value offset=0
+// CHECK-64-NEXT:             (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))))
+
+// CHECK-32:      (struct TypeLowering.EnumStructWithOwnership)
+// CHECK-32-NEXT: (struct size=13 alignment=4 stride=16 num_extra_inhabitants=254 bitwise_takable=0
+// CHECK-32-NEXT:   (field name=multiPayloadConcrete offset=0
+// CHECK-32-NEXT:     (multi_payload_enum size=5 alignment=4 stride=8 num_extra_inhabitants=254 bitwise_takable=0
+// CHECK-32-NEXT:       (field name=Left offset=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=0
+// CHECK-32-NEXT:           (field name=weakRef offset=0
+// CHECK-32-NEXT:             (reference kind=weak refcounting=native))))
+// CHECK-32-NEXT:       (field name=Right offset=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=0
+// CHECK-32-NEXT:           (field name=weakRef offset=0
+// CHECK-32-NEXT:             (reference kind=weak refcounting=native))))))
+// CHECK-32-NEXT:   (field name=multiPayloadGeneric offset=8
+// CHECK-32-NEXT:     (multi_payload_enum size=5 alignment=4 stride=8 num_extra_inhabitants=254 bitwise_takable=0
+// CHECK-32-NEXT:       (field name=Left offset=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=0
+// CHECK-32-NEXT:           (field name=weakRef offset=0
+// CHECK-32-NEXT:             (reference kind=weak refcounting=native))))
+// CHECK-32-NEXT:       (field name=Right offset=0
+// CHECK-32-NEXT:         (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
+// CHECK-32-NEXT:           (field name=_value offset=0
+// CHECK-32-NEXT:             (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))))
 
 Bo
 // CHECK-64:      (builtin Builtin.NativeObject)
diff --git a/test/Reflection/typeref_lowering_imported.swift b/test/Reflection/typeref_lowering_imported.swift
index 0333274..472eb57 100644
--- a/test/Reflection/typeref_lowering_imported.swift
+++ b/test/Reflection/typeref_lowering_imported.swift
@@ -15,19 +15,19 @@
 
 12TypeLowering9HasCTypesV
 // CHECK:     (struct TypeLowering.HasCTypes)
-// CHECK-NEXT: (struct size=40 alignment=8 stride=40 num_extra_inhabitants=0
+// CHECK-NEXT: (struct size=40 alignment=8 stride=40 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-NEXT:   (field name=mcs offset=0
-// CHECK-NEXT:     (builtin size=24 alignment=8 stride=24 num_extra_inhabitants=0))
+// CHECK-NEXT:     (builtin size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-NEXT:   (field name=mce offset=24
-// CHECK-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))
+// CHECK-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-NEXT:   (field name=mcu offset=32
-// CHECK-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))
+// CHECK-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))
 
 
 12TypeLowering13AlsoHasCTypesV
-// CHECK:      (struct size=12 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK:      (struct size=12 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-NEXT:   (field name=mcu offset=0
-// CHECK-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))
+// CHECK-NEXT:     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-NEXT:   (field name=mcsbf offset=8
-// CHECK-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))
+// CHECK-NEXT:     (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))
 
diff --git a/test/Reflection/typeref_lowering_objc.swift b/test/Reflection/typeref_lowering_objc.swift
index ef7068b..0f164c0 100644
--- a/test/Reflection/typeref_lowering_objc.swift
+++ b/test/Reflection/typeref_lowering_objc.swift
@@ -7,7 +7,7 @@
 
 12TypeLowering14FunctionStructV
 // CHECK:      (struct TypeLowering.FunctionStruct)
-// CHECK-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647
+// CHECK-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-NEXT:   (field name=blockFunction offset=0
 // CHECK-NEXT:     (reference kind=strong refcounting=unknown)))
 
@@ -20,12 +20,23 @@
 // CHECK-NEXT: (reference kind=strong refcounting=unknown)
 
 12TypeLowering11HasObjCEnumV
-// CHECK: (struct size=24 alignment=8 stride=24 num_extra_inhabitants=2147483647
+// CHECK: (struct size=24 alignment=8 stride=24 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-NEXT:   (field name=optionalEnum offset=0
-// CHECK-NEXT:     (single_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-NEXT:     (single_payload_enum size=9 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-NEXT:       (field name=some offset=0
-// CHECK-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-NEXT:   (field name=reference offset=16
-// CHECK-NEXT:     (class_existential size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647
+// CHECK-NEXT:     (class_existential size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-NEXT:       (field name=object offset=0
 // CHECK-NEXT:         (reference kind=strong refcounting=unknown)))))
+
+12TypeLowering22UnownedReferenceStructV
+// CHECK-64:      (struct TypeLowering.UnownedReferenceStruct)
+// CHECK-64-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=0
+// CHECK-64-NEXT:   (field name=unownedRef offset=0
+// CHECK-64-NEXT:     (reference kind=unowned refcounting=unknown)))
+
+// CHECK-32:      (struct TypeLowering.UnownedReferenceStruct)
+// CHECK-32-NEXT: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=0
+// CHECK-32-NEXT:   (field name=unownedRef offset=0
+// CHECK-32-NEXT:     (reference kind=unowned refcounting=unknown)))
diff --git a/test/Runtime/demangleToMetadataObjC.swift b/test/Runtime/demangleToMetadataObjC.swift
index a18bd5f..0985ba1 100644
--- a/test/Runtime/demangleToMetadataObjC.swift
+++ b/test/Runtime/demangleToMetadataObjC.swift
@@ -15,6 +15,7 @@
 @objc protocol P1 { }
 protocol P2 { }
 @objc protocol P3: P1 { }
+@objc protocol mainP4 { }
 
 DemangleToMetadataTests.test("@objc classes") {
   expectEqual(type(of: C()), _typeByMangledName("4main1CC")!)
@@ -25,10 +26,13 @@
 }
 
 func f1_composition_objc_protocol(_: P1) { }
+func f1_composition_objc_protocol_P4(_: mainP4) { }
 
 DemangleToMetadataTests.test("@objc protocols") {
   expectEqual(type(of: f1_composition_objc_protocol),
               _typeByMangledName("yy4main2P1_pc")!)
+  expectEqual(type(of: f1_composition_objc_protocol_P4),
+              _typeByMangledName("yy4main0A2P4_pc")!)
 }
 
 DemangleToMetadataTests.test("Objective-C classes") {
diff --git a/test/SIL/Parser/basic.sil b/test/SIL/Parser/basic.sil
index d4ba7d8..3168e0c 100644
--- a/test/SIL/Parser/basic.sil
+++ b/test/SIL/Parser/basic.sil
@@ -9,7 +9,7 @@
 sil_global private @globalinit_token0 : $Builtin.Word
 
 class TestArrayStorage {
-  @sil_stored var count: Int32
+  @_hasStorage var count: Int32
   init()
 }
 
@@ -1622,7 +1622,7 @@
 }
 
 class A {
-  @sil_stored var property: Any { get set }
+  @_hasStorage var property: Any { get set }
   deinit
   init()
 }
@@ -1679,6 +1679,20 @@
   return %20 : $()
 }
 
+// CHECK-LABEL: sil [dynamically_replacable] @test_dynamically_replaceable
+sil [dynamically_replacable] @test_dynamically_replaceable : $@convention(thin) () -> () {
+bb0:
+  %0 = tuple ()
+  return %0 : $()
+}
+
+// CHECK-LABEL: sil [dynamic_replacement_for "test_dynamically_replaceable"] @test_dynamic_replacement_for
+sil [dynamic_replacement_for "test_dynamically_replaceable"] @test_dynamic_replacement_for : $@convention(thin) () -> () {
+bb0:
+  %0 = tuple ()
+  return %0 : $()
+}
+
 struct EmptyStruct {}
 
 sil @test_empty_destructure : $@convention(thin) () -> () {
diff --git a/test/SIL/Parser/final.swift b/test/SIL/Parser/final.swift
index c382695..6be8eef 100644
--- a/test/SIL/Parser/final.swift
+++ b/test/SIL/Parser/final.swift
@@ -1,14 +1,14 @@
 // RUN: %target-swift-frontend %s -emit-silgen | %FileCheck %s
 
 // CHECK: final class Rect
-// CHECK: @sil_stored @_hasInitialValue final var orgx: Double
+// CHECK: @_hasStorage @_hasInitialValue final var orgx: Double
 final class Rect {
   var orgx = 0.0
 }
 
 protocol P { }
 // CHECK: struct Rect2 : P {
-// CHECK: @sil_stored @_hasInitialValue var orgx: Double
+// CHECK: @_hasStorage @_hasInitialValue var orgx: Double
 struct Rect2 : P {
   var orgx = 0.0
 }
diff --git a/test/SIL/Parser/stored_property.sil b/test/SIL/Parser/stored_property.sil
index 5ec62c5..1ae76da 100644
--- a/test/SIL/Parser/stored_property.sil
+++ b/test/SIL/Parser/stored_property.sil
@@ -2,9 +2,9 @@
 
 import Swift
 
-// CHECK: @sil_stored var orgx
+// CHECK: @_hasStorage var orgx
 class Rect {
-  @sil_stored var orgx: Double { get }
+  @_hasStorage var orgx: Double { get }
   init(orgx: Double)
 }
 
diff --git a/test/SIL/Serialization/basic.sil b/test/SIL/Serialization/basic.sil
index a7e7e8c..d3b6bc9 100644
--- a/test/SIL/Serialization/basic.sil
+++ b/test/SIL/Serialization/basic.sil
@@ -23,7 +23,7 @@
 }
 
 class TestArrayStorage {
-  @sil_stored var count: Int32
+  @_hasStorage var count: Int32
   init()
 }
 
diff --git a/test/SIL/Serialization/dynamically_replaceable.sil b/test/SIL/Serialization/dynamically_replaceable.sil
new file mode 100644
index 0000000..4ddde1f
--- /dev/null
+++ b/test/SIL/Serialization/dynamically_replaceable.sil
@@ -0,0 +1,31 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend %s -emit-module -o %t/tmp.swiftmodule
+// RUN: %target-sil-opt %t/tmp.swiftmodule -disable-sil-linking | %FileCheck %s
+
+
+// CHECK-DAG-LABEL: sil [serialized] [dynamically_replacable] [canonical] @test_dynamically_replaceable
+sil [serialized] [dynamically_replacable] @test_dynamically_replaceable : $@convention(thin) () -> () {
+bb0:
+  %0 = tuple ()
+  return %0 : $()
+}
+
+// CHECK-DAG-LABEL: sil [serialized] [dynamic_replacement_for "test_dynamically_replaceable"] [canonical] @test_dynamic_replacement_for
+// CHECK: prev_dynamic_function_ref @test_dynamic_replacement_for
+sil [serialized] [dynamic_replacement_for "test_dynamically_replaceable"] @test_dynamic_replacement_for : $@convention(thin) () -> () {
+bb0:
+  %0 = prev_dynamic_function_ref @test_dynamic_replacement_for : $@convention(thin) () -> ()
+  %1 = apply %0() : $@convention(thin) () -> ()
+  %2 = tuple ()
+  return %2 : $()
+}
+
+// CHECK-DAG-LABEL: sil [serialized] [canonical] @test_dynamically_replaceable_impl
+// CHECK:  dynamic_function_ref @test_dynamically_replaceable
+sil [serialized] @test_dynamically_replaceable_impl : $@convention(thin) () -> () {
+bb0:
+  %0 = dynamic_function_ref @test_dynamically_replaceable : $@convention(thin) () -> ()
+  %1 = apply %0() : $@convention(thin) () -> ()
+  %2 = tuple ()
+  return %2 : $()
+}
diff --git a/test/SIL/ownership-verifier/definite_init.sil b/test/SIL/ownership-verifier/definite_init.sil
index f4f0a49..9a52669 100644
--- a/test/SIL/ownership-verifier/definite_init.sil
+++ b/test/SIL/ownership-verifier/definite_init.sil
@@ -529,7 +529,7 @@
 
 
 struct MyStruct3 {
-  @sil_stored var c: C
+  @_hasStorage var c: C
 }
 sil @selfinit_mystruct3 : $@convention(thin) () -> @owned MyStruct3
 
diff --git a/test/SILGen/Inputs/private_import_module.swift b/test/SILGen/Inputs/private_import_module.swift
new file mode 100644
index 0000000..48623a7
--- /dev/null
+++ b/test/SILGen/Inputs/private_import_module.swift
@@ -0,0 +1,9 @@
+private protocol HasDefaultFoo {}
+
+extension HasDefaultFoo {
+  private func foo() {}
+}
+
+private class Base {
+  func foo() {}
+}
diff --git a/test/SILGen/addressors.swift b/test/SILGen/addressors.swift
index 49a1dee..1fdcdaa 100644
--- a/test/SILGen/addressors.swift
+++ b/test/SILGen/addressors.swift
@@ -277,136 +277,26 @@
   e.value = 0
 }
 
-class F {
-  var data: UnsafeMutablePointer<Int32> = UnsafeMutablePointer.allocate(capacity: 100)
-
-  final var value: Int32 {
-    addressWithNativeOwner {
-      return (UnsafePointer(data), Builtin.castToNativeObject(self))
-    }
-    mutableAddressWithNativeOwner {
-      return (data, Builtin.castToNativeObject(self))
-    }
-  }
-}
-
-// CHECK-LABEL: sil hidden @$s10addressors1FC5values5Int32Vvlo : $@convention(method) (@guaranteed F) -> (UnsafePointer<Int32>, @owned Builtin.NativeObject) {
-// CHECK-LABEL: sil hidden @$s10addressors1FC5values5Int32Vvao : $@convention(method) (@guaranteed F) -> (UnsafeMutablePointer<Int32>, @owned Builtin.NativeObject) {
-
-func test_f0(_ f: F) -> Int32 {
-  return f.value
-}
-// CHECK-LABEL: sil hidden @$s10addressors7test_f0ys5Int32VAA1FCF : $@convention(thin) (@guaranteed F) -> Int32 {
-// CHECK: bb0([[SELF:%0]] : $F):
-// CHECK:   [[ADDRESSOR:%.*]] = function_ref @$s10addressors1FC5values5Int32Vvlo : $@convention(method) (@guaranteed F) -> (UnsafePointer<Int32>, @owned Builtin.NativeObject)
-// CHECK:   [[T0:%.*]] = apply [[ADDRESSOR]]([[SELF]])
-// CHECK:   [[PTR:%.*]] = tuple_extract [[T0]] : $(UnsafePointer<Int32>, Builtin.NativeObject), 0
-// CHECK:   [[OWNER:%.*]] = tuple_extract [[T0]] : $(UnsafePointer<Int32>, Builtin.NativeObject), 1
-// CHECK:   [[T0:%.*]] = struct_extract [[PTR]]
-// CHECK:   [[T1:%.*]] = pointer_to_address [[T0]] : $Builtin.RawPointer to [strict] $*Int32
-// CHECK:   [[T2:%.*]] = mark_dependence [[T1]] : $*Int32 on [[OWNER]] : $Builtin.NativeObject
-// CHECK:   [[ACCESS:%.*]] = begin_access [read] [unsafe] [[T2]] : $*Int32
-// CHECK:   [[VALUE:%.*]] = load [[ACCESS]] : $*Int32
-// CHECK:   strong_release [[OWNER]] : $Builtin.NativeObject
-// CHECK-NOT:   strong_release [[SELF]] : $F
-// CHECK:   return [[VALUE]] : $Int32
-
-func test_f1(_ f: F) {
-  f.value = 14
-}
-// CHECK-LABEL: sil hidden @$s10addressors7test_f1yyAA1FCF : $@convention(thin) (@guaranteed F) -> () {
-// CHECK: bb0([[SELF:%0]] : $F):
-// CHECK:   [[T0:%.*]] = integer_literal $Builtin.Int32, 14
-// CHECK:   [[VALUE:%.*]] = struct $Int32 ([[T0]] : $Builtin.Int32)
-// CHECK:   [[ADDRESSOR:%.*]] = function_ref @$s10addressors1FC5values5Int32Vvao : $@convention(method) (@guaranteed F) -> (UnsafeMutablePointer<Int32>, @owned Builtin.NativeObject)
-// CHECK:   [[T0:%.*]] = apply [[ADDRESSOR]]([[SELF]])
-// CHECK:   [[PTR:%.*]] = tuple_extract [[T0]] : $(UnsafeMutablePointer<Int32>, Builtin.NativeObject), 0
-// CHECK:   [[OWNER:%.*]] = tuple_extract [[T0]] : $(UnsafeMutablePointer<Int32>, Builtin.NativeObject), 1
-// CHECK:   [[T0:%.*]] = struct_extract [[PTR]]
-// CHECK:   [[T1:%.*]] = pointer_to_address [[T0]] : $Builtin.RawPointer to [strict] $*Int32
-// CHECK:   [[T2:%.*]] = mark_dependence [[T1]] : $*Int32 on [[OWNER]] : $Builtin.NativeObject
-// CHECK:   [[ACCESS:%.*]] = begin_access [modify] [unsafe] [[T2]] : $*Int32
-// CHECK:   store [[VALUE]] to [[ACCESS]] : $*Int32
-// CHECK:   strong_release [[OWNER]] : $Builtin.NativeObject
-// CHECK-NOT:   strong_release [[SELF]] : $F
-
-class G {
-  var data: UnsafeMutablePointer<Int32> = UnsafeMutablePointer.allocate(capacity: 100)
-
-  var value: Int32 {
-    addressWithNativeOwner {
-      return (UnsafePointer(data), Builtin.castToNativeObject(self))
-    }
-    mutableAddressWithNativeOwner {
-      return (data, Builtin.castToNativeObject(self))
-    }
-  }
-}
-// CHECK-LABEL: sil hidden [transparent] @$s10addressors1GC5values5Int32Vvg : $@convention(method) (@guaranteed G) -> Int32 {
-// CHECK: bb0([[SELF:%0]] : $G):
-// CHECK:   [[ADDRESSOR:%.*]] = function_ref @$s10addressors1GC5values5Int32Vvlo : $@convention(method) (@guaranteed G) -> (UnsafePointer<Int32>, @owned Builtin.NativeObject)
-// CHECK:   [[T0:%.*]] = apply [[ADDRESSOR]]([[SELF]])
-// CHECK:   [[PTR:%.*]] = tuple_extract [[T0]] : $(UnsafePointer<Int32>, Builtin.NativeObject), 0
-// CHECK:   [[OWNER:%.*]] = tuple_extract [[T0]] : $(UnsafePointer<Int32>, Builtin.NativeObject), 1
-// CHECK:   [[T0:%.*]] = struct_extract [[PTR]]
-// CHECK:   [[T1:%.*]] = pointer_to_address [[T0]] : $Builtin.RawPointer to [strict] $*Int32
-// CHECK:   [[T2:%.*]] = mark_dependence [[T1]] : $*Int32 on [[OWNER]] : $Builtin.NativeObject
-// CHECK:   [[ACCESS:%.*]] = begin_access [read] [unsafe] [[T2]] : $*Int32
-// CHECK:   [[VALUE:%.*]] = load [[ACCESS]] : $*Int32
-// CHECK:   strong_release [[OWNER]] : $Builtin.NativeObject
-// CHECK:   return [[VALUE]] : $Int32
-
-// CHECK-LABEL: sil hidden [transparent] @$s10addressors1GC5values5Int32Vvs : $@convention(method) (Int32, @guaranteed G) -> () {
-// CHECK: bb0([[VALUE:%0]] : $Int32, [[SELF:%1]] : $G):
-// CHECK:   [[ADDRESSOR:%.*]] = function_ref @$s10addressors1GC5values5Int32Vvao : $@convention(method) (@guaranteed G) -> (UnsafeMutablePointer<Int32>, @owned Builtin.NativeObject)
-// CHECK:   [[T0:%.*]] = apply [[ADDRESSOR]]([[SELF]])
-// CHECK:   [[PTR:%.*]] = tuple_extract [[T0]] : $(UnsafeMutablePointer<Int32>, Builtin.NativeObject), 0
-// CHECK:   [[OWNER:%.*]] = tuple_extract [[T0]] : $(UnsafeMutablePointer<Int32>, Builtin.NativeObject), 1
-// CHECK:   [[T0:%.*]] = struct_extract [[PTR]]
-// CHECK:   [[T1:%.*]] = pointer_to_address [[T0]] : $Builtin.RawPointer to [strict] $*Int32
-// CHECK:   [[T2:%.*]] = mark_dependence [[T1]] : $*Int32 on [[OWNER]] : $Builtin.NativeObject
-// CHECK:   [[ACCESS:%.*]] = begin_access [modify] [unsafe] [[T2]] : $*Int32
-// CHECK:   store [[VALUE]] to [[ACCESS]] : $*Int32
-// CHECK:   strong_release [[OWNER]] : $Builtin.NativeObject
-
-// CHECK-LABEL: sil hidden [transparent] @$s10addressors1GC5values5Int32VvM : $@yield_once @convention(method) (@guaranteed G) -> @yields @inout Int32 {
-// CHECK: bb0([[SELF:%0]] : $G):
-//   Call the addressor.
-// CHECK:   [[ADDRESSOR:%.*]] = function_ref @$s10addressors1GC5values5Int32Vvao : $@convention(method) (@guaranteed G) -> (UnsafeMutablePointer<Int32>, @owned Builtin.NativeObject)
-// CHECK:   [[T0:%.*]] = apply [[ADDRESSOR]]([[SELF]])
-// CHECK:   [[T1:%.*]] = tuple_extract [[T0]] : $(UnsafeMutablePointer<Int32>, Builtin.NativeObject), 0
-// CHECK:   [[OWNER:%.*]] = tuple_extract [[T0]] : $(UnsafeMutablePointer<Int32>, Builtin.NativeObject), 1
-//   Get the address.
-// CHECK:   [[PTR:%.*]] = struct_extract [[T1]] : $UnsafeMutablePointer<Int32>, #UnsafeMutablePointer._rawValue
-// CHECK:   [[ADDR_TMP:%.*]] = pointer_to_address [[PTR]]
-// CHECK:   [[ADDR:%.*]] = mark_dependence [[ADDR_TMP]] : $*Int32 on [[OWNER]]
-//   Yield.
-// CHECK:   [[ACCESS:%.*]] = begin_access [modify] [unsafe] [[ADDR]] : $*Int32
-// CHECK:   yield [[ACCESS]] : $*Int32, resume bb1, unwind bb2
-// CHECK:   end_access [[ACCESS]]
-//   Clean up.
-// CHECK:   strong_release [[OWNER]] : $Builtin.NativeObject
-
 class Base {
   var data: UnsafeMutablePointer<Int32> = UnsafeMutablePointer.allocate(capacity: 100)
 
   var value: Int32 {
-    addressWithNativeOwner {
-      return (UnsafePointer(data), Builtin.castToNativeObject(self))
+    unsafeAddress {
+      return UnsafePointer(data)
     }
-    mutableAddressWithNativeOwner {
-      return (data, Builtin.castToNativeObject(self))
+    unsafeMutableAddress {
+      return data
     }
   }
 }
 
 class Sub : Base {
   override var value: Int32 {
-    addressWithNativeOwner {
-      return (UnsafePointer(data), Builtin.castToNativeObject(self))
+    unsafeAddress {
+      return UnsafePointer(data)
     }
-    mutableAddressWithNativeOwner {
-      return (data, Builtin.castToNativeObject(self))
+    unsafeMutableAddress {
+      return data
     }
   }
 }
diff --git a/test/SILGen/auto_closures.swift b/test/SILGen/auto_closures.swift
index 778d841..dc6977b 100644
--- a/test/SILGen/auto_closures.swift
+++ b/test/SILGen/auto_closures.swift
@@ -39,7 +39,7 @@
 public class Sub : Base {
   // CHECK-LABEL: sil hidden @$s13auto_closures3SubC1xAA4BoolVvg : $@convention(method) (@guaranteed Sub) -> Bool {
   // CHECK: bb0([[SELF:%.*]] : @guaranteed $Sub):
-  // CHECK: [[AUTOCLOSURE_FUNC:%.*]] = function_ref @$s13auto_closures3SubC1xAA4BoolVvgAFyXKfu_ : $@convention(thin) (@guaranteed Sub) -> Bool
+  // CHECK: [[AUTOCLOSURE_FUNC:%.*]] = function_ref @$s13auto_closures3SubC1xAA4BoolVvgAFyXEfu_ : $@convention(thin) (@guaranteed Sub) -> Bool
   // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
   // CHECK: [[AUTOCLOSURE:%.*]] = partial_apply [callee_guaranteed] [[AUTOCLOSURE_FUNC]]([[SELF_COPY]])
   // CHECK: [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[AUTOCLOSURE]]
@@ -48,7 +48,7 @@
   // CHECK: return [[RET]] : $Bool
   // CHECK: }
 
-  // CHECK-LABEL: sil private [transparent] @$s13auto_closures3SubC1xAA4BoolVvgAFyXKfu_ : $@convention(thin) (@guaranteed Sub) -> Bool {
+  // CHECK-LABEL: sil private [transparent] @$s13auto_closures3SubC1xAA4BoolVvgAFyXEfu_ : $@convention(thin) (@guaranteed Sub) -> Bool {
   // CHECK: [[SUPER:%[0-9]+]] = function_ref @$s13auto_closures4BaseC1xAA4BoolVvg : $@convention(method) (@guaranteed Base) -> Bool
   // CHECK: [[RET:%.*]] = apply [[SUPER]]({{%.*}})
   // CHECK: return [[RET]]
@@ -57,9 +57,9 @@
 
 // CHECK-LABEL: sil hidden @$s13auto_closures20closureInAutoclosureyAA4BoolVAD_ADtF : $@convention(thin) (Bool, Bool) -> Bool {
 // CHECK: }
-// CHECK-LABEL: sil private [transparent] @$s13auto_closures20closureInAutoclosureyAA4BoolVAD_ADtFADyXKfu_ : $@convention(thin) (Bool, Bool) -> Bool {
+// CHECK-LABEL: sil private [transparent] @$s13auto_closures20closureInAutoclosureyAA4BoolVAD_ADtFADyXEfu_ : $@convention(thin) (Bool, Bool) -> Bool {
 // CHECK: }
-// CHECK-LABEL: sil private @$s13auto_closures20closureInAutoclosureyAA4BoolVAD_ADtFADyXKfu_A2DXEfU_ : $@convention(thin) (Bool, Bool) -> Bool {
+// CHECK-LABEL: sil private @$s13auto_closures20closureInAutoclosureyAA4BoolVAD_ADtFADyXEfu_A2DXEfU_ : $@convention(thin) (Bool, Bool) -> Bool {
 // CHECK: }
 func compareBool(_ lhs: Bool, _ rhs: Bool) -> Bool { return false_ }
 func testBool(_ x: Bool, _ pred: (Bool) -> Bool) -> Bool {
diff --git a/test/SILGen/class_bound_protocols.swift b/test/SILGen/class_bound_protocols.swift
index 6b4428a..e8bcf0f 100644
--- a/test/SILGen/class_bound_protocols.swift
+++ b/test/SILGen/class_bound_protocols.swift
@@ -169,8 +169,6 @@
   // CHECK-NEXT: dealloc_stack [[TEMPORARY]] : $*@opened("{{.*}}") InheritsMutatingMethod
   x.mutateMe()
 
-  // CHECK-NEXT: [[RESULT_BOX:%.*]] = alloc_stack $Value
-  // CHECK-NEXT: [[RESULT:%.*]] = mark_uninitialized [var] [[RESULT_BOX]] : $*Value
   // CHECK-NEXT: [[X_ADDR:%.*]] = begin_access [read] [unknown] %0 : $*InheritsMutatingMethod
   // CHECK-NEXT: [[X_VALUE:%.*]] = load [copy] [[X_ADDR]] : $*InheritsMutatingMethod
   // CHECK-NEXT: [[X_PAYLOAD:%.*]] = open_existential_ref [[X_VALUE]] : $InheritsMutatingMethod to $@opened("{{.*}}") InheritsMutatingMethod
@@ -192,9 +190,7 @@
   // CHECK-NEXT: end_borrow
   // CHECK-NEXT: destroy_addr
   // CHECK-NEXT: end_access [[X_ADDR]] : $*InheritsMutatingMethod
-  // CHECK-NEXT: assign [[RESULT_VALUE]] to [[RESULT]] : $*Value
   // CHECK-NEXT: dealloc_stack [[TEMPORARY]] : $*@opened("{{.*}}") InheritsMutatingMethod
-  // CHECK-NEXT: dealloc_stack [[RESULT_BOX]] : $*Value
   _ = x.mutatingCounter
 
   // CHECK-NEXT: [[X_ADDR:%.*]] = begin_access [modify] [unknown] %0 : $*InheritsMutatingMethod
diff --git a/test/SILGen/closures.swift b/test/SILGen/closures.swift
index fb543a3..28e1978 100644
--- a/test/SILGen/closures.swift
+++ b/test/SILGen/closures.swift
@@ -602,7 +602,7 @@
   func f() {
     // CHECK: sil private @[[INNER_FUNC_1]] : $@convention(thin) (@guaranteed SuperSub) -> () {
     // CHECK: bb0([[ARG:%.*]] : @guaranteed $SuperSub):
-    // CHECK:   [[INNER:%.*]] = function_ref @[[INNER_FUNC_2:\$s8closures8SuperSubC1fyyFyycfU_yyKXKfu_]] : $@convention(thin) (@guaranteed SuperSub) -> @error Error
+    // CHECK:   [[INNER:%.*]] = function_ref @[[INNER_FUNC_2:\$s8closures8SuperSubC1fyyFyycfU_yyKXEfu_]] : $@convention(thin) (@guaranteed SuperSub) -> @error Error
     // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
     // CHECK:   [[PA:%.*]] = partial_apply [callee_guaranteed] [[INNER]]([[ARG_COPY]])
     // CHECK:   [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PA]]
diff --git a/test/SILGen/default_arguments.swift b/test/SILGen/default_arguments.swift
index 72fa50f..4731051 100644
--- a/test/SILGen/default_arguments.swift
+++ b/test/SILGen/default_arguments.swift
@@ -60,10 +60,10 @@
                    y: @autoclosure () -> Int = #line) { }
 // CHECK-LABEL: sil hidden @$s17default_arguments17testAutocloseFileyyF
 func testAutocloseFile() {
-  // CHECK-LABEL: sil private [transparent] @$s17default_arguments17testAutocloseFileyyFSSyXKfu_ : $@convention(thin) () -> @owned String
+  // CHECK-LABEL: sil private [transparent] @$s17default_arguments17testAutocloseFileyyFSSyXEfu_ : $@convention(thin) () -> @owned String
   // CHECK: string_literal utf8{{.*}}default_arguments.swift
 
-  // CHECK-LABEL: sil private [transparent] @$s17default_arguments17testAutocloseFileyyFSiyXKfu0_ : $@convention(thin) () -> Int
+  // CHECK-LABEL: sil private [transparent] @$s17default_arguments17testAutocloseFileyyFSiyXEfu0_ : $@convention(thin) () -> Int
   // CHECK: integer_literal $Builtin.IntLiteral, [[@LINE+1]]
   autocloseFile()
 }
@@ -92,7 +92,7 @@
 // CHECK:         string_literal utf8 "testCallWithMagicLiterals()"
 // CHECK-LABEL: sil private @$s17default_arguments25testCallWithMagicLiteralsyyFyyXEfU_
 // CHECK:         string_literal utf8 "testCallWithMagicLiterals()"
-// CHECK-LABEL: sil private [transparent] @$s17default_arguments25testCallWithMagicLiteralsyyFyyXKfu_
+// CHECK-LABEL: sil private [transparent] @$s17default_arguments25testCallWithMagicLiteralsyyFyyXEfu_
 // CHECK:         string_literal utf8 "testCallWithMagicLiterals()"
 func testCallWithMagicLiterals() {
   testMagicLiterals()
diff --git a/test/SILGen/dynamic.swift b/test/SILGen/dynamic.swift
index f515c0f..091ec68 100644
--- a/test/SILGen/dynamic.swift
+++ b/test/SILGen/dynamic.swift
@@ -444,13 +444,13 @@
 public class Sub : Base {
   // CHECK-LABEL: sil hidden @$s7dynamic3SubC1xSbvg : $@convention(method) (@guaranteed Sub) -> Bool {
   // CHECK: bb0([[SELF:%.*]] : @guaranteed $Sub):
-  // CHECK:     [[AUTOCLOSURE:%.*]] = function_ref @$s7dynamic3SubC1xSbvgSbyKXKfu_ : $@convention(thin) (@guaranteed Sub) -> (Bool, @error Error)
+  // CHECK:     [[AUTOCLOSURE:%.*]] = function_ref @$s7dynamic3SubC1xSbvgSbyKXEfu_ : $@convention(thin) (@guaranteed Sub) -> (Bool, @error Error)
   // CHECK:     [[SELF_COPY:%.*]] = copy_value [[SELF]]
   // CHECK:     = partial_apply [callee_guaranteed] [[AUTOCLOSURE]]([[SELF_COPY]])
   // CHECK:     return {{%.*}} : $Bool
   // CHECK: } // end sil function '$s7dynamic3SubC1xSbvg'
 
-  // CHECK-LABEL: sil private [transparent] @$s7dynamic3SubC1xSbvgSbyKXKfu_ : $@convention(thin) (@guaranteed Sub) -> (Bool, @error Error) {
+  // CHECK-LABEL: sil private [transparent] @$s7dynamic3SubC1xSbvgSbyKXEfu_ : $@convention(thin) (@guaranteed Sub) -> (Bool, @error Error) {
   // CHECK: bb0([[VALUE:%.*]] : @guaranteed $Sub):
   // CHECK:     [[VALUE_COPY:%.*]] = copy_value [[VALUE]]
   // CHECK:     [[CAST_VALUE_COPY:%.*]] = upcast [[VALUE_COPY]]
@@ -460,7 +460,7 @@
   // CHECK:     = apply [[SUPER]]([[BORROWED_CAST_VALUE_COPY]])
   // CHECK:     end_borrow [[BORROWED_CAST_VALUE_COPY]]
   // CHECK:     destroy_value [[CAST_VALUE_COPY]]
-  // CHECK: } // end sil function '$s7dynamic3SubC1xSbvgSbyKXKfu_'
+  // CHECK: } // end sil function '$s7dynamic3SubC1xSbvgSbyKXEfu_'
   override var x: Bool { return false || super.x }
 }
 
diff --git a/test/SILGen/dynamic_callable_attribute.swift b/test/SILGen/dynamic_callable_attribute.swift
new file mode 100644
index 0000000..9bf9ae9
--- /dev/null
+++ b/test/SILGen/dynamic_callable_attribute.swift
@@ -0,0 +1,26 @@
+// RUN: %target-swift-emit-silgen -verify %s | %FileCheck %s
+
+// Check that dynamic calls resolve to the right `dynamicallyCall` method in SIL.
+
+@dynamicCallable
+public struct Callable {
+  func dynamicallyCall(withArguments: [Int]) {}
+  func dynamicallyCall(withKeywordArguments: KeyValuePairs<String, Int>) {}
+}
+
+@_silgen_name("foo")
+public func foo(a: Callable) {
+  // The first two calls should resolve to the `withArguments:` method.
+  a()
+  a(1, 2, 3)
+  // The last call should resolve to the `withKeywordArguments:` method.
+  a(1, 2, 3, label: 4)
+}
+
+// CHECK-LABEL: sil @foo
+// CHECK: bb0(%0 : @trivial $Callable):
+// CHECK: [[DYN_CALL_1:%.*]] = function_ref @$s26dynamic_callable_attribute8CallableV15dynamicallyCall13withArgumentsySaySiG_tF
+// CHECK-NEXT: apply [[DYN_CALL_1]]
+// CHECK: [[DYN_CALL_2:%.*]] = function_ref @$s26dynamic_callable_attribute8CallableV15dynamicallyCall13withArgumentsySaySiG_tF
+// CHECK-NEXT: apply [[DYN_CALL_2]]
+// CHECK: [[DYN_CALL_3:%.*]] = function_ref @$s26dynamic_callable_attribute8CallableV15dynamicallyCall20withKeywordArgumentsys13KeyValuePairsVySSSiG_tF
diff --git a/test/SILGen/dynamically_replaceable.swift b/test/SILGen/dynamically_replaceable.swift
new file mode 100644
index 0000000..ffff84d
--- /dev/null
+++ b/test/SILGen/dynamically_replaceable.swift
@@ -0,0 +1,273 @@
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -swift-version 5 %s | %FileCheck %s
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -swift-version 5 %s -enable-implicit-dynamic | %FileCheck %s --check-prefix=IMPLICIT
+
+// CHECK-LABEL: sil hidden @$s23dynamically_replaceable014maybe_dynamic_B0yyF : $@convention(thin) () -> () {
+// IMPLICIT-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable014maybe_dynamic_B0yyF : $@convention(thin) () -> () {
+func maybe_dynamic_replaceable() {
+}
+
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable08dynamic_B0yyF : $@convention(thin) () -> () {
+dynamic func dynamic_replaceable() {
+}
+
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable6StruktV1xACSi_tcfC : $@convention(method) (Int, @thin Strukt.Type) -> Strukt
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable6StruktV08dynamic_B0yyF : $@convention(method) (Strukt) -> () {
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable6StruktV08dynamic_B4_varSivg
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable6StruktV08dynamic_B4_varSivs
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable6StruktVyS2icig : $@convention(method) (Int, Strukt) -> Int
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable6StruktVyS2icis : $@convention(method) (Int, Int, @inout Strukt) -> ()
+struct Strukt {
+  dynamic init(x: Int) {
+  }
+  dynamic func dynamic_replaceable() {
+  }
+
+  dynamic var dynamic_replaceable_var : Int {
+    get {
+      return 10
+    }
+    set {
+    }
+  }
+
+  dynamic subscript(x : Int) -> Int {
+    get {
+      return 10
+    }
+    set {
+    }
+  }
+}
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable5KlassC1xACSi_tcfC : $@convention(method) (Int, @thick Klass.Type) -> @owned Klass
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable5KlassC08dynamic_B0yyF : $@convention(method) (@guaranteed Klass) -> () {
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable5KlassC08dynamic_B4_varSivg
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable5KlassC08dynamic_B4_varSivs
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable5KlassCyS2icig : $@convention(method) (Int, @guaranteed Klass) -> Int
+// CHECK_LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable5KlassCyS2icis : $@convention(method) (Int, Int, @guaranteed Klass) -> ()
+class Klass {
+  dynamic init(x: Int) {
+  }
+  dynamic func dynamic_replaceable() {
+  }
+  dynamic func dynamic_replaceable2() {
+  }
+  dynamic var dynamic_replaceable_var : Int {
+    get {
+      return 10
+    }
+    set {
+    }
+  }
+  dynamic subscript(x : Int) -> Int {
+    get {
+      return 10
+    }
+    set {
+    }
+  }
+}
+
+// CHECK-LABEL: sil hidden [dynamically_replacable] @$s23dynamically_replaceable6globalSivg : $@convention(thin) () -> Int {
+dynamic var global : Int {
+  return 1
+}
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable08dynamic_B0yyF"] @$s23dynamically_replaceable11replacementyyF : $@convention(thin) () -> () {
+@_dynamicReplacement(for: dynamic_replaceable())
+func replacement() {
+}
+
+extension Klass {
+  // Calls to the replaced function inside the replacing function should be
+  // statically dispatched.
+
+  // CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable5KlassC08dynamic_B0yyF"] @$s23dynamically_replaceable5KlassC11replacementyyF : $@convention(method) (@guaranteed Klass) -> () {
+  // CHECK: [[FN:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable5KlassC11replacementyyF
+  // CHECK: apply [[FN]](%0) : $@convention(method) (@guaranteed Klass) -> ()
+  // CHECK: [[METHOD:%.*]] = class_method %0 : $Klass, #Klass.dynamic_replaceable2!1
+  // CHECK: = apply [[METHOD]](%0) : $@convention(method) (@guaranteed Klass) -> ()
+  // CHECK: return
+  @_dynamicReplacement(for: dynamic_replaceable())
+  func replacement() {
+    dynamic_replaceable()
+    dynamic_replaceable2()
+  }
+
+  // CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable5KlassC1xACSi_tcfC"] @$s23dynamically_replaceable5KlassC1yACSi_tcfC : $@convention(method) (Int, @thick Klass.Type) -> @owned Klass {
+  // CHECK:  [[FUN:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable5KlassC1yACSi_tcfC
+  // CHECK:  apply [[FUN]]({{.*}}, %1)
+  @_dynamicReplacement(for: init(x:))
+  convenience init(y: Int) {
+    self.init(x: y + 1)
+  }
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable5KlassC08dynamic_B4_varSivg"] @$s23dynamically_replaceable5KlassC1rSivg : $@convention(method) (@guaranteed Klass) -> Int {
+// CHECK: bb0([[ARG:%.*]] : @guaranteed $Klass):
+// CHECK:   [[ORIG:%.*]] = prev_dynamic_function_ref  @$s23dynamically_replaceable5KlassC1rSivg
+// CHECK:   apply [[ORIG]]([[ARG]]) : $@convention(method) (@guaranteed Klass) -> Int
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable5KlassC08dynamic_B4_varSivs"] @$s23dynamically_replaceable5KlassC1rSivs : $@convention(method) (Int, @guaranteed Klass) -> () {
+// CHECK: bb0({{.*}} : @trivial $Int, [[SELF:%.*]] : @guaranteed $Klass):
+// CHECK:   [[ORIG:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable5KlassC1rSivs
+// CHECK:   apply [[ORIG]]({{.*}}, [[SELF]]) : $@convention(method)
+  @_dynamicReplacement(for: dynamic_replaceable_var)
+  var r : Int {
+    get {
+      return dynamic_replaceable_var + 1
+    }
+    set {
+      dynamic_replaceable_var = newValue + 1
+    }
+  }
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable5KlassCyS2icig"] @$s23dynamically_replaceable5KlassC1xS2i_tcig
+// CHECK: bb0({{.*}} : @trivial $Int, [[SELF:%.*]] : @guaranteed $Klass):
+// CHECK:   [[ORIG:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable5KlassC1xS2i_tcig
+// CHECK:   apply [[ORIG]]({{.*}}, [[SELF]]) : $@convention(method) (Int, @guaranteed Klass) -> Int
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable5KlassCyS2icis"] @$s23dynamically_replaceable5KlassC1xS2i_tcis
+// CHECK: bb0({{.*}} : @trivial $Int, {{.*}} : @trivial $Int, [[SELF:%.*]] : @guaranteed $Klass):
+// CHECK:   [[ORIG:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable5KlassC1xS2i_tcis
+// CHECK:   apply [[ORIG]]({{.*}}, {{.*}}, [[SELF]]) : $@convention(method) (Int, Int, @guaranteed Klass) -> ()
+
+  @_dynamicReplacement(for: subscript(_:))
+  subscript(x y: Int) -> Int {
+    get {
+      return self[y]
+    }
+    set {
+      self[y] = newValue
+    }
+  }
+}
+
+extension Strukt {
+
+  // CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable6StruktV08dynamic_B0yyF"] @$s23dynamically_replaceable6StruktV11replacementyyF : $@convention(method) (Strukt) -> () {
+  // CHECK:   [[FUN:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable6StruktV11replacementyyF
+  // CHECK:   apply [[FUN]](%0) : $@convention(method) (Strukt) -> ()
+  @_dynamicReplacement(for: dynamic_replaceable())
+  func replacement() {
+    dynamic_replaceable()
+  }
+  // CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable6StruktV1xACSi_tcfC"] @$s23dynamically_replaceable6StruktV1yACSi_tcfC : $@convention(method) (Int, @thin Strukt.Type) -> Strukt {
+  // CHECK: [[FUN:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable6StruktV1yACSi_tcfC
+  // CHECK: apply [[FUN]]({{.*}}, %1)
+  @_dynamicReplacement(for: init(x:))
+  init(y: Int) {
+    self.init(x: y + 1)
+  }
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable6StruktV08dynamic_B4_varSivg"] @$s23dynamically_replaceable6StruktV1rSivg
+// CHECK: bb0([[ARG:%.*]] : @trivial $Strukt):
+// CHECK:   [[ORIG:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable6StruktV1rSivg
+// CHECK:   apply [[ORIG]]([[ARG]]) : $@convention(method) (Strukt) -> Int
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable6StruktV08dynamic_B4_varSivs"] @$s23dynamically_replaceable6StruktV1rSivs
+// CHECK: bb0({{.*}} : @trivial $Int, [[ARG:%.*]] : @trivial $*Strukt):
+// CHECK:   [[BA:%.*]] = begin_access [modify] [unknown] [[ARG]] : $*Strukt
+// CHECK:   [[ORIG:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable6StruktV1rSivs
+// CHECK:   apply [[ORIG]]({{.*}}, [[BA]]) : $@convention(method) (Int, @inout Strukt) -> ()
+// CHECK:   end_access [[BA]] : $*Strukt
+  @_dynamicReplacement(for: dynamic_replaceable_var)
+  var r : Int {
+    get {
+      return dynamic_replaceable_var + 1
+    }
+    set {
+      dynamic_replaceable_var = newValue + 1
+    }
+  }
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable6StruktVyS2icig"] @$s23dynamically_replaceable6StruktV1xS2i_tcig
+// CHECK: bb0({{.*}} : @trivial $Int, [[SELF:%.*]] : @trivial $Strukt):
+// CHECK:   [[ORIG:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable6StruktV1xS2i_tcig
+// CHECK:   apply [[ORIG]]({{.*}}, [[SELF]]) : $@convention(method) (Int, Strukt) -> Int
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable6StruktVyS2icis"] @$s23dynamically_replaceable6StruktV1xS2i_tcis
+// CHECK: bb0({{.*}} : @trivial $Int, {{.*}} : @trivial $Int, [[SELF:%.*]] : @trivial $*Strukt):
+// CHECK:   [[BA:%.*]] = begin_access [modify] [unknown] [[SELF]] : $*Strukt
+// CHECK:   [[ORIG:%.*]] = prev_dynamic_function_ref @$s23dynamically_replaceable6StruktV1xS2i_tcis
+// CHECK:   apply [[ORIG]]({{.*}}, {{.*}}, [[BA]]) : $@convention(method) (Int, Int, @inout Strukt) -> ()
+// CHECK:   end_access [[BA]] : $*Strukt
+
+ @_dynamicReplacement(for: subscript(_:))
+ subscript(x y: Int) -> Int {
+    get {
+      return self[y]
+    }
+    set {
+      self[y] = newValue
+    }
+  }
+}
+
+
+struct GenericS<T> {
+  dynamic init(x: Int) {
+  }
+  dynamic func dynamic_replaceable() {
+  }
+
+  dynamic var dynamic_replaceable_var : Int {
+    get {
+      return 10
+    }
+    set {
+    }
+  }
+
+  dynamic subscript(x : Int) -> Int {
+    get {
+      return 10
+    }
+    set {
+    }
+  }
+}
+
+extension GenericS {
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable8GenericSV08dynamic_B0yyF"] @$s23dynamically_replaceable8GenericSV11replacementyyF
+// CHECK: prev_dynamic_function_ref @$s23dynamically_replaceable8GenericSV11replacementyyF
+  @_dynamicReplacement(for: dynamic_replaceable())
+  func replacement() {
+    dynamic_replaceable()
+  }
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable8GenericSV1xACyxGSi_tcfC"] @$s23dynamically_replaceable8GenericSV1yACyxGSi_tcfC
+// CHECK: prev_dynamic_function_ref @$s23dynamically_replaceable8GenericSV1yACyxGSi_tcfC
+  @_dynamicReplacement(for: init(x:))
+  init(y: Int) {
+    self.init(x: y + 1)
+  }
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable8GenericSV08dynamic_B4_varSivg"] @$s23dynamically_replaceable8GenericSV1rSivg
+// CHECK: prev_dynamic_function_ref @$s23dynamically_replaceable8GenericSV1rSivg
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable8GenericSV08dynamic_B4_varSivs"] @$s23dynamically_replaceable8GenericSV1rSivs
+// CHECK: prev_dynamic_function_ref @$s23dynamically_replaceable8GenericSV1rSivs
+  @_dynamicReplacement(for: dynamic_replaceable_var)
+  var r : Int {
+    get {
+      return dynamic_replaceable_var + 1
+    }
+    set {
+      dynamic_replaceable_var = newValue + 1
+    }
+  }
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable8GenericSVyS2icig"] @$s23dynamically_replaceable8GenericSV1xS2i_tcig
+// CHECK: prev_dynamic_function_ref @$s23dynamically_replaceable8GenericSV1xS2i_tcig
+
+// CHECK-LABEL: sil hidden [dynamic_replacement_for "$s23dynamically_replaceable8GenericSVyS2icis"] @$s23dynamically_replaceable8GenericSV1xS2i_tcis
+// CHECK: prev_dynamic_function_ref @$s23dynamically_replaceable8GenericSV1xS2i_tcis
+ @_dynamicReplacement(for: subscript(_:))
+ subscript(x y: Int) -> Int {
+    get {
+      return self[y]
+    }
+    set {
+      self[y] = newValue
+    }
+  }
+}
diff --git a/test/SILGen/errors.swift b/test/SILGen/errors.swift
index 524c194..668c58d 100644
--- a/test/SILGen/errors.swift
+++ b/test/SILGen/errors.swift
@@ -694,45 +694,6 @@
 // CHECK-NEXT: throw [[ERROR]]
 // CHECK: } // end sil function '$s6errors16supportStructure_4nameyAA6BridgeVz_SStKF'
 
-struct OwnedBridge {
-  var owner : AnyObject
-  subscript(name: String) -> Pylon {
-    addressWithOwner { return (someValidPointer(), owner) }
-    mutableAddressWithOwner { return (someValidPointer(), owner) }
-  }
-}
-func supportStructure(_ b: inout OwnedBridge, name: String) throws {
-  try b[name].support()
-}
-// CHECK:    sil hidden @$s6errors16supportStructure_4nameyAA11OwnedBridgeVz_SStKF :
-// CHECK:    bb0([[ARG1:%.*]] : @trivial $*OwnedBridge, [[ARG2:%.*]] : @guaranteed $String):
-// CHECK:      [[ARG2_COPY:%.*]] = copy_value [[ARG2]] : $String
-// CHECK:      [[WRITE:%.*]] = begin_access [modify] [unknown] %0 : $*OwnedBridge
-// CHECK-NEXT: // function_ref
-// CHECK-NEXT: [[ADDRESSOR:%.*]] = function_ref @$s6errors11OwnedBridgeVyAA5PylonVSSciaO :
-// CHECK-NEXT: [[T0:%.*]] = apply [[ADDRESSOR]]([[ARG2_COPY]], [[WRITE]])
-// CHECK-NEXT: ([[T1:%.*]], [[OWNER:%.*]]) = destructure_tuple [[T0]]
-// CHECK-NEXT: [[T3:%.*]] = struct_extract [[T1]]
-// CHECK-NEXT: [[T4:%.*]] = pointer_to_address [[T3]]
-// CHECK-NEXT: [[T5:%.*]] = mark_dependence [[T4]] : $*Pylon on [[OWNER]]
-// CHECK-NEXT: [[ACCESS:%.*]] = begin_access [modify] [unsafe] [[T5]] : $*Pylon
-// CHECK:      [[SUPPORT:%.*]] = function_ref @$s6errors5PylonV7supportyyKF
-// CHECK-NEXT: try_apply [[SUPPORT]]([[ACCESS]]) : {{.*}}, normal [[BB_NORMAL:bb[0-9]+]], error [[BB_ERROR:bb[0-9]+]]
-// CHECK:    [[BB_NORMAL]]
-// CHECK-NEXT: end_access [[ACCESS]] : $*Pylon
-// CHECK-NEXT: end_access [[WRITE]]
-// CHECK-NEXT: destroy_value [[OWNER]] : $AnyObject
-// CHECK-NEXT: destroy_value [[ARG2_COPY]] : $String
-// CHECK-NEXT: tuple ()
-// CHECK-NEXT: return
-// CHECK:    [[BB_ERROR]]([[ERROR:%.*]] : @owned $Error):
-// CHECK-NEXT: end_access [[ACCESS]] : $*Pylon
-// CHECK-NEXT: destroy_value [[OWNER]] : $AnyObject
-// CHECK-NEXT: end_access [[WRITE]]
-// CHECK-NEXT: destroy_value [[ARG2_COPY]] : $String
-// CHECK-NEXT: throw [[ERROR]]
-// CHECK: } // end sil function '$s6errors16supportStructure_4nameyAA11OwnedBridgeVz_SStKF'
-
 // ! peepholes its argument with getSemanticsProvidingExpr().
 // Test that that doesn't look through try!.
 // rdar://21515402
diff --git a/test/SILGen/existential_metatypes.swift b/test/SILGen/existential_metatypes.swift
index 208dfbd..2e3d5f3 100644
--- a/test/SILGen/existential_metatypes.swift
+++ b/test/SILGen/existential_metatypes.swift
@@ -3,7 +3,9 @@
 @_semantics("typechecker.type(of:)")
 public func type<T, Metatype>(of value: T) -> Metatype {}
 
-struct Value {}
+struct Value {
+  func method() {}
+}
 
 protocol P {
   init()
@@ -73,3 +75,18 @@
   var type: P.Type = S.self
   return type.value
 }
+
+// rdar://45956703
+// CHECK-LABEL: sil hidden @$s21existential_metatypes31getterResultStaticStorageAccessyyF
+var _type: P.Type { get {return S.self } set {} }
+func getterResultStaticStorageAccess() {
+  // CHECK:      [[GET_TYPE:%.*]] = function_ref @$s21existential_metatypes5_typeAA1P_pXpvg
+  // CHECK-NEXT: [[TYPE:%.*]] = apply [[GET_TYPE]]() : $@convention(thin) () -> @thick P.Type
+  // CHECK-NEXT: [[OPEN:%.*]] = open_existential_metatype [[TYPE]] : $@thick P.Type to $@thick ([[ARCHETYPE:@opened(.*) P]]).Type
+  // CHECK-NEXT: [[GET_VALUE:%.*]] = witness_method $[[ARCHETYPE]], #P.value!getter
+  // CHECK-NEXT: [[VALUE:%.*]] = apply [[GET_VALUE]]<[[ARCHETYPE]]>([[OPEN]])
+  // CHECK-NEXT: // function_ref
+  // CHECK-NEXT: [[METHOD:%.*]] = function_ref @$s21existential_metatypes5ValueV6methodyyF
+  // CHECK-NEXT: apply [[METHOD]]([[VALUE]])
+  _type.value.method()
+}
diff --git a/test/SILGen/expressions.swift b/test/SILGen/expressions.swift
index ccc9ead..0b2386e 100644
--- a/test/SILGen/expressions.swift
+++ b/test/SILGen/expressions.swift
@@ -631,20 +631,21 @@
 // CHECK: bb0(%0 : @trivial $*NonTrivialStruct, %1 : @guaranteed $WritableKeyPath<NonTrivialStruct, Int>):
 // CHECK-NEXT: debug_value_addr %0
 // CHECK-NEXT: debug_value %1
+// CHECK-NEXT: [[KP_TEMP:%[0-9]+]] = copy_value %1
 // CHECK-NEXT: [[S_READ:%[0-9]+]] = begin_access [read] [unknown] %0
+// CHECK-NEXT: [[KP:%[0-9]+]] = upcast [[KP_TEMP]]
 // CHECK-NEXT: [[S_TEMP:%[0-9]+]] = alloc_stack $NonTrivialStruct
 // CHECK-NEXT: copy_addr [[S_READ]] to [initialization] [[S_TEMP]]
-// CHECK-NEXT: [[KP_TEMP:%[0-9]+]] = copy_value %1
-// CHECK-NEXT: [[KP:%[0-9]+]] = upcast [[KP_TEMP]]
-// CHECK-NEXT: [[RESULT:%[0-9]+]] = alloc_stack $Int
 // CHECK-NEXT: // function_ref
-// CHECK-NEXT: [[PROJECT_FN:%[0-9]+]] = function_ref @$ss23_projectKeyPathReadOnly{{[_0-9a-zA-Z]*}}F
+// CHECK-NEXT: [[PROJECT_FN:%[0-9]+]] = function_ref @swift_getAtKeyPath :
+// CHECK-NEXT: [[RESULT:%[0-9]+]] = alloc_stack $Int
 // CHECK-NEXT: apply [[PROJECT_FN]]<NonTrivialStruct, Int>([[RESULT]], [[S_TEMP]], [[KP]])
+// CHECK-NEXT: load [trivial] [[RESULT]]
 // CHECK-NEXT: end_access [[S_READ]]
 // CHECK-NEXT: dealloc_stack [[RESULT]]
-// CHECK-NEXT: destroy_value [[KP]]
 // CHECK-NEXT: destroy_addr [[S_TEMP]]
 // CHECK-NEXT: dealloc_stack [[S_TEMP]]
+// CHECK-NEXT: destroy_value [[KP]]
 // CHECK-NEXT: [[METATYPE:%[0-9]+]] = metatype $@thin Int.Type
 // CHECK-NOT: destroy_value %1
 // CHECK-NEXT: return [[METATYPE]]
diff --git a/test/SILGen/functions.swift b/test/SILGen/functions.swift
index 0f56fdc..ead4e21 100644
--- a/test/SILGen/functions.swift
+++ b/test/SILGen/functions.swift
@@ -1,4 +1,3 @@
-
 // RUN: %target-swift-emit-silgen -module-name functions -Xllvm -sil-full-demangle -parse-stdlib -parse-as-library -enable-sil-ownership %s | %FileCheck %s
 
 import Swift // just for Optional
@@ -422,27 +421,6 @@
 @inline(never)
 func noinline_callee() {}
 
-// CHECK-LABEL: sil hidden [always_inline] @$s9functions20always_inline_calleeyyF : $@convention(thin) () -> ()
-@inline(__always)
-func always_inline_callee() {}
-
-// CHECK-LABEL: sil [serialized] [always_inline] @$s9functions27public_always_inline_calleeyyF : $@convention(thin) () -> ()
-@inline(__always)
-public func public_always_inline_callee() {}
-
-protocol AlwaysInline {
-  func alwaysInlined()
-}
-
-// CHECK-LABEL: sil hidden [always_inline] @$s9functions19AlwaysInlinedMemberV06alwaysC0{{[_0-9a-zA-Z]*}}F : $@convention(method) (AlwaysInlinedMember) -> () {
-
-// protocol witness for functions.AlwaysInline.alwaysInlined <A : functions.AlwaysInline>(functions.AlwaysInline.Self)() -> () in conformance functions.AlwaysInlinedMember : functions.AlwaysInline in functions
-// CHECK-LABEL: sil private [transparent] [thunk] [always_inline] @$s9functions19AlwaysInlinedMemberVAA0B6InlineA2aDP06alwaysC0{{[_0-9a-zA-Z]*}}FTW : $@convention(witness_method: AlwaysInline) (@in_guaranteed AlwaysInlinedMember) -> () {
-struct AlwaysInlinedMember : AlwaysInline {
-  @inline(__always)
-  func alwaysInlined() {}
-}
-
 // CHECK-LABEL: sil hidden [Onone] @$s9functions10onone_funcyyF : $@convention(thin) () -> ()
 @_optimize(none)
 func onone_func() {}
diff --git a/test/SILGen/inlinable_attribute.swift b/test/SILGen/inlinable_attribute.swift
index 1ddec0c..619071b 100644
--- a/test/SILGen/inlinable_attribute.swift
+++ b/test/SILGen/inlinable_attribute.swift
@@ -129,3 +129,21 @@
 
 // CHECK-LABEL: sil private @$s19inlinable_attribute21PrivateDerivedFromUFI{{.+}}LLC5horseAdA5HorseC_tcfc : $@convention(method) (@owned Horse, @owned PrivateDerivedFromUFI) -> @owned PrivateDerivedFromUFI
 private class PrivateDerivedFromUFI : UFIBase {}
+
+// Make sure that nested functions are also serializable.
+
+// CHECK-LABEL: sil [serialized] @$s19inlinable_attribute3basyyF
+@inlinable
+public func bas() {
+  // CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3basyyF3zimL_yyF
+  func zim() {
+    // CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3basyyF3zimL_yyF4zangL_yyF
+    func zang() { }
+  }
+
+  // CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3bas{{[_0-9a-zA-Z]*}}U_
+  let zung = {
+    // CHECK-LABEL: sil shared [serialized] @$s19inlinable_attribute3basyyFyycfU_7zippityL_yyF
+    func zippity() { }
+  }
+}
diff --git a/test/SILGen/keypath_application.swift b/test/SILGen/keypath_application.swift
index 85e9dcd..83dcad1 100644
--- a/test/SILGen/keypath_application.swift
+++ b/test/SILGen/keypath_application.swift
@@ -12,34 +12,99 @@
               kp: KeyPath<A, B>,
               wkp: WritableKeyPath<A, B>,
               rkp: ReferenceWritableKeyPath<A, B>) {
+  // CHECK: [[ROOT_COPY:%.*]] = copy_value [[READONLY:%0]] :
+  // CHECK: [[KP_COPY:%.*]] = copy_value [[KP:%3]]
   // CHECK: [[ROOT_TMP:%.*]] = alloc_stack $A
-  // CHECK: [[ROOT_COPY:%.*]] = copy_value %0
   // CHECK: store [[ROOT_COPY]] to [init] [[ROOT_TMP]]
-  // CHECK: [[KP_COPY:%.*]] = copy_value %3
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: [[GET:%.*]] = function_ref @swift_getAtKeyPath :
   // CHECK: [[RESULT_TMP:%.*]] = alloc_stack $B
-  // CHECK: apply [[PROJECT]]<A, B>([[RESULT_TMP]], [[ROOT_TMP]], [[KP_COPY]])
+  // CHECK: apply [[GET]]<A, B>([[RESULT_TMP]], [[ROOT_TMP]], [[KP_COPY]])
   // CHECK: [[RESULT:%.*]] = load [take] [[RESULT_TMP]]
   // CHECK: destroy_value [[RESULT]]
   _ = readonly[keyPath: kp]
+
+  // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[WRITABLE:%1]] :
+  // CHECK: [[ROOT_COPY:%.*]] = load [copy] [[ACCESS]]
+  // CHECK: end_access [[ACCESS]]
+  // CHECK: [[KP_COPY:%.*]] = copy_value [[KP]]
+  // CHECK: [[ROOT_TMP:%.*]] = alloc_stack $A
+  // CHECK: store [[ROOT_COPY]] to [init] [[ROOT_TMP]]
+  // CHECK: [[GET:%.*]] = function_ref @swift_getAtKeyPath :
+  // CHECK: [[RESULT_TMP:%.*]] = alloc_stack $B
+  // CHECK: apply [[GET]]<A, B>([[RESULT_TMP]], [[ROOT_TMP]], [[KP_COPY]])
+  // CHECK: [[RESULT:%.*]] = load [take] [[RESULT_TMP]]
+  // CHECK: destroy_value [[RESULT]]
   _ = writable[keyPath: kp]
+
+  // CHECK: [[ROOT_COPY:%.*]] = copy_value [[READONLY]] :
+  // CHECK: [[KP_COPY:%.*]] = copy_value [[WKP:%4]]
+  // CHECK: [[KP_UPCAST:%.*]] = upcast [[KP_COPY]] : $WritableKeyPath<A, B> to $KeyPath<A, B>
+  // CHECK: [[ROOT_TMP:%.*]] = alloc_stack $A
+  // CHECK: store [[ROOT_COPY]] to [init] [[ROOT_TMP]]
+  // CHECK: [[GET:%.*]] = function_ref @swift_getAtKeyPath :
+  // CHECK: [[RESULT_TMP:%.*]] = alloc_stack $B
+  // CHECK: apply [[GET]]<A, B>([[RESULT_TMP]], [[ROOT_TMP]], [[KP_UPCAST]])
+  // CHECK: [[RESULT:%.*]] = load [take] [[RESULT_TMP]]
+  // CHECK: destroy_value [[RESULT]]
   _ = readonly[keyPath: wkp]
 
-  // CHECK: function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath
   _ = writable[keyPath: wkp]
 
-  // CHECK: function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath
   _ = readonly[keyPath: rkp]
-  // CHECK: function_ref @{{.*}}_projectKeyPathReadOnly
+
+  // CHECK: function_ref @swift_getAtKeyPath
   _ = writable[keyPath: rkp]
 
-  // CHECK: function_ref @{{.*}}_projectKeyPathWritable
+
+  // CHECK:      [[KP_COPY:%.*]] = copy_value [[WKP]]
+  // CHECK-NEXT: [[VALUE_COPY:%.*]] = copy_value [[VALUE:%2]] : $B
+  // CHECK-NEXT: [[ACCESS:%.*]] = begin_access [modify] [unknown] [[WRITABLE]] :
+  // CHECK-NEXT: [[VALUE_TEMP:%.*]] = alloc_stack $B
+  // CHECK-NEXT: store [[VALUE_COPY]] to [init] [[VALUE_TEMP]]
+  // CHECK-NEXT: // function_ref
+  // CHECK-NEXT: [[SET:%.*]] = function_ref @swift_setAtWritableKeyPath :
+  // CHECK-NEXT: apply [[SET]]<A, B>([[ACCESS]], [[KP_COPY]], [[VALUE_TEMP]])
+  // CHECK-NEXT: end_access [[ACCESS]]
+  // CHECK-NEXT: dealloc_stack [[VALUE_TEMP]]
+  // CHECK-NEXT: destroy_value [[KP_COPY]]
   writable[keyPath: wkp] = value
-  // CHECK: function_ref @{{.*}}_projectKeyPathReferenceWritable
+
+  // CHECK-NEXT: [[ROOT_COPY:%.*]] = copy_value [[READONLY]] :
+  // CHECK-NEXT: [[KP_COPY:%.*]] = copy_value [[RKP:%5]]
+  // CHECK-NEXT: [[VALUE_COPY:%.*]] = copy_value [[VALUE]] : $B
+  // CHECK-NEXT: [[ROOT_TEMP:%.*]] = alloc_stack $A
+  // CHECK-NEXT: store [[ROOT_COPY]] to [init] [[ROOT_TEMP]]
+  // CHECK-NEXT: [[VALUE_TEMP:%.*]] = alloc_stack $B
+  // CHECK-NEXT: store [[VALUE_COPY]] to [init] [[VALUE_TEMP]]
+  // CHECK-NEXT: // function_ref
+  // CHECK-NEXT: [[SET:%.*]] = function_ref @swift_setAtReferenceWritableKeyPath :
+  // CHECK-NEXT: apply [[SET]]<A, B>([[ROOT_TEMP]], [[KP_COPY]], [[VALUE_TEMP]])
+  // CHECK-NEXT: dealloc_stack [[VALUE_TEMP]]
+  // CHECK-NEXT: destroy_addr [[ROOT_TEMP]]
+  // CHECK-NEXT: dealloc_stack [[ROOT_TEMP]]
+  // CHECK-NEXT: destroy_value [[KP_COPY]]
   readonly[keyPath: rkp] = value
-  // CHECK: function_ref @{{.*}}_projectKeyPathReferenceWritable
+
+  // CHECK-NEXT: [[ACCESS:%.*]] = begin_access [read] [unknown] [[WRITABLE]] :
+  // CHECK-NEXT: [[ROOT_COPY:%.*]] = load [copy] [[ACCESS]] :
+  // CHECK-NEXT: end_access [[ACCESS]]
+  // CHECK-NEXT: [[KP_COPY:%.*]] = copy_value [[RKP:%5]]
+  // CHECK-NEXT: [[VALUE_COPY:%.*]] = copy_value [[VALUE]] : $B
+  // CHECK-NEXT: [[ROOT_TEMP:%.*]] = alloc_stack $A
+  // CHECK-NEXT: store [[ROOT_COPY]] to [init] [[ROOT_TEMP]]
+  // CHECK-NEXT: [[VALUE_TEMP:%.*]] = alloc_stack $B
+  // CHECK-NEXT: store [[VALUE_COPY]] to [init] [[VALUE_TEMP]]
+  // CHECK-NEXT: // function_ref
+  // CHECK-NEXT: [[SET:%.*]] = function_ref @swift_setAtReferenceWritableKeyPath :
+  // CHECK-NEXT: apply [[SET]]<A, B>([[ROOT_TEMP]], [[KP_COPY]], [[VALUE_TEMP]])
+  // CHECK-NEXT: dealloc_stack [[VALUE_TEMP]]
+  // CHECK-NEXT: destroy_addr [[ROOT_TEMP]]
+  // CHECK-NEXT: dealloc_stack [[ROOT_TEMP]]
+  // CHECK-NEXT: destroy_value [[KP_COPY]]
   writable[keyPath: rkp] = value
-}
+} // CHECK-LABEL: } // end sil function '{{.*}}loadable
 
 // CHECK-LABEL: sil hidden @{{.*}}addressOnly
 func addressOnly(readonly: P, writable: inout P,
@@ -47,26 +112,26 @@
                  kp: KeyPath<P, Q>,
                  wkp: WritableKeyPath<P, Q>,
                  rkp: ReferenceWritableKeyPath<P, Q>) {
-  // CHECK: function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = readonly[keyPath: kp]
-  // CHECK: function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = writable[keyPath: kp]
-  // CHECK: function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = readonly[keyPath: wkp]
 
-  // CHECK: function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = writable[keyPath: wkp]
 
-  // CHECK: function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = readonly[keyPath: rkp]
-  // CHECK: function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = writable[keyPath: rkp]
 
-  // CHECK: function_ref @{{.*}}_projectKeyPathWritable
+  // CHECK: function_ref @swift_setAtWritableKeyPath :
   writable[keyPath: wkp] = value
-  // CHECK: function_ref @{{.*}}_projectKeyPathReferenceWritable
+  // CHECK: function_ref @swift_setAtReferenceWritableKeyPath :
   readonly[keyPath: rkp] = value
-  // CHECK: function_ref @{{.*}}_projectKeyPathReferenceWritable
+  // CHECK: function_ref @swift_setAtReferenceWritableKeyPath :
   writable[keyPath: rkp] = value
 }
 
@@ -77,26 +142,26 @@
                   kp: KeyPath<() -> (), (A) -> B>,
                   wkp: WritableKeyPath<() -> (), (A) -> B>,
                   rkp: ReferenceWritableKeyPath<() -> (), (A) -> B>) {
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = readonly[keyPath: kp]
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = writable[keyPath: kp]
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = readonly[keyPath: wkp]
 
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = writable[keyPath: wkp]
 
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = readonly[keyPath: rkp]
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathReadOnly
+  // CHECK: function_ref @swift_getAtKeyPath :
   _ = writable[keyPath: rkp]
 
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathWritable
+  // CHECK: function_ref @swift_setAtWritableKeyPath :
   writable[keyPath: wkp] = value
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathReferenceWritable
+  // CHECK: function_ref @swift_setAtReferenceWritableKeyPath :
   readonly[keyPath: rkp] = value
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}_projectKeyPathReferenceWritable
+  // CHECK: function_ref @swift_setAtReferenceWritableKeyPath :
   writable[keyPath: rkp] = value
 }
 
@@ -106,17 +171,17 @@
                 pkpA: PartialKeyPath<A>,
                 pkpB: PartialKeyPath<Int>,
                 akp: AnyKeyPath) {
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}projectKeyPathAny
+  // CHECK: [[PROJECT:%.*]] = function_ref @swift_getAtAnyKeyPath :
   // CHECK: apply [[PROJECT]]<A>
   _ = valueA[keyPath: akp]
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}projectKeyPathPartial
+  // CHECK: [[PROJECT:%.*]] = function_ref @swift_getAtPartialKeyPath :
   // CHECK: apply [[PROJECT]]<A>
   _ = valueA[keyPath: pkpA]
 
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}projectKeyPathAny
+  // CHECK: [[PROJECT:%.*]] = function_ref @swift_getAtAnyKeyPath :
   // CHECK: apply [[PROJECT]]<Int>
   _ = valueB[keyPath: akp]
-  // CHECK: [[PROJECT:%.*]] = function_ref @{{.*}}projectKeyPathPartial
+  // CHECK: [[PROJECT:%.*]] = function_ref @swift_getAtPartialKeyPath :
   // CHECK: apply [[PROJECT]]<Int>
   _ = valueB[keyPath: pkpB]
 }
@@ -135,24 +200,22 @@
   // -- get 'b'
   // CHECK: function_ref @$sSi19keypath_applicationE1bSivg
   // -- apply keypath y
-  // CHECK: [[PROJECT_FN:%.*]] = function_ref @{{.*}}_projectKeyPathWritable
-  // CHECK: [[PROJECT_RET:%.*]] = apply [[PROJECT_FN]]
-  // CHECK: ({{%.*}}, [[OWNER_Y:%.*]]) = destructure_tuple [[PROJECT_RET]]
+  // CHECK: [[PROJECT_FN:%.*]] = function_ref @swift_modifyAtWritableKeyPath :
+  // CHECK: ([[Y_ADDR:%.*]], [[Y_TOKEN:%.*]]) = begin_apply [[PROJECT_FN]]<Int, Int>
   // -- get 'u'
   // CHECK: function_ref @$sSi19keypath_applicationE1uSivg
   // -- apply keypath z
-  // CHECK: [[PROJECT_FN:%.*]] = function_ref @{{.*}}_projectKeyPathWritable
-  // CHECK: [[PROJECT_RET:%.*]] = apply [[PROJECT_FN]]
-  // CHECK: ({{%.*}}, [[OWNER_Z:%.*]]) = destructure_tuple [[PROJECT_RET]]
+  // CHECK: [[PROJECT_FN:%.*]] = function_ref @swift_modifyAtWritableKeyPath :
+  // CHECK: ([[Z_ADDR:%.*]], [[Z_TOKEN:%.*]]) = begin_apply [[PROJECT_FN]]<Int, Int>
 
   // -- set 'tt'
   // CHECK: function_ref @$sSi19keypath_applicationE2ttSivs
   // -- destroy owner for keypath projection z
-  // CHECK: destroy_value [[OWNER_Z]]
+  // CHECK: end_apply [[Z_TOKEN]]
   // -- set 'u'
   // CHECK: function_ref @$sSi19keypath_applicationE1uSivs
   // -- destroy owner for keypath projection y
-  // CHECK: destroy_value [[OWNER_Y]]
+  // CHECK: end_apply [[Y_TOKEN]]
   // -- set 'b'
   // CHECK: function_ref @$sSi19keypath_applicationE1bSivs
 
diff --git a/test/SILGen/keypath_dynamic.swift b/test/SILGen/keypath_dynamic.swift
new file mode 100644
index 0000000..cb9dedb
--- /dev/null
+++ b/test/SILGen/keypath_dynamic.swift
@@ -0,0 +1,19 @@
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -module-name A %s | %FileCheck %s
+
+struct Foo {
+  var x : Int {
+    get {
+      return 1
+    }
+    set {
+    }
+  }
+
+  func foo(_ kp: WritableKeyPath<Foo, Int>) {
+  }
+
+  func test() {
+    // CHECK: keypath $WritableKeyPath<Foo, Int>, (root $Foo; settable_property $Int,  id @$s1A3FooV1xSivg
+    foo(\.x)
+  }
+}
diff --git a/test/SILGen/lifetime.swift b/test/SILGen/lifetime.swift
index 423d537..15ea1e6 100644
--- a/test/SILGen/lifetime.swift
+++ b/test/SILGen/lifetime.swift
@@ -768,15 +768,3 @@
   // CHECK-NOT: tuple_extract [[TUPLE]]
   // CHECK-NOT: destroy_value [[TUPLE]]
 }
-
-class C {
-  var v = ""
-  // CHECK-LABEL: sil hidden @$s8lifetime1CC18ignored_assignment{{[_0-9a-zA-Z]*}}F
-  func ignored_assignment() {
-    // CHECK: [[STRING:%.*]] = alloc_stack $String
-    // CHECK: [[UNINIT:%.*]] = mark_uninitialized [var] [[STRING]]
-    // CHECK: assign {{%.*}} to [[UNINIT]]
-    // CHECK: destroy_addr [[UNINIT]]
-    _ = self.v
-  }
-}
diff --git a/test/SILGen/mangling.swift b/test/SILGen/mangling.swift
index 5612665..e4e5358 100644
--- a/test/SILGen/mangling.swift
+++ b/test/SILGen/mangling.swift
@@ -98,8 +98,8 @@
 struct HasVarInit {
   static var state = true && false
 }
-// CHECK-LABEL: // function_ref implicit closure #1 : @autoclosure () throws -> Swift.Bool in variable initialization expression of static mangling.HasVarInit.state : Swift.Bool
-// CHECK-NEXT:  function_ref @$s8mangling10HasVarInitV5stateSbvpZfiSbyKXKfu_
+// CHECK-LABEL: // function_ref implicit closure #1 () throws -> Swift.Bool in variable initialization expression of static mangling.HasVarInit.state : Swift.Bool
+// CHECK-NEXT:  function_ref @$s8mangling10HasVarInitV5stateSbvpZfiSbyKXEfu_
 
 // auto_closures should not collide with the equivalent non-auto_closure
 // function type.
diff --git a/test/SILGen/nested-function-fragility.swift b/test/SILGen/nested-function-fragility.swift
deleted file mode 100644
index 5f772cc..0000000
--- a/test/SILGen/nested-function-fragility.swift
+++ /dev/null
@@ -1,63 +0,0 @@
-// RUN: %target-swift-emit-silgen -enable-sil-ownership -module-name main %s | %FileCheck %s
-internal func internalFunc() {}
-
-// CHECK-LABEL: sil @$s4main3fooyyF
-public func foo() {
-  // CHECK-LABEL: sil private [always_inline] @$s4main3foo{{[_0-9a-zA-Z]*}}zim
-  @inline(__always)
-  func zim() {
-    // CHECK-LABEL: sil private @$s4main3fooyyF3zimL_yyF4zangL_yyF
-    func zang() { internalFunc() }
-    internalFunc()
-  }
-
-  // CHECK-LABEL: sil private @$s4main3foo{{[_0-9a-zA-Z]*}}U_
-  let zung = {
-    // CHECK-LABEL: sil private [always_inline] @$s4main3fooyyFyycfU_7zippityL_yyF
-    @inline(__always)
-    func zippity() { internalFunc() }
-    internalFunc()
-  }
-}
-
-// CHECK-LABEL: sil hidden [always_inline] @$s4main3baryyF
-@inline(__always)
-internal func bar() {
-  // CHECK-LABEL: sil private [always_inline] @$s4main3baryyF3zimL_yyF
-  @inline(__always)
-  func zim() {
-    // CHECK-LABEL: sil private @$s4main3baryyF3zimL_yyF4zangL_yyF
-    func zang() { internalFunc() }
-    internalFunc()
-  }
-
-  // CHECK-LABEL: sil private @$s4main3bar{{[_0-9a-zA-Z]*}}U_
-  let zung = {
-    // CHECK-LABEL: sil private [always_inline] @$s4main3baryyFyycfU_7zippityL_yyF
-    @inline(__always)
-    func zippity() { internalFunc() }
-    internalFunc()
-  }
-}
-
-public func publicFunc() {}
-
-// CHECK-LABEL: sil [serialized] [always_inline] @$s4main3basyyF
-@inline(__always)
-public func bas() {
-  // CHECK-LABEL: sil shared [serialized] [always_inline] @$s4main3basyyF3zimL_yyF
-  @inline(__always)
-  func zim() {
-    // CHECK-LABEL: sil shared [serialized] @$s4main3basyyF3zimL_yyF4zangL_yyF
-    func zang() { publicFunc() }
-    publicFunc()
-  }
-
-  // CHECK-LABEL: sil shared [serialized] @$s4main3bas{{[_0-9a-zA-Z]*}}U_
-  let zung = {
-    // CHECK-LABEL: sil shared [serialized] [always_inline] @$s4main3basyyFyycfU_7zippityL_yyF
-    @inline(__always)
-    func zippity() { publicFunc() }
-    publicFunc()
-  }
-}
diff --git a/test/SILGen/pound_assert.swift b/test/SILGen/pound_assert.swift
new file mode 100644
index 0000000..dabe175
--- /dev/null
+++ b/test/SILGen/pound_assert.swift
@@ -0,0 +1,21 @@
+// RUN: %target-swift-frontend -enable-experimental-static-assert -emit-silgen %s | %FileCheck %s
+
+// CHECK-LABEL: sil hidden @$s12pound_assert15noCustomMessage{{[_0-9a-zA-Z]*}}
+func noCustomMessage() {
+  #assert(true)
+  // CHECK: [[GET_LOGIC_VALUE:%.*]] = function_ref {{.*}}_getBuiltinLogicValue
+  // CHECK-NEXT: [[LOGIC_VALUE:%.*]] = apply [[GET_LOGIC_VALUE]]
+  // CHECK-NEXT: [[MESSAGE:%.*]] = string_literal utf8 ""
+  // CHECK-NEXT: builtin "poundAssert"([[LOGIC_VALUE]] : $Builtin.Int1, [[MESSAGE]] : $Builtin.RawPointer)
+}
+// CHECK: } // end sil function '$s12pound_assert15noCustomMessage{{[_0-9a-zA-Z]*}}'
+
+// CHECK-LABEL: sil hidden @$s12pound_assert13customMessage{{[_0-9a-zA-Z]*}}
+func customMessage() {
+  #assert(true, "custom message")
+  // CHECK: [[GET_LOGIC_VALUE:%.*]] = function_ref {{.*}}_getBuiltinLogicValue
+  // CHECK-NEXT: [[LOGIC_VALUE:%.*]] = apply [[GET_LOGIC_VALUE]]
+  // CHECK-NEXT: [[MESSAGE:%.*]] = string_literal utf8 "custom message"
+  // CHECK-NEXT: builtin "poundAssert"([[LOGIC_VALUE]] : $Builtin.Int1, [[MESSAGE]] : $Builtin.RawPointer)
+}
+// CHECK: } // end sil function '$s12pound_assert13customMessage{{[_0-9a-zA-Z]*}}'
diff --git a/test/SILGen/private_import.swift b/test/SILGen/private_import.swift
new file mode 100644
index 0000000..a1f74c6
--- /dev/null
+++ b/test/SILGen/private_import.swift
@@ -0,0 +1,64 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-swift-frontend -module-name Mod -emit-module -enable-private-imports -enable-sil-ownership -swift-version 5 -o %t %S/Inputs/private_import_module.swift
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -I %t -primary-file %s %S/private_import_other.swift -module-name main -swift-version 5 | %FileCheck %s
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -I %t %s %S/private_import_other.swift -module-name main -swift-version 5 | %FileCheck %s
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -I %t %S/private_import_other.swift %s -module-name main -swift-version 5 | %FileCheck %s
+// RUN: %target-swift-emit-ir -enable-sil-ownership -I %t -primary-file %s %S/private_import_other.swift -module-name main -o /dev/null
+// RUN: %target-swift-emit-ir -enable-sil-ownership -I %t -O -primary-file %s %S/private_import_other.swift -module-name main -o /dev/null
+
+
+@_private(sourceFile: "private_import_module.swift") import Mod
+
+public protocol Fooable {
+  func foo()
+}
+
+struct FooImpl: Fooable, HasDefaultFoo {}
+public struct PublicFooImpl: Fooable, HasDefaultFoo {}
+
+// CHECK-LABEL: sil{{.*}} @$s4main7FooImplVAA7FooableA2aDP3fooyyFTW : $@convention(witness_method: Fooable) (@in_guaranteed FooImpl) -> () {
+// CHECK: function_ref @$s3Mod13HasDefaultFoo33_{{.*}}PAAE3fooyyF
+// CHECK: } // end sil function '$s4main7FooImplVAA7FooableA2aDP3fooyyFTW'
+
+// CHECK-LABEL: sil{{.*}} @$s4main13PublicFooImplVAA7FooableA2aDP3fooyyFTW : $@convention(witness_method: Fooable) (@in_guaranteed PublicFooImpl) -> () {
+// CHECK: function_ref @$s3Mod13HasDefaultFoo33_{{.*}}PAAE3fooyyF
+// CHECK: } // end sil function '$s4main13PublicFooImplVAA7FooableA2aDP3fooyyFTW'
+
+private class PrivateSub: Base {
+  fileprivate override func foo() {}
+}
+class Sub: Base {
+  internal override func foo() {}
+}
+public class PublicSub: Base {
+  public override func foo() {}
+}
+
+// CHECK-LABEL: sil_vtable PrivateSub {
+// CHECK-NEXT:   #Base.foo!1: {{.*}} : @$s4main10PrivateSub33_{{.*}}3fooyyF
+// CHECK-NEXT:   #Base.init!allocator.1: {{.*}} : @$s4main10PrivateSub33_{{.*}}ADycfC
+// CHECK-NEXT:   #PrivateSub.deinit!deallocator.1: @$s4main10PrivateSub33_{{.*}}fD
+// CHECK-NEXT: }
+
+// CHECK-LABEL: sil_vtable Sub {
+// CHECK-NEXT:   #Base.foo!1: {{.*}} : @$s4main3SubC3fooyyF
+// CHECK-NEXT:   #Base.init!allocator.1: {{.*}} : @$s4main3SubCACycfC
+// CHECK-NEXT:   #Sub.deinit!deallocator.1: @$s4main3SubCfD
+// CHECK-NEXT: }
+
+// CHECK-LABEL: sil_vtable [serialized] PublicSub {
+// CHECK-NEXT:   #Base.foo!1: {{.*}} : @$s4main9PublicSubC3fooyyF
+// CHECK-NEXT:   #Base.init!allocator.1: {{.*}} : @$s4main9PublicSubCACycfC
+// CHECK-NEXT:   #PublicSub.deinit!deallocator.1: @$s4main9PublicSubCfD
+// CHECK-NEXT: }
+
+
+
+// CHECK-LABEL: sil_witness_table hidden FooImpl: Fooable module main {
+// CHECK-NEXT:  method #Fooable.foo!1: {{.*}} : @$s4main7FooImplVAA7FooableA2aDP3fooyyFTW
+// CHECK-NEXT: }
+
+// CHECK-LABEL: sil_witness_table [serialized] PublicFooImpl: Fooable module main {
+// CHECK-NEXT:  method #Fooable.foo!1: {{.*}} : @$s4main13PublicFooImplVAA7FooableA2aDP3fooyyFTW
+// CHECK-NEXT: }
diff --git a/test/SILGen/private_import_other.swift b/test/SILGen/private_import_other.swift
new file mode 100644
index 0000000..93e3440
--- /dev/null
+++ b/test/SILGen/private_import_other.swift
@@ -0,0 +1,43 @@
+// RUN: %empty-directory(%t)
+
+// RUN: %target-swift-frontend -module-name Mod -emit-module -enable-private-imports -enable-sil-ownership -swift-version 5 -o %t %S/Inputs/private_import_module.swift
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -I %t -primary-file %s %S/private_import.swift -module-name main -swift-version 5 | %FileCheck %s
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -I %t %s %S/private_import.swift -module-name main -swift-version 5 | %FileCheck %s
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -I %t %S/private_import.swift %s -module-name main -swift-version 5 | %FileCheck %s
+// RUN: %target-swift-emit-ir -enable-sil-ownership -I %t -primary-file %s %S/private_import.swift -module-name main -o /dev/null
+// RUN: %target-swift-emit-ir -enable-sil-ownership -I %t -O -primary-file %s %S/private_import.swift -module-name main -o /dev/null
+
+@_private(sourceFile: "private_import_module.swift") import Mod
+
+func use<F: Fooable>(_ f: F) { f.foo() }
+func test(internalFoo: FooImpl, publicFoo: PublicFooImpl) {
+  use(internalFoo)
+  use(publicFoo)
+
+  internalFoo.foo()
+  publicFoo.foo()
+}
+
+// CHECK-LABEL: sil hidden @$s4main4test11internalFoo06publicD0yAA0D4ImplV_AA06PublicdF0VtF
+// CHECK: [[USE_1:%.+]] = function_ref @$s4main3useyyxAA7FooableRzlF
+// CHECK: = apply [[USE_1]]<FooImpl>({{%.+}}) : $@convention(thin) <τ_0_0 where τ_0_0 : Fooable> (@in_guaranteed τ_0_0) -> ()
+// CHECK: [[USE_2:%.+]] = function_ref @$s4main3useyyxAA7FooableRzlF
+// CHECK: = apply [[USE_2]]<PublicFooImpl>({{%.+}}) : $@convention(thin) <τ_0_0 where τ_0_0 : Fooable> (@in_guaranteed τ_0_0) -> ()
+// CHECK: [[IMPL_1:%.+]] = function_ref @$s3Mod13HasDefaultFoo33_{{.*}}PAAE3fooyyF
+// CHECK: = apply [[IMPL_1]]<FooImpl>({{%.+}}) : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaultFoo> (@in_guaranteed τ_0_0) -> ()
+// CHECK: [[IMPL_2:%.+]] = function_ref @$s3Mod13HasDefaultFoo33_{{.*}}PAAE3fooyyF
+// CHECK: = apply [[IMPL_2]]<PublicFooImpl>({{%.+}}) : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaultFoo> (@in_guaranteed τ_0_0) -> ()
+// CHECK: } // end sil function '$s4main4test11internalFoo06publicD0yAA0D4ImplV_AA06PublicdF0VtF'
+
+func test(internalSub: Sub, publicSub: PublicSub) {
+  internalSub.foo()
+  publicSub.foo()
+}
+
+// CHECK-LABEL: sil hidden @$s4main4test11internalSub06publicD0yAA0D0C_AA06PublicD0CtF
+// CHECK: bb0([[ARG0:%.*]] : @guaranteed $Sub, [[ARG1:%.*]] : @guaranteed $PublicSub):
+// CHECK: = class_method [[ARG0]] : $Sub, #Sub.foo!1
+// CHECK: = class_method [[ARG1]] : $PublicSub, #PublicSub.foo!1
+// CHECK: } // end sil function '$s4main4test11internalSub06publicD0yAA0D0C_AA06PublicD0CtF'
+
+
diff --git a/test/SILGen/properties.swift b/test/SILGen/properties.swift
index 18846f1..f137c36 100644
--- a/test/SILGen/properties.swift
+++ b/test/SILGen/properties.swift
@@ -1211,9 +1211,7 @@
 }
 
 // sil hidden @$s10properties19overlappingLoadExpr1cyAA13ReferenceTypeCz_tF : $@convention(thin) (@inout ReferenceType) -> () {
-// CHECK:        [[RESULT:%.*]] = alloc_stack $Int
-// CHECK-NEXT:   [[UNINIT:%.*]] = mark_uninitialized [var] [[RESULT]] : $*Int
-// CHECK-NEXT:   [[C_INOUT:%.*]] = begin_access [read] [unknown] %0 : $*ReferenceType
+// CHECK:        [[C_INOUT:%.*]] = begin_access [read] [unknown] %0 : $*ReferenceType
 // CHECK-NEXT:   [[C:%.*]] = load [copy] [[C_INOUT:%.*]] : $*ReferenceType
 // CHECK-NEXT:   end_access [[C_INOUT]] : $*ReferenceType
 // CHECK-NEXT:   [[C_BORROW:%.*]] = begin_borrow [[C]]
@@ -1231,13 +1229,11 @@
 // CHECK-NEXT:   [[GETTER:%.*]] = witness_method $@opened("{{.*}}") NonmutatingProtocol, #NonmutatingProtocol.x!getter.1 : <Self where Self : NonmutatingProtocol> (Self) -> () -> Int, [[C_FIELD_PAYLOAD]] : $*@opened("{{.*}}") NonmutatingProtocol : $@convention(witness_method: NonmutatingProtocol) <τ_0_0 where τ_0_0 : NonmutatingProtocol> (@in_guaranteed τ_0_0) -> Int
 // CHECK-NEXT:   [[RESULT_VALUE:%.*]] = apply [[GETTER]]<@opened("{{.*}}") NonmutatingProtocol>([[C_FIELD_BORROW]]) : $@convention(witness_method: NonmutatingProtocol) <τ_0_0 where τ_0_0 : NonmutatingProtocol> (@in_guaranteed τ_0_0) -> Int
 // CHECK-NEXT:   destroy_addr [[C_FIELD_BORROW]]
-// CHECK-NEXT:   assign [[RESULT_VALUE]] to [[UNINIT]] : $*Int
 // CHECK-NEXT:   destroy_addr [[C_FIELD_COPY]] : $*@opened("{{.*}}") NonmutatingProtocol
 // CHECK-NEXT:   dealloc_stack [[C_FIELD_BORROW]]
 // CHECK-NEXT:   dealloc_stack [[C_FIELD_COPY]] : $*@opened("{{.*}}") NonmutatingProtocol
 // CHECK-NEXT:   destroy_addr [[C_FIELD_BOX]] : $*NonmutatingProtocol
 // CHECK-NEXT:   dealloc_stack [[C_FIELD_BOX]] : $*NonmutatingProtocol
-// CHECK-NEXT:   dealloc_stack [[RESULT]] : $*Int
 // CHECK-NEXT:   tuple ()
 // CHECK-NEXT:   return
 
diff --git a/test/SILGen/protocol_with_superclass.swift b/test/SILGen/protocol_with_superclass.swift
index 0274907..7e694f6 100644
--- a/test/SILGen/protocol_with_superclass.swift
+++ b/test/SILGen/protocol_with_superclass.swift
@@ -245,6 +245,30 @@
 // CHECK: class_method %1 : $ClassWithDefault<Int>, #ClassWithDefault.makeT!1 : <T> (ClassWithDefault<T>) -> () -> T, $@convention(method) <τ_0_0> (@guaranteed ClassWithDefault<τ_0_0>) -> @out τ_0_0
 // CHECK: return
 
+class BaseClass : BaseProto {}
+
+protocol RefinedProto : BaseClass {}
+
+func takesBaseProtocol(_: BaseProto) {}
+
+func passesRefinedProtocol(_ r: RefinedProto) {
+  takesBaseProtocol(r)
+}
+
+// CHECK-LABEL: sil hidden @$s24protocol_with_superclass21passesRefinedProtocolyyAA0E5Proto_pF : $@convention(thin) (@guaranteed RefinedProto) -> ()
+// CHECK:     bb0(%0 : @guaranteed $RefinedProto):
+// CHECK:       [[OPENED:%.*]] = open_existential_ref %0 : $RefinedProto to $@opened("{{.*}}") RefinedProto
+// CHECK-NEXT:  [[BASE:%.*]] = alloc_stack $BaseProto
+// CHECK-NEXT:  [[BASE_PAYLOAD:%.*]] = init_existential_addr [[BASE]] : $*BaseProto, $@opened("{{.*}}") RefinedProto
+// CHECK-NEXT:  [[OPENED_COPY:%.*]] = copy_value [[OPENED]] : $@opened("{{.*}}") RefinedProto
+// CHECK-NEXT:  store [[OPENED_COPY]] to [init] [[BASE_PAYLOAD]] : $*@opened("{{.*}}") RefinedProto
+// CHECK:       [[FUNC:%.*]] = function_ref @$s24protocol_with_superclass17takesBaseProtocolyyAA0E5Proto_pF : $@convention(thin) (@in_guaranteed BaseProto) -> ()
+// CHECK-NEXT:  apply [[FUNC]]([[BASE]]) : $@convention(thin) (@in_guaranteed BaseProto) -> ()
+// CHECK-NEXT:  destroy_addr [[BASE]] : $*BaseProto
+// CHECK-NEXT:  dealloc_stack [[BASE]] : $*BaseProto
+// CHECK-NEXT:  [[RESULT:%.*]] = tuple ()
+// CHECK-NEXT:  return [[RESULT]] : $()
+
 // CHECK-LABEL: sil_witness_table hidden ConformsToSillyDefault: SillyDefault module protocol_with_superclass {
 // CHECK-NEXT: method #SillyDefault.makeT!1: <Self where Self : SillyDefault> (Self) -> () -> Int : @$s24protocol_with_superclass22ConformsToSillyDefaultCAA0fG0A2aDP5makeTSiyFTW
 // CHECK-NEXT: }
diff --git a/test/SILGen/protocol_with_superclass_where_clause.swift b/test/SILGen/protocol_with_superclass_where_clause.swift
index 8c521da..f69f671 100644
--- a/test/SILGen/protocol_with_superclass_where_clause.swift
+++ b/test/SILGen/protocol_with_superclass_where_clause.swift
@@ -245,6 +245,30 @@
 // CHECK: class_method %1 : $ClassWithDefault<Int>, #ClassWithDefault.makeT!1 : <T> (ClassWithDefault<T>) -> () -> T, $@convention(method) <τ_0_0> (@guaranteed ClassWithDefault<τ_0_0>) -> @out τ_0_0
 // CHECK: return
 
+class BaseClass : BaseProto {}
+
+protocol RefinedProto where Self : BaseClass {}
+
+func takesBaseProtocol(_: BaseProto) {}
+
+func passesRefinedProtocol(_ r: RefinedProto) {
+  takesBaseProtocol(r)
+}
+
+// CHECK-LABEL: sil hidden @$s24protocol_with_superclass21passesRefinedProtocolyyAA0E5Proto_pF : $@convention(thin) (@guaranteed RefinedProto) -> ()
+// CHECK:     bb0(%0 : @guaranteed $RefinedProto):
+// CHECK:       [[OPENED:%.*]] = open_existential_ref %0 : $RefinedProto to $@opened("{{.*}}") RefinedProto
+// CHECK-NEXT:  [[BASE:%.*]] = alloc_stack $BaseProto
+// CHECK-NEXT:  [[BASE_PAYLOAD:%.*]] = init_existential_addr [[BASE]] : $*BaseProto, $@opened("{{.*}}") RefinedProto
+// CHECK-NEXT:  [[OPENED_COPY:%.*]] = copy_value [[OPENED]] : $@opened("{{.*}}") RefinedProto
+// CHECK-NEXT:  store [[OPENED_COPY]] to [init] [[BASE_PAYLOAD]] : $*@opened("{{.*}}") RefinedProto
+// CHECK:       [[FUNC:%.*]] = function_ref @$s24protocol_with_superclass17takesBaseProtocolyyAA0E5Proto_pF : $@convention(thin) (@in_guaranteed BaseProto) -> ()
+// CHECK-NEXT:  apply [[FUNC]]([[BASE]]) : $@convention(thin) (@in_guaranteed BaseProto) -> ()
+// CHECK-NEXT:  destroy_addr [[BASE]] : $*BaseProto
+// CHECK-NEXT:  dealloc_stack [[BASE]] : $*BaseProto
+// CHECK-NEXT:  [[RESULT:%.*]] = tuple ()
+// CHECK-NEXT:  return [[RESULT]] : $()
+
 // CHECK-LABEL: sil_witness_table hidden ConformsToSillyDefault: SillyDefault module protocol_with_superclass {
 // CHECK-NEXT: method #SillyDefault.makeT!1: <Self where Self : SillyDefault> (Self) -> () -> Int : @$s24protocol_with_superclass22ConformsToSillyDefaultCAA0fG0A2aDP5makeTSiyFTW
 // CHECK-NEXT: }
diff --git a/test/SILGen/read_accessor.swift b/test/SILGen/read_accessor.swift
index 909d60a..282c87c 100644
--- a/test/SILGen/read_accessor.swift
+++ b/test/SILGen/read_accessor.swift
@@ -117,4 +117,91 @@
   func useReadable() {
     var v = readable
   }
+
+  var computed: String {
+    return compute()
+  }
+
+// CHECK-LABEL: sil hidden @$s13read_accessor11TupleReaderV0A8ComputedSSvr
+// CHECK:         [[GETTER:%.*]] = function_ref @$s13read_accessor11TupleReaderV8computedSSvg
+// CHECK-NEXT:    [[VALUE:%.]] = apply [[GETTER]](%0)
+// CHECK-NEXT:    [[BORROW:%.*]] = begin_borrow [[VALUE]] : $String
+// CHECK-NEXT:    yield [[BORROW]] : $String, resume bb1
+// CHECK:       bb1:
+// CHECK-NEXT:    end_borrow [[BORROW]] : $String
+// CHECK-NEXT:    destroy_value [[VALUE]] : $String
+  var readComputed : String {
+    _read {
+      yield computed
+    }
+  }
 }
+
+struct TestKeyPath {
+  var readable: String {
+    _read {
+      yield ""
+    }
+  }
+
+  func useKeyPath() -> String {
+    return self[keyPath: \.readable]
+  }
+}
+//   Key-path getter for TestKeyPath.readable
+// CHECK-LABEL: sil shared [thunk] @$s13read_accessor11TestKeyPathV8readableSSvpACTK
+// CHECK:       bb0(%0 : @trivial $*String, %1 : @trivial $*TestKeyPath):
+// CHECK-NEXT:    [[SELF:%.*]] = load [trivial] %1
+// CHECK-NEXT:    // function_ref
+// CHECK-NEXT:    [[READ:%.*]] = function_ref @$s13read_accessor11TestKeyPathV8readableSSvr
+// CHECK-NEXT:    ([[VALUE:%.*]], [[TOKEN:%.*]]) = begin_apply [[READ]]([[SELF]])
+// CHECK-NEXT:    [[COPY:%.*]] = copy_value [[VALUE]]
+// CHECK-NEXT:    end_apply [[TOKEN]]
+// CHECK-NEXT:    store [[COPY]] to [init] %0 : $*String
+// CHECK-NEXT:    [[RET:%.*]] = tuple ()
+// CHECK-NEXT:    return [[RET]] : $()
+// CHECK-LABEL: } // end sil function '$s13read_accessor11TestKeyPathV8readableSSvpACTK'
+
+//   Check that we emit a read coroutine but not a getter for this.
+//   This test assumes that we emit accessors in a particular order.
+// CHECK-LABEL: sil [transparent] @$s13read_accessor20TestBorrowedPropertyV14borrowedStringSSvpfi
+// CHECK-NOT:   sil [transparent] [serialized] @$s13read_accessor20TestBorrowedPropertyV14borrowedStringSSvg
+// CHECK:       sil [transparent] [serialized] @$s13read_accessor20TestBorrowedPropertyV14borrowedStringSSvr
+// CHECK-NOT:   sil [transparent] [serialized] @$s13read_accessor20TestBorrowedPropertyV14borrowedStringSSvg
+// CHECK-LABEL: sil [transparent] [serialized] @$s13read_accessor20TestBorrowedPropertyV14borrowedStringSSvs
+public struct TestBorrowedProperty {
+  @_borrowed
+  public var borrowedString = ""
+}
+
+protocol ReadableTitle {
+  @_borrowed
+  var title: String { get }
+}
+class OverridableGetter : ReadableTitle {
+  var title: String = ""
+}
+//   The concrete read accessor is generated on-demand and does a class dispatch to the getter.
+// CHECK-LABEL: sil shared @$s13read_accessor17OverridableGetterC5titleSSvr
+// CHECK:       class_method %0 : $OverridableGetter, #OverridableGetter.title!getter.1
+// CHECK-LABEL: // end sil function '$s13read_accessor17OverridableGetterC5titleSSvr'
+//   The read witness thunk does a direct call to the concrete read accessor.
+// CHECK-LABEL: sil private [transparent] [thunk] @$s13read_accessor17OverridableGetterCAA13ReadableTitleA2aDP5titleSSvrTW
+// CHECK:       function_ref @$s13read_accessor17OverridableGetterC5titleSSvr
+// CHECK-LABEL: // end sil function '$s13read_accessor17OverridableGetterCAA13ReadableTitleA2aDP5titleSSvrTW'
+
+protocol GettableTitle {
+  var title: String { get }
+}
+class OverridableReader : GettableTitle {
+  @_borrowed
+  var title: String = ""
+}
+//   The concrete getter is generated on-demand and does a class dispatch to the read accessor.
+// CHECK-LABEL: sil shared @$s13read_accessor17OverridableReaderC5titleSSvg
+// CHECK:       class_method %0 : $OverridableReader, #OverridableReader.title!read.1
+// CHECK-LABEL: // end sil function '$s13read_accessor17OverridableReaderC5titleSSvg'
+//   The getter witness thunk does a direct call to the concrete getter.
+// CHECK-LABEL: sil private [transparent] [thunk] @$s13read_accessor17OverridableReaderCAA13GettableTitleA2aDP5titleSSvgTW
+// CHECK:       function_ref @$s13read_accessor17OverridableReaderC5titleSSvg
+// CHECK-LABEL: // end sil function '$s13read_accessor17OverridableReaderCAA13GettableTitleA2aDP5titleSSvgTW'
diff --git a/test/SILGen/struct_resilience.swift b/test/SILGen/struct_resilience.swift
index 5ef3027..cbb2404 100644
--- a/test/SILGen/struct_resilience.swift
+++ b/test/SILGen/struct_resilience.swift
@@ -1,7 +1,7 @@
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -module-name struct_resilience -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -enable-sil-ownership -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
-// RUN: %target-swift-emit-silgen -module-name struct_resilience -I %t -enable-sil-ownership -enable-resilience %s | %FileCheck %s
+// RUN: %target-swift-frontend -emit-module -enable-resilience -emit-module-path=%t/resilient_struct.swiftmodule -enable-sil-ownership %S/../Inputs/resilient_struct.swift
+// RUN: %target-swift-emit-silgen -I %t -enable-sil-ownership -enable-resilience %s | %FileCheck %s
 
 import resilient_struct
 
@@ -195,8 +195,8 @@
   return s.w
 }
 
-// CHECK-LABEL: sil [serialized] [always_inline] @$s17struct_resilience26publicInlineAlwaysFunctionySiAA6MySizeVF : $@convention(thin) (@in_guaranteed MySize) -> Int
-@inline(__always) public func publicInlineAlwaysFunction(_ s: MySize) -> Int {
+// CHECK-LABEL: sil [serialized] @$s17struct_resilience23publicInlinableFunctionySiAA6MySizeVF : $@convention(thin) (@in_guaranteed MySize) -> Int
+@inlinable public func publicInlinableFunction(_ s: MySize) -> Int {
 
   // Since the body of a public transparent function might be inlined into
   // other resilience domains, we have to use accessors
diff --git a/test/SILGen/struct_resilience_testable.swift b/test/SILGen/struct_resilience_testable.swift
new file mode 100644
index 0000000..d885987
--- /dev/null
+++ b/test/SILGen/struct_resilience_testable.swift
@@ -0,0 +1,19 @@
+
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -enable-resilience -enable-testing -emit-module-path=%t/resilient_struct.swiftmodule -enable-sil-ownership %S/../Inputs/resilient_struct.swift
+// RUN: %target-swift-emit-silgen -I %t -enable-sil-ownership %s | %FileCheck %s
+
+@testable import resilient_struct
+
+// CHECK-LABEL: sil @$s26struct_resilience_testable37takesResilientStructWithInternalFieldySi010resilient_A00eghI0VF : $@convention(thin) (@in_guaranteed ResilientWithInternalField) -> Int
+// CHECK: [[COPY:%.*]] = alloc_stack $ResilientWithInternalField
+// CHECK: copy_addr %0 to [initialization] [[COPY]] : $*ResilientWithInternalField
+// CHECK: [[FN:%.*]] = function_ref @$s16resilient_struct26ResilientWithInternalFieldV1xSivg : $@convention(method) (@in_guaranteed ResilientWithInternalField) -> Int
+// CHECK: [[RESULT:%.*]] = apply [[FN]]([[COPY]])
+// CHECK: destroy_addr [[COPY]]
+// CHECK: dealloc_stack [[COPY]]
+// CHECK: return [[RESULT]]
+
+public func takesResilientStructWithInternalField(_ s: ResilientWithInternalField) -> Int {
+  return s.x
+}
diff --git a/test/SILGen/synthesized_conformance_class.swift b/test/SILGen/synthesized_conformance_class.swift
index 19b00b1..b29edd3 100644
--- a/test/SILGen/synthesized_conformance_class.swift
+++ b/test/SILGen/synthesized_conformance_class.swift
@@ -5,7 +5,7 @@
     init(x: T) { self.x = x }
 }
 // CHECK-LABEL: final class Final<T> {
-// CHECK:   @sil_stored final var x: T { get set }
+// CHECK:   @_hasStorage final var x: T { get set }
 // CHECK:   init(x: T)
 // CHECK:   deinit
 // CHECK:   enum CodingKeys : CodingKey {
@@ -25,7 +25,7 @@
     init(x: T) { self.x = x }
 }
 // CHECK-LABEL: class Nonfinal<T> {
-// CHECK:   @sil_stored var x: T { get set }
+// CHECK:   @_hasStorage var x: T { get set }
 // CHECK:   init(x: T)
 // CHECK:   deinit
 // CHECK:   enum CodingKeys : CodingKey {
diff --git a/test/SILGen/synthesized_conformance_struct.swift b/test/SILGen/synthesized_conformance_struct.swift
index 563c0a4..c5b26f9 100644
--- a/test/SILGen/synthesized_conformance_struct.swift
+++ b/test/SILGen/synthesized_conformance_struct.swift
@@ -6,7 +6,7 @@
 }
 
 // CHECK-LABEL: struct Struct<T> {
-// CHECK:   @sil_stored var x: T { get set }
+// CHECK:   @_hasStorage var x: T { get set }
 // CHECK:   init(x: T)
 // CHECK:   enum CodingKeys : CodingKey {
 // CHECK:     case x
diff --git a/test/SILGen/witness_tables_serialized.swift b/test/SILGen/witness_tables_serialized.swift
index b07d63f..924d7be 100644
--- a/test/SILGen/witness_tables_serialized.swift
+++ b/test/SILGen/witness_tables_serialized.swift
@@ -1,4 +1,7 @@
-// RUN: %target-swift-emit-silgen -enable-sil-ownership %s | %FileCheck %s
+// This file is also used by witness_tables_serialized_import.swift.
+
+// RUN: %target-swift-emit-silgen -enable-sil-ownership %s | %FileCheck -check-prefix CHECK -check-prefix CHECK-NONRESILIENT %s
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -enable-resilience %s | %FileCheck -check-prefix CHECK -check-prefix CHECK-RESILIENT %s
 
 public protocol PublicProtocol {}
 
@@ -8,11 +11,20 @@
 @_fixed_layout
 public struct PublicStruct : PublicProtocol, InternalProtocol {}
 
+public struct PublicResilientStruct : PublicProtocol, InternalProtocol {}
+
 @usableFromInline
 internal struct InternalStruct : PublicProtocol, InternalProtocol {}
 
-// CHECK-LABEL: sil_witness_table [serialized] PublicStruct: PublicProtocol
-// CHECK-LABEL: sil_witness_table [serialized] PublicStruct: InternalProtocol
+// CHECK: sil_witness_table [serialized] PublicStruct: PublicProtocol
+// CHECK: sil_witness_table [serialized] PublicStruct: InternalProtocol
 
-// CHECK-LABEL: sil_witness_table [serialized] InternalStruct: PublicProtocol
-// CHECK-LABEL: sil_witness_table [serialized] InternalStruct: InternalProtocol
+// CHECK-NONRESILIENT: sil_witness_table [serialized] PublicResilientStruct: PublicProtocol
+// CHECK-NONRESILIENT: sil_witness_table [serialized] PublicResilientStruct: InternalProtocol
+// CHECK-RESILIENT: sil_witness_table PublicResilientStruct: PublicProtocol
+// CHECK-RESILIENT: sil_witness_table PublicResilientStruct: InternalProtocol
+
+// CHECK-NONRESILIENT: sil_witness_table [serialized] InternalStruct: PublicProtocol
+// CHECK-NONRESILIENT: sil_witness_table [serialized] InternalStruct: InternalProtocol
+// CHECK-RESILIENT: sil_witness_table InternalStruct: PublicProtocol
+// CHECK-RESILIENT: sil_witness_table InternalStruct: InternalProtocol
diff --git a/test/SILGen/witness_tables_serialized_import.swift b/test/SILGen/witness_tables_serialized_import.swift
new file mode 100644
index 0000000..ba323ab
--- /dev/null
+++ b/test/SILGen/witness_tables_serialized_import.swift
@@ -0,0 +1,15 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -enable-sil-ownership -emit-module %S/witness_tables_serialized.swift -o %t -enable-resilience
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -I %t %s | %FileCheck %s
+
+import witness_tables_serialized
+
+public protocol AnotherPublicProtocol {}
+
+@usableFromInline
+internal protocol AnotherInternalProtocol {}
+
+extension PublicResilientStruct : AnotherPublicProtocol, AnotherInternalProtocol {}
+
+// CHECK: sil_witness_table [serialized] PublicResilientStruct: AnotherPublicProtocol
+// CHECK: sil_witness_table [serialized] PublicResilientStruct: AnotherInternalProtocol
diff --git a/test/SILOptimizer/abcopts.sil b/test/SILOptimizer/abcopts.sil
index 33e9a0f..244b60f 100644
--- a/test/SILOptimizer/abcopts.sil
+++ b/test/SILOptimizer/abcopts.sil
@@ -13,7 +13,7 @@
 }
 
 final class StorageBase {
-  @sil_stored var header: Int64
+  @_hasStorage var header: Int64
 }
 
 struct ArrayInt{
diff --git a/test/SILOptimizer/access_dom.sil b/test/SILOptimizer/access_dom.sil
index 8926a7f..78d2e26 100644
--- a/test/SILOptimizer/access_dom.sil
+++ b/test/SILOptimizer/access_dom.sil
@@ -11,7 +11,7 @@
 import SwiftShims
 
 struct X {
-  @sil_stored var i: Int64 { get set }
+  @_hasStorage var i: Int64 { get set }
   init(i: Int64)
   init()
 }
diff --git a/test/SILOptimizer/access_enforcement_noescape.swift b/test/SILOptimizer/access_enforcement_noescape.swift
index 6f36050..212be46 100644
--- a/test/SILOptimizer/access_enforcement_noescape.swift
+++ b/test/SILOptimizer/access_enforcement_noescape.swift
@@ -1,5 +1,4 @@
 // RUN: %target-swift-frontend -module-name access_enforcement_noescape -enable-sil-ownership -enforce-exclusivity=checked -Onone -emit-sil -swift-version 4 -parse-as-library %s | %FileCheck %s
-// REQUIRES: asserts
 
 // This tests SILGen and AccessEnforcementSelection as a single set of tests.
 // (Some static/dynamic enforcement selection is done in SILGen, and some is
diff --git a/test/SILOptimizer/access_enforcement_options.swift b/test/SILOptimizer/access_enforcement_options.swift
new file mode 100644
index 0000000..04bc8f6
--- /dev/null
+++ b/test/SILOptimizer/access_enforcement_options.swift
@@ -0,0 +1,37 @@
+// RUN: %target-swift-frontend -enable-sil-ownership -Onone -emit-sil -parse-as-library %s | %FileCheck %s --check-prefix=CHECK --check-prefix=NONE
+// RUN: %target-swift-frontend -enable-sil-ownership -Osize -emit-sil -parse-as-library %s | %FileCheck %s --check-prefix=CHECK --check-prefix=OPT
+// RUN: %target-swift-frontend -enable-sil-ownership -O -emit-sil -parse-as-library %s | %FileCheck %s --check-prefix=CHECK --check-prefix=OPT
+// RUN: %target-swift-frontend -enable-sil-ownership -Ounchecked -emit-sil -parse-as-library %s | %FileCheck %s --check-prefix=CHECK --check-prefix=UNCHECKED
+
+@inline(never)
+func takesInoutAndEscaping(_: inout Int, _ f: @escaping () -> ()) {
+  f()
+}
+
+@inline(never)
+func escapeClosure(_ f: @escaping () -> ()) -> () -> () {
+  return f
+}
+
+public func accessIntTwice() {
+  var x = 0
+  takesInoutAndEscaping(&x, escapeClosure({ x = 3 }))
+}
+
+// accessIntTwice()
+// CHECK-LABEL: sil @$s26access_enforcement_options0A8IntTwiceyyF : $@convention(thin) () -> () {
+// CHECK: [[BOX:%.*]] = alloc_box ${ var Int }, var, name "x"
+// CHECK: [[PROJ:%.*]] = project_box [[BOX]] : ${ var Int }, 0
+// NONE: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[PROJ]] : $*Int
+// OPT: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[PROJ]] : $*Int
+// UNCHECKED-NOT: = begin_access
+// CHECK-LABEL: } // end sil function '$s26access_enforcement_options0A8IntTwiceyyF'
+
+// closure #1 in accessIntTwice()
+// CHECK-LABEL: sil private @$s26access_enforcement_options0A8IntTwiceyyFyycfU_ : $@convention(thin) (@guaranteed { var Int }) -> () {
+// CHECK: bb0(%0 : ${ var Int }):
+// CHECK: [[PROJ:%.*]] = project_box %0 : ${ var Int }, 0
+// NONE: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[PROJ]] : $*Int
+// OPT: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[PROJ]] : $*Int
+// UNCHECKED-NOT: = begin_access
+// CHECK-LABEL: } // end sil function '$s26access_enforcement_options0A8IntTwiceyyFyycfU_'
diff --git a/test/SILOptimizer/access_enforcement_opts.sil b/test/SILOptimizer/access_enforcement_opts.sil
index 48d5ef5..b8f2fc0 100644
--- a/test/SILOptimizer/access_enforcement_opts.sil
+++ b/test/SILOptimizer/access_enforcement_opts.sil
@@ -9,7 +9,7 @@
 
 
 struct X {
-  @sil_stored var i: Int64 { get set }
+  @_hasStorage var i: Int64 { get set }
   init(i: Int64)
   init()
 }
@@ -1332,7 +1332,7 @@
 // CHECK-NEXT: [[REFY:%.*]] = ref_element_addr %0 : $RefElemClass, #RefElemClass.y
 // CHECK-NEXT: [[BEGINX:%.*]] = begin_access [modify] [dynamic] [[REFX]] : $*BitfieldOne
 // CHECK: end_access [[BEGINX]] : $*BitfieldOne
-// CHECK: [[BEGINY:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[REFY]] : $*Int32
+// CHECK: [[BEGINY:%.*]] = begin_access [modify] [dynamic] [[REFY]] : $*Int32
 // CHECK: [[BEGINX2:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[REFX]] : $*BitfieldOne
 // CHECK-NEXT: end_access [[BEGINX2]] : $*BitfieldOne
 // CHECK-NEXT: end_access [[BEGINY]] : $*Int32
@@ -1358,6 +1358,34 @@
   return %10 : $()
 }
 
+class RefElemNoConflictClass {
+  var x : Int32
+  var y : Int32
+  init()
+}
+
+// Checks that we can detect not having a nested conflict in class when we are accessing
+// fields that do no alias
+// CHECK-LABEL: sil @ref_elem_no_alias : $@convention(thin) (RefElemNoConflictClass) -> () {
+// CHECK: [[REFX:%.*]] = ref_element_addr %0 : $RefElemNoConflictClass, #RefElemNoConflictClass.x
+// CHECK-NEXT: [[REFY:%.*]] = ref_element_addr %0 : $RefElemNoConflictClass, #RefElemNoConflictClass.y
+// CHECK: [[BEGINY:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[REFY]] : $*Int32
+// CHECK: [[BEGINX:%.*]] = begin_access [modify] [dynamic] [no_nested_conflict] [[REFX]] : $*Int32
+// CHECK-NEXT: end_access [[BEGINX]] : $*Int32
+// CHECK-NEXT: end_access [[BEGINY]] : $*Int32
+// CHECK-LABEL: } // end sil function 'ref_elem_no_alias'
+sil @ref_elem_no_alias : $@convention(thin) (RefElemNoConflictClass) -> () {
+bb0(%0 : $RefElemNoConflictClass):
+  %x = ref_element_addr %0 : $RefElemNoConflictClass, #RefElemNoConflictClass.x
+  %y = ref_element_addr %0 : $RefElemNoConflictClass, #RefElemNoConflictClass.y
+  %b2 = begin_access [modify] [dynamic] %y : $*Int32
+  %b3 = begin_access [modify] [dynamic] %x : $*Int32
+  end_access %b3 : $*Int32
+  end_access %b2 : $*Int32
+  %10 = tuple ()
+  return %10 : $()
+}
+
 // public func testStronglyConnectedComponent() {
 // During the merge optimization,
 // Check that we don't merge cross strongly component boundaries for now
@@ -1487,4 +1515,43 @@
   return %10 : $()
 }
 
+// public func testPhiArgs() {
+// Check that we can merge scopes with Phi args - avoiding a crash we've seen in the past
+//
+// CHECK-LABEL: sil @testPhiArgs : $@convention(thin) () -> () {
+// CHECK: [[GLOBAL:%.*]] = global_addr @globalX : $*X
+// CHECK: cond_br {{.*}}, bb1, bb2
+// CHECK: bb1
+// CHECK: br bb3([[GLOBAL]] : $*X)
+// CHECK: bb2
+// CHECK: br bb3([[GLOBAL]] : $*X)
+// CHECK: bb3([[GLOBALPHI:%.*]] : $*X):
+// CHECK: [[BEGIN:%.*]] = begin_access [read] [dynamic] [[GLOBALPHI]] : $*X
+// CHECK-NEXT: load
+// CHECK-NEXT: load
+// CHECK-NEXT: end_access [[BEGIN]] : $*X
+// CHECK-NOT: begin_access
+// CHECK-LABEL: } // end sil function 'testPhiArgs'
+sil @testPhiArgs : $@convention(thin) () -> () {
+bb0:
+  %0 = global_addr @globalX: $*X
+  %cond = integer_literal $Builtin.Int1, 1
+  cond_br %cond, bb1, bb2
+  
+bb1:
+  br bb3(%0 : $*X)
+  
+bb2:
+  br bb3(%0 : $*X)
+  
+bb3(%1 : $*X):
+  %2 = begin_access [read] [dynamic] %1 : $*X
+  %3 = load %2 : $*X
+  end_access %2 : $*X
+  %4 = begin_access [read] [dynamic] %0 : $*X
+  %5 = load %4 : $*X
+  end_access %4 : $*X
+  %10 = tuple ()
+  return %10 : $()
+}
 
diff --git a/test/SILOptimizer/access_marker_elim.sil b/test/SILOptimizer/access_marker_elim.sil
index e01fb04..fcaf45b 100644
--- a/test/SILOptimizer/access_marker_elim.sil
+++ b/test/SILOptimizer/access_marker_elim.sil
@@ -1,5 +1,5 @@
 // RUN: %target-sil-opt -enforce-exclusivity=unchecked -emit-sorted-sil -access-marker-elim %s | %FileCheck %s --check-prefix=UNCHECKED
-// FIXME: %target-sil-opt -enforce-exclusivity=checked -emit-sorted-sil -access-marker-elim %s | %FileCheck %s --check-prefix=CHECKED
+// RUN: %target-sil-opt -enforce-exclusivity=checked -emit-sorted-sil -access-marker-elim %s | %FileCheck %s --check-prefix=CHECKED
 
 sil_stage raw
 
@@ -8,7 +8,7 @@
 import SwiftShims
 
 public struct S {
-  @sil_stored var i: Builtin.Int64 { get set }
+  @_hasStorage var i: Builtin.Int64 { get set }
   init(i: Int)
 }
 
@@ -78,7 +78,7 @@
 // UNCHECKED-LABEL: } // end sil function 'f020_boxArg'
 //
 // CHECKED-LABEL: sil hidden @f020_boxArg : $@convention(thin) (@owned { var Builtin.Int64 }) -> () {
-// CHECKED: bb0(%0 : ${ var Builtin.Int64 }):
+// CHECKED: bb0(%0 : @owned ${ var Builtin.Int64 }):
 // CHECKED:  [[ADR:%.*]] = project_box %0 : ${ var Builtin.Int64 }, 0
 // CHECKED:  [[VAL:%.*]] = integer_literal $Builtin.Int64, 42
 // CHECKED:  [[ACCESS:%.*]] = begin_access [modify] [unknown] [[ADR]]
diff --git a/test/SILOptimizer/access_marker_verify.swift b/test/SILOptimizer/access_marker_verify.swift
index 8d5fb8f..57465e1 100644
--- a/test/SILOptimizer/access_marker_verify.swift
+++ b/test/SILOptimizer/access_marker_verify.swift
@@ -223,13 +223,10 @@
 // CHECK:   end_access
 // CHECK:   [[CAPTURE:%.*]] = copy_value %0 : ${ var Int }
 // CHECK:   partial_apply [callee_guaranteed] %{{.*}}([[CAPTURE]]) : $@convention(thin) (@guaranteed { var Int }) -> ()
-// CHECK:   alloc_stack $Int
-// CHECK:   [[UNINIT:%.*]] = mark_uninitialized [var]
 // CHECK:   begin_access [read] [unknown] [[PROJ]]
 // CHECK:   [[VAL:%.*]] = load [trivial]
 // CHECK:   end_access
 // CHECK-NOT: begin_access
-// CHECK:   assign [[VAL]] to [[UNINIT]] : $*Int
 // CHECK:   return {{.*}} : $@callee_guaranteed () -> ()
 // CHECK-LABEL: } // end sil function '$s20access_marker_verify16testCaptureLocalyycyF'
 
@@ -948,15 +945,12 @@
 // CHECK: partial_apply [callee_guaranteed] %{{.*}}([[PROJ]]) : $@convention(thin) (@inout_aliasable P) -> ()
 // CHECK-NOT: begin_access
 // CHECK: apply
-// CHECK: [[TMP:%.*]] = alloc_stack $P
-// CHECK: [[UNINIT:%.*]] = mark_uninitialized [var] [[TMP]] : $*P
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJ]] : $*P
 // CHECK: [[COPY:%.*]] = alloc_stack $P
 // CHECK-NOT: begin_access
 // CHECK: copy_addr [[ACCESS]] to [initialization] [[COPY]] : $*P
 // CHECK: end_access
 // CHECK-NOT: begin_access
-// CHECK: copy_addr [take] [[COPY]] to [[UNINIT]] : $*P
 // CHECK-LABEL: } // end sil function '$s20access_marker_verify20testLocalExistentialyyF'
 
 // --- address-only argument.
diff --git a/test/SILOptimizer/access_sink.sil b/test/SILOptimizer/access_sink.sil
index 4d38667..0730610 100644
--- a/test/SILOptimizer/access_sink.sil
+++ b/test/SILOptimizer/access_sink.sil
@@ -11,7 +11,7 @@
 import SwiftShims
 
 struct X {
-  @sil_stored var i: Int64 { get set }
+  @_hasStorage var i: Int64 { get set }
   init(i: Int64)
   init()
 }
@@ -215,3 +215,68 @@
   %ret = tuple ()
   return %ret : $()
 }
+
+// testSinkAfterEscapingClosureCheck:
+// <rdar://problem/45846920> TestFoundation, TestProcess, closure
+// argument passed as @noescape to Objective-C has escaped
+class IntWrapper {
+  var value: Builtin.Int64
+
+  init(v: Builtin.Int64) {
+    value = v
+  }
+}
+
+sil @takesNoEscapeBlockClosure : $@convention(thin) (@guaranteed @convention(block) @noescape () -> ()) -> ()
+
+sil @closureThatModifiesCapture: $@convention(thin) ({ var Builtin.Int64 }) -> ()
+
+sil [reabstraction_thunk] @thunkForCalleeGuaranteed : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> ()) -> ()
+sil [reabstraction_thunk] @withoutActuallyEscapingThunk : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+
+// The Copy release cannot be moved below the is_escaping_closure check.
+//
+// CHECK-LABEL: sil @testSinkAfterEscapingClosureCheck : $@convention(thin) (@guaranteed IntWrapper) -> () {
+// CHECK: bb0(%0 : $IntWrapper):
+// CHECK: [[BA:%.*]] = begin_access [read] [dynamic] %{{.*}} : $*Builtin.Int64
+// CHECK: [[COPY:%.*]] = copy_block %{{.*}} : $@convention(block) @noescape () -> ()
+// CHECK: [[F:%.*]] = function_ref @takesNoEscapeBlockClosure : $@convention(thin) (@guaranteed @convention(block) @noescape () -> ()) -> ()
+// CHECK: apply [[F]]([[COPY]]) : $@convention(thin) (@guaranteed @convention(block) @noescape () -> ()) -> ()
+// CHECK: strong_release [[COPY]] : $@convention(block) @noescape () -> ()
+// CHECK: is_escaping_closure
+// CHECK: cond_fail
+// CHECK: end_access [[BA]] : $*Builtin.Int64
+// CHECK-LABEL: } // end sil function 'testSinkAfterEscapingClosureCheck'
+sil @testSinkAfterEscapingClosureCheck : $@convention(thin) (@guaranteed IntWrapper) -> () {
+bb0(%0 : $IntWrapper):
+  %va = ref_element_addr %0 : $IntWrapper, #IntWrapper.value
+  %ba = begin_access [read] [dynamic] %va : $*Builtin.Int64
+  %value = load %ba : $*Builtin.Int64
+  %box = alloc_box ${ var Builtin.Int64 }
+  %boxaddr = project_box %box : ${ var Builtin.Int64 }, 0
+  store %value to %boxaddr : $*Builtin.Int64
+  %closureF = function_ref @closureThatModifiesCapture : $@convention(thin) ({ var Builtin.Int64 }) -> ()
+  %closure = partial_apply [callee_guaranteed] %closureF(%box) : $@convention(thin) ({ var Builtin.Int64 }) -> ()
+  %conv = convert_escape_to_noescape %closure : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+  %thunk = function_ref @withoutActuallyEscapingThunk : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  %pathunk = partial_apply [callee_guaranteed] %thunk(%conv) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  %md = mark_dependence %pathunk : $@callee_guaranteed () -> () on %conv : $@noescape @callee_guaranteed () -> ()
+  strong_retain %md : $@callee_guaranteed () -> ()
+  %allocblock = alloc_stack $@block_storage @callee_guaranteed () -> ()
+  %blockaddr = project_block_storage %allocblock : $*@block_storage @callee_guaranteed () -> ()
+  store %md to %blockaddr : $*@callee_guaranteed () -> ()
+  %blockF = function_ref @thunkForCalleeGuaranteed : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> ()) -> ()
+  %initblock = init_block_storage_header %allocblock : $*@block_storage @callee_guaranteed () -> (), invoke %blockF : $@convention(c) (@inout_aliasable @block_storage @callee_guaranteed () -> ()) -> (), type $@convention(block) @noescape () -> ()
+  %copyblock = copy_block %initblock : $@convention(block) @noescape () -> ()
+  %f = function_ref @takesNoEscapeBlockClosure : $@convention(thin) (@guaranteed @convention(block) @noescape () -> ()) -> ()
+  %call = apply %f(%copyblock) : $@convention(thin) (@guaranteed @convention(block) @noescape () -> ()) -> ()
+  strong_release %copyblock : $@convention(block) @noescape () -> ()
+  %isescape = is_escaping_closure %md : $@callee_guaranteed () -> ()
+  cond_fail %isescape : $Builtin.Int1
+  end_access %ba : $*Builtin.Int64
+  destroy_addr %blockaddr : $*@callee_guaranteed() -> ()
+  dealloc_stack %allocblock : $*@block_storage @callee_guaranteed () -> ()
+  strong_release %box : ${ var Builtin.Int64 }
+  %ret = tuple ()
+  return %ret : $()
+}
diff --git a/test/SILOptimizer/access_summary_analysis.sil b/test/SILOptimizer/access_summary_analysis.sil
index 73fd1de..8eb1a35 100644
--- a/test/SILOptimizer/access_summary_analysis.sil
+++ b/test/SILOptimizer/access_summary_analysis.sil
@@ -7,13 +7,13 @@
 import SwiftShims
 
 struct StructWithStoredProperties {
-  @sil_stored var f: Int
-  @sil_stored var g: Int
+  @_hasStorage var f: Int
+  @_hasStorage var g: Int
 }
 
 struct StructWithStructWithStoredProperties {
-  @sil_stored var a: StructWithStoredProperties
-  @sil_stored var b: StructWithStoredProperties
+  @_hasStorage var a: StructWithStoredProperties
+  @_hasStorage var b: StructWithStoredProperties
 }
 
 // CHECK-LABEL: @assignsToCapture
diff --git a/test/SILOptimizer/access_wmo.sil b/test/SILOptimizer/access_wmo.sil
index 445374a..9995135 100644
--- a/test/SILOptimizer/access_wmo.sil
+++ b/test/SILOptimizer/access_wmo.sil
@@ -16,13 +16,13 @@
 public var publicGlobal: Int64
 
 public class C {
-  @sil_stored var setterProp: Int64 { get set }
-  @sil_stored final var finalProp: Int64 { get set }
-  @sil_stored var inlinedProp: Int64 { get set }
-  @sil_stored var internalProp: Int64 { get set }
-  @sil_stored var keyPathProp: Int64 { get set }
-  @sil_stored final var finalKeyPathProp: Int64 { get set }
-  @sil_stored public var publicProp: Int64 { get set }
+  @_hasStorage var setterProp: Int64 { get set }
+  @_hasStorage final var finalProp: Int64 { get set }
+  @_hasStorage var inlinedProp: Int64 { get set }
+  @_hasStorage var internalProp: Int64 { get set }
+  @_hasStorage var keyPathProp: Int64 { get set }
+  @_hasStorage final var finalKeyPathProp: Int64 { get set }
+  @_hasStorage public var publicProp: Int64 { get set }
   init()
   deinit
 }
diff --git a/test/SILOptimizer/accessed_storage_analysis.sil b/test/SILOptimizer/accessed_storage_analysis.sil
index 3b20f9b..ee90195 100644
--- a/test/SILOptimizer/accessed_storage_analysis.sil
+++ b/test/SILOptimizer/accessed_storage_analysis.sil
@@ -333,14 +333,14 @@
 }
 
 class C {
-  @sil_stored var property: Int
+  @_hasStorage var property: Int
   deinit
   init()
 }
 
 // CHECK-LABEL: @readIdentifiedClass
 // CHECK: [read] Class %0 = argument of bb0 : $C
-// CHECK: Field: @sil_stored var property: Int
+// CHECK: Field: @_hasStorage var property: Int
 sil @readIdentifiedClass : $@convention(thin) (@guaranteed C) -> Int {
 bb0(%0 : $C):
   %1 = ref_element_addr %0 : $C, #C.property
@@ -352,7 +352,7 @@
 
 // CHECK-LABEL: @writeIdentifiedClass
 // CHECK: [modify] Class %0 = argument of bb0 : $C
-// CHECK: Field: @sil_stored var property: Int
+// CHECK: Field: @_hasStorage var property: Int
 sil @writeIdentifiedClass : $@convention(thin) (@guaranteed C, Int) -> () {
 bb0(%0 : $C, %1 : $Int):
   %2 = ref_element_addr %0 : $C, #C.property
@@ -365,7 +365,7 @@
 
 // CHECK-LABEL: @readWriteIdentifiedClass
 // CHECK: [modify] Class   %1 = alloc_ref $C
-// CHECK: Field: @sil_stored var property: Int
+// CHECK: Field: @_hasStorage var property: Int
 sil @readWriteIdentifiedClass : $@convention(thin) (Int) -> (Int) {
 bb0(%0 : $Int):
   %1 = alloc_ref $C
@@ -380,7 +380,7 @@
 
 // CHECK-LABEL: @readIdentifiedNestedClass
 // CHECK: [read] Class %0 = argument of bb0 : $C
-// CHECK: Field: @sil_stored var property: Int
+// CHECK: Field: @_hasStorage var property: Int
 sil @readIdentifiedNestedClass : $@convention(thin) (@guaranteed C) -> Int {
 bb0(%0 : $C):
   %1 = ref_element_addr %0 : $C, #C.property
@@ -394,7 +394,7 @@
 
 // CHECK-LABEL: @writeIdentifiedNestedClass
 // CHECK: [modify] Class %0 = argument of bb0 : $C
-// CHECK: Field: @sil_stored var property: Int
+// CHECK: Field: @_hasStorage var property: Int
 sil @writeIdentifiedNestedClass : $@convention(thin) (@guaranteed C, Int) -> () {
 bb0(%0 : $C, %1 : $Int):
   %2 = ref_element_addr %0 : $C, #C.property
@@ -409,7 +409,7 @@
 
 // CHECK-LABEL: @readWriteIdentifiedNestedClass
 // CHECK: [modify] Class   %1 = alloc_ref $C
-// CHECK: Field: @sil_stored var property: Int
+// CHECK: Field: @_hasStorage var property: Int
 sil @readWriteIdentifiedNestedClass : $@convention(thin) (Int) -> (Int) {
 bb0(%0 : $Int):
   %1 = alloc_ref $C
@@ -541,7 +541,7 @@
 // Test directly recursive argument access.
 // CHECK-LABEL: @readRecursiveArgument
 // CHECK:   [read] Class %0 = argument of bb0 : $C
-// CHECK:   Field: @sil_stored var property: Int
+// CHECK:   Field: @_hasStorage var property: Int
 sil @readRecursiveArgument : $@convention(thin) (@guaranteed C, Int) -> Int {
 bb0(%0 : $C, %1 : $Int):
   %propaddr = ref_element_addr %0 : $C, #C.property
@@ -556,7 +556,7 @@
 // Test a class argument access from an optional caller value.
 // CHECK-LABEL: @readOptionalArgumentInCallee
 // CHECK:   [read] Class   %1 = unchecked_enum_data %0 : $Optional<C>, #Optional.some!enumelt.1
-// CHECK:   Field: @sil_stored var property: Int
+// CHECK:   Field: @_hasStorage var property: Int
 sil @readOptionalArgumentInCallee : $@convention(thin) (@guaranteed Optional<C>) -> Int {
 bb0(%0 : $Optional<C>):
   %c = unchecked_enum_data %0 : $Optional<C>, #Optional.some!enumelt.1
@@ -567,7 +567,7 @@
 
 // CHECK-LABEL: @readOptionalArgumentInCalleeHelper
 // CHECK:   [read] Class %0 = argument of bb0 : $C
-// CHECK:   Field: @sil_stored var property: Int
+// CHECK:   Field: @_hasStorage var property: Int
 sil private @readOptionalArgumentInCalleeHelper : $@convention(thin) (@guaranteed C) -> Int {
 bb0(%0 : $C):
   %propaddr = ref_element_addr %0 : $C, #C.property
diff --git a/test/SILOptimizer/allocbox_to_stack.sil b/test/SILOptimizer/allocbox_to_stack.sil
index 2d82dac..5db8a10 100644
--- a/test/SILOptimizer/allocbox_to_stack.sil
+++ b/test/SILOptimizer/allocbox_to_stack.sil
@@ -537,7 +537,7 @@
 }
 
 struct S<T : Count> {
-  @sil_stored var t: T
+  @_hasStorage var t: T
   var count: Int { get }
   func test(i: Int) -> Bool
   init(t: T)
diff --git a/test/SILOptimizer/allocbox_to_stack_ownership.sil b/test/SILOptimizer/allocbox_to_stack_ownership.sil
index 9025a7a..b51d3dd 100644
--- a/test/SILOptimizer/allocbox_to_stack_ownership.sil
+++ b/test/SILOptimizer/allocbox_to_stack_ownership.sil
@@ -533,7 +533,7 @@
 }
 
 struct S<T : Count> {
-  @sil_stored var t: T
+  @_hasStorage var t: T
   var count: Int { get }
   func test(i: Int) -> Bool
   init(t: T)
diff --git a/test/SILOptimizer/arcsequenceopts.sil b/test/SILOptimizer/arcsequenceopts.sil
index e0edb4a..a7ad1aa 100644
--- a/test/SILOptimizer/arcsequenceopts.sil
+++ b/test/SILOptimizer/arcsequenceopts.sil
@@ -50,7 +50,7 @@
 sil @cls_use : $@convention(thin) (@owned Cls) -> ()
 
 class Container {
-  @sil_stored var c : Cls
+  @_hasStorage var c : Cls
   init()
 }
 
diff --git a/test/SILOptimizer/array_contentof_opt.swift b/test/SILOptimizer/array_contentof_opt.swift
index 0a6ab5d..7a0dfad 100644
--- a/test/SILOptimizer/array_contentof_opt.swift
+++ b/test/SILOptimizer/array_contentof_opt.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -O -sil-verify-all -emit-sil  %s | %FileCheck %s
+// RUN: %target-swift-frontend -O -sil-verify-all -emit-sil -enforce-exclusivity=unchecked  %s | %FileCheck %s
 // REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
 
 // This is an end-to-end test of the array(contentsOf) -> array(Element) optimization
diff --git a/test/SILOptimizer/array_count_propagation.sil b/test/SILOptimizer/array_count_propagation.sil
index bc6ce42..ac2f87c 100644
--- a/test/SILOptimizer/array_count_propagation.sil
+++ b/test/SILOptimizer/array_count_propagation.sil
@@ -6,22 +6,22 @@
 import Swift
 
 struct MyInt {
-  @sil_stored var _value: Builtin.Int64
+  @_hasStorage var _value: Builtin.Int64
 }
 
 struct MyBool {}
 
 struct _MyBridgeStorage {
-  @sil_stored var rawValue : Builtin.BridgeObject
+  @_hasStorage var rawValue : Builtin.BridgeObject
 }
 
 struct _MyArrayBuffer<T> {
-  @sil_stored var _storage : _MyBridgeStorage
+  @_hasStorage var _storage : _MyBridgeStorage
 }
 
 
 struct MyArray<T> {
-  @sil_stored var _buffer : _MyArrayBuffer<T>
+  @_hasStorage var _buffer : _MyArrayBuffer<T>
 }
 
 sil @swift_bufferAllocate : $@convention(thin)() -> @owned AnyObject
diff --git a/test/SILOptimizer/array_element_propagation.sil b/test/SILOptimizer/array_element_propagation.sil
index cdf04f6..e807ad9 100644
--- a/test/SILOptimizer/array_element_propagation.sil
+++ b/test/SILOptimizer/array_element_propagation.sil
@@ -6,23 +6,23 @@
 import Swift
 
 struct MyInt {
-  @sil_stored var _value: Builtin.Int64
+  @_hasStorage var _value: Builtin.Int64
 }
 
 struct MyBool {}
 struct _MyDependenceToken {}
 
 struct _MyBridgeStorage {
-  @sil_stored var rawValue : Builtin.BridgeObject
+  @_hasStorage var rawValue : Builtin.BridgeObject
 }
 
 struct _MyArrayBuffer<T> {
-  @sil_stored var _storage : _MyBridgeStorage
+  @_hasStorage var _storage : _MyBridgeStorage
 }
 
 
 struct MyArray<T> {
-  @sil_stored var _buffer : _MyArrayBuffer<T>
+  @_hasStorage var _buffer : _MyArrayBuffer<T>
 }
 
 sil @swift_bufferAllocate : $@convention(thin)() -> @owned AnyObject
diff --git a/test/SILOptimizer/basic-aa.sil b/test/SILOptimizer/basic-aa.sil
index d8e2445..aa3d7bb 100644
--- a/test/SILOptimizer/basic-aa.sil
+++ b/test/SILOptimizer/basic-aa.sil
@@ -509,8 +509,8 @@
 }
 
 public final class C {
-  @sil_stored final var a: Int { get set }
-  @sil_stored final var b: Int { get set }
+  @_hasStorage final var a: Int { get set }
+  @_hasStorage final var b: Int { get set }
    deinit
   init()
 }
diff --git a/test/SILOptimizer/basic-instruction-properties.sil b/test/SILOptimizer/basic-instruction-properties.sil
index 1f9c989..35b04e6 100644
--- a/test/SILOptimizer/basic-instruction-properties.sil
+++ b/test/SILOptimizer/basic-instruction-properties.sil
@@ -5,8 +5,8 @@
 import Builtin
 
 class X {
-  @sil_stored var a: Builtin.Int32
-  @sil_stored var x: X
+  @_hasStorage var a: Builtin.Int32
+  @_hasStorage var x: X
 
   init()
   func foo()
diff --git a/test/SILOptimizer/bridged_casts_folding.swift b/test/SILOptimizer/bridged_casts_folding.swift
index 489f2d1..7b63476 100644
--- a/test/SILOptimizer/bridged_casts_folding.swift
+++ b/test/SILOptimizer/bridged_casts_folding.swift
@@ -1,5 +1,5 @@
 
-// RUN: %target-swift-frontend -O -emit-sil %s | %FileCheck %s
+// RUN: %target-swift-frontend -O -emit-sil -enforce-exclusivity=unchecked %s | %FileCheck %s
 
 // REQUIRES: objc_interop
 
diff --git a/test/SILOptimizer/closure_specialize_consolidated.sil b/test/SILOptimizer/closure_specialize_consolidated.sil
index e429d17..96b1c81 100644
--- a/test/SILOptimizer/closure_specialize_consolidated.sil
+++ b/test/SILOptimizer/closure_specialize_consolidated.sil
@@ -16,12 +16,12 @@
 }
 
 public class C {
-  @sil_stored var c: C? { get set }
+  @_hasStorage var c: C? { get set }
   init()
 }
 
 public struct S: Q {
-  @sil_stored var c: C? { get set }
+  @_hasStorage var c: C? { get set }
   init(c: C?)
   init()
 }
diff --git a/test/SILOptimizer/conditionforwarding.sil b/test/SILOptimizer/conditionforwarding.sil
index d34800f..f5dc46a 100644
--- a/test/SILOptimizer/conditionforwarding.sil
+++ b/test/SILOptimizer/conditionforwarding.sil
@@ -10,7 +10,7 @@
 enum E3 { case A, B, C }
 
 class C {
-  @sil_stored var x : Builtin.Int64
+  @_hasStorage var x : Builtin.Int64
   init()
 }
 
diff --git a/test/SILOptimizer/copyforward.sil b/test/SILOptimizer/copyforward.sil
index 09473eb..50588ad 100644
--- a/test/SILOptimizer/copyforward.sil
+++ b/test/SILOptimizer/copyforward.sil
@@ -604,8 +604,8 @@
 }
 
 public struct S<T> {
-  @sil_stored var f: T { get set }
-  @sil_stored var g: T { get set }
+  @_hasStorage var f: T { get set }
+  @_hasStorage var g: T { get set }
   init(f: T, g: T)
 }
 
diff --git a/test/SILOptimizer/cowarray_opt.sil b/test/SILOptimizer/cowarray_opt.sil
index a264b00..57b9fd1 100644
--- a/test/SILOptimizer/cowarray_opt.sil
+++ b/test/SILOptimizer/cowarray_opt.sil
@@ -39,7 +39,7 @@
 }
 
 class MyArrayStorage {
-  @sil_stored var header: Int
+  @_hasStorage var header: Int
 
   init()
   deinit
@@ -478,7 +478,7 @@
 
 
 struct MyInt {
-  @sil_stored var _value: Builtin.Int64
+  @_hasStorage var _value: Builtin.Int64
   init(_ value: Int16)
 }
 
diff --git a/test/SILOptimizer/definite_init_crashes.sil b/test/SILOptimizer/definite_init_crashes.sil
index e848ce1..da402cc 100644
--- a/test/SILOptimizer/definite_init_crashes.sil
+++ b/test/SILOptimizer/definite_init_crashes.sil
@@ -85,13 +85,13 @@
 public struct MyErrorType : Error {}
 
 public struct NonTrivial {
-  @sil_stored let ptr: Builtin.NativeObject
+  @_hasStorage let ptr: Builtin.NativeObject
 }
 
 public struct AStruct {
-  @sil_stored public let name: NonTrivial
-  @sil_stored public let foobar: NonTrivial
-  @sil_stored public let protoType: Proto.Type
+  @_hasStorage public let name: NonTrivial
+  @_hasStorage public let foobar: NonTrivial
+  @_hasStorage public let protoType: Proto.Type
 }
 
 sil @mayThrow : $@convention(thin) () -> (@owned NonTrivial, @error Error)
diff --git a/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil b/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
index 4b71c8d..556edcc 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
@@ -79,7 +79,7 @@
 
 // <rdar://problem/20608881> DI miscompiles this testcase into a memory leak
 struct MyStruct3 {
-  @sil_stored var c: C
+  @_hasStorage var c: C
 }
 sil @selfinit_mystruct3 : $@convention(thin) () -> @owned MyStruct3
 
diff --git a/test/SILOptimizer/destructor_analysis.sil b/test/SILOptimizer/destructor_analysis.sil
index 9ee4c4b..52da6d4 100644
--- a/test/SILOptimizer/destructor_analysis.sil
+++ b/test/SILOptimizer/destructor_analysis.sil
@@ -14,7 +14,7 @@
 }
 
 struct Foo {
-  @sil_stored var subFoos: ArrayOf<Foo>
+  @_hasStorage var subFoos: ArrayOf<Foo>
   init()
 }
 
diff --git a/test/SILOptimizer/devirt_jump_thread.sil b/test/SILOptimizer/devirt_jump_thread.sil
index 4921abb..401dd79 100644
--- a/test/SILOptimizer/devirt_jump_thread.sil
+++ b/test/SILOptimizer/devirt_jump_thread.sil
@@ -17,7 +17,7 @@
 }
 
 public class FooClass {
-  @sil_stored var value: Int32 { get set }
+  @_hasStorage var value: Int32 { get set }
   @inline(never) func foo(x: Int32) -> Int32
   init(value: Int32)
    deinit
diff --git a/test/SILOptimizer/devirtualize.sil b/test/SILOptimizer/devirtualize.sil
index 5a07d00..2d7fc06 100644
--- a/test/SILOptimizer/devirtualize.sil
+++ b/test/SILOptimizer/devirtualize.sil
@@ -57,7 +57,7 @@
 }
 
 private class Node {
-  @sil_stored var index: Int { get set }
+  @_hasStorage var index: Int { get set }
   init(index: Int)
    deinit
 }
diff --git a/test/SILOptimizer/eager_specialize.sil b/test/SILOptimizer/eager_specialize.sil
index b744967..9c78278 100644
--- a/test/SILOptimizer/eager_specialize.sil
+++ b/test/SILOptimizer/eager_specialize.sil
@@ -18,13 +18,13 @@
 }
 
 struct X : AnElt {
-  @sil_stored var i: Int { get set }
+  @_hasStorage var i: Int { get set }
   init(i: Int)
 }
 
 struct S : HasElt {
   typealias Elt = X
-  @sil_stored var e: X { get set }
+  @_hasStorage var e: X { get set }
   init(e: Elt)
 }
 
diff --git a/test/SILOptimizer/escape_analysis.sil b/test/SILOptimizer/escape_analysis.sil
index c346056..b3c87a2 100644
--- a/test/SILOptimizer/escape_analysis.sil
+++ b/test/SILOptimizer/escape_analysis.sil
@@ -21,13 +21,13 @@
 }
 
 class Y {
-  @sil_stored var x: X
+  @_hasStorage var x: X
 
   init(newx: X)
 }
 
 class Z {
-  @sil_stored var x: X
+  @_hasStorage var x: X
   init(newx: X)
   deinit
 }
@@ -52,7 +52,7 @@
 }
 
 class LinkedNode {
-  @sil_stored var next: LinkedNode;
+  @_hasStorage var next: LinkedNode;
 
   init(_ n: LinkedNode)
 }
diff --git a/test/SILOptimizer/exclusivity_static_diagnostics.sil b/test/SILOptimizer/exclusivity_static_diagnostics.sil
index 772a5a8..dcdaef7 100644
--- a/test/SILOptimizer/exclusivity_static_diagnostics.sil
+++ b/test/SILOptimizer/exclusivity_static_diagnostics.sil
@@ -230,7 +230,7 @@
 
 
 class ClassWithStoredProperty {
-  @sil_stored var f: Int
+  @_hasStorage var f: Int
   init()
 }
 // CHECK-LABEL: sil hidden @classStoredProperty
diff --git a/test/SILOptimizer/existential_type_propagation.sil b/test/SILOptimizer/existential_type_propagation.sil
index 3a0f457..eb27b3c 100644
--- a/test/SILOptimizer/existential_type_propagation.sil
+++ b/test/SILOptimizer/existential_type_propagation.sil
@@ -21,7 +21,7 @@
 }
 
 public final class ArrayClassReaderWriter : ReaderWriterType {
-  @sil_stored private final var elements: [Int32] { get set }
+  @_hasStorage private final var elements: [Int32] { get set }
   @inline(never) public init()
   @inline(never) public final func read(index: Int32) -> Int32
   public final func write(index: Int32, value: Int32)
diff --git a/test/SILOptimizer/generic_specialization_loops_detection_with_loops.swift b/test/SILOptimizer/generic_specialization_loops_detection_with_loops.swift
index df3ae61..30d8f31 100644
--- a/test/SILOptimizer/generic_specialization_loops_detection_with_loops.swift
+++ b/test/SILOptimizer/generic_specialization_loops_detection_with_loops.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -O -emit-sil -Xllvm -sil-print-generic-specialization-loops -Xllvm -sil-print-generic-specialization-info %s 2>&1 | %FileCheck --check-prefix=CHECK %s
+// RUN: %target-swift-frontend -O -emit-sil -enforce-exclusivity=unchecked -Xllvm -sil-print-generic-specialization-loops -Xllvm -sil-print-generic-specialization-info %s 2>&1 | %FileCheck --check-prefix=CHECK %s
 
 // Check that the generic specializer does not hang a compiler by
 // creating and infinite loop of generic specializations.
diff --git a/test/SILOptimizer/globalopt_global_propagation.swift b/test/SILOptimizer/globalopt_global_propagation.swift
index a663106..0b9d375 100644
--- a/test/SILOptimizer/globalopt_global_propagation.swift
+++ b/test/SILOptimizer/globalopt_global_propagation.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend  -O -emit-sil  %s | %FileCheck %s
-// RUN: %target-swift-frontend  -O -wmo -emit-sil  %s | %FileCheck -check-prefix=CHECK-WMO %s
+// RUN: %target-swift-frontend  -O -emit-sil -enforce-exclusivity=unchecked  %s | %FileCheck %s
+// RUN: %target-swift-frontend  -O -wmo -emit-sil -enforce-exclusivity=unchecked  %s | %FileCheck -check-prefix=CHECK-WMO %s
 
 // Check that values of internal and private global variables, which are provably assigned only 
 // once, are propagated into their uses and enable further optimizations like constant
diff --git a/test/SILOptimizer/globalopt_let_propagation.swift b/test/SILOptimizer/globalopt_let_propagation.swift
index 347cec6..978e993 100644
--- a/test/SILOptimizer/globalopt_let_propagation.swift
+++ b/test/SILOptimizer/globalopt_let_propagation.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend  -O -emit-sil -primary-file %s | %FileCheck %s
+// RUN: %target-swift-frontend  -O -emit-sil -enforce-exclusivity=unchecked -primary-file %s | %FileCheck %s
 
 // Check that values of static let and global let variables are propagated into their uses
 // and enable further optimizations like constant propagation, simplifications, etc.
diff --git a/test/SILOptimizer/illegal_escaping_address.swift b/test/SILOptimizer/illegal_escaping_address.swift
index 2a44e38..747a037 100644
--- a/test/SILOptimizer/illegal_escaping_address.swift
+++ b/test/SILOptimizer/illegal_escaping_address.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -O -sil-verify-all -emit-sil -parse-as-library %s
+// RUN: %target-swift-frontend -O -sil-verify-all -emit-sil -enforce-exclusivity=unchecked -parse-as-library %s
 
 // Check that the compiler does not crash for illegal escaping of an address
 // of a local variable.
diff --git a/test/SILOptimizer/inline_begin_apply.sil b/test/SILOptimizer/inline_begin_apply.sil
index fa76e06..0bf0a83 100644
--- a/test/SILOptimizer/inline_begin_apply.sil
+++ b/test/SILOptimizer/inline_begin_apply.sil
@@ -436,3 +436,99 @@
   %ret = tuple ()
   return %ret : $()
 }
+
+sil [transparent] @stack_overlap : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32) {
+entry:
+  %marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
+  %temp = alloc_stack $Builtin.Int32
+  %1000 = integer_literal $Builtin.Int32, 1000
+  store %1000 to [trivial] %temp : $*Builtin.Int32
+  %2000 = integer_literal $Builtin.Int32, 2000
+  apply %marker(%2000) : $@convention(thin) (Builtin.Int32) -> ()
+  yield %temp : $*Builtin.Int32, resume resume, unwind unwind
+
+resume:
+  %3000 = integer_literal $Builtin.Int32, 3000
+  apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> ()
+  dealloc_stack %temp : $*Builtin.Int32
+  %4000 = integer_literal $Builtin.Int32, 4000
+  apply %marker(%4000) : $@convention(thin) (Builtin.Int32) -> ()
+  %ret = tuple ()
+  return %ret : $()
+
+unwind:
+  dealloc_stack %temp : $*Builtin.Int32
+  unwind
+}
+
+// CHECK-LABEL: sil @test_stack_overlap_dealloc
+// CHECK:       bb0:
+// CHECK-NEXT:    [[A16:%.*]] = alloc_stack $Builtin.Int16
+// CHECK-NEXT:    // function_ref
+// CHECK-NEXT:    [[MARKER:%.*]] = function_ref @marker
+// CHECK-NEXT:    [[A32:%.*]] = alloc_stack $Builtin.Int32
+// CHECK-NEXT:    [[I1000:%.*]] = integer_literal $Builtin.Int32, 1000
+// CHECK-NEXT:    store [[I1000]] to [trivial] [[A32]]
+// CHECK-NEXT:    [[I2000:%.*]] = integer_literal $Builtin.Int32, 2000
+// CHECK-NEXT:    apply [[MARKER]]([[I2000]])
+// CHECK-NEXT:    br bb1
+// CHECK:       bb1:
+// CHECK-NEXT:    [[I3000:%.*]] = integer_literal $Builtin.Int32, 3000
+// CHECK-NEXT:    apply [[MARKER]]([[I3000]])
+// CHECK-NEXT:    dealloc_stack [[A32]] : $*Builtin.Int32
+//   Note that this has been delayed to follow stack discipline.
+// CHECK-NEXT:    dealloc_stack [[A16]] : $*Builtin.Int16
+// CHECK-NEXT:    [[I4000:%.*]] = integer_literal $Builtin.Int32, 4000
+// CHECK-NEXT:    apply [[MARKER]]([[I4000]])
+// CHECK-NEXT:    tuple ()
+// CHECK-NEXT:    br [[END:bb[0-9]+]]
+// CHECK:       [[END]]:
+// CHECK-NEXT:    [[RET:%.*]] = tuple ()
+// CHECK-NEXT:    return [[RET]] : $()
+// CHECK-LABEL: // end sil function 'test_stack_overlap_dealloc'
+sil @test_stack_overlap_dealloc : $() -> () {
+bb0:
+  %stack = alloc_stack $Builtin.Int16
+  %0 = function_ref @stack_overlap : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
+  (%value, %token) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
+  dealloc_stack %stack : $*Builtin.Int16
+  end_apply %token
+  %ret = tuple ()
+  return %ret : $()
+}
+
+// CHECK-LABEL: sil @test_stack_overlap_alloc
+// CHECK:       bb0:
+// CHECK-NEXT:    // function_ref
+// CHECK-NEXT:    [[MARKER:%.*]] = function_ref @marker
+// CHECK-NEXT:    [[A32:%.*]] = alloc_stack $Builtin.Int32
+// CHECK-NEXT:    [[I1000:%.*]] = integer_literal $Builtin.Int32, 1000
+// CHECK-NEXT:    store [[I1000]] to [trivial] [[A32]]
+// CHECK-NEXT:    [[I2000:%.*]] = integer_literal $Builtin.Int32, 2000
+// CHECK-NEXT:    apply [[MARKER]]([[I2000]])
+// CHECK-NEXT:    [[A16:%.*]] = alloc_stack $Builtin.Int16
+// CHECK-NEXT:    br bb1
+// CHECK:       bb1:
+// CHECK-NEXT:    [[I3000:%.*]] = integer_literal $Builtin.Int32, 3000
+// CHECK-NEXT:    apply [[MARKER]]([[I3000]])
+// CHECK-NEXT:    [[I4000:%.*]] = integer_literal $Builtin.Int32, 4000
+// CHECK-NEXT:    apply [[MARKER]]([[I4000]])
+// CHECK-NEXT:    tuple ()
+// CHECK-NEXT:    br [[END:bb[0-9]+]]
+// CHECK:       [[END]]:
+// CHECK-NEXT:    dealloc_stack [[A16]] : $*Builtin.Int16
+//   Note that this has been delayed to follow stack discipline.
+// CHECK-NEXT:    dealloc_stack [[A32]] : $*Builtin.Int32
+// CHECK-NEXT:    [[RET:%.*]] = tuple ()
+// CHECK-NEXT:    return [[RET]] : $()
+// CHECK-LABEL: // end sil function 'test_stack_overlap_alloc'
+sil @test_stack_overlap_alloc : $() -> () {
+bb0:
+  %0 = function_ref @stack_overlap : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
+  (%value, %token) = begin_apply %0() : $@convention(thin) @yield_once () -> (@yields @inout Builtin.Int32)
+  %stack = alloc_stack $Builtin.Int16
+  end_apply %token
+  dealloc_stack %stack : $*Builtin.Int16
+  %ret = tuple ()
+  return %ret : $()
+}
diff --git a/test/SILOptimizer/inline_heuristics.sil b/test/SILOptimizer/inline_heuristics.sil
index bb2e985..615b2c2 100644
--- a/test/SILOptimizer/inline_heuristics.sil
+++ b/test/SILOptimizer/inline_heuristics.sil
@@ -438,7 +438,7 @@
 // CHECK: end sil function 'testExclusivity' 
 
 struct X {
-  @sil_stored var i: Int64 { get set }
+  @_hasStorage var i: Int64 { get set }
   init(i: Int64)
   init()
 }
diff --git a/test/SILOptimizer/let_propagation.swift b/test/SILOptimizer/let_propagation.swift
index 01fb138..bed74de 100644
--- a/test/SILOptimizer/let_propagation.swift
+++ b/test/SILOptimizer/let_propagation.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -primary-file %s  -emit-sil -O | %FileCheck %s
+// RUN: %target-swift-frontend -primary-file %s  -emit-sil -enforce-exclusivity=unchecked -O | %FileCheck %s
 
 // Check that LoadStoreOpts can handle "let" variables properly.
 // Such variables should be loaded only once and their loaded values can be reused.
diff --git a/test/SILOptimizer/licm_exclusivity.sil b/test/SILOptimizer/licm_exclusivity.sil
index 57ad5dc..5891500 100644
--- a/test/SILOptimizer/licm_exclusivity.sil
+++ b/test/SILOptimizer/licm_exclusivity.sil
@@ -7,7 +7,7 @@
 import Swift
 
 struct X {
-  @sil_stored var i: Int64 { get set }
+  @_hasStorage var i: Int64 { get set }
   init(i: Int64)
   init()
 }
diff --git a/test/SILOptimizer/licm_exclusivity.swift b/test/SILOptimizer/licm_exclusivity.swift
index 85236b1..5fc49f5 100644
--- a/test/SILOptimizer/licm_exclusivity.swift
+++ b/test/SILOptimizer/licm_exclusivity.swift
@@ -35,12 +35,14 @@
 // TEST2: Hoist and Sink pairs attempt
 // TEST2: Hoisted
 
-// TESTSIL-LABEL: sil @$s16licm_exclusivity20count_unicodeScalarsyySS17UnicodeScalarViewVF : $@convention(thin) (@guaranteed String.UnicodeScalarView) -> () {
-// TESTSIL: bb0(%0 : $String.UnicodeScalarView)
-// TESTSIL-NEXT: %1 = global_addr @$s16licm_exclusivity5countSivp : $*Int
-// TESTSIL: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int
-// TESTSIL: end_access
-// TESTSIL: return
+// FIXME: <rdar://problem/45931225> Re-enable the below
+//
+// xTESTSIL-LABEL: sil @$s16licm_exclusivity20count_unicodeScalarsyySS17UnicodeScalarViewVF : $@convention(thin) (@guaranteed String.UnicodeScalarView) -> () {
+// xTESTSIL: bb0(%0 : $String.UnicodeScalarView)
+// xTESTSIL-NEXT: %1 = global_addr @$s16licm_exclusivity5countSivp : $*Int
+// xTESTSIL: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int
+// xTESTSIL: end_access
+// xTESTSIL: return
 var count: Int = 0
 public func count_unicodeScalars(_ s: String.UnicodeScalarView) {
   for _ in s {
diff --git a/test/SILOptimizer/mandatory_inlining.sil b/test/SILOptimizer/mandatory_inlining.sil
index 0160371..a269fca 100644
--- a/test/SILOptimizer/mandatory_inlining.sil
+++ b/test/SILOptimizer/mandatory_inlining.sil
@@ -17,7 +17,7 @@
 
 struct L {
   var start: Int32 { get }
-  @sil_stored let o: P2
+  @_hasStorage let o: P2
   init(o: P2)
 }
 
diff --git a/test/SILOptimizer/mem-behavior.sil b/test/SILOptimizer/mem-behavior.sil
index 390c702..0f40df9 100644
--- a/test/SILOptimizer/mem-behavior.sil
+++ b/test/SILOptimizer/mem-behavior.sil
@@ -6,8 +6,8 @@
 import Swift
 
 class X {
-  @sil_stored var a: Int32
-  @sil_stored var x: X
+  @_hasStorage var a: Int32
+  @_hasStorage var x: X
 
   init()
 }
diff --git a/test/SILOptimizer/objectoutliner.sil b/test/SILOptimizer/objectoutliner.sil
index c13e622..4982d23 100644
--- a/test/SILOptimizer/objectoutliner.sil
+++ b/test/SILOptimizer/objectoutliner.sil
@@ -7,7 +7,7 @@
 import Swift
 
 class Obj {
-  @sil_stored var value: Int64
+  @_hasStorage var value: Int64
   init()
 }
 
diff --git a/test/SILOptimizer/opened_archetype_operands_tracking.sil b/test/SILOptimizer/opened_archetype_operands_tracking.sil
index 3332211..7b72a81 100644
--- a/test/SILOptimizer/opened_archetype_operands_tracking.sil
+++ b/test/SILOptimizer/opened_archetype_operands_tracking.sil
@@ -72,7 +72,7 @@
 }
 
 final class ItemStorage<V> : DynamicStorage where V : View {
-  @sil_stored final let content: V
+  @_hasStorage final let content: V
   init(content: V)
   deinit
   override init()
@@ -83,7 +83,7 @@
 }
 
 public struct DynamicItem {
-  @sil_stored private var storage: DynamicStorage { get set }
+  @_hasStorage private var storage: DynamicStorage { get set }
   public init(view: View)
 }
 
@@ -136,8 +136,8 @@
 
 final class Foo<T> where T : P {
   init(_ x: T)
-  @sil_stored final var x: T { get set }
-  @sil_stored final var y: T { get set }
+  @_hasStorage final var x: T { get set }
+  @_hasStorage final var y: T { get set }
   deinit
 }
 
diff --git a/test/SILOptimizer/optionset.swift b/test/SILOptimizer/optionset.swift
index 3be6ff1..5904fd3 100644
--- a/test/SILOptimizer/optionset.swift
+++ b/test/SILOptimizer/optionset.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend  -parse-as-library -primary-file %s -O -sil-verify-all -module-name=test -emit-sil | %FileCheck %s
-// RUN: %target-swift-frontend  -parse-as-library -primary-file %s -Osize -sil-verify-all -module-name=test -emit-sil | %FileCheck %s
+// RUN: %target-swift-frontend  -parse-as-library -primary-file %s -O -sil-verify-all -module-name=test -emit-sil -enforce-exclusivity=unchecked | %FileCheck %s
+// RUN: %target-swift-frontend  -parse-as-library -primary-file %s -Osize -sil-verify-all -module-name=test -emit-sil -enforce-exclusivity=unchecked | %FileCheck %s
 // REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
 
 public struct TestOptions: OptionSet {
diff --git a/test/SILOptimizer/outliner.swift b/test/SILOptimizer/outliner.swift
index 128b22f..8d1f368 100644
--- a/test/SILOptimizer/outliner.swift
+++ b/test/SILOptimizer/outliner.swift
@@ -1,5 +1,5 @@
-// RUN: %target-swift-frontend -Osize -import-objc-header %S/Inputs/Outliner.h %s -emit-sil | %FileCheck %s
-// RUN: %target-swift-frontend -Osize -g -import-objc-header %S/Inputs/Outliner.h %s -emit-sil | %FileCheck %s
+// RUN: %target-swift-frontend -Osize -import-objc-header %S/Inputs/Outliner.h %s -emit-sil -enforce-exclusivity=unchecked | %FileCheck %s
+// RUN: %target-swift-frontend -Osize -g -import-objc-header %S/Inputs/Outliner.h %s -emit-sil -enforce-exclusivity=unchecked | %FileCheck %s
 
 // REQUIRES: objc_interop
 
diff --git a/test/SILOptimizer/ownership_model_eliminator.sil b/test/SILOptimizer/ownership_model_eliminator.sil
index 8e84a80..1d55a5f 100644
--- a/test/SILOptimizer/ownership_model_eliminator.sil
+++ b/test/SILOptimizer/ownership_model_eliminator.sil
@@ -232,7 +232,7 @@
 }
 
 class TestArrayStorage {
-  @sil_stored var count: Builtin.Int32
+  @_hasStorage var count: Builtin.Int32
   init()
 }
 
diff --git a/test/SILOptimizer/pound_assert_removed.swift b/test/SILOptimizer/pound_assert_removed.swift
new file mode 100644
index 0000000..2129e8e
--- /dev/null
+++ b/test/SILOptimizer/pound_assert_removed.swift
@@ -0,0 +1,8 @@
+// RUN: %target-swift-frontend -enable-experimental-static-assert -emit-silgen %s | %target-sil-opt -irgen-prepare | %FileCheck %s
+
+// Tests that mandatory SIL passes remove the builtin poundAssert instruction.
+// CHECK-LABEL: pound_assert_removed14builtinRemoved
+public func builtinRemoved() {
+  #assert(true)
+  // CHECK-NOT: builtin "poundAssert"
+}
diff --git a/test/SILOptimizer/redundant_load_elim_with_casts.sil b/test/SILOptimizer/redundant_load_elim_with_casts.sil
index bb825c9..25daf4f 100644
--- a/test/SILOptimizer/redundant_load_elim_with_casts.sil
+++ b/test/SILOptimizer/redundant_load_elim_with_casts.sil
@@ -362,7 +362,7 @@
 }
 
 class Empty {}
-struct HoldsRef { @sil_stored var c: Empty }
+struct HoldsRef { @_hasStorage var c: Empty }
 
 sil @mutator : $@convention(method) (@inout HoldsRef) -> ()
 
diff --git a/test/SILOptimizer/retain_release_code_motion.sil b/test/SILOptimizer/retain_release_code_motion.sil
index 5e16954..0cc3bf3 100644
--- a/test/SILOptimizer/retain_release_code_motion.sil
+++ b/test/SILOptimizer/retain_release_code_motion.sil
@@ -62,7 +62,7 @@
 }
 
 struct Unowned {
-  @sil_stored unowned let x: @sil_unowned Builtin.NativeObject
+  @_hasStorage unowned let x: @sil_unowned Builtin.NativeObject
 }
 
 sil @createS : $@convention(thin) () -> @owned S
@@ -265,7 +265,7 @@
 }
 
 final class MyArrayBuffer {
-  @sil_stored var dummyElements: Int32
+  @_hasStorage var dummyElements: Int32
   init()
 }
 
diff --git a/test/SILOptimizer/semantic-arc-opts.sil b/test/SILOptimizer/semantic-arc-opts.sil
index 7e54ab9..58e50ff 100644
--- a/test/SILOptimizer/semantic-arc-opts.sil
+++ b/test/SILOptimizer/semantic-arc-opts.sil
@@ -10,6 +10,11 @@
 
 sil @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
 
+struct NativeObjectPair {
+  var obj1 : Builtin.NativeObject
+  var obj2 : Builtin.NativeObject
+}
+
 ///////////
 // Tests //
 ///////////
@@ -94,3 +99,92 @@
   %9999 = tuple()
   return %9999 : $()
 }
+
+// CHECK-LABEL: sil @copy_struct_extract_guaranteed_use : $@convention(thin) (@guaranteed NativeObjectPair) -> () {
+// CHECK: bb0([[ARG:%.*]] : @guaranteed $NativeObjectPair):
+// CHECK-NOT: copy_value
+// CHECK-NOT: begin_borrow
+// CHECK:   [[FIELD:%.*]] = struct_extract [[ARG]]
+// CHECK:   apply {{%.*}}([[FIELD]]) :
+// CHECK-NEXT: tuple
+// CHECK-NEXT: return
+// CHECK: } // end sil function 'copy_struct_extract_guaranteed_use'
+sil @copy_struct_extract_guaranteed_use : $@convention(thin) (@guaranteed NativeObjectPair) -> () {
+bb0(%0 : @guaranteed $NativeObjectPair):
+  %1 = copy_value %0 : $NativeObjectPair
+  %2 = begin_borrow %1 : $NativeObjectPair
+  %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
+  %4 = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  apply %4(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  end_borrow %2 : $NativeObjectPair
+  destroy_value %1 : $NativeObjectPair
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @struct_extract_copy_guaranteed_use : $@convention(thin) (@guaranteed NativeObjectPair) -> () {
+// CHECK: bb0([[ARG:%.*]] : @guaranteed $NativeObjectPair):
+// CHECK:   [[FIELD:%.*]] = struct_extract [[ARG]]
+// CHECK:   apply {{%.*}}([[FIELD]])
+// CHECK-NOT: destroy_value
+// CHECK: } // end sil function 'struct_extract_copy_guaranteed_use'
+sil @struct_extract_copy_guaranteed_use : $@convention(thin) (@guaranteed NativeObjectPair) -> () {
+bb0(%0 : @guaranteed $NativeObjectPair):
+  %1 = struct_extract %0 : $NativeObjectPair, #NativeObjectPair.obj1
+  %2 = copy_value %1 : $Builtin.NativeObject
+  %3 = begin_borrow %2 : $Builtin.NativeObject
+  %4 = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  apply %4(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  end_borrow %3 : $Builtin.NativeObject
+  destroy_value %2 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// For now we do not support recreating forwarding instructions since we do not
+// dynamically recompute ownership.
+// CHECK-LABEL: sil @do_not_process_forwarding_uses : $@convention(thin) (@guaranteed NativeObjectPair) -> () {
+// CHECK: copy_value
+// CHECK: } // end sil function 'do_not_process_forwarding_uses'
+sil @do_not_process_forwarding_uses : $@convention(thin) (@guaranteed NativeObjectPair) -> () {
+bb0(%0 : @guaranteed $NativeObjectPair):
+  %1 = copy_value %0 : $NativeObjectPair
+  (%2, %3) = destructure_struct %1 : $NativeObjectPair
+  %4 = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  apply %4(%2) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  apply %4(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  destroy_value %2 : $Builtin.NativeObject
+  destroy_value %3 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @do_not_process_forwarding_uses_2 : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+// CHECK: copy_value
+// CHECK: } // end sil function 'do_not_process_forwarding_uses_2'
+sil @do_not_process_forwarding_uses_2 : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : @guaranteed $Builtin.NativeObject):
+  %1 = copy_value %0 : $Builtin.NativeObject
+  %2 = unchecked_ref_cast %1 : $Builtin.NativeObject to $Builtin.NativeObject
+  %4 = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  apply %4(%2) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  destroy_value %2 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// Do not eliminate a copy from an unowned value. This will cause us to pass the
+// unowned value as guaranteed... =><=.
+//
+// CHECK-LABEL: sil @unowned_arg_copy : $@convention(thin) (Builtin.NativeObject) -> () {
+// CHECK: copy_value
+// CHECK: } // end sil function 'unowned_arg_copy'
+sil @unowned_arg_copy : $@convention(thin) (Builtin.NativeObject) -> () {
+bb0(%0 : @unowned $Builtin.NativeObject):
+  %1 = copy_value %0 : $Builtin.NativeObject
+  %2 = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  apply %2(%1) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
+  destroy_value %1 : $Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/SILOptimizer/side-effect.sil b/test/SILOptimizer/side-effect.sil
index dfb0620..3175fbc 100644
--- a/test/SILOptimizer/side-effect.sil
+++ b/test/SILOptimizer/side-effect.sil
@@ -27,8 +27,8 @@
 }
 
 class X {
-  @sil_stored var a: Int32
-  @sil_stored var x: X
+  @_hasStorage var a: Int32
+  @_hasStorage var x: X
 
   init()
 }
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index a6460da..29b1ff0 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -2352,10 +2352,8 @@
 
 // CHECK-LABEL:   sil @remove_dead_code_after_unreachable
 // CHECK-NEXT:      bb0
-// CHECK-NOT:       integer_literal $Builtin.Int32, -2
 // CHECK-NEXT:      unreachable
-// CHECK-NOT:       integer_literal $Builtin.Int32, -2
-// CHECK-NEXT:      }
+// CHECK-NEXT:      } // end sil function 'remove_dead_code_after_unreachable'
 sil @remove_dead_code_after_unreachable : $@convention(thin) () -> (Int32) {
 bb0:
   unreachable
@@ -3217,7 +3215,7 @@
 
 
 public final class VV {
-  @sil_stored final var m: PM { get set }
+  @_hasStorage final var m: PM { get set }
   init()
   deinit
 }
diff --git a/test/SILOptimizer/sil_combine_concrete_existential.sil b/test/SILOptimizer/sil_combine_concrete_existential.sil
index 54d63b0..9e93646 100644
--- a/test/SILOptimizer/sil_combine_concrete_existential.sil
+++ b/test/SILOptimizer/sil_combine_concrete_existential.sil
@@ -409,3 +409,31 @@
   %v = tuple ()
   return %v : $()
 }
+
+sil @takeany :  $@convention(thin) (@in_guaranteed AnyP) -> ()
+
+// CHECK-LABEL: sil @testWitnessCopiedSelfWithIndirectResult2 : $@convention(thin) () -> () {
+// CHECK: [[IN:%[0-9]+]] = alloc_stack $AnyP
+// CHECK: [[EA:%[0-9]+]] = init_existential_addr [[IN]]
+// CHECK: [[OUT:%[0-9]+]] = alloc_stack $StructOfAnyP
+// CHECK: witness_method $StructOfAnyP, #AnyP.returnsSelf!1 : <Self where Self : AnyP> (Self) -> () -> @dynamic_self Self : $@convention(witness_method: AnyP) <τ_0_0 where τ_0_0 : AnyP> (@in_guaranteed τ_0_0) -> @out StructOfAnyP
+// CHECK: apply %{{.*}}<StructOfAnyP>([[OUT]], [[EA]]) : $@convention(witness_method: AnyP) <τ_0_0 where τ_0_0 : AnyP> (@in_guaranteed τ_0_0) -> @out StructOfAnyP
+// CHECK-LABEL: } // end sil function 'testWitnessCopiedSelfWithIndirectResult2'
+sil @testWitnessCopiedSelfWithIndirectResult2 : $() -> () {
+bb0:
+  %a0 = alloc_stack $AnyP
+  %ie0 = init_existential_addr %a0 : $*AnyP, $StructOfAnyP
+  %f1 = function_ref @takeany :  $@convention(thin) (@in_guaranteed AnyP) -> ()
+  %c1 = apply %f1(%a0) :  $@convention(thin) (@in_guaranteed AnyP) -> ()
+  %a1 = alloc_stack $AnyP
+  copy_addr %a0 to [initialization] %a1 : $*AnyP
+  %o0 = open_existential_addr immutable_access %a1 : $*AnyP to $*@opened("7C4DAF8E-D722-11E8-920A-D0817AD9F6DD") AnyP
+  %a2 = alloc_stack $StructOfAnyP
+  %w0 = witness_method $@opened("7C4DAF8E-D722-11E8-920A-D0817AD9F6DD") AnyP, #AnyP.returnsSelf!1 : <Self where Self : AnyP> (Self) -> () -> @dynamic_self Self, %o0 : $*@opened("7C4DAF8E-D722-11E8-920A-D0817AD9F6DD") AnyP : $@convention(witness_method: AnyP) <τ_0_0 where τ_0_0 : AnyP> (@in_guaranteed τ_0_0) -> @out StructOfAnyP
+  %c0 = apply %w0<@opened("7C4DAF8E-D722-11E8-920A-D0817AD9F6DD") AnyP>(%a2, %o0) : $@convention(witness_method: AnyP) <τ_0_0 where τ_0_0 : AnyP> (@in_guaranteed τ_0_0) -> @out StructOfAnyP
+  dealloc_stack %a2 : $*StructOfAnyP
+  dealloc_stack %a1 : $*AnyP
+  dealloc_stack %a0 : $*AnyP
+  %v = tuple ()
+  return %v : $()
+}
diff --git a/test/SILOptimizer/sil_combine_enums.sil b/test/SILOptimizer/sil_combine_enums.sil
index c6f6129..728a76d 100644
--- a/test/SILOptimizer/sil_combine_enums.sil
+++ b/test/SILOptimizer/sil_combine_enums.sil
@@ -423,8 +423,8 @@
 public class C {}
 public struct S {}
 public struct T {
-  @sil_stored let c: C
-  @sil_stored let s: S
+  @_hasStorage let c: C
+  @_hasStorage let s: S
 }
 public enum X {
   case none
diff --git a/test/SILOptimizer/sil_combine_objc_bridge.sil b/test/SILOptimizer/sil_combine_objc_bridge.sil
index 5a6967d..a82500d 100644
--- a/test/SILOptimizer/sil_combine_objc_bridge.sil
+++ b/test/SILOptimizer/sil_combine_objc_bridge.sil
@@ -20,7 +20,7 @@
 }
 
 struct AnArray<T> : _ObjectiveCBridgeable {
-  @sil_stored var Buffer : Builtin.NativeObject
+  @_hasStorage var Buffer : Builtin.NativeObject
 
   func _bridgeToObjectiveC() -> AnNSArray {
     return AnNSArray()
diff --git a/test/SILOptimizer/sil_combine_protocol_conf.swift b/test/SILOptimizer/sil_combine_protocol_conf.swift
index fd6e116..4d8102a 100644
--- a/test/SILOptimizer/sil_combine_protocol_conf.swift
+++ b/test/SILOptimizer/sil_combine_protocol_conf.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -O -wmo -emit-sil -Xllvm -sil-disable-pass=DeadFunctionElimination | %FileCheck %s
+// RUN: %target-swift-frontend %s -O -wmo -emit-sil -Xllvm -sil-disable-pass=DeadFunctionElimination -enforce-exclusivity=unchecked | %FileCheck %s
 
 // case 1: class protocol -- should optimize
 internal protocol SomeProtocol : class {
diff --git a/test/SILOptimizer/sil_simplify_instrs.sil b/test/SILOptimizer/sil_simplify_instrs.sil
index 2bf99b9..44eb8b5 100644
--- a/test/SILOptimizer/sil_simplify_instrs.sil
+++ b/test/SILOptimizer/sil_simplify_instrs.sil
@@ -130,7 +130,7 @@
 }
 
 class IntClass {
-  @sil_stored var value: Builtin.Int32 { get set }
+  @_hasStorage var value: Builtin.Int32 { get set }
   init(value: Builtin.Int32)
   @objc deinit
 }
diff --git a/test/SILOptimizer/simplify_cfg_args_crash.sil b/test/SILOptimizer/simplify_cfg_args_crash.sil
index f0dd82a..7800f08 100644
--- a/test/SILOptimizer/simplify_cfg_args_crash.sil
+++ b/test/SILOptimizer/simplify_cfg_args_crash.sil
@@ -36,13 +36,13 @@
 // Verify that we do not crash in argument splitting (rdar://problem/25008398).
 
 class C {
-  @sil_stored let x: Builtin.Int32
+  @_hasStorage let x: Builtin.Int32
   init()
 }
 
 struct Pair {
-  @sil_stored let first: C
-  @sil_stored let second: C
+  @_hasStorage let first: C
+  @_hasStorage let second: C
 }
 
 // CHECK-LABEL: @simplify_args_crash
diff --git a/test/SILOptimizer/simplify_cfg_jump_thread_crash.sil b/test/SILOptimizer/simplify_cfg_jump_thread_crash.sil
index f6f87ec..b83d2c1 100644
--- a/test/SILOptimizer/simplify_cfg_jump_thread_crash.sil
+++ b/test/SILOptimizer/simplify_cfg_jump_thread_crash.sil
@@ -50,8 +50,8 @@
 public final class AA {
 }
 public final class BB {
-  @sil_stored internal weak final var n:  BB!
-  @sil_stored internal final var o: AA!
+  @_hasStorage internal weak final var n:  BB!
+  @_hasStorage internal final var o: AA!
 }
 
 // Test that SimplifyCFG does not hang when compiling an infinite loop with switch_enum.
diff --git a/test/SILOptimizer/sr-5068.sil b/test/SILOptimizer/sr-5068.sil
index 1636160..4d2989a 100644
--- a/test/SILOptimizer/sr-5068.sil
+++ b/test/SILOptimizer/sr-5068.sil
@@ -42,7 +42,7 @@
 var currentModel: Model { get }
 
 public class Model : Object {
-  @sil_stored var id: Int { get set }
+  @_hasStorage var id: Int { get set }
   override init()
   init(value: Any)
   deinit
diff --git a/test/SILOptimizer/stack_promotion.sil b/test/SILOptimizer/stack_promotion.sil
index 66db7b7..9915d8f 100644
--- a/test/SILOptimizer/stack_promotion.sil
+++ b/test/SILOptimizer/stack_promotion.sil
@@ -7,20 +7,20 @@
 import SwiftShims
 
 class XX {
-	@sil_stored var x: Int32
+	@_hasStorage var x: Int32
 
 	init()
 }
 
 class YY {
-	@sil_stored var xx: XX
+	@_hasStorage var xx: XX
 
 	init(newx: XX)
 }
 
 class DummyArrayStorage<Element> {
-  @sil_stored var count : Int
-  @sil_stored var capacity : Int
+  @_hasStorage var count : Int
+  @_hasStorage var capacity : Int
   init()
 }
 
diff --git a/test/SILOptimizer/static_arrays.swift b/test/SILOptimizer/static_arrays.swift
index adfce54..dddb8b6 100644
--- a/test/SILOptimizer/static_arrays.swift
+++ b/test/SILOptimizer/static_arrays.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend  -primary-file %s -O -sil-verify-all -Xllvm -sil-disable-pass=FunctionSignatureOpts -module-name=test -emit-sil | %FileCheck %s
+// RUN: %target-swift-frontend  -primary-file %s -O -sil-verify-all -Xllvm -sil-disable-pass=FunctionSignatureOpts -module-name=test -emit-sil -enforce-exclusivity=unchecked | %FileCheck %s
 
 // Also do an end-to-end test to check all components, including IRGen.
 // RUN: %empty-directory(%t) 
diff --git a/test/SILOptimizer/string_literals.swift b/test/SILOptimizer/string_literals.swift
index 121fd83..0e46a9f 100644
--- a/test/SILOptimizer/string_literals.swift
+++ b/test/SILOptimizer/string_literals.swift
@@ -2,6 +2,10 @@
 // RUN: %target-swift-frontend -parse-as-library -Osize -emit-ir  %s | %FileCheck %s
 // REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
 
+// FIXME(rdar://problem/45856408): The 7-bit discriminator complicates codegen
+// on 32-bit platforms.
+// UNSUPPORTED: PTRSIZE=32
+
 // This is an end-to-end test to ensure that the optimizer generates
 // optimal code for string literals
 
diff --git a/test/SILOptimizer/unsafe_guaranteed_peephole.sil b/test/SILOptimizer/unsafe_guaranteed_peephole.sil
index 97c35cd..7560708 100644
--- a/test/SILOptimizer/unsafe_guaranteed_peephole.sil
+++ b/test/SILOptimizer/unsafe_guaranteed_peephole.sil
@@ -375,7 +375,7 @@
 }
 
 struct MyInt {
-  @sil_stored var val: Builtin.Int32
+  @_hasStorage var val: Builtin.Int32
 }
 
 // CHECK-LABEL: sil @testUnsafeGuaranteed_sideeffectfree_inst
diff --git a/test/Sema/pound_assert.swift b/test/Sema/pound_assert.swift
new file mode 100644
index 0000000..598e2f0
--- /dev/null
+++ b/test/Sema/pound_assert.swift
@@ -0,0 +1,13 @@
+// RUN: %target-typecheck-verify-swift -enable-experimental-static-assert
+
+#assert(true)
+
+#assert(true, "error message")
+
+#assert(false)
+
+#assert(false, "error message")
+
+#assert(123) // expected-error{{'Int' is not convertible to 'Bool'}}
+
+#assert(123, "error message") // expected-error{{'Int' is not convertible to 'Bool'}}
diff --git a/test/Sema/string_to_substring_conversion.swift b/test/Sema/string_to_substring_conversion.swift
index e0e66ef..99bf3bc 100644
--- a/test/Sema/string_to_substring_conversion.swift
+++ b/test/Sema/string_to_substring_conversion.swift
@@ -5,7 +5,7 @@
 
 // CTP_Initialization
 do {
-  let s1: Substring = { return s }() // expected-error {{cannot convert value of type 'String' to specified type 'Substring'}} {{37-37=[]}}
+  let s1: Substring = { return s }() // expected-error {{cannot convert value of type 'String' to closure result type 'Substring'}} {{33-33=[]}}
   _ = s1
 }
 
diff --git a/test/Sema/substring_to_string_conversion_swift4.swift b/test/Sema/substring_to_string_conversion_swift4.swift
index 0642bde..6f43173 100644
--- a/test/Sema/substring_to_string_conversion_swift4.swift
+++ b/test/Sema/substring_to_string_conversion_swift4.swift
@@ -5,7 +5,7 @@
 
 // CTP_Initialization
 do {
-  let s1: String = { return ss }() // expected-error {{cannot convert value of type 'Substring' to specified type 'String'}} {{20-20=String(}} {{35-35=)}}
+  let s1: String = { return ss }() // expected-error {{cannot convert value of type 'Substring' to closure result type 'String'}} {{29-29=String(}} {{31-31=)}}
   _ = s1
 }
 
diff --git a/test/Sema/typo_correction.swift b/test/Sema/typo_correction.swift
index 73af308..033d4b5 100644
--- a/test/Sema/typo_correction.swift
+++ b/test/Sema/typo_correction.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -typo-correction-limit 20
+// RUN: %target-typecheck-verify-swift -typo-correction-limit 22
 // RUN: not %target-swift-frontend -typecheck -disable-typo-correction %s 2>&1 | %FileCheck %s -check-prefix=DISABLED
 // RUN: not %target-swift-frontend -typecheck -typo-correction-limit 0 %s 2>&1 | %FileCheck %s -check-prefix=DISABLED
 // RUN: not %target-swift-frontend -typecheck -DIMPORT_FAIL %s 2>&1 | %FileCheck %s -check-prefix=DISABLED
@@ -177,3 +177,17 @@
     }
   }
 }
+
+// Don't show underscored names as typo corrections unless the typed name also
+// begins with an underscore.
+func test_underscored_no_match() {
+  let _ham = 0
+  _ = ham
+  // expected-error@-1 {{use of unresolved identifier 'ham'}}
+}
+
+func test_underscored_match() {
+  let _eggs = 4 // expected-note {{'_eggs' declared here}}
+  _ = _fggs + 1
+  // expected-error@-1 {{use of unresolved identifier '_fggs'; did you mean '_eggs'?}}
+}
diff --git a/test/Serialization/Inputs/def_always_inline.swift b/test/Serialization/Inputs/def_always_inline.swift
index 01f8fd8..bdb3d53 100644
--- a/test/Serialization/Inputs/def_always_inline.swift
+++ b/test/Serialization/Inputs/def_always_inline.swift
@@ -1,4 +1,4 @@
-@inline(__always) public func testAlwaysInline(x: Bool) -> Bool {
+@inline(__always) @inlinable public func testAlwaysInline(x: Bool) -> Bool {
   return x
 }
 
@@ -7,7 +7,7 @@
   @usableFromInline
   var x: Bool
 
-  @inline(__always)
+  @inline(__always) @inlinable
   public init(x x2: Bool) {
     self.x = x2
   }
diff --git a/test/Serialization/Inputs/def_basic.sil b/test/Serialization/Inputs/def_basic.sil
index 50f6ada..02ffd28 100644
--- a/test/Serialization/Inputs/def_basic.sil
+++ b/test/Serialization/Inputs/def_basic.sil
@@ -1223,8 +1223,8 @@
 }
 
 public class WeakUnownedTest {
-  @sil_stored public unowned var unownedVal: @sil_unowned AnyObject { get set }
-  @sil_stored public weak var weakVal: @sil_weak AnyObject? { get set }
+  @_hasStorage public unowned var unownedVal: @sil_unowned AnyObject { get set }
+  @_hasStorage public weak var weakVal: @sil_weak AnyObject? { get set }
   public init(protoVal: AnyObject)
   deinit
 }
@@ -1249,7 +1249,7 @@
 
 
 class A {
-  @sil_stored var property: Any { get set }
+  @_hasStorage var property: Any { get set }
   deinit
   init()
 }
diff --git a/test/Serialization/Inputs/private_import_other.swift b/test/Serialization/Inputs/private_import_other.swift
new file mode 100644
index 0000000..8126e38
--- /dev/null
+++ b/test/Serialization/Inputs/private_import_other.swift
@@ -0,0 +1,10 @@
+private struct Base {
+  private func bar() {}
+}
+
+struct Value {
+}
+
+extension Value {
+  fileprivate func foo() {}
+}
diff --git a/test/Serialization/Inputs/private_import_other_2.swift b/test/Serialization/Inputs/private_import_other_2.swift
new file mode 100644
index 0000000..8209dbd
--- /dev/null
+++ b/test/Serialization/Inputs/private_import_other_2.swift
@@ -0,0 +1,11 @@
+private struct Base {
+  private func member() {}
+  private func bar() {}
+}
+
+private struct Other {
+}
+
+extension Value {
+  fileprivate func foo() {}
+}
diff --git a/test/Serialization/load-invalid-arch.swift b/test/Serialization/load-invalid-arch.swift
index 4b02aae..8f3c468 100644
--- a/test/Serialization/load-invalid-arch.swift
+++ b/test/Serialization/load-invalid-arch.swift
@@ -5,23 +5,29 @@
 // RUN: touch %t/new_module.swiftmodule/ppc65.swiftmodule
 // RUN: touch %t/new_module.swiftmodule/i387.swiftdoc
 // RUN: touch %t/new_module.swiftmodule/ppc65.swiftdoc
-// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -DTARGET_ARCHITECTURE=$(echo %target-swiftmodule-name | cut -d. -f1)
+// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=$(echo %target-swiftmodule-name | cut -d. -f1)
 
 // RUN: %empty-directory(%t)
 // RUN: mkdir -p %t/new_module.framework/Modules/new_module.swiftmodule/
 // RUN: touch %t/new_module.framework/Modules/new_module.swiftmodule/i387.swiftmodule
 // RUN: touch %t/new_module.framework/Modules/new_module.swiftmodule/ppc65.swiftmodule
-// RUN: not %target-swift-frontend %s -F %t -typecheck -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -DTARGET_ARCHITECTURE=$(echo %target-swiftmodule-name | cut -d. -f1)
+// RUN: not %target-swift-frontend %s -F %t -typecheck -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=$(echo %target-swiftmodule-name | cut -d. -f1)
 
-//CHECK: {{.*}} error: could not find module 'new_module' for architecture '[[TARGET_ARCHITECTURE]]'; found: {{ppc65, i387|i387, ppc65}}
-//CHECK-NEXT: import new_module
-//CHECK-NEXT: 		^
-//CHECK: error: no such module 'new_module'
-//CHECK-NEXT: import new_module
-//CHECK-NEXT: 		^
-//CHECK: error: use of unresolved identifier 'new_module'
-//CHECK-NEXT: new_module.foo()
-//CHECK-NEXT: ^~~~~~~~~~
+// RUN: %empty-directory(%t)
+// RUN: mkdir %t/new_module.swiftmodule
+// RUN: not %target-swift-frontend %s -typecheck -I %t -show-diagnostics-after-fatal 2>&1 | %FileCheck %s -check-prefix=CHECK-EMPTY -check-prefix CHECK-ALL -DTARGET_ARCHITECTURE=$(echo %target-swiftmodule-name | cut -d. -f1)
+
+// CHECK-ALL-NOT: error:
+// CHECK: {{.*}} error: could not find module 'new_module' for architecture '[[TARGET_ARCHITECTURE]]'; found: {{ppc65, i387|i387, ppc65}}
+// CHECK-NEXT: import new_module
+// CHECK-NEXT: 		^
+// CHECK-ALL: error: no such module 'new_module'
+// CHECK-ALL-NEXT: import new_module
+// CHECK-ALL-NEXT: 		^
+// CHECK-ALL: error: use of unresolved identifier 'new_module'
+// CHECK-ALL-NEXT: new_module.foo()
+// CHECK-ALL-NEXT: ^~~~~~~~~~
+// CHECK-ALL-NOT: error:
 
 import new_module
 
diff --git a/test/Serialization/private_import.swift b/test/Serialization/private_import.swift
new file mode 100644
index 0000000..8108621
--- /dev/null
+++ b/test/Serialization/private_import.swift
@@ -0,0 +1,51 @@
+// RUN: %empty-directory(%t)
+
+// This test has two purposes. This first block just tests that we serialize
+// the -enable-private-imports flag correctly...
+
+// RUN: %target-swift-frontend -emit-module -DBASE -o %t %s
+// RUN: llvm-bcanalyzer -dump %t/private_import.swiftmodule > %t/private_import.dump.txt
+// RUN: %FileCheck -check-prefix=CHECK -check-prefix=NO-PRIVATE-IMPORT %s < %t/private_import.dump.txt
+
+// RUN: %target-build-swift -module-name private_import -emit-module -o %t -enable-private-imports %S/Inputs/private_import_other.swift %S/Inputs/private_import_other_2.swift
+// RUN: llvm-bcanalyzer -dump %t/private_import.swiftmodule > %t/private_import.dump.txt
+// RUN: %FileCheck -check-prefix=CHECK -check-prefix=PRIVATE-IMPORT %s < %t/private_import.dump.txt
+// RUN: %FileCheck -check-prefix=NEGATIVE %s < %t/private_import.dump.txt
+
+// RUN: %target-swift-frontend -emit-module -DCLIENT -o %t -enable-private-imports %s -module-name client -I %t
+// RUN: %target-swift-frontend -emit-sil -DMAIN %s -module-name main -I %t > /dev/null
+
+// CHECK: <MODULE_BLOCK {{.*}}>
+// PRIVATE-IMPORT: <ARE_PRIVATE_IMPORTS_ENABLED abbrevid={{[0-9]+}}/>
+// NO-PRIVATE-IMPORT-NOT: ARE_PRIVATE_IMPORTS_ENABLED
+// CHECK: </MODULE_BLOCK>
+// CHECK-NOT: <MODULE_BLOCK {{.*}}>
+
+// NEGATIVE-NOT: UnknownCode
+
+#if BASE
+#elseif  CLIENT
+
+  @_private(sourceFile: "private_import_other.swift") import private_import
+
+  extension Base {
+    private func foo() {}
+  }
+
+  public func unreleated() {}
+
+	// This should not conflict with Other from private_import_other_2.swift.
+  struct Other {}
+#elseif MAIN
+
+  @_private(sourceFile: "private_import_other.swift") import private_import
+  @_private(sourceFile: "private_import.swift") import client
+
+  Base().foo()
+  // This should not be ambigious.
+  Base().bar()
+  // This should not conflict with the second declaration in
+  // private_import_other_2.swift.
+  Value().foo()
+  unreleated()
+#endif
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 7facd36..2c1af8b 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -557,4 +557,8 @@
 
 #sourceLocation()</PoundSourceLocation>
 
-"<StringSegment>abc </StringSegment>\( } )<StringSegment> def</StringSegment>"
+"<StringSegment>abc </StringSegment>\( } )<StringSegment> def</StringSegment>"<PoundAssertStmt>
+
+#assert(<BooleanLiteralExpr>true</BooleanLiteralExpr>)</PoundAssertStmt><PoundAssertStmt>
+#assert(<BooleanLiteralExpr>false</BooleanLiteralExpr>)</PoundAssertStmt><PoundAssertStmt>
+#assert(<BooleanLiteralExpr>true</BooleanLiteralExpr>, "hello world")</PoundAssertStmt>
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index 2b4fd25..b17b017 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -558,3 +558,7 @@
 #sourceLocation()
 
 "abc \( } ) def"
+
+#assert(true)
+#assert(false)
+#assert(true, "hello world")
diff --git a/test/api-digester/Inputs/stdlib-stable-abi.json b/test/api-digester/Inputs/stdlib-stable-abi.json
index a59c9b3..150ccd9 100644
--- a/test/api-digester/Inputs/stdlib-stable-abi.json
+++ b/test/api-digester/Inputs/stdlib-stable-abi.json
@@ -126483,8 +126483,8 @@
     },
     {
       "kind": "Function",
-      "name": "_projectKeyPathPartial",
-      "printedName": "_projectKeyPathPartial(root:keyPath:)",
+      "name": "_getAtPartialKeyPath",
+      "printedName": "_getAtPartialKeyPath(root:keyPath:)",
       "children": [
         {
           "kind": "TypeNominal",
@@ -126511,18 +126511,15 @@
         }
       ],
       "declKind": "Func",
-      "usr": "s:s22_projectKeyPathPartial4root03keyC0ypx_s0dbC0CyxGtlF",
+      "usr": "s:swift_getAtPartialKeyPath",
       "moduleName": "Swift",
       "genericSig": "<τ_0_0>",
-      "declAttributes": [
-        "Inlinable"
-      ],
       "funcSelfKind": "NonMutating"
     },
     {
       "kind": "Function",
-      "name": "_projectKeyPathAny",
-      "printedName": "_projectKeyPathAny(root:keyPath:)",
+      "name": "_getAtAnyKeyPath",
+      "printedName": "_getAtAnyKeyPath(root:keyPath:)",
       "children": [
         {
           "kind": "TypeNominal",
@@ -126550,18 +126547,15 @@
         }
       ],
       "declKind": "Func",
-      "usr": "s:s18_projectKeyPathAny4root03keyC0ypSgx_s0dbC0CtlF",
+      "usr": "s:swift_getAtAnyKeyPath",
       "moduleName": "Swift",
       "genericSig": "<τ_0_0>",
-      "declAttributes": [
-        "Inlinable"
-      ],
       "funcSelfKind": "NonMutating"
     },
     {
       "kind": "Function",
-      "name": "_projectKeyPathReadOnly",
-      "printedName": "_projectKeyPathReadOnly(root:keyPath:)",
+      "name": "_getAtKeyPath",
+      "printedName": "_getAtKeyPath(root:keyPath:)",
       "children": [
         {
           "kind": "TypeNominal",
@@ -126593,64 +126587,26 @@
         }
       ],
       "declKind": "Func",
-      "usr": "s:s23_projectKeyPathReadOnly4root03keyC0q_x_s0bC0Cyxq_Gtr0_lF",
+      "usr": "s:swift_getAtKeyPath",
       "moduleName": "Swift",
       "genericSig": "<τ_0_0, τ_0_1>",
-      "declAttributes": [
-        "Inlinable"
-      ],
       "funcSelfKind": "NonMutating"
     },
     {
       "kind": "Function",
-      "name": "_projectKeyPathWritable",
-      "printedName": "_projectKeyPathWritable(root:keyPath:)",
+      "name": "_setAtWritableKeyPath",
+      "printedName": "_setAtWritableKeyPath(root:keyPath:value:)",
       "children": [
         {
           "kind": "TypeNominal",
-          "name": "Tuple",
-          "printedName": "(UnsafeMutablePointer<τ_0_1>, Optional<AnyObject>)",
-          "children": [
-            {
-              "kind": "TypeNominal",
-              "name": "UnsafeMutablePointer",
-              "printedName": "UnsafeMutablePointer<τ_0_1>",
-              "children": [
-                {
-                  "kind": "TypeNominal",
-                  "name": "GenericTypeParam",
-                  "printedName": "τ_0_1"
-                }
-              ],
-              "usr": "s:Sp"
-            },
-            {
-              "kind": "TypeNominal",
-              "name": "Optional",
-              "printedName": "Optional<AnyObject>",
-              "children": [
-                {
-                  "kind": "TypeNominal",
-                  "name": "ProtocolComposition",
-                  "printedName": "AnyObject"
-                }
-              ],
-              "usr": "s:Sq"
-            }
-          ]
+          "name": "Void",
+          "printedName": "()"
         },
         {
           "kind": "TypeNominal",
-          "name": "UnsafeMutablePointer",
-          "printedName": "UnsafeMutablePointer<τ_0_0>",
-          "children": [
-            {
-              "kind": "TypeNominal",
-              "name": "GenericTypeParam",
-              "printedName": "τ_0_0"
-            }
-          ],
-          "usr": "s:Sp"
+          "name": "GenericTypeParam",
+          "printedName": "τ_0_0",
+          "paramValueOwnership": "InOut"
         },
         {
           "kind": "TypeNominal",
@@ -126669,54 +126625,29 @@
             }
           ],
           "usr": "s:s15WritableKeyPathC"
+        },
+        {
+          "kind": "TypeNominal",
+          "name": "GenericTypeParam",
+          "printedName": "τ_0_1",
+          "paramValueOwnership": "Owned"
         }
       ],
       "declKind": "Func",
-      "usr": "s:s23_projectKeyPathWritable4root03keyC0Spyq_G_yXlSgtSpyxG_s0dbC0Cyxq_Gtr0_lF",
+      "usr": "s:swift_setAtWritableKeyPath",
       "moduleName": "Swift",
       "genericSig": "<τ_0_0, τ_0_1>",
-      "declAttributes": [
-        "Semantics"
-      ],
       "funcSelfKind": "NonMutating"
     },
     {
       "kind": "Function",
-      "name": "_projectKeyPathReferenceWritable",
-      "printedName": "_projectKeyPathReferenceWritable(root:keyPath:)",
+      "name": "_setAtReferenceWritableKeyPath",
+      "printedName": "_setAtReferenceWritableKeyPath(root:keyPath:value:)",
       "children": [
         {
           "kind": "TypeNominal",
-          "name": "Tuple",
-          "printedName": "(UnsafeMutablePointer<τ_0_1>, Optional<AnyObject>)",
-          "children": [
-            {
-              "kind": "TypeNominal",
-              "name": "UnsafeMutablePointer",
-              "printedName": "UnsafeMutablePointer<τ_0_1>",
-              "children": [
-                {
-                  "kind": "TypeNominal",
-                  "name": "GenericTypeParam",
-                  "printedName": "τ_0_1"
-                }
-              ],
-              "usr": "s:Sp"
-            },
-            {
-              "kind": "TypeNominal",
-              "name": "Optional",
-              "printedName": "Optional<AnyObject>",
-              "children": [
-                {
-                  "kind": "TypeNominal",
-                  "name": "ProtocolComposition",
-                  "printedName": "AnyObject"
-                }
-              ],
-              "usr": "s:Sq"
-            }
-          ]
+          "name": "Void",
+          "printedName": "()"
         },
         {
           "kind": "TypeNominal",
@@ -126740,15 +126671,18 @@
             }
           ],
           "usr": "s:s24ReferenceWritableKeyPathC"
+        },
+        {
+          "kind": "TypeNominal",
+          "name": "GenericTypeParam",
+          "printedName": "τ_0_1",
+          "paramValueOwnership": "Owned"
         }
       ],
       "declKind": "Func",
-      "usr": "s:s32_projectKeyPathReferenceWritable4root03keyC0Spyq_G_yXlSgtx_s0debC0Cyxq_Gtr0_lF",
+      "usr": "s:swift_setAtReferenceWritableKeyPath",
       "moduleName": "Swift",
       "genericSig": "<τ_0_0, τ_0_1>",
-      "declAttributes": [
-        "Semantics"
-      ],
       "funcSelfKind": "NonMutating"
     },
     {
diff --git a/test/api-digester/Outputs/cake-abi.json b/test/api-digester/Outputs/cake-abi.json
index c542156..dc86703 100644
--- a/test/api-digester/Outputs/cake-abi.json
+++ b/test/api-digester/Outputs/cake-abi.json
@@ -1344,6 +1344,11 @@
         },
         {
           "kind": "Conformance",
+          "name": "AdditiveArithmetic",
+          "printedName": "AdditiveArithmetic"
+        },
+        {
+          "kind": "Conformance",
           "name": "ExpressibleByIntegerLiteral",
           "printedName": "ExpressibleByIntegerLiteral",
           "children": [
diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index d3b43a1..10e7ad1 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -1238,6 +1238,11 @@
         },
         {
           "kind": "Conformance",
+          "name": "AdditiveArithmetic",
+          "printedName": "AdditiveArithmetic"
+        },
+        {
+          "kind": "Conformance",
           "name": "ExpressibleByIntegerLiteral",
           "printedName": "ExpressibleByIntegerLiteral",
           "children": [
diff --git a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
index e69de29..a87087c 100644
--- a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
+++ b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
@@ -0,0 +1,186 @@
+Func MutableCollection._partition(within:by:) has generic signature change from <τ_0_0 where τ_0_0 : MutableCollection, τ_0_0 : RandomAccessCollection> to <τ_0_0 where τ_0_0 : BidirectionalCollection, τ_0_0 : MutableCollection>
+Func MutableCollection._partition(within:by:) has been renamed to Func MutableCollection._partitionImpl(by:)
+Func MutableCollection._heapSort(within:by:) has been removed
+Func MutableCollection._heapify(within:by:) has been removed
+Func MutableCollection._introSort(within:by:) has been removed
+Func MutableCollection._introSortImpl(within:by:depthLimit:) has been removed
+Func MutableCollection._siftDown(_:within:by:) has been removed
+Func MutableCollection._sort3(_:_:_:by:) has been removed
+Func MutableCollection._partition(within:by:) has parameter 0 type change from Range<τ_0_0.Index> to (τ_0_0.Element) throws -> Bool
+
+Func BinaryInteger._description(radix:uppercase:) has been removed
+Struct _Buffer32 has been removed
+Struct _Buffer72 has been removed
+Func _int64ToString(_:radix:uppercase:) has been removed
+Func _int64ToStringImpl(_:_:_:_:_:) has been removed
+Func _uint64ToStringImpl(_:_:_:_:_:) has been removed
+Func _withUninitializedString(_:) has been removed
+
+Class _stdlib_AtomicInt has been removed
+Func _stdlib_atomicCompareExchangeStrongInt(object:expected:desired:) has been removed
+Func _stdlib_atomicCompareExchangeStrongInt32(object:expected:desired:) has been removed
+Func _stdlib_atomicCompareExchangeStrongInt64(object:expected:desired:) has been removed
+Func _stdlib_atomicCompareExchangeStrongUInt32(object:expected:desired:) has been removed
+Func _stdlib_atomicCompareExchangeStrongUInt64(object:expected:desired:) has been removed
+Func _swift_stdlib_atomicFetchAddInt(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchAddInt32(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchAddInt64(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchAddUInt32(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchAddUInt64(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchAndInt(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchAndInt32(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchAndInt64(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchAndUInt32(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchAndUInt64(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchOrInt(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchOrInt32(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchOrInt64(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchOrUInt32(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchOrUInt64(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchXorInt(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchXorInt32(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchXorInt64(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchXorUInt32(object:operand:) has been removed
+Func _swift_stdlib_atomicFetchXorUInt64(object:operand:) has been removed
+Func _swift_stdlib_atomicLoadInt(object:) has been removed
+Func _swift_stdlib_atomicLoadInt32(object:) has been removed
+Func _swift_stdlib_atomicLoadInt64(object:) has been removed
+Func _swift_stdlib_atomicLoadUInt32(object:) has been removed
+Func _swift_stdlib_atomicLoadUInt64(object:) has been removed
+Func _swift_stdlib_atomicStoreInt(object:desired:) has been removed
+Func _swift_stdlib_atomicStoreInt32(object:desired:) has been removed
+Func _swift_stdlib_atomicStoreInt64(object:desired:) has been removed
+Func _swift_stdlib_atomicStoreUInt32(object:desired:) has been removed
+Func _swift_stdlib_atomicStoreUInt64(object:desired:) has been removed
+
+Var _FixedArray16._count has been removed
+Var _FixedArray16.capacity has been removed
+Var _FixedArray16.count has been removed
+Var _FixedArray16.endIndex has been removed
+Var _FixedArray16.startIndex has been removed
+Var _FixedArray16.storage has been removed
+Var _FixedArray2._count has been removed
+Var _FixedArray2.capacity has been removed
+Var _FixedArray2.count has been removed
+Var _FixedArray2.endIndex has been removed
+Var _FixedArray2.startIndex has been removed
+Var _FixedArray2.storage has been removed
+Var _FixedArray4._count has been removed
+Var _FixedArray4.capacity has been removed
+Var _FixedArray4.count has been removed
+Var _FixedArray4.endIndex has been removed
+Var _FixedArray4.startIndex has been removed
+Var _FixedArray4.storage has been removed
+Var _FixedArray8._count has been removed
+Var _FixedArray8.capacity has been removed
+Var _FixedArray8.count has been removed
+Var _FixedArray8.endIndex has been removed
+Var _FixedArray8.startIndex has been removed
+Var _FixedArray8.storage has been removed
+Subscript _FixedArray16.subscript(_:) has been removed
+Subscript _FixedArray2.subscript(_:) has been removed
+Subscript _FixedArray4.subscript(_:) has been removed
+Subscript _FixedArray8.subscript(_:) has been removed
+Struct _FixedArray16 is now without @_fixed_layout
+Struct _FixedArray2 is now without @_fixed_layout
+Struct _FixedArray4 is now without @_fixed_layout
+Struct _FixedArray8 is now without @_fixed_layout
+Func _FixedArray16.append(_:) has been removed
+Func _FixedArray16.index(after:) has been removed
+Func _FixedArray16.index(before:) has been removed
+Func _FixedArray16.withUnsafeBufferPointer(_:) has been removed
+Func _FixedArray16.withUnsafeMutableBufferPointer(_:) has been removed
+Func _FixedArray2.append(_:) has been removed
+Func _FixedArray2.index(after:) has been removed
+Func _FixedArray2.index(before:) has been removed
+Func _FixedArray2.withUnsafeBufferPointer(_:) has been removed
+Func _FixedArray2.withUnsafeMutableBufferPointer(_:) has been removed
+Func _FixedArray4.append(_:) has been removed
+Func _FixedArray4.index(after:) has been removed
+Func _FixedArray4.index(before:) has been removed
+Func _FixedArray4.withUnsafeBufferPointer(_:) has been removed
+Func _FixedArray4.withUnsafeMutableBufferPointer(_:) has been removed
+Func _FixedArray8.append(_:) has been removed
+Func _FixedArray8.index(after:) has been removed
+Func _FixedArray8.index(before:) has been removed
+Func _FixedArray8.withUnsafeBufferPointer(_:) has been removed
+Func _FixedArray8.withUnsafeMutableBufferPointer(_:) has been removed
+Constructor _FixedArray16.init() has been removed
+Constructor _FixedArray16.init(allZeros:) has been removed
+Constructor _FixedArray16.init(count:) has been removed
+Constructor _FixedArray2.init() has been removed
+Constructor _FixedArray2.init(allZeros:) has been removed
+Constructor _FixedArray2.init(count:) has been removed
+Constructor _FixedArray4.init() has been removed
+Constructor _FixedArray4.init(allZeros:) has been removed
+Constructor _FixedArray4.init(count:) has been removed
+Constructor _FixedArray8.init() has been removed
+Constructor _FixedArray8.init(allZeros:) has been removed
+Constructor _FixedArray8.init(count:) has been removed
+
+Struct Hasher._Core has removed conformance to _HasherCore
+Protocol _HasherCore has been removed
+Struct _BufferingHasher has been removed
+Struct _HasherTailBuffer has been removed
+Var Hasher._core has declared type change from _BufferingHasher<Hasher._Core> to Hasher._Core
+Var Hasher._Core._buffer is added to a non-resilient type
+Var Hasher._Core._state in a non-resilient type changes position from 0 to 1
+
+Class _AbstractStringStorage has been removed
+Constructor _StringGuts.init(_:) has been removed
+Constructor _StringObject.init(_:) has been removed
+Constructor _StringStorage.init() has been removed
+Var _StringObject.nativeStorage has been removed
+Var _StringStorage._countAndFlags has been removed
+Var _StringStorage._realCapacityAndFlags has been removed
+Var _StringStorage.count has been removed
+Var _StringStorage.mutableStart has been removed
+Var _StringStorage.start has been removed
+Class _StringStorage is now without @_fixed_layout
+Class _SharedStringStorage has removed conformance to _NSStringCore
+Class _StringStorage has removed conformance to _NSStringCore
+Protocol _NSStringCore has been removed
+
+Func String.UnicodeScalarView._foreignSubscript(aligned:) has been removed
+Struct String.UnicodeScalarView has type witness type for Collection.Iterator changing from IndexingIterator<String.UnicodeScalarView> to String.UnicodeScalarView.Iterator
+Struct String.UnicodeScalarView has type witness type for Sequence.Iterator changing from IndexingIterator<String.UnicodeScalarView> to String.UnicodeScalarView.Iterator
+Func String._foreignSubscript(position:distance:) has been removed
+Struct String has type witness type for Collection.Iterator changing from IndexingIterator<String> to String.Iterator
+Struct String has type witness type for Sequence.Iterator changing from IndexingIterator<String> to String.Iterator
+Func Unicode.UTF32._decode(_:) has been removed
+Func _UnicodeParser._decode(_:repairingIllFormedSequences:into:) has been removed
+Func _UnicodeParser._parse(_:repairingIllFormedSequences:into:) has been removed
+Struct Unicode._ParsingIterator has been removed
+
+Constructor ManagedBuffer.init(_doNotCallMe:) has been removed
+Func _makeAnyHashableUpcastingToHashableBaseType(_:storingResultInto:) has been removed
+
+Func RandomNumberGenerator._fill(bytes:) has been removed
+Func SystemRandomNumberGenerator._fill(bytes:) has been removed
+
+Func _createStringTableCache(_:) has been removed
+Struct _StringSwitchContext has been removed
+
+Class __SwiftNativeNSEnumerator has been removed
+Constructor _RawDictionaryStorage.init() has been removed
+Constructor _RawSetStorage.init() has been removed
+Constructor __SwiftNativeNSDictionary.init() has been removed
+Constructor __SwiftNativeNSSet.init() has been removed
+Class _DictionaryStorage is now without @_fixed_layout
+Class _SetStorage is now without @_fixed_layout
+
+Protocol Numeric has generic signature change from <τ_0_0 : Equatable, τ_0_0 : ExpressibleByIntegerLiteral, τ_0_0.Magnitude : Comparable, τ_0_0.Magnitude : Numeric> to <τ_0_0 : AdditiveArithmetic, τ_0_0 : ExpressibleByIntegerLiteral, τ_0_0.Magnitude : Comparable, τ_0_0.Magnitude : Numeric>
+Func Numeric.+(_:) has been removed
+Func Numeric.+(_:_:) has been removed
+Func Numeric.+=(_:_:) has been removed
+Func Numeric.-(_:_:) has been removed
+Func Numeric.-=(_:_:) has been removed
+Protocol BinaryFloatingPoint has added inherited protocol AdditiveArithmetic
+Protocol BinaryInteger has added inherited protocol AdditiveArithmetic
+Protocol FixedWidthInteger has added inherited protocol AdditiveArithmetic
+Protocol FloatingPoint has added inherited protocol AdditiveArithmetic
+Protocol Numeric has added inherited protocol AdditiveArithmetic
+Protocol SignedInteger has added inherited protocol AdditiveArithmetic
+Protocol SignedNumeric has added inherited protocol AdditiveArithmetic
+Protocol UnsignedInteger has added inherited protocol AdditiveArithmetic
+
diff --git a/test/api-digester/Outputs/stability-stdlib-source.swift.expected b/test/api-digester/Outputs/stability-stdlib-source.swift.expected
index e33600e..4d679ef 100644
--- a/test/api-digester/Outputs/stability-stdlib-source.swift.expected
+++ b/test/api-digester/Outputs/stability-stdlib-source.swift.expected
@@ -1,5 +1,6 @@
 
 /* Generic Signature Changes */
+Protocol Numeric has generic signature change from <Self : Equatable, Self : ExpressibleByIntegerLiteral, Self.Magnitude : Comparable, Self.Magnitude : Numeric> to <Self : AdditiveArithmetic, Self : ExpressibleByIntegerLiteral, Self.Magnitude : Comparable, Self.Magnitude : Numeric>
 Protocol StringProtocol has generic signature change from <Self : BidirectionalCollection, Self : Comparable, Self : ExpressibleByStringLiteral, Self : Hashable, Self : LosslessStringConvertible, Self : TextOutputStream, Self : TextOutputStreamable, Self.Element == Character, Self.Index == String.Index, Self.SubSequence : StringProtocol, Self.UTF16View : BidirectionalCollection, Self.UTF8View : Collection, Self.UnicodeScalarView : BidirectionalCollection, Self.UTF16View.Element == UInt16, Self.UTF16View.Index == String.Index, Self.UTF8View.Element == UInt8, Self.UTF8View.Index == String.Index, Self.UnicodeScalarView.Element == Unicode.Scalar, Self.UnicodeScalarView.Index == String.Index, Self.SubSequence.UTF16View.Index == String.Index, Self.SubSequence.UTF8View.Index == String.Index, Self.SubSequence.UnicodeScalarView.Index == String.Index> to <Self : BidirectionalCollection, Self : Comparable, Self : ExpressibleByStringInterpolation, Self : Hashable, Self : LosslessStringConvertible, Self : TextOutputStream, Self : TextOutputStreamable, Self.Element == Character, Self.Index == String.Index, Self.StringInterpolation == DefaultStringInterpolation, Self.SubSequence : StringProtocol, Self.UTF16View : BidirectionalCollection, Self.UTF8View : Collection, Self.UnicodeScalarView : BidirectionalCollection, Self.UTF16View.Element == UInt16, Self.UTF16View.Index == String.Index, Self.UTF8View.Element == UInt8, Self.UTF8View.Index == String.Index, Self.UnicodeScalarView.Element == Unicode.Scalar, Self.UnicodeScalarView.Index == String.Index, Self.SubSequence.UTF16View.Index == String.Index, Self.SubSequence.UTF8View.Index == String.Index, Self.SubSequence.UnicodeScalarView.Index == String.Index>
 
 /* RawRepresentable Changes */
@@ -9,6 +10,11 @@
 Func Collection.prefix(through:) has been removed
 Func Collection.prefix(upTo:) has been removed
 Func Collection.suffix(from:) has been removed
+Func Numeric.+(_:) has been removed
+Func Numeric.+(_:_:) has been removed
+Func Numeric.+=(_:_:) has been removed
+Func Numeric.-(_:_:) has been removed
+Func Numeric.-=(_:_:) has been removed
 Func Sequence.filter(_:) has been removed
 Func Sequence.forEach(_:) has been removed
 Func Sequence.map(_:) has been removed
@@ -36,8 +42,16 @@
 
 /* Type Changes */
 Constructor String.init(stringInterpolation:) has parameter 0 type change from [String] to DefaultStringInterpolation
+Protocol BinaryFloatingPoint has added inherited protocol AdditiveArithmetic
+Protocol BinaryInteger has added inherited protocol AdditiveArithmetic
+Protocol FixedWidthInteger has added inherited protocol AdditiveArithmetic
+Protocol FloatingPoint has added inherited protocol AdditiveArithmetic
+Protocol Numeric has added inherited protocol AdditiveArithmetic
+Protocol SignedInteger has added inherited protocol AdditiveArithmetic
+Protocol SignedNumeric has added inherited protocol AdditiveArithmetic
 
 /* Decl Attribute changes */
 
 /* Protocol Requirement Changes */
 Protocol StringProtocol has added inherited protocol ExpressibleByStringInterpolation
+Protocol UnsignedInteger has added inherited protocol AdditiveArithmetic
diff --git a/test/api-digester/stability-stdlib-abi.swift b/test/api-digester/stability-stdlib-abi.swift
index 3c2f1b4..3b0ebe1 100644
--- a/test/api-digester/stability-stdlib-abi.swift
+++ b/test/api-digester/stability-stdlib-abi.swift
@@ -3,6 +3,6 @@
 // mkdir %t.tmp/module-cache && mkdir %t.tmp/dummy.sdk
 // RUN: %api-digester -dump-sdk -module Swift -o %t.tmp/current-stdlib.json -module-cache-path %t.tmp/module-cache -sdk %t.tmp/dummy.sdk -abi
 // RUN: %api-digester -diagnose-sdk -input-paths %S/Inputs/stdlib-stable-abi.json -input-paths %t.tmp/current-stdlib.json -abi -o %t.tmp/changes.txt
-// RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-abi.swift.expected -o - | sed '/^\s*$/d' > %t.tmp/stability-stdlib-abi.swift.expected
-// RUN: %clang -E -P -x c %t.tmp/changes.txt -o - | sed '/^\s*$/d' > %t.tmp/changes.txt.tmp
+// RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-abi.swift.expected -o - | sed '/^\s*$/d' | sort > %t.tmp/stability-stdlib-abi.swift.expected
+// RUN: %clang -E -P -x c %t.tmp/changes.txt -o - | sed '/^\s*$/d' | sort > %t.tmp/changes.txt.tmp
 // RUN: diff -u %t.tmp/stability-stdlib-abi.swift.expected %t.tmp/changes.txt.tmp
diff --git a/test/api-digester/stability-stdlib-source.swift b/test/api-digester/stability-stdlib-source.swift
index caf1ed8..4dc9c48 100644
--- a/test/api-digester/stability-stdlib-source.swift
+++ b/test/api-digester/stability-stdlib-source.swift
@@ -3,6 +3,6 @@
 // mkdir %t.tmp/module-cache && mkdir %t.tmp/dummy.sdk
 // RUN: %api-digester -dump-sdk -module Swift -o %t.tmp/current-stdlib.json -module-cache-path %t.tmp/module-cache -sdk %t.tmp/dummy.sdk
 // RUN: %api-digester -diagnose-sdk -input-paths %S/Inputs/stdlib-stable.json -input-paths %t.tmp/current-stdlib.json -o %t.tmp/changes.txt
-// RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-source.swift.expected -o - | sed '/^\s*$/d' > %t.tmp/stability-stdlib-source.swift.expected
-// RUN: %clang -E -P -x c %t.tmp/changes.txt -o - | sed '/^\s*$/d' > %t.tmp/changes.txt.tmp
+// RUN: %clang -E -P -x c %S/Outputs/stability-stdlib-source.swift.expected -o - | sed '/^\s*$/d' | sort > %t.tmp/stability-stdlib-source.swift.expected
+// RUN: %clang -E -P -x c %t.tmp/changes.txt -o - | sed '/^\s*$/d' | sort > %t.tmp/changes.txt.tmp
 // RUN: diff -u %t.tmp/stability-stdlib-source.swift.expected %t.tmp/changes.txt.tmp
diff --git a/test/attr/accessibility_print.swift b/test/attr/accessibility_print.swift
index 48ef9be..daa6908 100644
--- a/test/attr/accessibility_print.swift
+++ b/test/attr/accessibility_print.swift
@@ -365,12 +365,12 @@
 
 // CHECK-LABEL: public{{(\*/)?}} class PublicInitInheritor : PublicInitBase {
 public class PublicInitInheritor : PublicInitBase {
-  // CHECK: {{^}} public init()
-  // CHECK: {{^}} fileprivate init(other: PublicInitBase)
+  // CHECK: {{^}} override public init()
+  // CHECK: {{^}} override fileprivate init(other: PublicInitBase)
 } // CHECK: {{^[}]}}
 
 // CHECK-LABEL: {{(/\*)?private(\*/)?}} class PublicInitPrivateInheritor : PublicInitBase {
 private class PublicInitPrivateInheritor : PublicInitBase {
-  // CHECK: {{^}} internal init()
-  // CHECK: {{^}} fileprivate init(other: PublicInitBase)
+  // CHECK: {{^}} override internal init()
+  // CHECK: {{^}} override fileprivate init(other: PublicInitBase)
 } // CHECK: {{^[}]}}
diff --git a/test/attr/attr_autoclosure.swift b/test/attr/attr_autoclosure.swift
index e646a61..3801fd4 100644
--- a/test/attr/attr_autoclosure.swift
+++ b/test/attr/attr_autoclosure.swift
@@ -175,3 +175,38 @@
 func passThrowingToThrowingAC(_ fn: @autoclosure () throws -> Int) {
   takesThrowingAutoclosure(fn)
 }
+
+// rdar://problem/20591571 - Various type inference problems with @autoclosure
+func rdar_20591571() {
+  func foo(_ g: @autoclosure () -> Int) {
+    typealias G = ()->Int
+    let _ = unsafeBitCast(g, to: G.self) // expected-error {{converting non-escaping value to 'T' may allow it to escape}}
+  }
+
+  func id<T>(_: T) -> T {}
+  func same<T>(_: T, _: T) {}
+
+  func takesAnAutoclosure(_ fn: @autoclosure () -> Int, _ efn: @escaping @autoclosure () -> Int) {
+  // expected-note@-1 2{{parameter 'fn' is implicitly non-escaping}}
+
+    var _ = fn // expected-error {{non-escaping parameter 'fn' may only be called}}
+    let _ = fn // expected-error {{non-escaping parameter 'fn' may only be called}}
+
+    var _ = efn
+    let _ = efn
+
+    _ = id(fn)          // expected-error {{converting non-escaping value to 'T' may allow it to escape}}
+    _ = same(fn, { 3 }) // expected-error {{converting non-escaping value to 'T' may allow it to escape}}
+    _ = same({ 3 }, fn) // expected-error {{converting non-escaping value to 'T' may allow it to escape}}
+
+    withoutActuallyEscaping(fn) { _ in }              // Ok
+    withoutActuallyEscaping(fn) { (_: () -> Int) in } // Ok
+  }
+}
+
+// rdar://problem/30906031 - [SR-4188]: withoutActuallyEscaping doesn't accept an @autoclosure argument
+func rdar_30906031(in arr: [Int], fn: @autoclosure () -> Int) -> Bool {
+  return withoutActuallyEscaping(fn) { escapableF in // Ok
+    arr.lazy.filter { $0 >= escapableF() }.isEmpty
+  }
+}
diff --git a/test/attr/attr_borrowed.swift b/test/attr/attr_borrowed.swift
new file mode 100644
index 0000000..261d85a
--- /dev/null
+++ b/test/attr/attr_borrowed.swift
@@ -0,0 +1,20 @@
+// RUN: %target-typecheck-verify-swift
+// REQUIRES: objc_interop
+
+import Foundation
+
+@_borrowed // expected-error {{'@_borrowed' attribute cannot be applied to this declaration}}
+func foo() -> String {}
+
+@_borrowed
+var string = ""
+
+@objc protocol P {
+  @_borrowed // expected-error {{property cannot be '@_borrowed' if it is an @objc protocol requirement}}
+  var title: String { get }
+}
+
+@objc class A {
+  @_borrowed // expected-error {{property cannot be '@_borrowed' if it is '@objc dynamic'}}
+  @objc dynamic var title: String { return "" }
+}
diff --git a/test/attr/attr_dynamic_callable.swift b/test/attr/attr_dynamic_callable.swift
new file mode 100644
index 0000000..e2723d0
--- /dev/null
+++ b/test/attr/attr_dynamic_callable.swift
@@ -0,0 +1,423 @@
+// RUN: %target-typecheck-verify-swift
+
+@dynamicCallable
+struct Callable {
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int {
+    return arguments.count
+  }
+}
+
+@dynamicCallable
+struct DiscardableResult {
+  @discardableResult
+  func dynamicallyCall(withArguments arguments: [Double]) -> Int {
+    return arguments.count
+  }
+}
+
+@dynamicCallable
+struct Throwing {
+  func dynamicallyCall(withArguments arguments: [String]) throws -> Int {
+    return arguments.count
+  }
+}
+
+@dynamicCallable
+struct KeywordArgumentCallable {
+  @discardableResult
+  func dynamicallyCall(
+    withKeywordArguments arguments: KeyValuePairs<String, Float>
+  ) -> Int {
+    return arguments.count
+  }
+}
+
+func testCallable(
+  a: Callable, b: DiscardableResult, c: Throwing, d: KeywordArgumentCallable
+) {
+  _ = a()
+  let a1 = a(1, 2, 3, 4) // expected-warning {{initialization of immutable value 'a1' was never used}}
+
+  b()
+  b(1, 2, 3, 4.0)
+
+  _ = try? c()
+  let c1 = try! c("hello", "world") // expected-warning {{initialization of immutable value 'c1' was never used}}
+
+  d()
+  d(1, 2.0, 3)
+  d(x1: 1, 2.0, x2: 3)
+}
+
+func testIUO(
+  a: Callable!, b: DiscardableResult!, c: Throwing!, d: KeywordArgumentCallable!
+) {
+  print(a(1, 2, 3))
+  print(b(1, 2, 3.0))
+  print(try! c("hello", "world"))
+  print(d(foo: 1, 2.0, bar: 3))
+}
+
+//===----------------------------------------------------------------------===//
+// Returning a function
+//===----------------------------------------------------------------------===//
+
+@dynamicCallable
+struct CallableReturningFunction {
+  func dynamicallyCall(withArguments arguments: [Int]) -> (Int) -> Void {
+    return { x in () }
+  }
+}
+
+func testFunction(a: CallableReturningFunction) {
+  a(1, 2, 3)(1)
+}
+
+//===----------------------------------------------------------------------===//
+// Error cases
+//===----------------------------------------------------------------------===//
+
+// Arguments' type may not be variadic.
+// expected-error @+1 {{@dynamicCallable attribute requires 'Invalid1' to have either a valid 'dynamicallyCall(withArguments:)' method or 'dynamicallyCall(withKeywordArguments:)' method}}
+@dynamicCallable
+struct Invalid1 {
+  func dynamicallyCall(withArguments arguments: [Int]...) -> Int {
+    return 1
+  }
+}
+
+// Keyword arguments' key type must be ExpressibleByStringLiteral.
+// expected-error @+1 {{@dynamicCallable attribute requires 'Invalid2' to have either a valid 'dynamicallyCall(withArguments:)' method or 'dynamicallyCall(withKeywordArguments:)' method}}
+@dynamicCallable
+struct Invalid2 {
+  func dynamicallyCall(
+    withKeywordArguments arguments: KeyValuePairs<Int, Int>
+  ) -> Int {
+    return 1
+  }
+}
+
+// Dynamic calls with keyword arguments require `dynamicallyCall(withKeywordArguments:)` to be defined.
+@dynamicCallable
+class NoKeyword {
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int { return 1 }
+}
+@dynamicCallable
+protocol NoKeywordProtocol {
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int
+}
+
+func testInvalidKeywordCall(x: NoKeyword, y: NoKeywordProtocol & AnyObject) {
+  x(a: 1, b: 2) // expected-error {{@dynamicCallable type 'NoKeyword' cannot be applied with keyword arguments; missing 'dynamicCall(withKeywordArguments:)' method}}
+  y(a: 1, b: 2) // expected-error {{@dynamicCallable type 'NoKeywordProtocol & AnyObject' cannot be applied with keyword arguments; missing 'dynamicCall(withKeywordArguments:)' method}}
+}
+
+// expected-error @+1 {{'@dynamicCallable' attribute cannot be applied to this declaration}}
+@dynamicCallable
+extension Int {
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int {
+    return 1
+  }
+}
+
+// expected-error @+1 {{'@dynamicCallable' attribute cannot be applied to this declaration}}
+@dynamicCallable
+func NotAllowedOnFunc() {}
+
+// @dynamicCallable cannot be declared on a base class and fulfilled with a
+// derived class.
+
+// expected-error @+1 {{@dynamicCallable attribute requires 'InvalidBase' to have either a valid 'dynamicallyCall(withArguments:)' method or 'dynamicallyCall(withKeywordArguments:)' method}}
+@dynamicCallable
+class InvalidBase {}
+
+class InvalidDerived : InvalidBase {
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int {
+    return 1
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Multiple `dynamicallyCall` methods
+//===----------------------------------------------------------------------===//
+
+@dynamicCallable
+struct OverloadedCallable {
+  // expected-note @+1 {{found this candidate}}
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int {
+    return 1
+  }
+  // expected-note @+1 {{found this candidate}}
+  func dynamicallyCall(withArguments arguments: [Int]) -> Float {
+    return 1.0
+  }
+}
+
+func testOverloaded(x: OverloadedCallable) {
+  let _: Int = x(1, 2, 3)
+  let _: Float = x(1, 2, 3)
+  let _ = x(1, 2, 3) // expected-error {{ambiguous use of 'dynamicallyCall(withArguments:)'}}
+}
+
+//===----------------------------------------------------------------------===//
+// Existentials
+//===----------------------------------------------------------------------===//
+
+@dynamicCallable
+protocol CallableProtocol {
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int
+}
+
+@dynamicCallable
+protocol KeywordCallableProtocol {}
+extension KeywordCallableProtocol {
+  func dynamicallyCall(
+    withKeywordArguments arguments: KeyValuePairs<String, Double>
+  ) -> Int {
+    return arguments.count
+  }
+}
+
+extension String : CallableProtocol, KeywordCallableProtocol {
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int {
+    return arguments.count
+  }
+}
+
+func testProtoExtension() -> Int {
+  let str = "test"
+  return str(1, 2, 3) + str(label1: 1, 2, label2: 3)
+}
+
+struct CallableStruct : CallableProtocol {
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int {
+    return arguments.count
+  }
+}
+class CallableClass : KeywordCallableProtocol {}
+
+func testExistential(
+  a: CallableProtocol, b: KeywordCallableProtocol,
+  c: CallableStruct, d: CallableClass
+) -> Int {
+  // Types that define only the `withKeywordsArguments` method can be called
+  // with no argument labels.
+  _ = b() + b(1, 2) + d() + d(1, 2)
+  return a(1, 2, 3) + b(label1: 1, 2, label2: 3) + c(1, 2, 3) + d(label1: 1, 2, 3)
+}
+
+// Verify protocol compositions and refinements work.
+protocol SubProtocol : CallableProtocol {}
+
+typealias ProtocolComp = AnyObject & CallableProtocol
+typealias ProtocolComp2 = KeywordCallableProtocol & CallableClass
+
+func testExistential2(a: AnyObject & CallableProtocol,
+                      b: SubProtocol,
+                      c: ProtocolComp & AnyObject,
+                      d: CallableClass,
+                      e: CallableProtocol & KeywordCallableProtocol,
+                      f: CallableProtocol & ProtocolComp2) {
+  print(a(1, 2, 3))
+  print(b(1, 2, 3))
+  print(c(1, 2, 3))
+  print(d(1, 2, 3))
+  print(e() + e(label1: 1, 2, label2: 3))
+  print(f() + f(label1: 1, 2, label2: 3))
+}
+func testConstrainedClassType<C : AnyObject>(
+  a: C
+) -> Int where C : CallableProtocol {
+  return a(1, 2, 3)
+}
+func testRefinedProtocolType<P : FloatingPoint>(
+  a: P
+) -> Int where P : CallableProtocol {
+  return a(1, 2, 3)
+}
+
+//===----------------------------------------------------------------------===//
+// Extension tests
+//===----------------------------------------------------------------------===//
+
+extension Optional : KeywordCallableProtocol {}
+extension Array : KeywordCallableProtocol {}
+
+func testExtensions() {
+  let x: Int? = 3
+  // Test `Optional` extension.
+  print(x())
+  print(x(label: 1, 2))
+  // Test `Array` extension.
+  print([1]())
+  print([1](label: 1, 2))
+}
+
+//===----------------------------------------------------------------------===//
+// Class inheritance tests
+//===----------------------------------------------------------------------===//
+
+@dynamicCallable
+class BaseClass {
+  func dynamicallyCall(withArguments arguments: [Int]) -> Int {
+    return arguments.count
+  }
+}
+class DerivedClass1 : BaseClass {}
+
+class DerivedClass2 : BaseClass {
+  override func dynamicallyCall(withArguments arguments: [Int]) -> Int {
+    return arguments.count
+  }
+}
+
+class DerivedClass3 : BaseClass {
+  func dynamicallyCall(
+    withKeywordArguments arguments: KeyValuePairs<String, Int>
+  ) -> Int {
+    return arguments.count
+  }
+}
+
+func testDerivedClass(
+  a: BaseClass, b: DerivedClass1, c: DerivedClass2, d: DerivedClass3
+) -> Int {
+  return a() - b(1, 2) + c(3, 4) - d(x1: 5, 6, x2: 7)
+}
+
+//===----------------------------------------------------------------------===//
+// Enum tests
+//===----------------------------------------------------------------------===//
+
+@dynamicCallable
+enum BinaryOperation<T : Numeric> {
+  case add
+  case subtract
+  case multiply
+
+  func dynamicallyCall(withArguments arguments: [T]) -> T {
+    precondition(arguments.count == 2, "Must have 2 arguments")
+    let x = arguments[0]
+    let y = arguments[1]
+    switch self {
+    case .add:
+      return x + y
+    case .subtract:
+      return x - y
+    case .multiply:
+      return x * y
+    }
+  }
+}
+
+func testEnum() {
+  let ops: [BinaryOperation<Int>] = [.add, .subtract, .multiply]
+  for op in ops {
+    print(op(3, 4))
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Generics
+//===----------------------------------------------------------------------===//
+
+@dynamicCallable
+struct CallableGenericArray<A : ExpressibleByArrayLiteral> {
+  func dynamicallyCall(withArguments arguments: A) -> Int {
+    return 1
+  }
+}
+func testGenericArray<A : ExpressibleByArrayLiteral>(
+  a: CallableGenericArray<A>, x: A.ArrayLiteralElement
+) -> Int {
+  return a() + a(x, x)
+}
+
+@dynamicCallable
+struct CallableGenericDictionary<D : ExpressibleByDictionaryLiteral>
+  where D.Key : ExpressibleByStringLiteral {
+  func dynamicallyCall(withKeywordArguments arguments: D) -> Int {
+    return 1
+  }
+}
+func testGenericDictionary<D : ExpressibleByDictionaryLiteral>(
+  a: CallableGenericDictionary<D>, x: D.Value
+) -> Int where D.Key : ExpressibleByStringLiteral {
+  return a() + a(label1: x, x, label2: x)
+}
+
+@dynamicCallable
+struct CallableGeneric1<T> {
+  func dynamicallyCall(withArguments arguments: [T]) -> Int {
+    return arguments.count
+  }
+}
+func testGenericType1<T>(a: CallableGeneric1<T>, x: T) -> Int {
+  return a() + a(x, x)
+}
+func testConcreteGenericType2(a: CallableGeneric1<Int>) -> Int {
+  return a() + a(1, 2)
+}
+
+@dynamicCallable
+struct CallableGeneric2<T> {
+  func dynamicallyCall(withArguments arguments: [Any]) -> Int {
+    return arguments.count
+  }
+}
+func testGenericType2<T>(a: CallableGeneric2<T>) -> Int {
+  return a(1, 2) + a("asdf", 123)
+}
+func testConcreteGenericType2(a: CallableGeneric2<Int>) -> Int {
+  return a(1, 2) + a("asdf", 123)
+}
+
+@dynamicCallable
+struct CallableGeneric3<T> {
+  func dynamicallyCall(
+    withKeywordArguments arguments: KeyValuePairs<String, T>
+  ) -> Int {
+    return arguments.count
+  }
+}
+func testGenericType3<T>(a: CallableGeneric3<T>, x: T) -> Int {
+  return a() + a(x1: x, x, x, x2: x)
+}
+func testConcreteGenericType3(a: CallableGeneric3<Int>) -> Int {
+  return a() + a(x1: 123, 1, 2, x2: 123)
+}
+
+@dynamicCallable
+struct CallableGeneric4<T> {
+  func dynamicallyCall<U>(withArguments arguments: [U]) -> Int {
+    return arguments.count
+  }
+
+  func dynamicallyCall<U>(
+    withKeywordArguments arguments: KeyValuePairs<StaticString, U>
+  ) -> Int {
+    return arguments.count
+  }
+}
+func testGenericType4<T>(a: CallableGeneric4<T>) -> Int {
+  return a() + a(1, 2, 3) + a(x1: 1, 2, x3: 3)
+}
+
+@dynamicCallable
+class CallableGeneric5<T> {
+  func dynamicallyCall<U>(withArguments arguments: [U]) -> U {
+    return arguments[0]
+  }
+
+  func dynamicallyCall<U>(
+    withKeywordArguments arguments: KeyValuePairs<StaticString, U>
+  ) -> U {
+    return arguments[0].1
+  }
+}
+func testGenericType5<T>(a: CallableGeneric5<T>) -> Double {
+  return a(1, 2, 3) + a(x1: 1, 2, x3: 3)
+}
+func testArchetypeType5<T, C : CallableGeneric5<T>>(a: C) -> Double {
+  return a(1, 2, 3) + a(x1: 1, 2, x3: 3)
+}
diff --git a/test/NameBinding/dynamic-member-lookup.swift b/test/attr/attr_dynamic_member_lookup.swift
similarity index 66%
rename from test/NameBinding/dynamic-member-lookup.swift
rename to test/attr/attr_dynamic_member_lookup.swift
index 8238c04..4e07f42 100644
--- a/test/NameBinding/dynamic-member-lookup.swift
+++ b/test/attr/attr_dynamic_member_lookup.swift
@@ -1,4 +1,5 @@
 // RUN: %target-typecheck-verify-swift
+
 var global = 42
 
 @dynamicMemberLookup
@@ -33,30 +34,25 @@
   }
 }
 
-func test_function(b: Settable) {
-  var bm = b
-  bm.flavor = global
-}
-
 func test(a: Gettable, b: Settable, c: MutGettable, d: NonMutSettable) {
   global = a.wyverns
-  a.flavor = global    // expected-error {{cannot assign to property: 'a' is a 'let' constant}}
-  
+  a.flavor = global // expected-error {{cannot assign to property: 'a' is a 'let' constant}}
+
   global = b.flavor
   b.universal = global // expected-error {{cannot assign to property: 'b' is a 'let' constant}}
-  b.thing += 1         // expected-error {{left side of mutating operator isn't mutable: 'b' is a 'let' constant}}
+  b.thing += 1 // expected-error {{left side of mutating operator isn't mutable: 'b' is a 'let' constant}}
 
   var bm = b
   global = bm.flavor
   bm.universal = global
   bm.thing += 1
-  
+
   var cm = c
-  global = c.dragons  // expected-error {{cannot use mutating getter on immutable value: 'c' is a 'let' constant}}
+  global = c.dragons // expected-error {{cannot use mutating getter on immutable value: 'c' is a 'let' constant}}
   global = c[dynamicMember: "dragons"] // expected-error {{cannot use mutating getter on immutable value: 'c' is a 'let' constant}}
   global = cm.dragons
   c.woof = global // expected-error {{cannot use mutating getter on immutable value: 'c' is a 'let' constant}}
-  
+
   var dm = d
   global = d.dragons  // ok
   global = dm.dragons // ok
@@ -64,16 +60,15 @@
   dm.woof = global    // ok
 }
 
-
-func test_iuo(a : Gettable!, b : Settable!) {
+func testIUO(a: Gettable!, b: Settable!) {
   global = a.wyverns
-  a.flavor = global  // expected-error {{cannot assign through dynamic lookup property: 'a' is a 'let' constant}}
-  
+  a.flavor = global // expected-error {{cannot assign through dynamic lookup property: 'a' is a 'let' constant}}
+
   global = b.flavor
   b.universal = global // expected-error {{cannot assign through dynamic lookup property: 'b' is a 'let' constant}}
-  
-  var bm : Settable! = b
-  
+
+  var bm: Settable! = b
+
   global = bm.flavor
   bm.universal = global
 }
@@ -84,46 +79,25 @@
 
 @dynamicMemberLookup
 struct FnTest {
-  subscript(dynamicMember member: StaticString) -> (_ a : Int)->() {
-    return { a in () }
+  subscript(dynamicMember member: StaticString) -> (Int) -> () {
+    return { x in () }
   }
 }
-func test_function(x : FnTest) {
+func testFunction(x: FnTest) {
   x.phunky(12)
 }
-func test_function_iuo(x : FnTest!) {
+func testFunctionIUO(x: FnTest!) {
   x.flavor(12)
 }
 
 //===----------------------------------------------------------------------===//
-// Existential Cases
-//===----------------------------------------------------------------------===//
-
-
-@dynamicMemberLookup
-protocol ProtoExt { }
-extension ProtoExt {
-  subscript(dynamicMember member: String) -> String {
-    get {}
-  }
-}
-
-extension String: ProtoExt { }
-
-func testProtoExt() -> String {
-  let str = "test"
-  return str.sdfsdfsdf
-}
-
-
-//===----------------------------------------------------------------------===//
 // Explicitly declared members take precedence
 //===----------------------------------------------------------------------===//
 
 @dynamicMemberLookup
 struct Dog {
   public var name = "Kaylee"
-  
+
   subscript(dynamicMember member: String) -> String {
     return "Zoey"
   }
@@ -138,28 +112,27 @@
 //===----------------------------------------------------------------------===//
 
 @dynamicMemberLookup
-struct IUOResultTest {
+struct IUOResult {
   subscript(dynamicMember member: StaticString) -> Int! {
     get { return 42 }
     nonmutating set {}
   }
 }
 
-func test_iuo_result(x : IUOResultTest) {
-  x.foo?.negate()   // Test mutating writeback.
-  
-  let _ : Int = x.bar  // Test implicitly forced optional
+func testIUOResult(x: IUOResult) {
+  x.foo?.negate() // Test mutating writeback.
+
+  let _: Int = x.bar // Test implicitly forced optional
   let b = x.bar
   // expected-note@-1{{short-circuit}}
   // expected-note@-2{{coalesce}}
   // expected-note@-3{{force-unwrap}}
 
-  let _ : Int = b // expected-error {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
+  let _: Int = b // expected-error {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
   // expected-note@-1{{coalesce}}
   // expected-note@-2{{force-unwrap}}
 }
 
-
 //===----------------------------------------------------------------------===//
 // Error cases
 //===----------------------------------------------------------------------===//
@@ -167,7 +140,7 @@
 // Subscript index must be ExpressibleByStringLiteral.
 @dynamicMemberLookup
 struct Invalid1 {
-  // expected-error @+1 {{@dynamicMemberLookup attribute requires 'Invalid1' to have a 'subscript(dynamicMember:)' member with a string index}}
+  // expected-error @+1 {{@dynamicMemberLookup attribute requires 'Invalid1' to have a 'subscript(dynamicMember:)' method with an 'ExpressibleByStringLiteral' parameter}}
   subscript(dynamicMember member: Int) -> Int {
     return 42
   }
@@ -176,7 +149,7 @@
 // Subscript may not be variadic.
 @dynamicMemberLookup
 struct Invalid2 {
-  // expected-error @+1 {{@dynamicMemberLookup attribute requires 'Invalid2' to have a 'subscript(dynamicMember:)' member with a string index}}
+  // expected-error @+1 {{@dynamicMemberLookup attribute requires 'Invalid2' to have a 'subscript(dynamicMember:)' method with an 'ExpressibleByStringLiteral' parameter}}
   subscript(dynamicMember member: String...) -> Int {
     return 42
   }
@@ -194,13 +167,12 @@
   }
 }
 
-func testAmbiguity(a : Ambiguity) {
-  let _ : Int = a.flexibility
-  let _ : Float = a.dynamism
-  _ = a.dynamism  // expected-error {{ambiguous use of 'subscript(dynamicMember:)'}}
+func testAmbiguity(a: Ambiguity) {
+  let _: Int = a.flexibility
+  let _: Float = a.dynamism
+  _ = a.dynamism // expected-error {{ambiguous use of 'subscript(dynamicMember:)'}}
 }
 
-
 // expected-error @+1 {{'@dynamicMemberLookup' attribute cannot be applied to this declaration}}
 @dynamicMemberLookup
 extension Int {
@@ -209,15 +181,14 @@
   }
 }
 
-@dynamicMemberLookup  // expected-error {{'@dynamicMemberLookup' attribute cannot be applied to this declaration}}
-func NotAllowedOnFunc() {
-}
-
+// expected-error @+1 {{'@dynamicMemberLookup' attribute cannot be applied to this declaration}}
+@dynamicMemberLookup
+func NotAllowedOnFunc() {}
 
 // @dynamicMemberLookup cannot be declared on a base class and fulfilled with a
 // derived class.
 
-// expected-error @+1 {{@dynamicMemberLookup attribute requires 'InvalidBase' to have a 'subscript(dynamicMember:)' member with a string index}}
+// expected-error @+1 {{@dynamicMemberLookup attribute requires 'InvalidBase' to have a 'subscript(dynamicMember:)' method with an 'ExpressibleByStringLiteral' parameter}}
 @dynamicMemberLookup
 class InvalidBase {}
 
@@ -226,44 +197,57 @@
 // expected-error @+1 {{value of type 'InvalidDerived' has no member 'dynamicallyLookedUp'}}
 _ = InvalidDerived().dynamicallyLookedUp
 
-
 //===----------------------------------------------------------------------===//
-// Test Existential
+// Existentials
 //===----------------------------------------------------------------------===//
 
 @dynamicMemberLookup
-protocol PyVal {
-  subscript(dynamicMember member: StaticString) -> PyVal { get nonmutating set }
-}
-extension PyVal {
-  subscript(dynamicMember member: StaticString) -> PyVal {
-    get { fatalError() } nonmutating set {}
+protocol DynamicProtocol {
+  subscript(dynamicMember member: StaticString) -> DynamicProtocol {
+    get nonmutating set
   }
 }
 
-struct MyType : PyVal {
+struct MyDynamicStruct : DynamicProtocol {
+  subscript(dynamicMember member: StaticString) -> DynamicProtocol {
+    get { fatalError() }
+    nonmutating set {}
+  }
 }
 
-
-func testMutableExistential(a : PyVal, b : MyType) -> PyVal {
+func testMutableExistential(a: DynamicProtocol,
+                            b: MyDynamicStruct) -> DynamicProtocol {
   a.x.y = b
   b.x.y = b
   return a.foo.bar.baz
 }
 
+// Verify protocol compositions and protocol refinements work.
+protocol SubDynamicProtocol : DynamicProtocol {}
+typealias ProtocolComp = AnyObject & DynamicProtocol
 
-// Verify the protocol compositions and protocol refinements work.
-protocol SubPyVal : PyVal { }
-
-typealias ProtocolComp = AnyObject & PyVal
-
-func testMutableExistential2(a : AnyObject & PyVal, b : SubPyVal,
-                             c : ProtocolComp & AnyObject)  {
+func testMutableExistential2(a: AnyObject & DynamicProtocol,
+                             b: SubDynamicProtocol,
+                             c: ProtocolComp & AnyObject) {
   a.x.y = b
   b.x.y = b
   c.x.y = b
 }
 
+@dynamicMemberLookup
+protocol ProtoExt {}
+extension ProtoExt {
+  subscript(dynamicMember member: String) -> String {
+    get {}
+  }
+}
+
+extension String: ProtoExt {}
+
+func testProtoExt() -> String {
+  let str = "test"
+  return str.sdfsdfsdf
+}
 
 //===----------------------------------------------------------------------===//
 // JSON example
@@ -276,7 +260,7 @@
   case ArrayValue(Array<JSON>)
   case DictionaryValue(Dictionary<String, JSON>)
 
-  var stringValue : String? {
+  var stringValue: String? {
     if case .StringValue(let str) = self {
       return str
     }
@@ -294,7 +278,7 @@
     }
     return nil
   }
-  
+
   subscript(dynamicMember member: String) -> JSON? {
     if case .DictionaryValue(let dict) = self {
       return dict[member]
@@ -302,13 +286,13 @@
     return nil
   }
 }
-func test_json_example(x : JSON) -> String? {
+func testJsonExample(x: JSON) -> String? {
   _ = x.name?.first
   return x.name?.first?.stringValue
 }
 
 //===----------------------------------------------------------------------===//
-// Derived Class Example
+// Class inheritance tests
 //===----------------------------------------------------------------------===//
 
 @dynamicMemberLookup
@@ -317,27 +301,24 @@
     return 42
   }
 }
-class DerivedClass : BaseClass {
-}
+class DerivedClass : BaseClass {}
 
-func testDerivedClass(x : BaseClass, y : DerivedClass) -> Int {
+func testDerivedClass(x: BaseClass, y: DerivedClass) -> Int {
   return x.life - y.the + x.universe - y.and + x.everything
 }
 
-
 // Test that derived classes can add a setter.
 class DerivedClassWithSetter : BaseClass {
   override subscript(dynamicMember member: String) -> Int {
     get { return super[dynamicMember: member] }
-    set { }
+    set {}
   }
 }
 
-func testOverrideSubscript(a : BaseClass, b: DerivedClassWithSetter) {
+func testOverrideSubscript(a: BaseClass, b: DerivedClassWithSetter) {
   let x = a.frotz + b.garbalaz
   b.baranozo = x
-  
-  a.balboza = 12  // expected-error {{cannot assign to property}}
+  a.balboza = 12 // expected-error {{cannot assign to property}}
 }
 
 //===----------------------------------------------------------------------===//
@@ -352,12 +333,12 @@
   }
 }
 
-func testGenericType<T>(a : SettableGeneric1<T>, b : T) -> T? {
+func testGenericType<T>(a: SettableGeneric1<T>, b: T) -> T? {
   a.dfasdf = b
   return a.dfsdffff
 }
 
-func testConcreteGenericType(a : SettableGeneric1<Int>) -> Int? {
+func testConcreteGenericType(a: SettableGeneric1<Int>) -> Int? {
   a.dfasdf = 42
   return a.dfsdffff
 }
@@ -370,17 +351,42 @@
   }
 }
 
-func testGenericType2<T>(a : SettableGeneric2<T>, b : T) -> T? {
+func testGenericType2<T>(a: SettableGeneric2<T>, b: T) -> T? {
   a[dynamicMember: "fasdf"] = b
   a.dfasdf = b
   return a.dfsdffff
 }
 
-func testConcreteGenericType2(a : SettableGeneric2<Int>) -> Int? {
+func testConcreteGenericType2(a: SettableGeneric2<Int>) -> Int? {
   a.dfasdf = 42
   return a.dfsdffff
 }
 
+// SR-8077 test case.
+// `subscript(dynamicMember:)` works as a `@dynamicMemberLookup` protocol
+// requirement.
+@dynamicMemberLookup
+protocol GenericProtocol {
+  associatedtype S: ExpressibleByStringLiteral
+  associatedtype T
+  subscript(dynamicMember member: S) -> T { get }
+}
+
+@dynamicMemberLookup
+class GenericClass<S: ExpressibleByStringLiteral, T> {
+  let t: T
+  init(_ t: T) { self.t = t }
+  subscript(dynamicMember member: S) -> T { return t }
+}
+
+func testGenerics<S, T, P: GenericProtocol>(
+  a: P,
+  b: AnyObject & GenericClass<S, T>
+) where P.S == S, P.T == T {
+  let _: T = a.wew
+  let _: T = b.lad
+}
+
 //===----------------------------------------------------------------------===//
 // Keypaths
 //===----------------------------------------------------------------------===//
@@ -391,8 +397,3 @@
 }
 _ = \C.[dynamicMember: "hi"]
 _ = \C.testLookup
-
-
-
-
-
diff --git a/test/attr/attr_inlinable.swift b/test/attr/attr_inlinable.swift
index 3704366..fb45443 100644
--- a/test/attr/attr_inlinable.swift
+++ b/test/attr/attr_inlinable.swift
@@ -20,7 +20,7 @@
 private struct PrivateStruct {}
 // expected-note@-1 3{{struct 'PrivateStruct' is not '@usableFromInline' or public}}
 struct InternalStruct {}
-// expected-note@-1 4{{struct 'InternalStruct' is not '@usableFromInline' or public}}
+// expected-note@-1 3{{struct 'InternalStruct' is not '@usableFromInline' or public}}
 @usableFromInline struct VersionedStruct {
   @usableFromInline init() {}
 }
@@ -79,18 +79,6 @@
     // expected-error@-1 {{struct 'PrivateStruct' is private and cannot be referenced from an '@inlinable' function}}
   }
 
-  @inline(__always)
-  public func publicInlineAlwaysMethod(x: Any) {
-    struct Nested {}
-    // expected-error@-1 {{type 'Nested' cannot be nested inside an '@inline(__always)' function}}
-
-    switch x {
-      case is InternalStruct:
-      // expected-error@-1 {{struct 'InternalStruct' is internal and cannot be referenced from an '@inline(__always)' function}}
-        _ = ()
-    }
-  }
-
   private func privateMethod() {}
   // expected-note@-1 {{instance method 'privateMethod()' is not '@usableFromInline' or public}}
 
@@ -109,13 +97,6 @@
     // expected-error@-1 {{type 'Nested' cannot be nested inside an '@inlinable' function}}
   }
 
-  @inline(__always)
-  @usableFromInline
-  func versionedInlineAlwaysMethod() {
-    struct Nested {}
-    // expected-error@-1 {{type 'Nested' cannot be nested inside an '@inline(__always)' function}}
-  }
-
   @_transparent
   func internalTransparentMethod() {
     struct Nested {}
diff --git a/test/attr/attr_native_dynamic.swift b/test/attr/attr_native_dynamic.swift
new file mode 100644
index 0000000..0f08113
--- /dev/null
+++ b/test/attr/attr_native_dynamic.swift
@@ -0,0 +1,297 @@
+// RUN: %target-swift-frontend -swift-version 5 -typecheck -dump-ast %s 2>&1 | %FileCheck  %s
+
+struct Strukt {
+  // CHECK: (struct_decl {{.*}} "Strukt"
+  // CHECK: (var_decl {{.*}} "dynamicStorageOnlyVar" type='Int' interface type='Int' access=internal dynamic readImpl=stored writeImpl=stored readWriteImpl=stored
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=dynamicStorageOnlyVar
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic set_for=dynamicStorageOnlyVar
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=dynamicStorageOnlyVar
+  dynamic var dynamicStorageOnlyVar : Int = 0
+
+  // CHECK: (var_decl {{.*}} "computedVar" type='Int' interface type='Int' access=internal dynamic readImpl=getter immutable
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=computedVar
+  dynamic var computedVar : Int {
+    return 0
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVar2" type='Int' interface type='Int' access=internal dynamic readImpl=getter immutable
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=computedVar2
+  dynamic var computedVar2 : Int {
+    get {
+      return 0
+    }
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVarGetterSetter" type='Int' interface type='Int' access=internal dynamic readImpl=getter writeImpl=setter readWriteImpl=materialize_to_temporary
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=computedVarGetterSetter
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic set_for=computedVarGetterSetter
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=computedVarGetterSetter
+  dynamic var computedVarGetterSetter : Int {
+    get {
+      return 0
+    }
+    set {
+    }
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVarGetterModify" type='Int' interface type='Int' access=internal dynamic readImpl=getter writeImpl=modify_coroutine readWriteImpl=modify_coroutine
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=computedVarGetterModify
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _modify_for=computedVarGetterModify
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=computedVarGetterModify
+  dynamic var computedVarGetterModify : Int {
+    get {
+      return 0
+    }
+    _modify {
+    }
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVarReadSet" type='Int' interface type='Int' access=internal dynamic readImpl=read_coroutine writeImpl=setter readWriteImpl=materialize_to_temporary
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _read_for=computedVarReadSet
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic set_for=computedVarReadSet
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=computedVarReadSet
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=computedVarReadSet
+  dynamic var computedVarReadSet : Int {
+    _read {
+    }
+    set {
+    }
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVarReadModify" type='Int' interface type='Int' access=internal dynamic readImpl=read_coroutine writeImpl=modify_coroutine readWriteImpl=modify_coroutine
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _read_for=computedVarReadModify
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _modify_for=computedVarReadModify
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=computedVarReadModify
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=computedVarReadModify
+  dynamic var computedVarReadModify : Int {
+    _read {
+    }
+    _modify {
+    }
+  }
+
+  // CHECK: (var_decl {{.*}} "storedWithObserver" type='Int' interface type='Int' access=internal dynamic readImpl=stored writeImpl=stored_with_observers readWriteImpl=materialize_to_temporary
+  // CHECK: (accessor_decl {{.*}}access=private dynamic didSet_for=storedWithObserver
+  // CHECK: (accessor_decl {{.*}}access=internal dynamic get_for=storedWithObserver
+  // CHECK: (accessor_decl {{.*}}access=internal set_for=storedWithObserver
+  // CHECK: (accessor_decl {{.*}}access=internal _modify_for=storedWithObserver
+  dynamic var storedWithObserver : Int {
+    didSet {
+    }
+  }
+
+  // CHECK: (func_decl {{.*}} access=internal dynamic
+  dynamic func aMethod(arg: Int) -> Int {
+    return arg
+  }
+
+  // CHECK: (subscript_decl {{.*}} "subscript(_:)" {{.*}} access=internal dynamic readImpl=getter writeImpl=setter readWriteImpl=materialize_to_temporary
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic set_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=subscript(_:)
+  dynamic subscript(_ index: Int) -> Int {
+    get {
+      return 1
+    }
+    set {
+    }
+  }
+
+  // CHECK: (subscript_decl {{.*}} "subscript(_:)" {{.*}} access=internal dynamic readImpl=getter writeImpl=modify_coroutine readWriteImpl=modify_coroutine
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _modify_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=subscript(_:)
+  dynamic subscript(_ index: Float) -> Int {
+    get {
+      return 1
+    }
+    _modify {
+    }
+  }
+
+  // CHECK: (subscript_decl {{.*}} "subscript(_:)" {{.*}} access=internal dynamic readImpl=read_coroutine writeImpl=modify_coroutine readWriteImpl=modify_coroutine
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _read_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _modify_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=subscript(_:)
+  dynamic subscript(_ index: Double) -> Int {
+    _read {
+    }
+    _modify {
+    }
+  }
+
+  // CHECK: (subscript_decl {{.*}} "subscript(_:)" {{.*}} access=internal dynamic readImpl=read_coroutine writeImpl=setter readWriteImpl=materialize_to_temporary
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _read_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic set_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=subscript(_:)
+  dynamic subscript(_ index: Strukt) -> Int {
+    _read {
+    }
+    set {
+    }
+  }
+}
+
+class Klass {
+  // CHECK: (class_decl {{.*}} "Klass"
+  // CHECK: (var_decl {{.*}} "dynamicStorageOnlyVar" type='Int' interface type='Int' access=internal dynamic readImpl=stored writeImpl=stored readWriteImpl=stored
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=dynamicStorageOnlyVar
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic set_for=dynamicStorageOnlyVar
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=dynamicStorageOnlyVar
+  dynamic var dynamicStorageOnlyVar : Int = 0
+
+  // CHECK: (var_decl {{.*}} "computedVar" type='Int' interface type='Int' access=internal dynamic readImpl=getter immutable
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=computedVar
+  dynamic var computedVar : Int {
+    return 0
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVar2" type='Int' interface type='Int' access=internal dynamic readImpl=getter immutable
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=computedVar2
+  dynamic var computedVar2 : Int {
+    get {
+      return 0
+    }
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVarGetterSetter" type='Int' interface type='Int' access=internal dynamic readImpl=getter writeImpl=setter readWriteImpl=materialize_to_temporary
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=computedVarGetterSetter
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic set_for=computedVarGetterSetter
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=computedVarGetterSetter
+  dynamic var computedVarGetterSetter : Int {
+    get {
+      return 0
+    }
+    set {
+    }
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVarGetterModify" type='Int' interface type='Int' access=internal dynamic readImpl=getter writeImpl=modify_coroutine readWriteImpl=modify_coroutine
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=computedVarGetterModify
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _modify_for=computedVarGetterModify
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=computedVarGetterModify
+  dynamic var computedVarGetterModify : Int {
+    get {
+      return 0
+    }
+    _modify {
+    }
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVarReadSet" type='Int' interface type='Int' access=internal dynamic readImpl=read_coroutine writeImpl=setter readWriteImpl=materialize_to_temporary
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _read_for=computedVarReadSet
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic set_for=computedVarReadSet
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=computedVarReadSet
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=computedVarReadSet
+  dynamic var computedVarReadSet : Int {
+    _read {
+    }
+    set {
+    }
+  }
+
+  // CHECK: (var_decl {{.*}} "computedVarReadModify" type='Int' interface type='Int' access=internal dynamic readImpl=read_coroutine writeImpl=modify_coroutine readWriteImpl=modify_coroutine
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _read_for=computedVarReadModify
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _modify_for=computedVarReadModify
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=computedVarReadModify
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=computedVarReadModify
+  dynamic var computedVarReadModify : Int {
+    _read {
+    }
+    _modify {
+    }
+  }
+  // CHECK: (func_decl {{.*}} "aMethod(arg:)" {{.*}} access=internal dynamic
+  dynamic func aMethod(arg: Int) -> Int {
+    return arg
+  }
+
+  // CHECK-NOT: (func_decl {{.*}} "anotherMethod()" {{.*}} access=internal{{.*}} dynamic
+  func anotherMethod() -> Int {
+    return 3
+  }
+
+  // CHECK: (subscript_decl {{.*}} "subscript(_:)" {{.*}} access=internal dynamic readImpl=addressor writeImpl=mutable_addressor readWriteImpl=mutable_addressor
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic unsafeAddress_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic unsafeMutableAddress_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=subscript(_:)
+  dynamic subscript(_ index: Int) -> Int {
+    unsafeAddress {
+      fatalError()
+    }
+    unsafeMutableAddress {
+      fatalError()
+    }
+  }
+
+  // CHECK: (subscript_decl {{.*}} "subscript(_:)" {{.*}} access=internal dynamic readImpl=getter writeImpl=mutable_addressor readWriteImpl=mutable_addressor
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic get_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic unsafeMutableAddress_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=subscript(_:)
+  dynamic subscript(_ index: Float) -> Int {
+    get {
+      return 1
+    }
+    unsafeMutableAddress {
+      fatalError()
+    }
+  }
+
+  // CHECK: (subscript_decl {{.*}} "subscript(_:)" {{.*}} access=internal dynamic readImpl=read_coroutine writeImpl=mutable_addressor readWriteImpl=mutable_addressor
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _read_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic unsafeMutableAddress_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=subscript(_:)
+  dynamic subscript(_ index: Double) -> Int {
+    _read {
+    }
+    unsafeMutableAddress {
+      fatalError()
+    }
+  }
+
+  // CHECK: (subscript_decl {{.*}} "subscript(_:)" {{.*}} access=internal dynamic readImpl=addressor writeImpl=setter readWriteImpl=materialize_to_temporary
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic unsafeAddress_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic set_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal _modify_for=subscript(_:)
+  dynamic subscript(_ index: Int8) -> Int {
+    unsafeAddress {
+      fatalError()
+    }
+    set {
+    }
+  }
+
+  // CHECK: (subscript_decl {{.*}} "subscript(_:)" {{.*}} access=internal dynamic readImpl=addressor writeImpl=modify_coroutine readWriteImpl=modify_coroutine
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic unsafeAddress_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal dynamic _modify_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal get_for=subscript(_:)
+  // CHECK: (accessor_decl {{.*}} access=internal set_for=subscript(_:)
+  dynamic subscript(_ index: Int16) -> Int {
+    unsafeAddress {
+      fatalError()
+    }
+    _modify {
+    }
+  }
+}
+
+class SubKlass : Klass {
+
+  // CHECK: (class_decl {{.*}} "SubKlass"
+  // CHECK: (func_decl {{.*}} "aMethod(arg:)" interface type='(SubKlass) -> (Int) -> Int' access=internal {{.*}} dynamic
+  override dynamic func aMethod(arg: Int) -> Int {
+   return 23
+  }
+
+  // CHECK: (func_decl {{.*}} "anotherMethod()" interface type='(SubKlass) -> () -> Int' access=internal {{.*}} dynamic
+  override dynamic func anotherMethod() -> Int {
+   return 23
+  }
+}
diff --git a/test/attr/attr_noreturn.swift b/test/attr/attr_noreturn.swift
index d68b442..8dea761 100644
--- a/test/attr/attr_noreturn.swift
+++ b/test/attr/attr_noreturn.swift
@@ -34,8 +34,7 @@
 // expected-error@-2 {{'@noreturn' has been removed; functions that never return should have a return type of 'Never' instead}}{{1-11=}}{{53-56=Never}}
 
 // Test that error recovery gives us the 'Never' return type
-let x: Never = noReturn1(0)
-// expected-error@-1 {{constant 'x' cannot have enum type 'Never' with no cases}}
+let x: Never = noReturn1(0) // No error
 
 // @noreturn in function type declarations
 let valueNoReturn: @noreturn () -> ()
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index ac6a76a..034a14f 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -941,12 +941,11 @@
   // expected-note@-2 {{Swift structs cannot be represented in Objective-C}}
 
   var var_PlainEnum: PlainEnum
-  // expected-error@-1 {{stored property 'var_PlainEnum' cannot have enum type 'PlainEnum' with no cases}}
+// CHECK-LABEL: {{^}} var var_PlainEnum: PlainEnum
 
   @objc var var_PlainEnum_: PlainEnum
   // expected-error@-1 {{property cannot be marked @objc because its type cannot be represented in Objective-C}}
   // expected-note@-2 {{non-'@objc' enums cannot be represented in Objective-C}}
-  // expected-error@-3 {{stored property 'var_PlainEnum_' cannot have enum type 'PlainEnum' with no cases}}
 
   var var_PlainProtocol: PlainProtocol
 // CHECK-LABEL: {{^}}  var var_PlainProtocol: PlainProtocol
@@ -1272,7 +1271,6 @@
   // expected-error@-1 {{'unowned' may only be applied to class and class-bound protocol types, not 'PlainStruct'}}
   unowned var var_Unowned_bad3: PlainEnum
   // expected-error@-1 {{'unowned' may only be applied to class and class-bound protocol types, not 'PlainEnum'}}
-  // expected-error@-2 {{stored property 'var_Unowned_bad3' cannot have enum type 'PlainEnum' with no cases}}
   unowned var var_Unowned_bad4: String
   // expected-error@-1 {{'unowned' may only be applied to class and class-bound protocol types, not 'String'}}
 // CHECK-NOT: @objc{{.*}}Unowned_fail
diff --git a/test/attr/attr_usableFromInline_protocol.swift b/test/attr/attr_usableFromInline_protocol.swift
new file mode 100644
index 0000000..824eb47
--- /dev/null
+++ b/test/attr/attr_usableFromInline_protocol.swift
@@ -0,0 +1,42 @@
+// RUN: %target-typecheck-verify-swift -swift-version 5
+// RUN: %target-swift-frontend -typecheck -disable-access-control %s
+
+public protocol PublicProtoWithReqs {
+  associatedtype Assoc
+  func foo()
+}
+
+@usableFromInline struct UFIAdopter<T> : PublicProtoWithReqs {}
+// expected-error@-1 {{type alias 'Assoc' must be declared '@usableFromInline' because because it matches a requirement in protocol 'PublicProtoWithReqs'}} {{none}}
+extension UFIAdopter {
+  typealias Assoc = Int
+  // expected-note@-1 {{'Assoc' declared here}}
+  func foo() {}
+}
+
+@usableFromInline struct UFIAdopterAllInOne<T> : PublicProtoWithReqs {
+  typealias Assoc = Int
+  // expected-error@-1 {{type alias 'Assoc' must be declared '@usableFromInline' because because it matches a requirement in protocol 'PublicProtoWithReqs'}} {{none}}
+  func foo() {}
+}
+
+internal struct InternalAdopter<T> : PublicProtoWithReqs {}
+extension InternalAdopter {
+  typealias Assoc = Int // okay
+  func foo() {} // okay
+}
+
+
+@usableFromInline protocol UFIProtoWithReqs {
+  associatedtype Assoc
+  func foo()
+}
+
+public struct PublicAdopter<T> : UFIProtoWithReqs {}
+// expected-error@-1 {{type alias 'Assoc' must be declared '@usableFromInline' because because it matches a requirement in protocol 'UFIProtoWithReqs'}} {{none}}
+extension PublicAdopter {
+  typealias Assoc = Int
+  // expected-note@-1 {{'Assoc' declared here}}
+  func foo() {}
+}
+extension InternalAdopter: UFIProtoWithReqs {} // okay
diff --git a/test/attr/attributes.swift b/test/attr/attributes.swift
index 7054e38..4458ed9 100644
--- a/test/attr/attributes.swift
+++ b/test/attr/attributes.swift
@@ -214,12 +214,12 @@
 var thinFunc : @thin () -> () // expected-error {{attribute is not supported}}
 
 @inline(never) func nolineFunc() {}
-@inline(never) var noinlineVar : Int // expected-error {{'@inline(never)' attribute cannot be applied to this declaration}} {{1-16=}}
+@inline(never) var noinlineVar : Int { return 0 }
 @inline(never) class FooClass { // expected-error {{'@inline(never)' attribute cannot be applied to this declaration}} {{1-16=}}
 }
 
 @inline(__always) func AlwaysInlineFunc() {}
-@inline(__always) var alwaysInlineVar : Int // expected-error {{'@inline(__always)' attribute cannot be applied to this declaration}} {{1-19=}}
+@inline(__always) var alwaysInlineVar : Int { return 0 }
 @inline(__always) class FooClass2 { // expected-error {{'@inline(__always)' attribute cannot be applied to this declaration}} {{1-19=}}
 }
 
@@ -262,8 +262,8 @@
   @_optimize(size) var c : Int // expected-error {{'@_optimize(size)' attribute cannot be applied to stored properties}}
 }
 
-class SILStored {
-  @sil_stored var x : Int = 42  // expected-error {{'sil_stored' only allowed in SIL modules}}
+class HasStorage {
+  @_hasStorage var x : Int = 42  // ok, _hasStorage is allowed here
 }
 
 @_show_in_interface protocol _underscored {}
diff --git a/test/attr/private_import.swift b/test/attr/private_import.swift
new file mode 100644
index 0000000..758ae165
--- /dev/null
+++ b/test/attr/private_import.swift
@@ -0,0 +1,9 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -enable-private-imports -o %t %S/../Inputs/empty.swift
+// RUN: %target-swift-frontend -typecheck -I %t -I %S/Inputs/custom-modules %s -verify
+
+@_private(sourceFile: "Array.swift") import Swift // expected-error {{module 'Swift' was not compiled for private import}}
+@_private(sourceFile: "empty.swift") import empty // no-error
+@_private(sourceFile: "not_existing_file.swift") import empty // no-error
+
+@_private(sourceFile: "none") func foo() {} // expected-error {{@_private may only be used on 'import' declarations}} {{1-31=}}
diff --git a/test/decl/ext/generic.swift b/test/decl/ext/generic.swift
index c03a72c..ba3aead 100644
--- a/test/decl/ext/generic.swift
+++ b/test/decl/ext/generic.swift
@@ -175,3 +175,20 @@
     func foo() -> Element.AssocType {}
   }
 }
+
+// Deeply nested
+protocol P6 {
+  associatedtype Assoc1
+  associatedtype Assoc2
+}
+
+struct A<T, U, V> {
+  struct B<W, X, Y> {
+    struct C<Z: P6> {
+    }
+  }
+}
+
+extension A.B.C where T == V, X == Z.Assoc2 {
+  func f() { }
+}
diff --git a/test/decl/func/operator.swift b/test/decl/func/operator.swift
index 9c12f45..c2f2038 100644
--- a/test/decl/func/operator.swift
+++ b/test/decl/func/operator.swift
@@ -359,3 +359,41 @@
     if x == x && x = x { } // expected-error{{cannot convert value of type 'C6' to expected argument type 'Bool'}}
   }
 }
+
+prefix operator ∫
+
+prefix func ∫(arg: (Int, Int)) {}
+
+func testPrefixOperatorOnTuple() {
+
+  let foo = (1, 2)
+  _ = ∫foo
+  _ = (∫)foo
+  // expected-error@-1 {{consecutive statements on a line must be separated by ';'}}
+  // expected-warning@-2 {{expression of type '(Int, Int)' is unused}}
+  _ = (∫)(foo)
+  _ = ∫(1, 2)
+  _ = (∫)(1, 2) // expected-error {{operator function '∫' expects a single parameter of type '(Int, Int)'}}
+  _ = (∫)((1, 2))
+}
+
+postfix operator §
+
+postfix func §<T, U>(arg: (T, (U, U), T)) {} // expected-note {{in call to operator '§'}}
+
+func testPostfixOperatorOnTuple<A, B>(a: A, b: B) {
+
+  let foo = (a, (b, b), a)
+  _ = foo§
+
+  // FIX-ME: "...could not be inferred" is irrelevant
+  _ = (§)foo
+  // expected-error@-1 {{consecutive statements on a line must be separated by ';'}}
+  // expected-error@-2 {{generic parameter 'T' could not be inferred}}
+  // expected-warning@-3 {{expression of type '(A, (B, B), A)' is unused}}
+  _ = (§)(foo)
+  _ = (a, (b, b), a)§
+  _ = (§)(a, (b, b), a) // expected-error {{operator function '§' expects a single parameter of type '(T, (U, U), T)'}}
+  _ = (§)((a, (b, b), a))
+  _ = (a, ((), (b, (a, a), b)§), a)§
+}
diff --git a/test/decl/init/resilience.swift b/test/decl/init/resilience.swift
index 03e9d41..3963758 100644
--- a/test/decl/init/resilience.swift
+++ b/test/decl/init/resilience.swift
@@ -8,16 +8,12 @@
 // Animal is not @_fixed_layout, so we cannot define an @inlinable
 // designated initializer
 public struct Animal {
-  public let name: String // expected-note 3 {{declared here}}
+  public let name: String // expected-note 2 {{declared here}}
 
   @inlinable public init(name: String) {
     self.name = name // expected-error {{'let' property 'name' may not be initialized directly; use "self.init(...)" or "self = ..." instead}}
   }
 
-  @inline(__always) public init(dog: String) {
-    self.name = dog // expected-error {{'let' property 'name' may not be initialized directly; use "self.init(...)" or "self = ..." instead}}
-  }
-
   @_transparent public init(cat: String) {
     self.name = cat // expected-error {{'let' property 'name' may not be initialized directly; use "self.init(...)" or "self = ..." instead}}
   }
diff --git a/test/decl/protocol/protocol_with_superclass.swift b/test/decl/protocol/protocol_with_superclass.swift
index ae59a12..a5e5daa 100644
--- a/test/decl/protocol/protocol_with_superclass.swift
+++ b/test/decl/protocol/protocol_with_superclass.swift
@@ -294,6 +294,12 @@
   func takesT(_: T)
 }
 
+func takesBaseProtocol(_: BaseProtocol) {}
+
+func passesRefinedProtocol(_ r: RefinedProtocol) {
+  takesBaseProtocol(r)
+}
+
 class RefinedClass : BaseClass, RefinedProtocol {
   func takesT(_: T) {
     _ = T.self
diff --git a/test/decl/protocol/protocol_with_superclass_where_clause.swift b/test/decl/protocol/protocol_with_superclass_where_clause.swift
index 8ec60b0..50efc6d 100644
--- a/test/decl/protocol/protocol_with_superclass_where_clause.swift
+++ b/test/decl/protocol/protocol_with_superclass_where_clause.swift
@@ -300,6 +300,12 @@
   }
 }
 
+func takesBaseProtocol(_: BaseProtocol) {}
+
+func passesRefinedProtocol(_ r: RefinedProtocol) {
+  takesBaseProtocol(r)
+}
+
 class LoopClass : LoopProto {}
 protocol LoopProto where Self : LoopClass {}
 
diff --git a/test/decl/subscript/addressors.swift b/test/decl/subscript/addressors.swift
index aaf4ac4..e048638 100644
--- a/test/decl/subscript/addressors.swift
+++ b/test/decl/subscript/addressors.swift
@@ -179,37 +179,19 @@
   }
 }
 
-// FIXME: Actually plumb the work to fix the grammar in these
-// diagnostics if/when we productize them.  ("a addressor")
-struct RedundantAddressors1 {
+struct RedundantAddressors {
   var owner : Builtin.NativeObject
   subscript(index: Int) -> Int {
     unsafeAddress { return someValidAddress() } // expected-note {{previous definition of addressor here}}
-    addressWithNativeOwner { return (someValidAddress(), owner)  } // expected-error {{subscript already has an addressor}}
+    unsafeAddress { return someValidAddress() } // expected-error {{subscript already has an addressor}}
   }
 }
 
-struct RedundantMutableAddressors1 {
+struct RedundantMutableAddressors {
   var owner : Builtin.NativeObject
   subscript(index: Int) -> Int {
     unsafeAddress { return someValidAddress() }
     unsafeMutableAddress { return someValidAddress() } // expected-note {{previous definition of mutable addressor here}}
-    mutableAddressWithNativeOwner { return (someValidAddress(), owner)  } // expected-error {{subscript already has a mutable addressor}}
-  }
-}
-struct RedundantMutableAddressors2 {
-  var owner : Builtin.NativeObject
-  subscript(index: Int) -> Int {
-    unsafeAddress { return someValidAddress() }
-    unsafeMutableAddress { return someValidAddress() } // expected-note {{previous definition of mutable addressor here}}
-    mutableAddressWithNativeOwner { return (someValidAddress(), owner)  } // expected-error {{subscript already has a mutable addressor}}
-  }
-}
-struct RedundantMutableAddressors3 {
-  var owner : Builtin.NativeObject
-  subscript(index: Int) -> Int {
-    unsafeAddress { return someValidAddress() }
-    unsafeMutableAddress { return someValidAddress() } // expected-note {{previous definition of mutable addressor here}}
-    mutableAddressWithNativeOwner { return (someValidAddress(), owner)  } // expected-error {{subscript already has a mutable addressor}}
+    unsafeMutableAddress { return someValidAddress() } // expected-error {{subscript already has a mutable addressor}}
   }
 }
diff --git a/test/decl/subscript/noescape_accessors.swift b/test/decl/subscript/noescape_accessors.swift
index 638a394..bf4444f 100644
--- a/test/decl/subscript/noescape_accessors.swift
+++ b/test/decl/subscript/noescape_accessors.swift
@@ -59,7 +59,7 @@
     get {
       return 0
     }
-    mutableAddressWithNativeOwner {
+    unsafeMutableAddress {
       fatalError()
     }
   }
diff --git a/test/decl/var/properties.swift b/test/decl/var/properties.swift
index 6e1f6f7..40a457e 100644
--- a/test/decl/var/properties.swift
+++ b/test/decl/var/properties.swift
@@ -1268,24 +1268,12 @@
   weak var bar : WFI_P1 & WFI_P2
 }
 
-// SR-8811
-// Stored properties cannot have uninhabited types
+// SR-8811 (Warning)
 
-struct SR8811 {
-  var x: Never // expected-error {{stored property 'x' cannot have enum type 'Never' with no cases}}
-  
-  var y: (Int, Never, Bool) // expected-error {{stored property 'y' cannot have tuple type '(Int, Never, Bool)' containing enum with no cases}}
-}
+let sr8811a = fatalError() // expected-warning {{constant 'sr8811a' inferred to have type 'Never', which is an enum with no cases}} expected-note {{add an explicit type annotation to silence this warning}}
 
-let sr8811x: Never // expected-error {{constant 'sr8811x' cannot have enum type 'Never' with no cases}}
+let sr8811b: Never = fatalError() // Ok
 
-var sr8811y: (Int, Never) // expected-error {{variable 'sr8811y' cannot have tuple type '(Int, Never)' containing enum with no cases}}
+let sr8811c = (16, fatalError()) // expected-warning {{constant 'sr8811c' inferred to have type '(Int, Never)', which contains an enum with no cases}} expected-note {{add an explicit type annotation to silence this warning}}
 
-// Ok
-var sr8811z: Never {
-  return fatalError()
-}
-
-enum SR8811EmptyGenericEnum<A> {}
-
-let sr8811z: SR8811EmptyGenericEnum<Int> // expected-error {{constant 'sr8811z' cannot have enum type 'SR8811EmptyGenericEnum<Int>' with no cases}}
+let sr8811d: (Int, Never) = (16, fatalError()) // Ok
diff --git a/test/expr/closure/closures.swift b/test/expr/closure/closures.swift
index e9fde6d..4fa45e8 100644
--- a/test/expr/closure/closures.swift
+++ b/test/expr/closure/closures.swift
@@ -15,7 +15,7 @@
 var closure4 : (Int,Int) -> Int = { $0 + $1 }
 var closure5 : (Double) -> Int = {
        $0 + 1.0
-       // expected-error@+1 {{cannot convert value of type 'Double' to closure result type 'Int'}}
+       // expected-error@-1 {{cannot convert value of type 'Double' to closure result type 'Int'}}
 }
 
 var closure6 = $0  // expected-error {{anonymous closure argument not contained in a closure}}
diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift
index 0473b67..62b9e1e 100644
--- a/test/expr/expressions.swift
+++ b/test/expr/expressions.swift
@@ -584,9 +584,9 @@
   var pi_f3 = float.init(getPi()) // expected-error {{ambiguous use of 'init(_:)'}}
   var pi_f4 = float.init(pi_f)
 
-  var e = Empty(f) // expected-error {{variable 'e' cannot have enum type 'Empty' with no cases}}
+  var e = Empty(f) // expected-warning {{variable 'e' inferred to have type 'Empty', which is an enum with no cases}} expected-note {{add an explicit type annotation to silence this warning}}
   var e2 = Empty(d) // expected-error{{cannot convert value of type 'Double' to expected argument type 'Float'}}
-  var e3 = Empty(Float(d)) // expected-error {{variable 'e3' cannot have enum type 'Empty' with no cases}}
+  var e3 = Empty(Float(d)) // expected-warning {{variable 'e3' inferred to have type 'Empty', which is an enum with no cases}} expected-note {{add an explicit type annotation to silence this warning}}
 }
 
 struct Rule { // expected-note {{'init(target:dependencies:)' declared here}}
diff --git a/test/expr/unary/keypath/keypath-unimplemented.swift b/test/expr/unary/keypath/keypath-unimplemented.swift
index 2e2bc66..222ba45 100644
--- a/test/expr/unary/keypath/keypath-unimplemented.swift
+++ b/test/expr/unary/keypath/keypath-unimplemented.swift
@@ -12,3 +12,24 @@
 // rdar://problem/32209039 - Improve diagnostic when unsupported tuple element references are used in key path literals
 let _ = \(Int, String).0 // expected-error {{key path cannot reference tuple elements}}
 let _ = \(a: Int, b: String).b // expected-error {{key path cannot reference tuple elements}}
+
+struct TupleKeypath {
+    let labeled: (foo: Int, bar: String)
+    let unlabeled: (Int, Int)
+}
+
+let _: KeyPath<TupleKeypath, Int> = \TupleKeypath.labeled.foo // expected-error {{key path support for tuples is not implemented}}
+let _: KeyPath<TupleKeypath, String> = \TupleKeypath.labeled.bar // expected-error {{key path support for tuples is not implemented}}
+let _: KeyPath<TupleKeypath, Int> = \TupleKeypath.unlabeled.0 // expected-error {{key path support for tuples is not implemented}}
+let _: KeyPath<TupleKeypath, String> = \TupleKeypath.unlabeled.1 // expected-error {{key path support for tuples is not implemented}}
+
+struct S {
+  typealias X = (lhs: Int, rhs: Int)
+  typealias Y = (Int, Int)
+
+  let x: X
+  let y: Y
+}
+
+let _: KeyPath<S, Int> = \S.x.lhs // expected-error {{key path support for tuples is not implemented}}
+let _: KeyPath<S, Int> = \S.y.0   // expected-error {{key path support for tuples is not implemented}}
diff --git a/test/incrParse/inserted_text_starts_identifier.swift b/test/incrParse/inserted_text_starts_identifier.swift
new file mode 100644
index 0000000..14b0573
--- /dev/null
+++ b/test/incrParse/inserted_text_starts_identifier.swift
@@ -0,0 +1,6 @@
+// RUN: %empty-directory(%t)
+// RUN: %validate-incrparse %s --test-case STRING
+
+// SR-8995 rdar://problem/45259469
+
+self = <<STRING<|||_                            _>>>foo(1)[object1, object2] + o bar(1)
diff --git a/test/lit.cfg b/test/lit.cfg
index 7692aef..f3df0de 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -576,7 +576,7 @@
 swift_reflection_test_name = 'swift-reflection-test' + config.variant_suffix
 
 def use_interpreter_for_simple_runs():
-    def make_simple_target_run(gyb=False, stdlib=False, swift3=False, opt=""):
+    def make_simple_target_run(gyb=False, stdlib=False, opt=""):
         result = ''
         if gyb:
             result += ('%empty-directory(%t) && '
@@ -592,8 +592,6 @@
                swift_execution_tests_extra_flags))
         if stdlib:
             result += '-Xfrontend -disable-access-control '
-        if swift3:
-            result += '-swift-version 3 '
         if opt:
             result += opt + ' '
         if gyb:
@@ -601,13 +599,9 @@
         else:
             result += '%s'
         return result
-    config.target_run_stdlib_swiftgyb_swift3 = make_simple_target_run(gyb=True, stdlib=True, swift3=True)
-    config.target_run_stdlib_swiftgyb = make_simple_target_run(gyb=True, swift3=True)
-    config.target_run_simple_swiftgyb_swift3 = make_simple_target_run(gyb=True, swift3=True)
+    config.target_run_stdlib_swiftgyb = make_simple_target_run(gyb=True)
     config.target_run_simple_swiftgyb = make_simple_target_run(gyb=True)
-    config.target_run_stdlib_swift_swift3 = make_simple_target_run(stdlib=True, swift3=True)
     config.target_run_stdlib_swift = make_simple_target_run(stdlib=True)
-    config.target_run_simple_swift_swift3 = make_simple_target_run(swift3=True)
     config.target_run_simple_opt_Osize_swift = make_simple_target_run(opt='-Osize')
     config.target_run_simple_opt_O_swift = make_simple_target_run(opt='-O')
     config.target_run_simple_swift = make_simple_target_run()
@@ -1105,12 +1099,6 @@
         '%s %%t/a.out &&'
         '%s %%t/a.out'
         % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
-    config.target_run_simple_swift_swift3 = (
-        '%%empty-directory(%%t) && '
-        '%s %s %%s -o %%t/a.out -module-name main -swift-version 3 && '
-        '%s %%t/a.out &&'
-        '%s %%t/a.out'
-        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
     config.target_run_stdlib_swift = (
         '%%empty-directory(%%t) && '
         '%s %s %%s -o %%t/a.out -module-name main '
@@ -1118,13 +1106,6 @@
         '%s %%t/a.out &&'
         '%s %%t/a.out'
         % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
-    config.target_run_stdlib_swift_swift3 = (
-        '%%empty-directory(%%t) && '
-        '%s %s %%s -o %%t/a.out -module-name main '
-        '-Xfrontend -disable-access-control -swift-version 3 && '
-        '%s %%t/a.out &&'
-        '%s %%t/a.out'
-        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
     config.target_run_simple_swiftgyb = (
         '%%empty-directory(%%t) && '
         '%%gyb %%s -o %%t/main.swift && '
@@ -1134,15 +1115,6 @@
         '%%line-directive %%t/main.swift -- '
         '%s %%t/a.out'
         % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
-    config.target_run_simple_swiftgyb_swift3 = (
-        '%%empty-directory(%%t) && '
-        '%%gyb %%s -o %%t/main.swift && '
-        '%%line-directive %%t/main.swift -- '
-        '%s %s %%t/main.swift -o %%t/a.out -module-name main -swift-version 3 && '
-        '%s %%t/a.out &&'
-        '%%line-directive %%t/main.swift -- '
-        '%s %%t/a.out'
-        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
     config.target_run_stdlib_swiftgyb = (
         '%%empty-directory(%%t) && '
         '%%gyb %%s -o %%t/main.swift && '
@@ -1153,16 +1125,6 @@
         '%%line-directive %%t/main.swift -- '
         '%s %%t/a.out'
         % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
-    config.target_run_stdlib_swiftgyb_swift3 = (
-        '%%empty-directory(%%t) && '
-        '%%gyb %%s -o %%t/main.swift && '
-        '%%line-directive %%t/main.swift -- '
-        '%s %s %%t/main.swift -o %%t/a.out -module-name main -swift-version 3 '
-        '-Xfrontend -disable-access-control && '
-        '%s %%t/a.out &&'
-        '%%line-directive %%t/main.swift -- '
-        '%s %%t/a.out'
-        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
 
 subst_target_jit_run = ""
 if 'swift_interpreter' in config.available_features:
@@ -1224,15 +1186,11 @@
 config.substitutions.append(('%target-swift-frontend', config.target_swift_frontend))
 
 
-config.substitutions.append(('%target-run-simple-swiftgyb-swift3', config.target_run_simple_swiftgyb_swift3))
 config.substitutions.append(('%target-run-simple-swiftgyb', config.target_run_simple_swiftgyb))
-config.substitutions.append(('%target-run-simple-swift-swift3', config.target_run_simple_swift_swift3))
 config.substitutions.append(('%target-run-simple-swift', config.target_run_simple_swift))
 config.substitutions.append(('%target-run-simple-opt-O-swift', config.target_run_simple_opt_O_swift))
 config.substitutions.append(('%target-run-simple-opt-Osize-swift', config.target_run_simple_opt_Osize_swift))
-config.substitutions.append(('%target-run-stdlib-swiftgyb-swift3', config.target_run_stdlib_swiftgyb_swift3))
 config.substitutions.append(('%target-run-stdlib-swiftgyb', config.target_run_stdlib_swiftgyb))
-config.substitutions.append(('%target-run-stdlib-swift-swift3', config.target_run_stdlib_swift_swift3))
 config.substitutions.append(('%target-run-stdlib-swift', config.target_run_stdlib_swift))
 config.substitutions.append(('%target-repl-run-simple-swift', subst_target_repl_run_simple_swift))
 config.substitutions.append(('%target-run', config.target_run))
diff --git a/test/multifile/Inputs/protocol-extension-init-helper.swift b/test/multifile/Inputs/protocol-extension-init-helper.swift
new file mode 100644
index 0000000..0adf018
--- /dev/null
+++ b/test/multifile/Inputs/protocol-extension-init-helper.swift
@@ -0,0 +1,4 @@
+protocol P {
+  init()
+  var x: Int { get set }
+}
diff --git a/test/multifile/protocol-conformance-rdar-34584596.swift b/test/multifile/protocol-conformance-rdar-34584596.swift
index 5383d62..7bb2599 100644
--- a/test/multifile/protocol-conformance-rdar-34584596.swift
+++ b/test/multifile/protocol-conformance-rdar-34584596.swift
@@ -1,2 +1,2 @@
-// RUN: not --crash %target-swift-frontend -emit-ir -O -o - -primary-file %S/Inputs/rdar-34584596-A.swift %S/Inputs/rdar-34584596-B.swift %S/Inputs/rdar-34584596-C.swift -module-name main
+// RUN: %target-swift-frontend -emit-ir -O -o - -primary-file %S/Inputs/rdar-34584596-A.swift %S/Inputs/rdar-34584596-B.swift %S/Inputs/rdar-34584596-C.swift -module-name main
 
diff --git a/test/multifile/protocol-extension-init.swift b/test/multifile/protocol-extension-init.swift
new file mode 100644
index 0000000..a0736c3
--- /dev/null
+++ b/test/multifile/protocol-extension-init.swift
@@ -0,0 +1,8 @@
+// RUN: %target-swift-frontend -emit-ir -module-name test %S/Inputs/protocol-extension-init-helper.swift -primary-file %s
+
+// SE-9233: compute layout when emitting an other-constructor reference
+extension P {
+  public init(possibly: Bool) {
+    self.init()
+  }
+}
diff --git a/test/stdlib/Character.swift b/test/stdlib/Character.swift
index 0c18e04..6f6acc5 100644
--- a/test/stdlib/Character.swift
+++ b/test/stdlib/Character.swift
@@ -105,17 +105,18 @@
   "\u{00a9}\u{0300}\u{0300}\u{0300}\u{0300}", // UTF-8: 10 bytes
 ]
 
-// Only run it on ObjC platforms. Supported Linux versions do not have a
-// recent enough ICU
+// Only run it on recent enough versions of ICU
 #if _runtime(_ObjC)
-testCharacters += [
-  "\u{00a9}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}", // UTF-8: 12 bytes
-  "\u{00a9}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}", // UTF-8: 14 bytes
-  "\u{00a9}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}", // UTF-8: 16 bytes
+if #available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *) {
+  testCharacters += [
+    "\u{00a9}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}", // UTF-8: 12 bytes
+    "\u{00a9}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}", // UTF-8: 14 bytes
+    "\u{00a9}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}\u{0300}", // UTF-8: 16 bytes
 
-  "👩🏽‍💼", // UTF-8: 15 bytes
-  "👩‍👩‍👦‍👦", // UTF-8: 25 bytes
-]
+    "👩🏽‍💼", // UTF-8: 15 bytes
+    "👩‍👩‍👦‍👦", // UTF-8: 25 bytes
+  ]
+}
 #endif
 
 func randomGraphemeCluster(_ minSize: Int, _ maxSize: Int) -> String {
diff --git a/test/stdlib/Inputs/ArrayTypesAndHelpers.swift b/test/stdlib/Inputs/ArrayTypesAndHelpers.swift
index 118b79f..571bea6 100644
--- a/test/stdlib/Inputs/ArrayTypesAndHelpers.swift
+++ b/test/stdlib/Inputs/ArrayTypesAndHelpers.swift
@@ -1,4 +1,5 @@
 import Swift
+import SwiftPrivate
 import StdlibUnittest
 #if _runtime(_ObjC)
 import Darwin
diff --git a/test/stdlib/Inputs/DictionaryKeyValueTypes.swift b/test/stdlib/Inputs/DictionaryKeyValueTypes.swift
index 9fd935a..b118590 100644
--- a/test/stdlib/Inputs/DictionaryKeyValueTypes.swift
+++ b/test/stdlib/Inputs/DictionaryKeyValueTypes.swift
@@ -1,4 +1,5 @@
 import Swift
+import SwiftPrivate
 import StdlibUnittest
 
 func acceptsAnySet<T : Hashable>(_ s: Set<T>) {}
diff --git a/test/stdlib/Inputs/DictionaryKeyValueTypesObjC.swift b/test/stdlib/Inputs/DictionaryKeyValueTypesObjC.swift
index 7b2543b..38ba4ea 100644
--- a/test/stdlib/Inputs/DictionaryKeyValueTypesObjC.swift
+++ b/test/stdlib/Inputs/DictionaryKeyValueTypesObjC.swift
@@ -1,4 +1,5 @@
 import Swift
+import SwiftPrivate
 import Darwin
 import StdlibUnittest
 import Foundation
diff --git a/test/stdlib/ManagedBuffer.swift b/test/stdlib/ManagedBuffer.swift
index 24d288c..8d39d3f 100644
--- a/test/stdlib/ManagedBuffer.swift
+++ b/test/stdlib/ManagedBuffer.swift
@@ -40,7 +40,7 @@
 
 struct CountAndCapacity {
   var count: LifetimeTracked
-  let capacity: Int
+  var capacity: Int
 }
 
 // An example of ManagedBuffer, very similar to what Array will use.
@@ -96,6 +96,23 @@
     }
     self.count = count + 2
   }
+
+  class func tryGrow(_ buffer: inout TestManagedBuffer<T>, newCapacity: Int) -> Bool {
+    guard isKnownUniquelyReferenced(&buffer) else {
+      return false
+    }
+    guard newCapacity > buffer.capacity else {
+      return false
+    }
+
+    if tryReallocateUniquelyReferenced(buffer: &buffer,
+                                       newMinimumCapacity: newCapacity) {
+      buffer.header.capacity = newCapacity
+      return true
+    } else {
+      return false
+    }
+  }
 }
 
 class MyBuffer<T> {
@@ -241,4 +258,35 @@
   _fixLifetime(s2)
 }
 
+tests.test("canGrowUsingRealloc") {
+  #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
+  return // realloc currently unsupported on Darwin
+  #endif
+  func testGrow(_ buffer: inout TestManagedBuffer<LifetimeTracked>,
+                newCapacity: Int,
+                shouldSucceed: Bool = true) {
+    let s = TestManagedBuffer.tryGrow(&buffer, newCapacity: newCapacity)
+    expectEqual(s, shouldSucceed)
+    if shouldSucceed {
+      expectLE(newCapacity, buffer.myCapacity)
+      expectGE((newCapacity + 1) * 2, buffer.myCapacity)
+    }
+    repeat {
+      buffer.append(LifetimeTracked(buffer.count))
+    } while buffer.count < buffer.myCapacity - 2
+  }
+
+  var b = TestManagedBuffer<LifetimeTracked>.create(0)
+  // allow some over-allocation
+  expectLE(0, b.myCapacity)
+  expectGE(3, b.myCapacity)
+
+  testGrow(&b, newCapacity: 5)
+  testGrow(&b, newCapacity: 8)
+  testGrow(&b, newCapacity: 1000)
+  testGrow(&b, newCapacity: 16000)
+  var b2 = b
+  testGrow(&b, newCapacity: 2000, shouldSucceed: false)
+}
+
 runAllTests()
diff --git a/test/stdlib/NewString.swift b/test/stdlib/NewString.swift
index 9b2a2d8..fb388a4 100644
--- a/test/stdlib/NewString.swift
+++ b/test/stdlib/NewString.swift
@@ -108,7 +108,7 @@
 
   // The storage of the slice implements NSString directly
   // CHECK-NOT: @[[utf16address]] = "❅❆❄︎⛄️"
-  // CHECK-NEXT: Swift._StringStorage@[[sliceAddress]] = "❅❆❄︎⛄️"
+  // CHECK-NEXT: {{.*}}StringStorage@[[sliceAddress]] = "❅❆❄︎⛄️"
   let nsSlice = slice as NSString
   print("  \(repr(nsSlice))")
 
diff --git a/test/stdlib/NewStringAppending.swift b/test/stdlib/NewStringAppending.swift
index 1f498f7..d600c49 100644
--- a/test/stdlib/NewStringAppending.swift
+++ b/test/stdlib/NewStringAppending.swift
@@ -1,4 +1,4 @@
-// RUN: %target-run-stdlib-swift-swift3 | %FileCheck %s
+// RUN: %target-run-stdlib-swift | %FileCheck %s
 // REQUIRES: executable_test
 //
 // Parts of this test depend on memory allocator specifics.  The test
diff --git a/tools/SourceKit/CMakeLists.txt b/tools/SourceKit/CMakeLists.txt
index 067643e..6a397f5 100644
--- a/tools/SourceKit/CMakeLists.txt
+++ b/tools/SourceKit/CMakeLists.txt
@@ -101,7 +101,8 @@
 
   if(SWIFT_BUILD_SOURCEKIT)
     if(CMAKE_C_COMPILER_ID STREQUAL Clang AND
-       CMAKE_C_COMPILER_VERSION VERSION_GREATER 3.8)
+       CMAKE_C_COMPILER_VERSION VERSION_GREATER 3.8
+       OR LLVM_USE_SANITIZER)
      set(SWIFT_SOURCEKIT_C_COMPILER ${CMAKE_C_COMPILER})
      set(SWIFT_SOURCEKIT_CXX_COMPILER ${CMAKE_CXX_COMPILER})
    elseif(${CMAKE_SYSTEM_NAME} STREQUAL ${CMAKE_HOST_SYSTEM_NAME})
diff --git a/tools/SourceKit/tools/swift-lang/CMakeLists.txt b/tools/SourceKit/tools/swift-lang/CMakeLists.txt
index b9b3127..1999669 100644
--- a/tools/SourceKit/tools/swift-lang/CMakeLists.txt
+++ b/tools/SourceKit/tools/swift-lang/CMakeLists.txt
@@ -13,7 +13,7 @@
     UIDs.swift.gyb
 
     DEPENDS ${DEPENDS_LIST}
-    SWIFT_MODULE_DEPENDS_OSX Darwin
+    SWIFT_MODULE_DEPENDS_OSX Darwin Foundation
     PRIVATE_LINK_LIBRARIES ${SOURCEKITD_LINK_LIBS}
     SWIFT_COMPILE_FLAGS ${EXTRA_COMPILE_FLAGS}
     INSTALL_IN_COMPONENT ${INSTALLED_COMP}
diff --git a/tools/SourceKit/tools/swift-lang/SourceKitdResponse.swift b/tools/SourceKit/tools/swift-lang/SourceKitdResponse.swift
index 9370a0e..359cbef 100644
--- a/tools/SourceKit/tools/swift-lang/SourceKitdResponse.swift
+++ b/tools/SourceKit/tools/swift-lang/SourceKitdResponse.swift
@@ -12,17 +12,23 @@
 // This file provides convenient APIs to interpret a SourceKitd response.
 //===----------------------------------------------------------------------===//
 
+import Foundation
 import sourcekitd
 
 public class SourceKitdResponse: CustomStringConvertible {
 
   public struct Dictionary: CustomStringConvertible, CustomReflectable {
+    // The lifetime of this sourcekitd_variant_t is tied to the response it came
+    // from, so keep a reference to the response too.
     private let dict: sourcekitd_variant_t
+    private let context: SourceKitdResponse
 
-    public init(dict: sourcekitd_variant_t) {
+
+    public init(dict: sourcekitd_variant_t, context: SourceKitdResponse) {
       assert(sourcekitd_variant_get_type(dict).rawValue ==
         SOURCEKITD_VARIANT_TYPE_DICTIONARY.rawValue)
       self.dict = dict
+      self.context = context
     }
 
     public func getString(_ key: SourceKitdUID) -> String {
@@ -47,12 +53,21 @@
 
     public func getArray(_ key: SourceKitdUID) -> Array {
       let value = sourcekitd_variant_dictionary_get_value(dict, key.uid)
-      return Array(arr: value)
+      return Array(arr: value, context: context)
     }
 
     public func getDictionary(_ key: SourceKitdUID) -> Dictionary {
       let value = sourcekitd_variant_dictionary_get_value(dict, key.uid)
-      return Dictionary(dict: value)
+      return Dictionary(dict: value, context: context)
+    }
+
+    public func getData(_ key: SourceKitdUID) -> Data {
+      let value = sourcekitd_variant_dictionary_get_value(dict, key.uid)
+      let size = sourcekitd_variant_data_get_size(value)
+      guard let ptr = sourcekitd_variant_data_get_ptr(value), size > 0 else {
+        return Data()
+      }
+      return Data(bytes: ptr, count: size)
     }
 
     public func getOptional(_ key: SourceKitdUID) -> Variant? {
@@ -61,7 +76,7 @@
           SOURCEKITD_VARIANT_TYPE_NULL.rawValue {
         return nil
       }
-      return Variant(val: value)
+      return Variant(val: value, context: context)
     }
 
     public var description: String {
@@ -74,17 +89,21 @@
   }
 
   public struct Array: CustomStringConvertible {
+    // The lifetime of this sourcekitd_variant_t is tied to the response it came
+    // from, so keep a reference to the response too.
     private let arr: sourcekitd_variant_t
+    private let context: SourceKitdResponse
 
     public var count: Int {
       let count = sourcekitd_variant_array_get_count(arr)
       return Int(count)
     }
 
-    public init(arr: sourcekitd_variant_t) {
+    public init(arr: sourcekitd_variant_t, context: SourceKitdResponse) {
       assert(sourcekitd_variant_get_type(arr).rawValue ==
           SOURCEKITD_VARIANT_TYPE_ARRAY.rawValue)
       self.arr = arr
+      self.context = context
     }
 
     public func getString(_ index: Int) -> String {
@@ -109,20 +128,21 @@
 
     public func getArray(_ index: Int) -> Array {
       let value = sourcekitd_variant_array_get_value(arr, index)
-      return Array(arr: value)
+      return Array(arr: value, context: context)
     }
 
     public func getDictionary(_ index: Int) -> Dictionary {
       let value = sourcekitd_variant_array_get_value(arr, index)
-      return Dictionary(dict: value)
+      return Dictionary(dict: value, context: context)
     }
 
     public func enumerate(_ applier: (_ index: Int, _ value: Variant) -> Bool) {
       // The block passed to sourcekit_variant_array_apply() does not actually
       // escape, it's synchronous and not called after returning.
+      let context = self.context
       withoutActuallyEscaping(applier) { escapingApplier in
         _ = sourcekitd_variant_array_apply(arr) { (index, elem) -> Bool in
-          return escapingApplier(Int(index), Variant(val: elem))
+          return escapingApplier(Int(index), Variant(val: elem, context: context))
         }
       }
     }
@@ -134,10 +154,14 @@
   }
 
   public struct Variant: CustomStringConvertible {
+    // The lifetime of this sourcekitd_variant_t is tied to the response it came
+    // from, so keep a reference to the response too.
     private let val: sourcekitd_variant_t
+    fileprivate let context: SourceKitdResponse
 
-    fileprivate init(val: sourcekitd_variant_t) {
+    fileprivate init(val: sourcekitd_variant_t, context: SourceKitdResponse) {
       self.val = val
+      self.context = context
     }
 
     public func getString() -> String {
@@ -167,11 +191,19 @@
     }
 
     public func getArray() -> Array {
-      return Array(arr: val)
+      return Array(arr: val, context: context)
     }
 
     public func getDictionary() -> Dictionary {
-      return Dictionary(dict: val)
+      return Dictionary(dict: val, context: context)
+    }
+
+    public func getData() -> Data {
+      let size = sourcekitd_variant_data_get_size(val)
+      guard let ptr = sourcekitd_variant_data_get_ptr(val), size > 0 else {
+        return Data()
+      }
+      return Data(bytes: ptr, count: size)
     }
 
     public var description: String {
@@ -182,7 +214,7 @@
   private let resp: sourcekitd_response_t
 
   public var value: Dictionary {
-    return Dictionary(dict: sourcekitd_response_get_value(resp))
+    return Dictionary(dict: sourcekitd_response_get_value(resp), context: self)
   }
 
   /// Copies the raw bytes of the JSON description of this documentation item.
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index b6bb2b9..67d0393 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -1601,8 +1601,7 @@
     for (auto LTD : LocalTypeDecls) {
       Mangle::ASTMangler Mangler;
       std::string MangledName = Mangler.mangleTypeForDebugger(
-          LTD->getDeclaredInterfaceType(), LTD->getDeclContext(),
-          LTD->getDeclContext()->getGenericEnvironmentOfContext());
+          LTD->getDeclaredInterfaceType(), LTD->getDeclContext());
       MangledNames.push_back(MangledName);
     }
 
@@ -2632,8 +2631,7 @@
   void tryDemangleType(Type T, const DeclContext *DC, CharSourceRange range) {
     Mangle::ASTMangler Mangler;
     std::string mangledName(Mangler.mangleTypeForDebugger(
-                              T->mapTypeOutOfContext(), DC,
-        DC->getGenericEnvironmentOfContext()));
+                              T->mapTypeOutOfContext(), DC));
     std::string Error;
     Type ReconstructedType = DC->mapTypeIntoContext(
         getTypeFromMangledSymbolname(Ctx, mangledName, Error));
diff --git a/tools/swift-reflection-test/overrides.c b/tools/swift-reflection-test/overrides.c
index e48aab8..8a6345c 100644
--- a/tools/swift-reflection-test/overrides.c
+++ b/tools/swift-reflection-test/overrides.c
@@ -1,5 +1,6 @@
 #include "overrides.h"
 
+#if !defined(_WIN32)
 extern pid_t fork(void);
 extern int execv(const char *path, char * const *argv);
 
@@ -10,4 +11,5 @@
 int _execv(const char *path, char * const *argv) {
   return execv(path, argv);
 }
+#endif
 
diff --git a/tools/swift-reflection-test/overrides.h b/tools/swift-reflection-test/overrides.h
index f88606d..916cf3c 100644
--- a/tools/swift-reflection-test/overrides.h
+++ b/tools/swift-reflection-test/overrides.h
@@ -2,5 +2,8 @@
 
 #include <sys/types.h>
 
+#if !defined(_WIN32)
 pid_t _fork(void);
 int _execv(const char *path, char * const *argv);
+#endif
+
diff --git a/tools/swift-reflection-test/swift-reflection-test.c b/tools/swift-reflection-test/swift-reflection-test.c
index 7f4459e..9e44321 100644
--- a/tools/swift-reflection-test/swift-reflection-test.c
+++ b/tools/swift-reflection-test/swift-reflection-test.c
@@ -27,7 +27,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
 #include <unistd.h>
+#elif defined(_WIN32)
+#include <io.h>
+#include <fcntl.h>
+#endif
 
 typedef struct PipeMemoryReader {
   int to_child[2];
@@ -194,10 +199,17 @@
 static
 PipeMemoryReader createPipeMemoryReader() {
   PipeMemoryReader Reader;
+#if defined(_WIN32)
+  if (pipe(Reader.to_child, 256, _O_BINARY))
+    errnoAndExit("Couldn't create pipes to child process");
+  if (pipe(Reader.from_child, 256, _O_BINARY))
+    errnoAndExit("Couldn't create pipes from child process");
+#else
   if (pipe(Reader.to_child))
     errnoAndExit("Couldn't create pipes to child process");
   if (pipe(Reader.from_child))
     errnoAndExit("Couldn't create pipes from child process");
+#endif
   return Reader;
 }
 
@@ -443,6 +455,8 @@
 int doDumpHeapInstance(const char *BinaryFilename) {
   PipeMemoryReader Pipe = createPipeMemoryReader();
 
+#if defined(_WIN32)
+#else
   pid_t pid = _fork();
   switch (pid) {
     case -1:
@@ -517,6 +531,7 @@
       }
     }
   }
+#endif
   return EXIT_SUCCESS;
 }
 
diff --git a/unittests/Parse/SyntaxParsingCacheTests.cpp b/unittests/Parse/SyntaxParsingCacheTests.cpp
index 628f48d..78173fa 100644
--- a/unittests/Parse/SyntaxParsingCacheTests.cpp
+++ b/unittests/Parse/SyntaxParsingCacheTests.cpp
@@ -1,119 +1,105 @@
 #include "swift/Parse/SyntaxParsingCache.h"
 #include "gtest/gtest.h"
 
+#include <iostream>
+
 using namespace swift;
 using namespace llvm;
 
+
+namespace llvm {
+template <typename T>
+void PrintTo(const Optional<T> &optVal, ::std::ostream *os) {
+  if (optVal.hasValue())
+    *os << *optVal;
+  else
+    *os << "None";
+}
+} // namespace llvm
+
+void check(ArrayRef<SourceEdit> Edits, ArrayRef<Optional<size_t>> expected) {
+  for (size_t Pos = 0; Pos != expected.size(); ++Pos) {
+    Optional<size_t> PrePos =
+        SyntaxParsingCache::translateToPreEditPosition(Pos, Edits);
+    EXPECT_EQ(PrePos, expected[Pos]) << "At post-edit position " << Pos;
+  }
+}
+
 class TranslateToPreEditPositionTest : public ::testing::Test {};
 
-TEST_F(TranslateToPreEditPositionTest, SingleEditBefore) {
+TEST_F(TranslateToPreEditPositionTest, SingleEdit1) {
   // Old: ab_xy
-  // New: a1b_xy
-  //
-  // Edits:
-  // (1) 1-2: a -> a1
-  //
-  // Lookup for _ at new position 4
+  // New: c_xy
 
   llvm::SmallVector<SourceEdit, 4> Edits = {
-      {1, 2, 2}
+      {0, 2, 1} // ab -> c
   };
 
-  size_t PreEditPos = SyntaxParsingCache::translateToPreEditPosition(4, Edits);
-  EXPECT_EQ(PreEditPos, 3u);
+  //            c     _  x  y
+  check(Edits, {None, 2, 3, 4});
 }
 
-TEST_F(TranslateToPreEditPositionTest, SingleEditDirectlyBefore) {
+TEST_F(TranslateToPreEditPositionTest, SingleEdit) {
   // Old: ab_xy
   // New: ablah_xy
-  //
-  // Edits:
-  // (1) 2-3: b -> blah
-  //
-  // Lookup for _ at new position 6
 
   llvm::SmallVector<SourceEdit, 4> Edits = {
-      {2, 3, 4}
+      {1, 2, 4} // b -> blah
   };
 
-  size_t PreEditPos = SyntaxParsingCache::translateToPreEditPosition(6, Edits);
-  EXPECT_EQ(PreEditPos, 3u);
+  //            a  b     l     a     h     _  x  y
+  check(Edits, {0, None, None, None, None, 2, 3, 4});
 }
 
-TEST_F(TranslateToPreEditPositionTest, SingleMultiCharacterEdit) {
+TEST_F(TranslateToPreEditPositionTest, SingleInsert) {
   // Old: ab_xy
-  // New: abcdef_xy
-  //
-  // Edits:
-  // (1) 1-3: ab -> abcdef
-  //
-  // Lookup for _ at new position 7
+  // New: 0123ab_xy
 
   llvm::SmallVector<SourceEdit, 4> Edits = {
-      {1, 3, 6}
+      {0, 0, 4} // '' -> 0123
   };
 
-  size_t PreEditPos = SyntaxParsingCache::translateToPreEditPosition(7, Edits);
-  EXPECT_EQ(PreEditPos, 3u);
+  //             0     1     2     3     a  b  _  x  y
+  check(Edits, { None, None, None, None, 0, 1, 2, 3, 4});
 }
 
-TEST_F(TranslateToPreEditPositionTest, EditAfterLookup) {
-  // Old: ab_xy
-  // New: ab_xyz
-  //
-  // Edits:
-  // (1) 4-6: xy -> xyz
-  //
-  // Lookup for _ at new position 3
+TEST_F(TranslateToPreEditPositionTest, SingleDelete) {
+  // Old: ab_xyz
+  // New: ab_z
 
-  llvm::SmallVector<SourceEdit, 4> Edits = {{4, 6, 4}};
+  llvm::SmallVector<SourceEdit, 4> Edits = {
+      {3, 5, 0} // xy -> ''
+  };
 
-  size_t PreEditPos = SyntaxParsingCache::translateToPreEditPosition(3, Edits);
-  EXPECT_EQ(PreEditPos, 3u);
+  //             a  b  _  z
+  check(Edits, { 0, 1, 2, 5 });
 }
 
 TEST_F(TranslateToPreEditPositionTest, SimpleMultiEdit) {
-  // Old: ab_xy
-  // New: a1b2_x3y4
-  //
-  // Edits:
-  // (1) 1-2: a -> a1
-  // (2) 2-3: b -> b2
-  // (3) 4-5: x -> x3
-  // (4) 5-6: y -> y4
-  //
-  // Lookup for _ at new position 5
+  // Old: _ab_xy
+  // New: _a1b2_x3y4
 
   llvm::SmallVector<SourceEdit, 4> Edits = {
-      {1, 2, 2},
-      {2, 3, 2},
-      {4, 5, 2},
-      {5, 6, 2},
+      {1, 2, 2}, // a -> a1
+      {2, 3, 2}, // b -> b2
+      {4, 5, 2}, // x -> x3
+      {5, 6, 2}, // y -> y4
   };
 
-  size_t PreEditPos = SyntaxParsingCache::translateToPreEditPosition(5, Edits);
-  EXPECT_EQ(PreEditPos, 3u);
+  //            _  a     1     b     1     _  x     3     y     4
+  check(Edits, {0, None, None, None, None, 3, None, None, None, None});
 }
 
-TEST_F(TranslateToPreEditPositionTest, LongMultiEdit) {
-  // Old: ab_xy
-  // New: a11111b2_x3y4
-  //
-  // Edits:
-  // (1) 1-2: a -> a11111
-  // (2) 2-3: b -> b2
-  // (3) 4-5: x -> x3
-  // (4) 5-6: y -> y4
-  //
-  // Lookup for _ at new position
+TEST_F(TranslateToPreEditPositionTest, ComplexMultiEdit) {
+  // Old: foo_bar_baz
+  // New: xx_edits_baz
 
   llvm::SmallVector<SourceEdit, 4> Edits = {
-      {1, 2, 6},
-      {2, 3, 2},
-      {4, 5, 2},
-      {5, 6, 2},
+      {0, 3, 2}, // foo -> xx
+      {4, 7, 0}, // bar -> ''
+      {7, 7, 5}, // '' -> edits
   };
 
-  size_t PreEditPos = SyntaxParsingCache::translateToPreEditPosition(9, Edits);
-  EXPECT_EQ(PreEditPos, 3u);
-}
\ No newline at end of file
+  //            x     x     _  e     d     i     t     s     _  b  a  z
+  check(Edits, {None, None, 3, None, None, None, None, None, 7, 8, 9, 10});
+}
diff --git a/unittests/SourceKit/SwiftLang/EditingTest.cpp b/unittests/SourceKit/SwiftLang/EditingTest.cpp
index 7fafc25..2294f17 100644
--- a/unittests/SourceKit/SwiftLang/EditingTest.cpp
+++ b/unittests/SourceKit/SwiftLang/EditingTest.cpp
@@ -266,7 +266,8 @@
   close(DocName);
 }
 
-TEST_F(EditTest, DiagsAfterCloseAndReopen) {
+// This test is failing occassionally in CI: rdar://45644449
+TEST_F(EditTest, DISABLED_DiagsAfterCloseAndReopen) {
   // Attempt to open the same file twice in a row. This tests (subject to
   // timing) cases where:
   // * the 2nd open happens before the first AST starts building
diff --git a/utils/backtrace-check b/utils/backtrace-check
index d765660..a304f68 100755
--- a/utils/backtrace-check
+++ b/utils/backtrace-check
@@ -36,19 +36,19 @@
     args = parser.parse_args()
 
     TARGET_RE = re.compile(
-        "(?P<index>\d+) +(?P<object>\S+) +(?P<address>0x[0-9a-fA-F]{16}) "
-        "(?P<routine>[^+]+) [+] (?P<offset>\d+)")
+        r"(?P<index>\d+) +(?P<object>\S+) +(?P<address>0x[0-9a-fA-F]{16}) "
+        r"(?P<routine>[^+]+) [+] (?P<offset>\d+)")
 
     lines = sys.stdin.readlines()
 
     found_stack_trace_start = False
     found_stack_trace_entry = False
-    for l in lines:
-        l = l.rstrip("\n")
+    for line in lines:
+        line = line.rstrip("\n")
 
         # First see if we found the start of our stack trace start. If so, set
         # the found stack trace flag and continue.
-        if l == "Current stack trace:":
+        if line == "Current stack trace:":
             assert(not found_stack_trace_start)
             found_stack_trace_start = True
             continue
@@ -59,7 +59,7 @@
             continue
 
         # Ok, we are in the middle of matching a stack trace entry.
-        m = TARGET_RE.match(l)
+        m = TARGET_RE.match(line)
         # If we fail to match, we have exited the stack trace entry region
         if m is None:
             break
diff --git a/utils/bug_reducer/tests/test_funcbugreducer.py b/utils/bug_reducer/tests/test_funcbugreducer.py
index c18495c..4363f7d 100644
--- a/utils/bug_reducer/tests/test_funcbugreducer.py
+++ b/utils/bug_reducer/tests/test_funcbugreducer.py
@@ -117,7 +117,7 @@
                         "$s9testbasic6foo413yyF" in output)
         re_end = 'testfuncbugreducer_testbasic_'
         re_end += '92196894259b5d6c98d1b77f19240904.sib'
-        output_file_re = re.compile('\*\*\* Final File: .*' + re_end)
+        output_file_re = re.compile(r'\*\*\* Final File: .*' + re_end)
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
         self.assertEquals(sum(output_matches), 1)
diff --git a/utils/bug_reducer/tests/test_optbugreducer.py b/utils/bug_reducer/tests/test_optbugreducer.py
index daede44..48479ba 100644
--- a/utils/bug_reducer/tests/test_optbugreducer.py
+++ b/utils/bug_reducer/tests/test_optbugreducer.py
@@ -105,7 +105,7 @@
         self.assertTrue('*** Found miscompiling passes!' in output)
         self.assertTrue('*** Final Passes: --bug-reducer-tester' in output)
         re_end = 'testoptbugreducer_testbasic_initial'
-        output_file_re = re.compile('\*\*\* Final File: .*' + re_end)
+        output_file_re = re.compile(r'\*\*\* Final File: .*' + re_end)
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
         self.assertEquals(sum(output_matches), 1)
@@ -134,7 +134,7 @@
         self.assertTrue('*** Found miscompiling passes!' in output)
         self.assertTrue('*** Final Passes: --bug-reducer-tester' in output)
         re_end = 'testoptbugreducer_testsuffixinneedofprefix_initial'
-        output_file_re = re.compile('\*\*\* Final File: .*' + re_end)
+        output_file_re = re.compile(r'\*\*\* Final File: .*' + re_end)
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
         self.assertEquals(sum(output_matches), 1)
@@ -167,7 +167,7 @@
         self.assertTrue('*** Final Passes: --bug-reducer-tester' in output)
         re_end = 'testoptbugreducer_testreducefunction_initial_'
         re_end += '30775a3d942671a403702a9846afa7a4.sib'
-        output_file_re = re.compile('\*\*\* Final File: .*' + re_end)
+        output_file_re = re.compile(r'\*\*\* Final File: .*' + re_end)
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
         self.assertEquals(sum(output_matches), 1)
diff --git a/utils/build-presets.ini b/utils/build-presets.ini
index 379b67d..5a44375 100644
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -1021,6 +1021,8 @@
 lldb
 llbuild
 swiftpm
+swiftsyntax
+skstresstester
 playgroundsupport
 
 # Build with debug info, this allows us to symbolicate crashes from
@@ -1044,6 +1046,9 @@
 install-lldb
 install-llbuild
 install-swiftpm
+install-swiftsyntax
+skip-install-swiftsyntax-module
+install-skstresstester
 install-playgroundsupport
 
 install-destdir=%(install_destdir)s
@@ -1150,7 +1155,8 @@
 skip-test-lldb
 skip-test-cmark
 skip-test-playgroundsupport
-
+skip-test-swiftsyntax
+skip-test-skstresstester
 
 #===------------------------------------------------------------------------===#
 # LLDB build configurations
diff --git a/utils/build-script b/utils/build-script
index ec6c8fd..86cbaa6 100755
--- a/utils/build-script
+++ b/utils/build-script
@@ -474,6 +474,7 @@
             "--xctest-build-type", args.build_variant,
             "--swiftpm-build-type", args.build_variant,
             "--swiftsyntax-build-type", args.build_variant,
+            "--skstresstester-build-type", args.build_variant,
             "--llbuild-build-type", args.build_variant,
             "--swift-enable-assertions", str(args.swift_assertions).lower(),
             "--swift-stdlib-enable-assertions", str(
@@ -593,6 +594,8 @@
             impl_args += ["--skip-build-swiftpm"]
         if not args.build_swiftsyntax:
             impl_args += ["--skip-build-swiftsyntax"]
+        if not args.build_skstresstester:
+            impl_args += ["--skip-build-skstresstester"]
         if not args.build_playgroundsupport:
             impl_args += ["--skip-build-playgroundsupport"]
         if args.build_swift_dynamic_stdlib:
@@ -637,6 +640,7 @@
                           "--skip-test-llbuild",
                           "--skip-test-swiftpm",
                           "--skip-test-swiftsyntax",
+                          "--skip-test-skstresstester",
                           "--skip-test-xctest",
                           "--skip-test-foundation",
                           "--skip-test-libdispatch",
diff --git a/utils/build-script-impl b/utils/build-script-impl
index e7bf8f7..6d253c5 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -83,6 +83,7 @@
     xctest-build-type           "Debug"          "the build variant for xctest"
     swiftpm-build-type          "Debug"          "the build variant for swiftpm"
     swiftsyntax-build-type      "Debug"          "the build variant for swiftSyntax"
+    skstresstester-build-type   "Debug"          "the build variant for the SourceKit stress tester"
     llbuild-enable-assertions   "1"              "enable assertions in llbuild"
     enable-asan                 ""               "enable Address Sanitizer"
     enable-ubsan                ""               "enable Undefined Behavior Sanitizer"
@@ -124,6 +125,7 @@
     skip-build-llbuild          ""               "set to skip building llbuild"
     skip-build-swiftpm          ""               "set to skip building swiftpm"
     skip-build-swiftsyntax      ""               "set to skip building swiftSyntax"
+    skip-build-skstresstester   ""               "set to skip building the SourceKit stress tester"
     skip-build-xctest           ""               "set to skip building xctest"
     skip-build-foundation       ""               "set to skip building foundation"
     skip-build-libdispatch      ""               "set to skip building libdispatch"
@@ -137,6 +139,7 @@
     skip-test-llbuild           ""               "set to skip testing llbuild"
     skip-test-swiftpm           ""               "set to skip testing swiftpm"
     skip-test-swiftsyntax       ""               "set to skip testing swiftSyntax"
+    skip-test-skstresstester    ""               "set to skip testing the SourceKit stress tester"
     skip-test-xctest            ""               "set to skip testing xctest"
     skip-test-foundation        ""               "set to skip testing foundation"
     skip-test-libdispatch       ""               "set to skip testing libdispatch"
@@ -191,6 +194,9 @@
     install-lldb                ""               "whether to install LLDB"
     install-llbuild             ""               "whether to install llbuild"
     install-swiftpm             ""               "whether to install swiftpm"
+    install-swiftsyntax         ""               "whether to install swiftsyntax"
+    skip-install-swiftsyntax-module ""           "set to skip installing swiftsyntax modules"
+    install-skstresstester      ""               "whether to install the SourceKit stress tester"
     install-xctest              ""               "whether to install xctest"
     install-foundation          ""               "whether to install foundation"
     install-libdispatch         ""               "whether to install libdispatch"
@@ -1169,6 +1175,7 @@
 LLBUILD_SOURCE_DIR="${WORKSPACE}/llbuild"
 SWIFTPM_SOURCE_DIR="${WORKSPACE}/swiftpm"
 SWIFTSYNTAX_SOURCE_DIR="${WORKSPACE}/swift-syntax"
+SKSTRESSTESTER_SOURCE_DIR="${WORKSPACE}/swift-stress-tester/SourceKitStressTester"
 XCTEST_SOURCE_DIR="${WORKSPACE}/swift-corelibs-xctest"
 FOUNDATION_SOURCE_DIR="${WORKSPACE}/swift-corelibs-foundation"
 LIBDISPATCH_SOURCE_DIR="${WORKSPACE}/swift-corelibs-libdispatch"
@@ -1209,8 +1216,9 @@
 if [[ ! "${SKIP_BUILD_LLDB}" ]] ; then
      PRODUCTS=("${PRODUCTS[@]}" lldb)
 fi
-# LLBuild, SwiftPM, SwiftSyntax and XCTest are dependent on Foundation, so Foundation must be
-# added to the list of build products first.
+# LLBuild, SwiftPM, SwiftSyntax, the SourceKit stress tester and XCTest are
+# dependent on Foundation, so Foundation must be added to the list of build
+# products first.
 if [[ ! "${SKIP_BUILD_LIBDISPATCH}" ]] ; then
      PRODUCTS=("${PRODUCTS[@]}" libdispatch)
 fi
@@ -1223,19 +1231,24 @@
 if [[ ! "${SKIP_BUILD_PLAYGROUNDSUPPORT}" ]] ; then
      PRODUCTS=("${PRODUCTS[@]}" playgroundsupport)
 fi
-# SwiftPM and SwiftSyntax are dependent on XCTest, so XCTest must be added to the list of
-# build products first.
+# SwiftPM, SwiftSyntax and the SourceKit stress tester are dependent on XCTest,
+# so XCTest must be added to the list of build products first.
 if [[ ! "${SKIP_BUILD_XCTEST}" ]] ; then
      PRODUCTS=("${PRODUCTS[@]}" xctest)
 fi
-# SwiftSyntax is dependent on SwiftPM, so SwiftPM must be added to the list of
-# build products first.
+# SwiftSyntax and the SourceKit stress tester are dependent on SwiftPM, so
+# SwiftPM must be added to the list of build products first.
 if [[ ! "${SKIP_BUILD_SWIFTPM}" ]] ; then
      PRODUCTS=("${PRODUCTS[@]}" swiftpm)
 fi
+# The SourceKit stress tester is dependent on SwiftSyntax, so it must be added
+# to the list of build products first.
 if [[ ! "${SKIP_BUILD_SWIFTSYNTAX}" ]] ; then
      PRODUCTS=("${PRODUCTS[@]}" swiftsyntax)
 fi
+if [[ ! "${SKIP_BUILD_SKSTRESSTESTER}" ]] ; then
+     PRODUCTS=("${PRODUCTS[@]}" skstresstester)
+fi
 
 # Checks if a given product is enabled (i.e. part of $PRODUCTS array)
 function contains_product() {
@@ -1546,6 +1559,9 @@
             swiftsyntax)
                 echo "${root}/${SWIFTSYNTAX_BUILD_TYPE}/bin"
                 ;;
+            skstresstester)
+                echo "${root}/${SKSTRESSTESTER_BUILD_TYPE}/bin"
+                ;;
             xctest)
                 echo "${root}/${XCTEST_BUILD_TYPE}/bin"
                 ;;
@@ -1685,6 +1701,9 @@
             swiftsyntax)
                 echo "--config ${SWIFTSYNTAX_BUILD_TYPE}"
                 ;;
+            skstresstester)
+                echo "--config ${SKSTRESSTESTER_BUILD_TYPE}"
+                ;;
             xctest)
                 echo "--config ${XCTEST_BUILD_TYPE}"
                 ;;
@@ -1794,6 +1813,36 @@
         --filecheck-exec="$(build_directory_bin ${LOCAL_HOST} llvm)/FileCheck")
 }
 
+function set_skstresstester_build_command() {
+    if [ "${SKIP_BUILD_SWIFTSYNTAX}" ]; then
+        echo "Error: Cannot build the SourceKit stress tester without SwiftSyntax."
+        exit 1
+    fi
+
+    local swiftsyntax_config="debug"
+    if [[ $(is_cmake_release_build_type "${SWIFTSYNTAX_BUILD_TYPE}") ]] ; then
+        swiftsyntax_config="release"
+    fi
+    local config="debug"
+    if [[ $(is_cmake_release_build_type "${SKSTRESSTESTER_BUILD_TYPE}") ]] ; then
+        config="release"
+    fi
+
+    skstresstester_build_command=("${SKSTRESSTESTER_SOURCE_DIR}/Utilities/build-script-helper.py")
+    if [[ "${VERBOSE_BUILD}" ]] ; then
+        skstresstester_build_command+=(-v)
+    fi
+
+    skstresstester_build_command+=(
+        --build-dir="${build_dir}"
+        --swiftc-exec="$(build_directory_bin ${LOCAL_HOST} swift)/swiftc"
+        --swift-build-exec="${SWIFT_BUILD}"
+        --swift-test-exec="${SWIFT_TEST}"
+        --sourcekitd-dir="$(build_directory ${host} swift)/lib"
+        --swiftsyntax-dir="$(build_directory ${host} swiftsyntax)/${swiftsyntax_config}"
+        --config="${config}")
+}
+
 # Construct the appropriate options to pass to an Xcode
 # build of any LLDB target.
 function set_lldb_xcodebuild_options() {
@@ -2474,6 +2523,16 @@
 
                 continue
                 ;;
+            skstresstester)
+                if [[ "$(uname -s)" != "Darwin" ]]; then
+                    echo "error: unable to build swift-stress-tester on this platform"
+                    continue
+                fi
+                set_skstresstester_build_command
+                call "${skstresstester_build_command[@]}"
+
+                continue
+                ;;
             xctest)
                 SWIFTC_BIN="$(build_directory_bin ${LOCAL_HOST} swift)/swiftc"
                 XCTEST_BUILD_DIR=$(build_directory ${host} xctest)
@@ -2991,13 +3050,14 @@
                     # This assumes that there are no spaces in any on these paths.
                     FOUNDATION_BUILD_DIR=$(build_directory ${host} foundation)
                     DOTEST_EXTRA="-I${FOUNDATION_BUILD_DIR}"
-                    DOTEST_EXTRA="-F${FOUNDATION_BUILD_DIR}/CoreFoundation-prefix/System/Library/Frameworks"
+                    DOTEST_EXTRA="-Xcc -F${FOUNDATION_BUILD_DIR}/CoreFoundation-prefix/System/Library/Frameworks"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -I${FOUNDATION_BUILD_DIR}/swift"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -I${LIBDISPATCH_SOURCE_DIR}"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -L${FOUNDATION_BUILD_DIR}"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -L${LIBDISPATCH_BUILD_DIR}"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -L${LIBDISPATCH_BUILD_DIR}/src"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${LIBDISPATCH_BUILD_DIR}/src"
+                    DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${LIBDISPATCH_BUILD_DIR}"
                     DOTEST_EXTRA="${DOTEST_EXTRA} -Xlinker -rpath -Xlinker ${FOUNDATION_BUILD_DIR}"
                 fi
                 call mkdir -p "${results_dir}"
@@ -3085,6 +3145,14 @@
                 # As swiftSyntax tests itself, we break early here.
                 continue
                 ;;
+            skstresstester)
+                if [[ "${SKIP_TEST_SKSTRESSTESTER}" ]]; then
+                    continue
+                fi
+                echo "--- Running tests for ${product} ---"
+                call "${skstresstester_build_command[@]}" test
+                continue
+                ;;
             xctest)
                 if [[ "${SKIP_TEST_XCTEST}" ]]; then
                     continue
@@ -3382,7 +3450,39 @@
                 continue
                 ;;
             swiftsyntax)
-                # SwiftSyntax is not installed as part of the toolchain
+                if [[ -z "${INSTALL_SWIFTSYNTAX}" ]] ; then
+                    continue
+                fi
+                if [[ -z "${INSTALL_DESTDIR}" ]] ; then
+                    echo "--install-destdir is required to install products."
+                    exit 1
+                fi
+                echo "--- Installing ${product} ---"
+                DYLIB_DIR="${host_install_destdir}${host_install_prefix}/lib/swift/${SWIFT_HOST_VARIANT}"
+                MODULE_DIR="${DYLIB_DIR}/${SWIFT_HOST_VARIANT_ARCH}"
+                if [[ -z "${SKIP_INSTALL_SWIFTSYNTAX_MODULE}" ]] ; then
+                    call "${swiftsyntax_build_command[@]}" --dylib-dir="${DYLIB_DIR}" --swiftmodule-dir "${MODULE_DIR}" --install
+                else
+                    call "${swiftsyntax_build_command[@]}" --dylib-dir="${DYLIB_DIR}" --install
+                fi
+
+                continue
+                ;;
+            skstresstester)
+                if [[ -z "${INSTALL_SKSTRESSTESTER}" ]] ; then
+                    continue
+                fi
+                if [[ -z "${INSTALL_DESTDIR}" ]] ; then
+                    echo "--install-destdir is required to install products."
+                    exit 1
+                fi
+                if [[ -z "${INSTALL_SWIFTSYNTAX}" ]] ; then
+                    echo "--install-swiftsyntax is required to install the SourceKit stress tester"
+                    exit 1
+                fi
+
+                echo "--- Installing ${product} ---"
+                call "${skstresstester_build_command[@]}" --prefix="${host_install_destdir}${host_install_prefix}" install
                 continue
                 ;;
             xctest)
diff --git a/utils/build_swift/driver_arguments.py b/utils/build_swift/driver_arguments.py
index c33c455..2c87e23 100644
--- a/utils/build_swift/driver_arguments.py
+++ b/utils/build_swift/driver_arguments.py
@@ -518,6 +518,9 @@
     option(['--swiftsyntax'], store_true('build_swiftsyntax'),
            help='build swiftSyntax')
 
+    option(['--skstresstester'], store_true('build_skstresstester'),
+           help='build the SourceKit stress tester')
+
     option('--xctest', toggle_true('build_xctest'),
            help='build xctest')
 
@@ -985,6 +988,8 @@
                      /llbuild                    (optional)
                      /swiftpm                    (optional, requires llbuild)
                      /swift-syntax               (optional, requires swiftpm)
+                     /swift-stress-tester        (optional,
+                                                   requires swift-syntax)
                      /compiler-rt                (optional)
                      /swift-corelibs-xctest      (optional)
                      /swift-corelibs-foundation  (optional)
diff --git a/utils/build_swift/tests/expected_options.py b/utils/build_swift/tests/expected_options.py
index d39ce4e..9b820f4 100644
--- a/utils/build_swift/tests/expected_options.py
+++ b/utils/build_swift/tests/expected_options.py
@@ -80,6 +80,7 @@
     'build_swift_stdlib_unittest_extra': False,
     'build_swiftpm': False,
     'build_swiftsyntax': False,
+    'build_skstresstester': False,
     'build_tvos': True,
     'build_tvos_device': False,
     'build_tvos_simulator': False,
@@ -396,6 +397,7 @@
     SetTrueOption('--skip-build'),
     SetTrueOption('--swiftpm', dest='build_swiftpm'),
     SetTrueOption('--swiftsyntax', dest='build_swiftsyntax'),
+    SetTrueOption('--skstresstester', dest='build_skstresstester'),
     SetTrueOption('-B', dest='benchmark'),
     SetTrueOption('-S', dest='skip_build'),
     SetTrueOption('-b', dest='build_llbuild'),
diff --git a/utils/cmpcodesize/cmpcodesize/compare.py b/utils/cmpcodesize/cmpcodesize/compare.py
index 51ea7d7..7f46246 100644
--- a/utils/cmpcodesize/cmpcodesize/compare.py
+++ b/utils/cmpcodesize/cmpcodesize/compare.py
@@ -21,7 +21,7 @@
     ["CPP", re.compile('^(__Z|_+swift)')],
 
     # Objective-C
-    ["ObjC", re.compile('^[+-]\[')],
+    ["ObjC", re.compile(r'^[+-]\[')],
 
     # Swift
     ["Partial Apply", re.compile('^__(TPA|T0.*T[aA]$)')],
@@ -80,7 +80,7 @@
     architectures = subprocess.check_output(
         ["otool", "-V", "-f", file_name]).split("\n")
     arch = None
-    arch_pattern = re.compile('architecture ([\S]+)')
+    arch_pattern = re.compile(r'architecture ([\S]+)')
     for architecture in architectures:
         arch_match = arch_pattern.match(architecture)
         if arch_match:
@@ -115,10 +115,10 @@
     start_addr = None
     end_addr = None
 
-    section_pattern = re.compile(' +sectname ([\S]+)')
-    size_pattern = re.compile(' +size ([\da-fx]+)')
-    asmline_pattern = re.compile('^([0-9a-fA-F]+)\s')
-    label_pattern = re.compile('^((\-*\[[^\]]*\])|[^\/\s]+):$')
+    section_pattern = re.compile(r' +sectname ([\S]+)')
+    size_pattern = re.compile(r' +size ([\da-fx]+)')
+    asmline_pattern = re.compile(r'^([0-9a-fA-F]+)\s')
+    label_pattern = re.compile(r'^((\-*\[[^\]]*\])|[^\/\s]+):$')
 
     for line in content:
         asmline_match = asmline_pattern.match(line)
diff --git a/utils/create-filecheck-test.py b/utils/create-filecheck-test.py
index 4a62616..03f012e 100755
--- a/utils/create-filecheck-test.py
+++ b/utils/create-filecheck-test.py
@@ -25,18 +25,18 @@
 args = parser.parse_args()
 
 seen_variables = set([])
-ssa_re = re.compile('[%](\d+)')
-for l in args.input.readlines():
-    l = l[:l.find('//')].rstrip() + "\n"
+ssa_re = re.compile(r'[%](\d+)')
+for line in args.input.readlines():
+    line = line[:line.find('//')].rstrip() + "\n"
     have_match = False
-    for match in ssa_re.finditer(l):
+    for match in ssa_re.finditer(line):
         have_match = True
         var = match.groups()[0]
         if var not in seen_variables:
-            l = l.replace('%' + var, '[[VAR_%s:%%[0-9]+]]' % var)
+            line = line.replace('%' + var, '[[VAR_%s:%%[0-9]+]]' % var)
             seen_variables.add(var)
         else:
-            l = l.replace('%' + var, '[[VAR_%s]]' % var)
+            line = line.replace('%' + var, '[[VAR_%s]]' % var)
     if have_match:
-        l = '// CHECK: ' + l
-    args.o.write(l)
+        line = '// CHECK: ' + line
+    args.o.write(line)
diff --git a/utils/generate_confusables.py b/utils/generate_confusables.py
index dbe963d..1b2e6da 100755
--- a/utils/generate_confusables.py
+++ b/utils/generate_confusables.py
@@ -57,7 +57,7 @@
 
     pairs = []
     with open(confusablesFilePath, 'r') as f:
-        pattern = re.compile("(.+)\W+;\W+(.+)\W+;")
+        pattern = re.compile(r"(.+)\W+;\W+(.+)\W+;")
         for line in f:
             match = pattern.match(line)
             if match is not None:
diff --git a/utils/gyb.py b/utils/gyb.py
index 2630d71..b5577ad 100755
--- a/utils/gyb.py
+++ b/utils/gyb.py
@@ -99,7 +99,7 @@
   )
 ''', re.VERBOSE | re.MULTILINE)
 
-gyb_block_close = re.compile('\}%[ \t]*\n?')
+gyb_block_close = re.compile(r'\}%[ \t]*\n?')
 
 
 def token_pos_to_index(token_pos, start, line_starts):
diff --git a/utils/gyb_syntax_support/AttributeNodes.py b/utils/gyb_syntax_support/AttributeNodes.py
index c5aa370..5097e1a 100644
--- a/utils/gyb_syntax_support/AttributeNodes.py
+++ b/utils/gyb_syntax_support/AttributeNodes.py
@@ -17,6 +17,7 @@
     #                | availability-spec-list
     #                | specialize-attr-spec-list
     #                | implements-attr-arguments
+    #                | named-attribute-string-argument
     #              )? ')'?
     Node('Attribute', kind='Syntax',
          description='''
@@ -42,6 +43,8 @@
                        Child('ObjCName', kind='ObjCSelector'),
                        Child('ImplementsArguments', 
                              kind='ImplementsAttributeArguments'),
+                       Child('NamedAttributeString',
+                             kind='NamedAttributeStringArgument'),
                    ], description='''
                    The arguments of the attribute. In case the attribute  \
                    takes multiple arguments, they are gather in the \
@@ -95,7 +98,38 @@
                    A trailing comma if this argument is followed by another one
                    '''),
          ]),
-
+    # The argument of '@_dynamic_replacement(for:)' or '@_private(sourceFile:)'
+    # named-attribute-string-arg -> 'name': string-literal
+    Node('NamedAttributeStringArgument', kind='Syntax',
+         description='''
+         The argument for the `@_dynamic_replacement` or `@_private` \
+         attribute of the form `for: "function()"` or `sourceFile: \
+         "Src.swift"`
+         ''',
+         children=[
+             Child('NameTok', kind='Token',
+                   description='The label of the argument'),
+             Child('Colon', kind='ColonToken',
+                   description='The colon separating the label and the value'),
+             Child('StringOrDeclname', kind='Syntax', node_choices=[
+                 Child('String', kind='StringLiteralToken'),
+                 Child('Declname', kind='DeclName'),
+             ]),
+         ]),
+    Node('DeclName', kind='Syntax', children=[
+         Child('DeclBaseName', kind='Syntax', description='''
+               The base name of the protocol\'s requirement.
+               ''',
+               node_choices=[
+                   Child('Identifier', kind='IdentifierToken'),
+                   Child('Operator', kind='PrefixOperatorToken'),
+               ]),
+         Child('DeclNameArguments', kind='DeclNameArguments',
+               is_optional=True, description='''
+               The argument labels of the protocol\'s requirement if it \
+               is a function requirement.
+               '''),
+         ]),
     # The argument of '@_implements(...)'
     # implements-attr-arguments -> simple-type-identifier ',' 
     #                              (identifier | operator) decl-name-arguments
diff --git a/utils/gyb_syntax_support/NodeSerializationCodes.py b/utils/gyb_syntax_support/NodeSerializationCodes.py
index 6c54557..3850d4e 100644
--- a/utils/gyb_syntax_support/NodeSerializationCodes.py
+++ b/utils/gyb_syntax_support/NodeSerializationCodes.py
@@ -229,6 +229,9 @@
     'YieldStmt': 224,
     'YieldList': 225,
     'IdentifierList': 226,
+    'NamedAttributeStringArgument': 227,
+    'DeclName': 228,
+    'PoundAssertStmt': 229,
 }
 
 
diff --git a/utils/gyb_syntax_support/StmtNodes.py b/utils/gyb_syntax_support/StmtNodes.py
index 377df08..ba4d113 100644
--- a/utils/gyb_syntax_support/StmtNodes.py
+++ b/utils/gyb_syntax_support/StmtNodes.py
@@ -326,4 +326,18 @@
                    is_optional=True),
              Child('Body', kind='CodeBlock'),
          ]),
+
+    # e.g. #assert(1 == 2)
+    Node('PoundAssertStmt', kind='Stmt',
+         children=[
+             Child('PoundAssert', kind='PoundAssertToken'),
+             Child('LeftParen', kind='LeftParenToken'),
+             Child('Condition', kind='Expr',
+                   description='The assertion condition.'),
+             Child('Comma', kind='CommaToken', is_optional=True,
+                   description='The comma after the assertion condition.'),
+             Child('Message', kind='StringLiteralToken', is_optional=True,
+                   description='The assertion message.'),
+             Child('RightParen', kind='RightParenToken'),
+         ]),
 ]
diff --git a/utils/gyb_syntax_support/Token.py b/utils/gyb_syntax_support/Token.py
index 52d5928..c01521b 100644
--- a/utils/gyb_syntax_support/Token.py
+++ b/utils/gyb_syntax_support/Token.py
@@ -268,6 +268,8 @@
                  serialization_code=72),
     PoundKeyword('PoundDsohandle', 'dsohandle', text='#dsohandle',
                  serialization_code=71),
+    PoundKeyword('PoundAssert', 'assert', text='#assert',
+                 serialization_code=117),
 
     PoundDirectiveKeyword('PoundSourceLocation', 'sourceLocation',
                           text='#sourceLocation', serialization_code=65),
diff --git a/utils/jobstats/jobstats.py b/utils/jobstats/jobstats.py
index 162e575..f7797ea 100644
--- a/utils/jobstats/jobstats.py
+++ b/utils/jobstats/jobstats.py
@@ -199,7 +199,7 @@
 AUXPAT = re.compile(AUXPATSTR)
 
 TIMERPATSTR = (r"time\.swift-(?P<jobkind>\w+)\." + AUXPATSTR +
-               "\.(?P<timerkind>\w+)$")
+               r"\.(?P<timerkind>\w+)$")
 TIMERPAT = re.compile(TIMERPATSTR)
 
 FILEPATSTR = (r"^stats-(?P<start>\d+)-swift-(?P<kind>\w+)-" +
@@ -266,7 +266,7 @@
                 if profiletype not in profiles:
                     profiles[profiletype] = dict()
                 profiles[profiletype][counter] = fullpath
-            except:
+            except Exception:
                 pass
     return profiles
 
diff --git a/utils/pass-pipeline/scripts/pipelines_build_script.py b/utils/pass-pipeline/scripts/pipelines_build_script.py
index 9733de6..1a482de 100755
--- a/utils/pass-pipeline/scripts/pipelines_build_script.py
+++ b/utils/pass-pipeline/scripts/pipelines_build_script.py
@@ -24,8 +24,8 @@
     build_script_args = [
         build_script,
         DEFAULT_PRESENTS,
-        'extra_swift_args=^Swift$;-Xfrontend\;' +
-        '-external-pass-pipeline-filename\;-Xfrontend\;%s' % data_file]
+        r'extra_swift_args=^Swift$;-Xfrontend\;' +
+        r'-external-pass-pipeline-filename\;-Xfrontend\;%s' % data_file]
     sys.stdout.write("Running build script with: %s..." %
                      ' '.join(build_script_args))
     sys.stdout.flush()
diff --git a/utils/process-stats-dir.py b/utils/process-stats-dir.py
index 3425b0c..fdfac8b 100755
--- a/utils/process-stats-dir.py
+++ b/utils/process-stats-dir.py
@@ -33,7 +33,7 @@
                       load_stats_dir, merge_all_jobstats)
 
 
-MODULE_PAT = re.compile('^(\w+)\.')
+MODULE_PAT = re.compile(r'^(\w+)\.')
 
 
 def module_name_of_stat(name):
@@ -439,7 +439,7 @@
     vargs = vars_of_args(args)
     merged = merge_all_jobstats(load_stats_dir(d, **vargs), **vargs)
     env = {}
-    ident = re.compile('(\w+)$')
+    ident = re.compile(r'(\w+)$')
     for (k, v) in merged.stats.items():
         if k.startswith("time.") or '.time.' in k:
             continue
@@ -472,7 +472,7 @@
     new_stats = merge_all_jobstats(load_stats_dir(new, **vargs), **vargs)
 
     env = {}
-    ident = re.compile('(\w+)$')
+    ident = re.compile(r'(\w+)$')
     for r in compare_stats(args, old_stats.stats, new_stats.stats):
         if r.name.startswith("time.") or '.time.' in r.name:
             continue
diff --git a/utils/pygments/swift.py b/utils/pygments/swift.py
index 03498b6..59587e0 100755
--- a/utils/pygments/swift.py
+++ b/utils/pygments/swift.py
@@ -33,7 +33,7 @@
 
     _isa = r'([a-zA-Z_][a-zA-Z0-9_]*)(\s*)(:)(\s*)([A-Z0-9_][a-zA-Z0-9_]*)'
     _isa_comma = r'([a-zA-Z_][a-zA-Z0-9_]*)(\s*)(:)(\s*)' + \
-                 '([A-Z0-9_][a-zA-Z0-9_]*)(,\s?)'
+                 r'([A-Z0-9_][a-zA-Z0-9_]*)(,\s?)'
     _name = u'([@a-zA-Z_\U00000100-\U00100000]' + \
             u'[a-zA-Z0-9_\U00000100-\U00100000]*)'
 
@@ -206,7 +206,7 @@
                 Name.Attribute,
                 Punctuation,
                 Whitespace)),
-            (':\s*', Punctuation),
+            (r':\s*', Punctuation),
             include('tuple'),
             include('var-isa-comma'),
             include('var-isa-pop'),
@@ -299,7 +299,7 @@
         ],
 
         'in-interpolated': [
-            ('\)', String.Interpol, '#pop'),
+            (r'\)', String.Interpol, '#pop'),
             include('root2'),
         ],
 
diff --git a/utils/resolve-crashes.py b/utils/resolve-crashes.py
index 19d8449..e716c63 100755
--- a/utils/resolve-crashes.py
+++ b/utils/resolve-crashes.py
@@ -18,9 +18,9 @@
 
 # The regular expression we use to match compiler-crasher lines.
 regex = re.compile(
-    '.*Swift(.*) :: '
-    '(compiler_crashers|compiler_crashers_2|IDE/crashers|SIL/crashers)'
-    '/(.*\.swift|.*\.sil).*')
+    r'.*Swift(.*) :: '
+    r'(compiler_crashers|compiler_crashers_2|IDE/crashers|SIL/crashers)'
+    r'/(.*\.swift|.*\.sil).*')
 
 # Take the output of lit as standard input.
 for line in sys.stdin:
diff --git a/utils/swift-bench.py b/utils/swift-bench.py
index 05c9a1e..f03cc82 100644
--- a/utils/swift-bench.py
+++ b/utils/swift-bench.py
@@ -174,7 +174,7 @@
     N = CommandLine.arguments[1].toInt()!
   }
 """
-        main_body = """
+        main_body = r"""
   name = "%s"
   if CommandLine.arguments.count <= 2 || CommandLine.arguments[2] == name {
     let start = __mach_absolute_time__()
diff --git a/utils/swift_build_support/swift_build_support/shell.py b/utils/swift_build_support/swift_build_support/shell.py
index a6046a7..70fb512 100644
--- a/utils/swift_build_support/swift_build_support/shell.py
+++ b/utils/swift_build_support/swift_build_support/shell.py
@@ -225,10 +225,10 @@
     if n_processes == 0:
         n_processes = cpu_count() * 2
 
-    l = Lock()
+    lk = Lock()
     print("Running ``%s`` with up to %d processes." %
           (fn.__name__, n_processes))
-    pool = Pool(processes=n_processes, initializer=init, initargs=(l,))
+    pool = Pool(processes=n_processes, initializer=init, initargs=(lk,))
     results = pool.map_async(func=fn, iterable=pool_args).get(999999)
     pool.close()
     pool.join()
diff --git a/utils/symbolicate-linux-fatal b/utils/symbolicate-linux-fatal
index 9fffd41..8ff5ee5 100755
--- a/utils/symbolicate-linux-fatal
+++ b/utils/symbolicate-linux-fatal
@@ -136,7 +136,7 @@
         try:
             framePC = int(stack_tokens[2], 16)
             symbol_offset = int(stack_tokens[-1], 10)
-        except:
+        except Exception:
             full_stack.append({"line": line, "framePC": 0, "dynlib_fname": ""})
             continue
 
@@ -161,7 +161,7 @@
         try:
             sym_line = symbolicate_one(frame_addr, frame_idx, dynlib_fname)
             print(sym_line)
-        except:
+        except Exception:
             print(frame["line"].rstrip())
         frame_idx = frame_idx + 1
 
diff --git a/utils/update_checkout/update-checkout-config.json b/utils/update_checkout/update-checkout-config.json
index d7dc82b..384eea1 100644
--- a/utils/update_checkout/update-checkout-config.json
+++ b/utils/update_checkout/update-checkout-config.json
@@ -18,6 +18,8 @@
             "remote": { "id": "apple/swift-package-manager" } },
         "swift-syntax": {
             "remote": { "id": "apple/swift-syntax" } },
+        "swift-stress-tester": {
+            "remote": { "id": "apple/swift-stress-tester" } },
         "compiler-rt": {
             "remote": { "id": "apple/swift-compiler-rt" } },
         "swift-corelibs-xctest": {
@@ -50,6 +52,7 @@
                 "llbuild": "master",
                 "swiftpm": "master",
                 "swift-syntax": "master",
+                "swift-stress-tester": "master",
                 "compiler-rt": "stable",
                 "swift-corelibs-xctest": "master",
                 "swift-corelibs-foundation": "master",
@@ -74,6 +77,7 @@
                 "llbuild": "master",
                 "swiftpm": "master",
                 "swift-syntax": "master",
+                "swift-stress-tester": "master",
                 "swift-corelibs-xctest": "master",
                 "swift-corelibs-foundation": "master",
                 "swift-corelibs-libdispatch": "master",
@@ -94,6 +98,7 @@
                 "llbuild": "swift-3.0-branch",
                 "swiftpm": "swift-3.0-branch",
                 "swift-syntax": "master",
+                "swift-stress-tester": "master",
                 "compiler-rt": "swift-3.0-branch",
                 "swift-corelibs-xctest": "swift-3.0-branch",
                 "swift-corelibs-foundation": "swift-3.0-branch",
@@ -114,6 +119,7 @@
                 "llbuild": "swift-3.1-branch",
                 "swiftpm": "swift-3.1-branch",
                 "swift-syntax": "master",
+                "swift-stress-tester": "master",
                 "compiler-rt": "swift-3.1-branch",
                 "swift-corelibs-xctest": "swift-3.1-branch",
                 "swift-corelibs-foundation": "swift-3.1-branch",
@@ -134,6 +140,7 @@
                 "llbuild": "swift-4.0-branch",
                 "swiftpm": "swift-4.0-branch",
                 "swift-syntax": "master",
+                "swift-stress-tester": "master",
                 "compiler-rt": "swift-4.0-branch",
                 "swift-corelibs-xctest": "swift-4.0-branch",
                 "swift-corelibs-foundation": "swift-4.0-branch",
@@ -154,6 +161,7 @@
                 "llbuild": "swift-4.1-branch",
                 "swiftpm": "swift-4.1-branch",
                 "swift-syntax": "master",
+                "swift-stress-tester": "master",
                 "compiler-rt": "swift-4.1-branch",
                 "swift-corelibs-xctest": "swift-4.1-branch",
                 "swift-corelibs-foundation": "swift-4.1-branch",
@@ -174,6 +182,7 @@
                 "llbuild": "swift-4.2-branch",
                 "swiftpm": "swift-4.2-branch",
                 "swift-syntax": "swift-4.2-branch",
+                "swift-stress-tester": "master",
                 "compiler-rt": "swift-4.2-branch",
                 "swift-corelibs-xctest": "swift-4.2-branch",
                 "swift-corelibs-foundation": "swift-4.2-branch",
@@ -191,15 +200,16 @@
                 "compiler-rt": "swift-5.0-branch",
                 "swift": "swift-5.0-branch",
                 "lldb": "swift-5.0-branch",
-                "cmark": "master",
-                "llbuild": "master",
-                "swiftpm": "master",
-                "swift-syntax": "master",
-                "swift-corelibs-xctest": "master",
-                "swift-corelibs-foundation": "master",
-                "swift-corelibs-libdispatch": "master",
-                "swift-integration-tests": "master",
-                "swift-xcode-playground-support": "master",
+                "cmark": "swift-5.0-branch",
+                "llbuild": "swift-5.0-branch",
+                "swiftpm": "swift-5.0-branch",
+                "swift-syntax": "swift-5.0-branch",
+                "swift-stress-tester": "swift-5.0-branch",
+                "swift-corelibs-xctest": "swift-5.0-branch",
+                "swift-corelibs-foundation": "swift-5.0-branch",
+                "swift-corelibs-libdispatch": "swift-5.0-branch",
+                "swift-integration-tests": "swift-5.0-branch",
+                "swift-xcode-playground-support": "swift-5.0-branch",
                 "ninja": "release",
                 "icu": "release-61-1"
             }
diff --git a/validation-test/IDE/crashers_2_fixed/0023-rdar41331096.swift b/validation-test/IDE/crashers_2_fixed/0023-rdar41331096.swift
new file mode 100644
index 0000000..e4641a8
--- /dev/null
+++ b/validation-test/IDE/crashers_2_fixed/0023-rdar41331096.swift
@@ -0,0 +1,15 @@
+// RUN: %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s
+
+enum E1 {
+  case X
+  case Y
+}
+enum E2 {
+  case A
+  case B
+  case C
+}
+
+func foo() -> ([E1], [E2]) {
+  return ([.X], [.A, .B, .#^A^#])
+}
diff --git a/validation-test/Reflection/existentials.swift b/validation-test/Reflection/existentials.swift
index ca486ca..a1f131c 100644
--- a/validation-test/Reflection/existentials.swift
+++ b/validation-test/Reflection/existentials.swift
@@ -90,19 +90,19 @@
 // CHECK-64-NEXT:   (struct Swift.Int))
 
 // CHECK-64:        Type info:
-// CHECK-64:        (struct size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64:        (struct size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=x offset=0
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=y offset=8
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=z offset=16
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an existential.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -113,19 +113,19 @@
 // CHECK-32-NEXT:   (struct Swift.Int))
 
 // CHECK-32:        Type info:
-// CHECK-32:        (struct size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32:        (struct size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=x offset=0
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=y offset=4
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=z offset=8
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // This value will be copied into a heap buffer, with a
 // pointer to it in the existential.
@@ -149,49 +149,49 @@
 // CHECK-64-NEXT:     (struct Swift.Int)
 // CHECK-64-NEXT:     (struct Swift.Int)))
 // CHECK-64: Type info:
-// CHECK-64-NEXT: (struct size=72 alignment=8 stride=72 num_extra_inhabitants=0
+// CHECK-64-NEXT: (struct size=72 alignment=8 stride=72 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=x offset=0
-// CHECK-64-NEXT:     (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field offset=0
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:       (field offset=8
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:       (field offset=16
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=y offset=24
-// CHECK-64-NEXT:     (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field offset=0
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:       (field offset=8
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:       (field offset=16
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:   (field name=z offset=48
-// CHECK-64-NEXT:     (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (tuple size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field offset=0
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:       (field offset=8
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:       (field offset=16
-// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_value offset=0
-// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
+// CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
 
 // CHECK-32: Reflecting an existential.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -210,49 +210,49 @@
 // CHECK-32-NEXT:     (struct Swift.Int)
 // CHECK-32-NEXT:     (struct Swift.Int)))
 // CHECK-32:        Type info:
-// CHECK-32:        (struct size=36 alignment=4 stride=36 num_extra_inhabitants=0
+// CHECK-32:        (struct size=36 alignment=4 stride=36 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=x offset=0
-// CHECK-32-NEXT:     (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field offset=0
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:       (field offset=4
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:       (field offset=8
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=y offset=12
-// CHECK-32-NEXT:     (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field offset=0
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:       (field offset=4
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:       (field offset=8
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-32-NEXT:   (field name=z offset=24
-// CHECK-32-NEXT:     (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (tuple size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field offset=0
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:       (field offset=4
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:       (field offset=8
-// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_value offset=0
-// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))))
+// CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))))
 
 var he = HasError(singleError: MyError(), errorInComposition: MyError(), customError: MyCustomError(), customErrorInComposition: MyCustomError())
 reflect(any: he)
@@ -265,31 +265,31 @@
 // CHECK-64:        Type info:
 // CHECK-64:        (struct size=144 alignment=8 stride=144
 // CHECK-64-NEXT:   (field name=singleError offset=0
-// CHECK-64-NEXT:     (error_existential size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647
+// CHECK-64-NEXT:     (error_existential size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=error offset=0
 // CHECK-64-NEXT:         (reference kind=strong refcounting=unknown))))
 // CHECK-64-NEXT:   (field name=errorInComposition offset=8
-// CHECK-64-NEXT:     (opaque_existential size=48 alignment=8 stride=48 num_extra_inhabitants=2147483647
+// CHECK-64-NEXT:     (opaque_existential size=48 alignment=8 stride=48 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=24
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=32
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=40
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=customError offset=56
-// CHECK-64-NEXT:     (opaque_existential size=40 alignment=8 stride=40 num_extra_inhabitants=2147483647
+// CHECK-64-NEXT:     (opaque_existential size=40 alignment=8 stride=40 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=24
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=32
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=customErrorInComposition offset=96
-// CHECK-64-NEXT:     (opaque_existential size=48 alignment=8 stride=48 num_extra_inhabitants=2147483647
+// CHECK-64-NEXT:     (opaque_existential size=48 alignment=8 stride=48 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=24
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=32
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-64-NEXT:       (field name=wtable offset=40
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1)))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an existential.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -297,33 +297,33 @@
 // CHECK-32: (struct existentials.HasError)
 
 // CHECK-32:        Type info:
-// CHECK-32:        (struct size=72 alignment=4 stride=72 num_extra_inhabitants=4096
+// CHECK-32:        (struct size=72 alignment=4 stride=72 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=singleError offset=0
-// CHECK-32-NEXT:     (error_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (error_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=error offset=0
 // CHECK-32-NEXT:         (reference kind=strong refcounting=unknown))))
 // CHECK-32-NEXT:   (field name=errorInComposition offset=4
-// CHECK-32-NEXT:     (opaque_existential size=24 alignment=4 stride=24 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (opaque_existential size=24 alignment=4 stride=24 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=12
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=16
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=20
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=customError offset=28
-// CHECK-32-NEXT:     (opaque_existential size=20 alignment=4 stride=20 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (opaque_existential size=20 alignment=4 stride=20 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=12
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=16
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=customErrorInComposition offset=48
-// CHECK-32-NEXT:     (opaque_existential size=24 alignment=4 stride=24 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (opaque_existential size=24 alignment=4 stride=24 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=12
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=16
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1))
 // CHECK-32-NEXT:       (field name=wtable offset=20
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 reflect(error: MyError())
 
@@ -333,11 +333,11 @@
 // CHECK-64: (struct existentials.MyError)
 
 // CHECK-64:        Type info:
-// CHECK-64:        (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64:        (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=i offset=0
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an error existential.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -345,10 +345,10 @@
 // CHECK-32: (struct existentials.MyError)
 
 // CHECK-32:        Type info:
-// CHECK-32:        (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32:        (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=i offset=0
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
diff --git a/validation-test/Reflection/functions.swift b/validation-test/Reflection/functions.swift
index 8c034ec..5672816 100644
--- a/validation-test/Reflection/functions.swift
+++ b/validation-test/Reflection/functions.swift
@@ -28,18 +28,18 @@
 // CHECK-NEXT:    (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=12 alignment=4 stride=12
+// CHECK-32-NEXT: (closure_context size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field offset=8
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-64:      Type info:
-// CHECK-64-NEXT: (closure_context size=24 alignment=8 stride=24
+// CHECK-64-NEXT: (closure_context size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field offset=16
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
   // Here the context is a single boxed value
   reflect(function: {print(y)})
@@ -47,18 +47,18 @@
 // CHECK-NEXT:    (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=24 alignment=4 stride=24
+// CHECK-32-NEXT: (closure_context size=24 alignment=4 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field offset=8
-// CHECK-32-NEXT:     (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=4096
+// CHECK-32-NEXT:     (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=metadata offset=12
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1)))))
 
 // CHECK-64:      Type info:
-// CHECK-64-NEXT: (closure_context size=48 alignment=8 stride=48
+// CHECK-64-NEXT: (closure_context size=48 alignment=8 stride=48 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field offset=16
-// CHECK-64-NEXT:     (opaque_existential size=32 alignment=8 stride=32 num_extra_inhabitants=2147483647
+// CHECK-64-NEXT:     (opaque_existential size=32 alignment=8 stride=32 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=metadata offset=24
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647)))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1)))))
 }
 
 concrete(x: 10, y: true)
@@ -87,25 +87,25 @@
 // CHECK-NEXT:    (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=12 alignment=4 stride=12
+// CHECK-32-NEXT: (closure_context size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field offset=8
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-64:      Type info:
-// CHECK-64-NEXT: (closure_context size=24 alignment=8 stride=24
+// CHECK-64-NEXT: (closure_context size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field offset=16
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
   reflect(function: {print(x); print(y); print(z)})
 // CHECK:         Type reference:
 // CHECK-NEXT:    (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=36 alignment=4 stride=36
+// CHECK-32-NEXT: (closure_context size=36 alignment=4 stride=36 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field offset=24
 // CHECK-32-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-32-NEXT:   (field offset=28
@@ -114,7 +114,7 @@
 // CHECK-32-NEXT:     (reference kind=strong refcounting=native)))
 
 // CHECK-64:      Type info:
-// CHECK-64-NEXT: (closure_context size=72 alignment=8 stride=72
+// CHECK-64-NEXT: (closure_context size=72 alignment=8 stride=72 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field offset=48
 // CHECK-64-NEXT:     (reference kind=strong refcounting=native))
 // CHECK-64-NEXT:   (field offset=56
@@ -189,34 +189,34 @@
   // CHECK-64: (builtin Builtin.NativeObject)
   
   // CHECK-64:        Type info:
-  // CHECK-64:        (closure_context size=32 alignment=8 stride=32
+  // CHECK-64:        (closure_context size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:   (field offset=16
-  // CHECK-64-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
+  // CHECK-64-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:       (field offset=0
-  // CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:           (field name=_value offset=0
-  // CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+  // CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-64-NEXT:       (field offset=8
-  // CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:           (field name=_value offset=0
-  // CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
+  // CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
 
   // CHECK-32: Reflecting an object.
   // CHECK-32: Type reference:
   // CHECK-32: (builtin Builtin.NativeObject)
 
   // CHECK-32:        Type info:
-  // CHECK-32:        (closure_context size=24 alignment=8 stride=24
+  // CHECK-32:        (closure_context size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:   (field offset=8
-  // CHECK-32-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
+  // CHECK-32-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:       (field offset=0
-  // CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+  // CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:           (field name=_value offset=0
-  // CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+  // CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-32-NEXT:       (field offset=8
-  // CHECK-32-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-32-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:           (field name=_value offset=0
-  // CHECK-32-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
+  // CHECK-32-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
   @_optimize(none)
   func arity1Capture1() -> (Int) -> () {
     let pair = (2, 333.0)
@@ -232,13 +232,13 @@
   // CHECK-64: (builtin Builtin.NativeObject)
 
   // CHECK-64:      Type info:
-  // CHECK-64:      (closure_context size=32 alignment=8 stride=32
+  // CHECK-64:      (closure_context size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT: (field offset=16
-  // CHECK-64-NEXT:   (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647
+  // CHECK-64-NEXT:   (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
   // CHECK-64-NEXT:     (field offset=0
-  // CHECK-64-NEXT:       (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-64-NEXT:       (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:         (field name=_value offset=0
-  // CHECK-64-NEXT:           (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+  // CHECK-64-NEXT:           (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-64-NEXT:     (field offset=8
   // CHECK-64-NEXT:       (reference kind=strong refcounting=native)))))
 
@@ -247,13 +247,13 @@
   // CHECK-32: (builtin Builtin.NativeObject)
   
   // CHECK-32:        Type info:
-  // CHECK-32:        (closure_context size=16 alignment=4 stride=16
+  // CHECK-32:        (closure_context size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:   (field offset=8
-  // CHECK-32-NEXT:     (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+  // CHECK-32-NEXT:     (tuple size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
   // CHECK-32-NEXT:       (field offset=0
-  // CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+  // CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:           (field name=_value offset=0
-  // CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+  // CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-32-NEXT:       (field offset=4
   // CHECK-32-NEXT:         (reference kind=strong refcounting=native)))))
   @_optimize(none)
@@ -272,11 +272,11 @@
   // CHECK-64: (builtin Builtin.NativeObject)
   
   // CHECK-64:        Type info:
-  // CHECK-64:        (closure_context size=24 alignment=8 stride=24
+  // CHECK-64:        (closure_context size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:   (field offset=16
-  // CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=2147483646
+  // CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=2147483646 bitwise_takable=1
   // CHECK-64-NEXT:       (field name=some offset=0
-  // CHECK-64-NEXT:         (class_existential size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647
+  // CHECK-64-NEXT:         (class_existential size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
   // CHECK-64-NEXT:           (field name=object offset=0
   // CHECK-64-NEXT:             (reference kind=strong refcounting=unknown))))))
 
@@ -285,11 +285,11 @@
   // CHECK-32: (builtin Builtin.NativeObject)
   
   // CHECK-32:        Type info:
-  // CHECK-32:        (closure_context size=12 alignment=4 stride=12
+  // CHECK-32:        (closure_context size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:   (field offset=8
-  // CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095
+  // CHECK-32-NEXT:     (single_payload_enum size=4 alignment=4 stride=4 num_extra_inhabitants=4095 bitwise_takable=1
   // CHECK-32-NEXT:       (field name=some offset=0
-  // CHECK-32-NEXT:         (class_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096
+  // CHECK-32-NEXT:         (class_existential size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
   // CHECK-32-NEXT:           (field name=object offset=0
   // CHECK-32-NEXT:             (reference kind=strong refcounting=unknown)))))
   @_optimize(none)
@@ -308,38 +308,38 @@
   // CHECK-64: Type reference:
   // CHECK-64: (builtin Builtin.NativeObject)
   // CHECK-64:        Type info:
-  // CHECK-64:        (closure_context size=40 alignment=8 stride=40
+  // CHECK-64:        (closure_context size=40 alignment=8 stride=40 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:   (field offset=16
   // CHECK-64-NEXT:     (reference kind=strong refcounting=native))
   // CHECK-64-NEXT:   (field offset=24
-  // CHECK-64-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
+  // CHECK-64-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:       (field offset=0
-  // CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:           (field name=_value offset=0
-  // CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+  // CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-64-NEXT:       (field offset=8
-  // CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-64-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:           (field name=_value offset=0
-  // CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
+  // CHECK-64-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
 
   // CHECK-32: Reflecting an object.
   // CHECK-32: Type reference:
   // CHECK-32: (builtin Builtin.NativeObject)
 
   // CHECK-32:        Type info:
-  // CHECK-32:        (closure_context size=32 alignment=8 stride=32
+  // CHECK-32:        (closure_context size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:   (field offset=8
   // CHECK-32-NEXT:     (reference kind=strong refcounting=native))
   // CHECK-32-NEXT:   (field offset=16
-  // CHECK-32-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
+  // CHECK-32-NEXT:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:       (field offset=0
-  // CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+  // CHECK-32-NEXT:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:           (field name=_value offset=0
-  // CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+  // CHECK-32-NEXT:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-32-NEXT:       (field offset=8
-  // CHECK-32-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-32-NEXT:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32-NEXT:           (field name=_value offset=0
-  // CHECK-32-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
+  // CHECK-32-NEXT:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
   @_optimize(none)
   func arity0Capture2() -> () -> () {
    let pair = (999, 1010.2)
@@ -356,11 +356,11 @@
   // CHECK-64: (builtin Builtin.NativeObject)
   
   // CHECK-64:        Type info:
-  // CHECK-64:        (closure_context size=32 alignment=8 stride=32
+  // CHECK-64:        (closure_context size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64-NEXT:   (field offset=16
   // CHECK-64-NEXT:     (reference kind=strong refcounting=native))
   // CHECK-64-NEXT:   (field offset=24
-  // CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=2147483646
+  // CHECK-64-NEXT:     (single_payload_enum size=8 alignment=8 stride=8 num_extra_inhabitants=2147483646 bitwise_takable=1
   // CHECK-64-NEXT:       (field name=some offset=0
   // CHECK-64-NEXT:         (reference kind=strong refcounting=native))))
 
@@ -369,7 +369,7 @@
   // CHECK-32: (builtin Builtin.NativeObject)
   
   // CHECK-32: Type info:
-  // CHECK-32: (closure_context size=16 alignment=4 stride=16
+  // CHECK-32: (closure_context size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32:   (field offset=8
   // CHECK-32:     (reference kind=strong refcounting=native))
   // CHECK-32:   (field offset=12
@@ -390,38 +390,38 @@
   // CHECK-64: (builtin Builtin.NativeObject)
   
   // CHECK-64: Type info:
-  // CHECK-64: (closure_context size=40 alignment=8 stride=40
+  // CHECK-64: (closure_context size=40 alignment=8 stride=40 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64:   (field offset=16
   // CHECK-64:     (reference kind=strong refcounting=native))
   // CHECK-64:   (field offset=24
-  // CHECK-64:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
+  // CHECK-64:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64:       (field offset=0
-  // CHECK-64:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-64:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64:           (field name=_value offset=0
-  // CHECK-64:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+  // CHECK-64:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-64:       (field offset=8
-  // CHECK-64:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-64:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64:           (field name=_value offset=0
-  // CHECK-64:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
+  // CHECK-64:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
 
   // CHECK-32: Reflecting an object.
   // CHECK-32: Type reference:
   // CHECK-32: (builtin Builtin.NativeObject)
   
   // CHECK-32: Type info:
-  // CHECK-32: (closure_context size=32 alignment=8 stride=32
+  // CHECK-32: (closure_context size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32:   (field offset=8
   // CHECK-32:     (reference kind=strong refcounting=native))
   // CHECK-32:   (field offset=16
-  // CHECK-32:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
+  // CHECK-32:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32:       (field offset=0
-  // CHECK-32:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+  // CHECK-32:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32:           (field name=_value offset=0
-  // CHECK-32:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+  // CHECK-32:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-32:       (field offset=8
-  // CHECK-32:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-32:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32:           (field name=_value offset=0
-  // CHECK-32:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
+  // CHECK-32:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
   @_optimize(none)
   func arity2Capture2() -> (Int, String) -> () {
    let pair = (999, 1010.2)
@@ -439,38 +439,38 @@
   // CHECK-64: (builtin Builtin.NativeObject)
  
   // CHECK-64: Type info:
-  // CHECK-64: (closure_context size=40 alignment=8 stride=40
+  // CHECK-64: (closure_context size=40 alignment=8 stride=40 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64:   (field offset=16
   // CHECK-64:     (reference kind=strong refcounting=native))
   // CHECK-64:   (field offset=24
-  // CHECK-64:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
+  // CHECK-64:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64:       (field offset=0
-  // CHECK-64:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-64:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64:           (field name=_value offset=0
-  // CHECK-64:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+  // CHECK-64:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-64:       (field offset=8
-  // CHECK-64:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-64:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-64:           (field name=_value offset=0
-  // CHECK-64:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
+  // CHECK-64:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
 
   // CHECK-32: Reflecting an object.
   // CHECK-32: Type reference:
   // CHECK-32: (builtin Builtin.NativeObject)
   
   // CHECK-32: Type info:
-  // CHECK-32: (closure_context size=32 alignment=8 stride=32
+  // CHECK-32: (closure_context size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32:   (field offset=8
   // CHECK-32:     (reference kind=strong refcounting=native))
   // CHECK-32:   (field offset=16
-  // CHECK-32:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0
+  // CHECK-32:     (tuple size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32:       (field offset=0
-  // CHECK-32:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+  // CHECK-32:         (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32:           (field name=_value offset=0
-  // CHECK-32:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+  // CHECK-32:             (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
   // CHECK-32:       (field offset=8
-  // CHECK-32:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+  // CHECK-32:         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
   // CHECK-32:           (field name=_value offset=0
-  // CHECK-32:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))))
+  // CHECK-32:             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
   @_optimize(none)
   func arity3Capture2() -> (Int, String, AnyObject?) -> () {
    let pair = (999, 1010.2)
@@ -502,7 +502,7 @@
 // CHECK-64: (builtin Builtin.NativeObject)
 
 // CHECK-64:        Type info:
-// CHECK-64:        (closure_context size=24 alignment=8 stride=24
+// CHECK-64:        (closure_context size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=0
 // CHECK-64-NEXT:   (field offset=16
 // CHECK-64-NEXT:     (reference kind=weak refcounting=native)))
 
@@ -512,7 +512,7 @@
 // CHECK-32: (builtin Builtin.NativeObject)
 
 // CHECK-32:        Type info:
-// CHECK-32:        (closure_context size=12 alignment=4 stride=12
+// CHECK-32:        (closure_context size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=0
 // CHECK-32-NEXT:   (field offset=8
 // CHECK-32-NEXT:     (reference kind=weak refcounting=native)))
 
@@ -523,7 +523,7 @@
 // CHECK-64: (builtin Builtin.NativeObject)
 
 // CHECK-64:        Type info:
-// CHECK-64:        (closure_context size=24 alignment=8 stride=24
+// CHECK-64:        (closure_context size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field offset=16
 // CHECK-64-NEXT:     (reference kind=unowned refcounting=native)))
 
@@ -533,7 +533,7 @@
 // CHECK-32: (builtin Builtin.NativeObject)
 
 // CHECK-32:        Type info:
-// CHECK-32:        (closure_context size=12 alignment=4 stride=12
+// CHECK-32:        (closure_context size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field offset=8
 // CHECK-32-NEXT:     (reference kind=unowned refcounting=native)))
 
diff --git a/validation-test/Reflection/functions_objc.swift b/validation-test/Reflection/functions_objc.swift
index 29eb555..9feda85 100644
--- a/validation-test/Reflection/functions_objc.swift
+++ b/validation-test/Reflection/functions_objc.swift
@@ -19,15 +19,15 @@
 // CHECK-32-NEXT: (builtin Builtin.NativeObject)
 
 // CHECK-32:      Type info:
-// CHECK-32-NEXT: (closure_context size=36 alignment=4 stride=36 num_extra_inhabitants=0
+// CHECK-32-NEXT: (closure_context size=36 alignment=4 stride=36 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field offset=8
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field offset=12
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:   (field offset=16
-// CHECK-32-NEXT:     (builtin size=16 alignment=4 stride=16 num_extra_inhabitants=0))
+// CHECK-32-NEXT:     (builtin size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-32-NEXT:   (field offset=32
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown)))
 
@@ -35,15 +35,15 @@
 // CHECK-64-NEXT: (builtin Builtin.NativeObject)
 
 // CHECK-64:      Type info:
-// CHECK-64-NEXT: (closure_context size=72 alignment=8 stride=72 num_extra_inhabitants=0
+// CHECK-64-NEXT: (closure_context size=72 alignment=8 stride=72 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field offset=16
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field offset=24
 // CHECK-64-NEXT:     (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:   (field offset=32
-// CHECK-64-NEXT:     (builtin size=32 alignment=8 stride=32 num_extra_inhabitants=0))
+// CHECK-64-NEXT:     (builtin size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1))
 // CHECK-64-NEXT:   (field offset=64
 // CHECK-64-NEXT:     (reference kind=strong refcounting=unknown)))
 }
diff --git a/validation-test/Reflection/inherits_NSObject.swift b/validation-test/Reflection/inherits_NSObject.swift
index 3791f6f..77759dd 100644
--- a/validation-test/Reflection/inherits_NSObject.swift
+++ b/validation-test/Reflection/inherits_NSObject.swift
@@ -25,30 +25,30 @@
 // CHECK-64: (class inherits_NSObject.BaseNSClass)
 
 // CHECK-64: Type info:
-// CHECK-64-NEXT: (class_instance size=17 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64-NEXT: (class_instance size=17 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=w offset=8
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=x offset=16
-// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254)))))
+// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_NSObject.BaseNSClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=9 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=9 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=w offset=4
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=x offset=8
-// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254)))))
+// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1)))))
 
 class DerivedNSClass : BaseNSClass {
   var y: Bool = false
@@ -63,30 +63,30 @@
 // CHECK-64: (class inherits_NSObject.DerivedNSClass)
 
 // CHECK-64: Type info:
-// CHECK-64-NEXT: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0
+// CHECK-64-NEXT: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=y offset=17
-// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254))))
+// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=z offset=24
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_NSObject.DerivedNSClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=y offset=9
-// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254))))
+// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=z offset=12
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // Note: dynamic layout starts at offset 8, not 16
 class GenericBaseNSClass<T> : NSObject {
@@ -102,11 +102,11 @@
 // CHECK-64:   (struct Swift.Int))
 
 // CHECK-64: Type info:
-// CHECK-64-NEXT: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-64-NEXT: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=w offset=8
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
@@ -114,11 +114,11 @@
 // CHECK-32:   (struct Swift.Int))
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=8 alignment=4 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=8 alignment=4 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=w offset=4
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 class AlignedNSClass : NSObject {
   var w: Int = 0
@@ -133,26 +133,26 @@
 // CHECK-64: (class inherits_NSObject.AlignedNSClass)
 
 // CHECK-64: Type info:
-// CHECK-64-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0
+// CHECK-64-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=w offset=8
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=x offset=16
-// CHECK-64-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-64-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_NSObject.AlignedNSClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=w offset=4
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=x offset=16
-// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 class GenericAlignedNSClass<T> : NSObject {
   var w: T = 0 as! T
@@ -168,13 +168,13 @@
 // CHECK-64:   (struct Swift.Int))
 
 // CHECK-64: Type info:
-// CHECK-64-NEXT: (class_instance size=48 alignment=16 stride=48 num_extra_inhabitants=0
+// CHECK-64-NEXT: (class_instance size=48 alignment=16 stride=48 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=w offset=16
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=x offset=32
-// CHECK-64-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-64-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
@@ -182,12 +182,12 @@
 // CHECK-32:   (struct Swift.Int))
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=48 alignment=16 stride=48 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=48 alignment=16 stride=48 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=w offset=16
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=x offset=32
-// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 doneReflecting()
diff --git a/validation-test/Reflection/inherits_ObjCClasses.swift b/validation-test/Reflection/inherits_ObjCClasses.swift
index cca23ae..fd8c1a4 100644
--- a/validation-test/Reflection/inherits_ObjCClasses.swift
+++ b/validation-test/Reflection/inherits_ObjCClasses.swift
@@ -28,18 +28,18 @@
 // CHECK-64: (class inherits_ObjCClasses.FirstClassA)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=xx offset=16
-// CHECK-64:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-64:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_ObjCClasses.FirstClassA)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=xx offset=16
-// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 // Variant B: word size alignment
 class FirstClassB : FirstClass {
@@ -53,22 +53,22 @@
 // CHECK-64: (class inherits_ObjCClasses.FirstClassB)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=zz offset=16
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_ObjCClasses.FirstClassB)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=zz offset=8
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 //// SecondClass -- base class, has two word-sized ivars
 
@@ -84,18 +84,18 @@
 // CHECK-64: (class inherits_ObjCClasses.SecondClassA)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=48 alignment=16 stride=48 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=48 alignment=16 stride=48 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=xx offset=32
-// CHECK-64:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-64:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_ObjCClasses.SecondClassA)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=xx offset=16
-// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 // Variant B: word size alignment
 class SecondClassB : SecondClass {
@@ -109,22 +109,22 @@
 // CHECK-64: (class inherits_ObjCClasses.SecondClassB)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=zz offset=24
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_ObjCClasses.SecondClassB)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=zz offset=12
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 //// ThirdClass -- base class, has three word-sized ivars
 
@@ -140,18 +140,18 @@
 // CHECK-64: (class inherits_ObjCClasses.ThirdClassA)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=48 alignment=16 stride=48 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=48 alignment=16 stride=48 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=xx offset=32
-// CHECK-64:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-64:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_ObjCClasses.ThirdClassA)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=32 alignment=16 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=xx offset=16
-// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0)))
+// CHECK-32-NEXT:     (builtin size=16 alignment=16 stride=16 num_extra_inhabitants=0 bitwise_takable=1)))
 
 // Variant B: word size alignment
 class ThirdClassB : ThirdClass {
@@ -165,21 +165,21 @@
 // CHECK-64: (class inherits_ObjCClasses.ThirdClassB)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=40 alignment=8 stride=40 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=40 alignment=8 stride=40 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=zz offset=32
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_ObjCClasses.ThirdClassB)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=zz offset=16
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
diff --git a/validation-test/Reflection/inherits_Swift.swift b/validation-test/Reflection/inherits_Swift.swift
index 24cdb64..3f46ed4 100644
--- a/validation-test/Reflection/inherits_Swift.swift
+++ b/validation-test/Reflection/inherits_Swift.swift
@@ -25,30 +25,30 @@
 // CHECK-64: (class inherits_Swift.BaseClass)
 
 // CHECK-64: Type info:
-// CHECK-64-NEXT: (class_instance size=25 alignment=8 stride=32 num_extra_inhabitants=0
+// CHECK-64-NEXT: (class_instance size=25 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=w offset=16
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=x offset=24
-// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254)))))
+// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_Swift.BaseClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=13 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=13 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=w offset=8
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=x offset=12
-// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254)))))
+// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1)))))
 
 let baseObject = BaseClass()
 reflect(object: baseObject)
@@ -61,29 +61,29 @@
 // CHECK-64: (class inherits_Swift.DerivedClass)
 
 // CHECK-64: Type info:
-// CHECK-64-NEXT: (class_instance size=40 alignment=8 stride=40 num_extra_inhabitants=0
+// CHECK-64-NEXT: (class_instance size=40 alignment=8 stride=40 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:  (field name=y offset=25
-// CHECK-64-NEXT:    (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-64-NEXT:    (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-64-NEXT:      (field name=_value offset=0
-// CHECK-64-NEXT:        (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254))))
+// CHECK-64-NEXT:        (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1))))
 // CHECK-64-NEXT:  (field name=z offset=32
-// CHECK-64-NEXT:    (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:    (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:      (field name=_value offset=0
-// CHECK-64-NEXT:        (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64-NEXT:        (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class inherits_Swift.DerivedClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=y offset=13
-// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254))))
+// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=z offset=16
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_Array.swift b/validation-test/Reflection/reflect_Array.swift
index ede0462..784e431 100644
--- a/validation-test/Reflection/reflect_Array.swift
+++ b/validation-test/Reflection/reflect_Array.swift
@@ -26,9 +26,9 @@
 // CHECK-64: (class reflect_Array.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=1
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
 // (unstable implementation details omitted)
 
 // CHECK-32: Reflecting an object.
@@ -37,9 +37,9 @@
 // CHECK-32: (class reflect_Array.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=1
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // (unstable implementation details omitted)
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_Bool.swift b/validation-test/Reflection/reflect_Bool.swift
index a3d3c94..2512574 100644
--- a/validation-test/Reflection/reflect_Bool.swift
+++ b/validation-test/Reflection/reflect_Bool.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_Bool.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=17 alignment=1 stride=17 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=17 alignment=1 stride=17 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-64:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254)))))
+// CHECK-64:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_Bool.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=9 alignment=1 stride=9 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=9 alignment=1 stride=9 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254)))))
+// CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_Character.swift b/validation-test/Reflection/reflect_Character.swift
index 58551ff..c402513 100644
--- a/validation-test/Reflection/reflect_Character.swift
+++ b/validation-test/Reflection/reflect_Character.swift
@@ -25,35 +25,34 @@
 // CHECK-64: (class reflect_Character.TestClass)
 
 // CHECK-64-LABEL: Type info:
-// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT: (field name=t offset=16
-// CHECK-64-NEXT:   (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
+// CHECK-64-NEXT:   (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:     (field name=_str offset=0
-// CHECK-64-NEXT:       (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
+// CHECK-64-NEXT:       (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:         (field name=_guts offset=0
-// CHECK-64-NEXT:           (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
+// CHECK-64-NEXT:           (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:             (field name=_object offset=0
-// CHECK-64-NEXT:               (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
+// CHECK-64-NEXT:               (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:                 (field name=_countAndFlags offset=0
-// CHECK-64-NEXT:                   (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:                   (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                     (field name=_storage offset=0
-// CHECK-64-NEXT:                       (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:                       (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                         (field name=_value offset=0
-// CHECK-64-NEXT:                           (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                           (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:                 (field name=_object offset=8
-// CHECK-64-NEXT:                   (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1)))))))))))
+// CHECK-64-NEXT:                   (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1)))))))))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Type reference:
 // CHECK-32: (class reflect_Character.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=t offset=8
-// CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=128
+// CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=253 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_str offset=0
-// CHECK-32-NEXT:         (struct size=12 alignment=4 stride=12 num_extra_inhabitants=128
-// (unstable implementation details omitted)
+// CHECK-32-NEXT:         (struct size=12 alignment=4 stride=12 num_extra_inhabitants=253 bitwise_takable=1
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_Dictionary.swift b/validation-test/Reflection/reflect_Dictionary.swift
index aa6efd9..6b2d732 100644
--- a/validation-test/Reflection/reflect_Dictionary.swift
+++ b/validation-test/Reflection/reflect_Dictionary.swift
@@ -26,9 +26,9 @@
 // CHECK-64: (class reflect_Dictionary.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=1
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
 // (unstable implementation details omitted)
 
 // CHECK-32: Reflecting an object.
@@ -37,9 +37,9 @@
 // CHECK-32: (class reflect_Dictionary.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=1
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // (unstable implementation details omitted)
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_Double.swift b/validation-test/Reflection/reflect_Double.swift
index 04a4e20..3107012 100644
--- a/validation-test/Reflection/reflect_Double.swift
+++ b/validation-test/Reflection/reflect_Double.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_Double.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_Double.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_Float.swift b/validation-test/Reflection/reflect_Float.swift
index 50cf214..b1a8748 100644
--- a/validation-test/Reflection/reflect_Float.swift
+++ b/validation-test/Reflection/reflect_Float.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_Float.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_Float.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_Int.swift b/validation-test/Reflection/reflect_Int.swift
index 61f54c3..b650728 100644
--- a/validation-test/Reflection/reflect_Int.swift
+++ b/validation-test/Reflection/reflect_Int.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_Int.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_Int.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_Int16.swift b/validation-test/Reflection/reflect_Int16.swift
index ec156fa..0041fb1 100644
--- a/validation-test/Reflection/reflect_Int16.swift
+++ b/validation-test/Reflection/reflect_Int16.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_Int16.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=18 alignment=2 stride=18 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=18 alignment=2 stride=18 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_Int16.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=10 alignment=2 stride=10 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=10 alignment=2 stride=10 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_Int32.swift b/validation-test/Reflection/reflect_Int32.swift
index 61913f0..99e2428 100644
--- a/validation-test/Reflection/reflect_Int32.swift
+++ b/validation-test/Reflection/reflect_Int32.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_Int32.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_Int32.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_Int64.swift b/validation-test/Reflection/reflect_Int64.swift
index 61753db..b641c29 100644
--- a/validation-test/Reflection/reflect_Int64.swift
+++ b/validation-test/Reflection/reflect_Int64.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_Int64.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_Int64.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_Int8.swift b/validation-test/Reflection/reflect_Int8.swift
index f28dda5..4e4d251 100644
--- a/validation-test/Reflection/reflect_Int8.swift
+++ b/validation-test/Reflection/reflect_Int8.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_Int8.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=17 alignment=1 stride=17 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=17 alignment=1 stride=17 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_Int8.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=9 alignment=1 stride=9 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=9 alignment=1 stride=9 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_NSArray.swift b/validation-test/Reflection/reflect_NSArray.swift
index c85f887..621b055 100644
--- a/validation-test/Reflection/reflect_NSArray.swift
+++ b/validation-test/Reflection/reflect_NSArray.swift
@@ -27,7 +27,7 @@
 // CHECK-64: (class reflect_NSArray.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
 // CHECK-64:     (reference kind=strong refcounting=unknown)))
 
@@ -37,7 +37,7 @@
 // CHECK-32: (class reflect_NSArray.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
 // CHECK-32:     (reference kind=strong refcounting=unknown)))
 
diff --git a/validation-test/Reflection/reflect_NSNumber.swift b/validation-test/Reflection/reflect_NSNumber.swift
index f14a9eb..d90cdc1 100644
--- a/validation-test/Reflection/reflect_NSNumber.swift
+++ b/validation-test/Reflection/reflect_NSNumber.swift
@@ -27,7 +27,7 @@
 // CHECK-64: (class reflect_NSNumber.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
 // CHECK-64:     (reference kind=strong refcounting=unknown)))
 
@@ -37,7 +37,7 @@
 // CHECK-32: (class reflect_NSNumber.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
 // CHECK-32:     (reference kind=strong refcounting=unknown)))
 
diff --git a/validation-test/Reflection/reflect_NSSet.swift b/validation-test/Reflection/reflect_NSSet.swift
index bb7323f..2a42157 100644
--- a/validation-test/Reflection/reflect_NSSet.swift
+++ b/validation-test/Reflection/reflect_NSSet.swift
@@ -27,7 +27,7 @@
 // CHECK-64: (class reflect_NSSet.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
 // CHECK-64:     (reference kind=strong refcounting=unknown)))
 
@@ -37,7 +37,7 @@
 // CHECK-32: (class reflect_NSSet.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
 // CHECK-32:     (reference kind=strong refcounting=unknown)))
 
diff --git a/validation-test/Reflection/reflect_NSString.swift b/validation-test/Reflection/reflect_NSString.swift
index b9f984e..e3bd7b1 100644
--- a/validation-test/Reflection/reflect_NSString.swift
+++ b/validation-test/Reflection/reflect_NSString.swift
@@ -27,7 +27,7 @@
 // CHECK-64: (class reflect_NSString.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
 // CHECK-64:     (reference kind=strong refcounting=unknown)))
 
@@ -37,7 +37,7 @@
 // CHECK-32: (class reflect_NSString.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
 // CHECK-32:     (reference kind=strong refcounting=unknown)))
 
diff --git a/validation-test/Reflection/reflect_Set.swift b/validation-test/Reflection/reflect_Set.swift
index 5d05934..d31609f 100644
--- a/validation-test/Reflection/reflect_Set.swift
+++ b/validation-test/Reflection/reflect_Set.swift
@@ -26,9 +26,9 @@
 // CHECK-64: (class reflect_Set.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=1
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
 // (unstable implementation details omitted)
 
 // CHECK-32: Reflecting an object.
@@ -37,9 +37,9 @@
 // CHECK-32: (class reflect_Set.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=1
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // (unstable implementation details omitted)
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_String.swift b/validation-test/Reflection/reflect_String.swift
index 360b37b..56aaa22 100644
--- a/validation-test/Reflection/reflect_String.swift
+++ b/validation-test/Reflection/reflect_String.swift
@@ -26,10 +26,9 @@
 // CHECK-64: (class reflect_String.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64-NEXT: (class_instance size=32 alignment=8 stride=32
+// CHECK-64-NEXT: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=t offset=16
-// CHECK-64-NEXT:     (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
-
+// CHECK-64-NEXT:     (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // (unstable implementation details omitted)
 
 // CHECK-32: Reflecting an object.
@@ -38,22 +37,22 @@
 // CHECK-32: (class reflect_String.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20
+// CHECK-32-NEXT: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=t offset=8
-// CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=128
+// CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=253 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_guts offset=0
-// CHECK-32-NEXT:         (struct size=12 alignment=4 stride=12 num_extra_inhabitants=128
+// CHECK-32-NEXT:         (struct size=12 alignment=4 stride=12 num_extra_inhabitants=253 bitwise_takable=1
 // CHECK-32-NEXT:           (field name=_object offset=0
-// CHECK-32-NEXT:             (struct size=12 alignment=4 stride=12 num_extra_inhabitants=128
+// CHECK-32-NEXT:             (struct size=12 alignment=4 stride=12 num_extra_inhabitants=253 bitwise_takable=1
 // (unstable implementation details omitted)
 // CHECK-32:               (field name=_variant offset=4
-// CHECK-32-NEXT:                 (multi_payload_enum size=5 alignment=4 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (multi_payload_enum size=5 alignment=4 stride=8 num_extra_inhabitants=253 bitwise_takable=1
 // (unstable implementation details omitted)
 // CHECK-32:               (field name=_discriminator offset=9
-// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=128
+// CHECK-32-NEXT:                 (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=128 bitwise_takable=1
 // (unstable implementation details omitted)
 // CHECK-32:               (field name=_flags offset=10
-// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:                 (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // (unstable implementation details omitted)
 
 doneReflecting()
diff --git a/validation-test/Reflection/reflect_UInt.swift b/validation-test/Reflection/reflect_UInt.swift
index 51e8155..c0ce673 100644
--- a/validation-test/Reflection/reflect_UInt.swift
+++ b/validation-test/Reflection/reflect_UInt.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_UInt.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_UInt.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_UInt16.swift b/validation-test/Reflection/reflect_UInt16.swift
index 8d90023..4ed509b 100644
--- a/validation-test/Reflection/reflect_UInt16.swift
+++ b/validation-test/Reflection/reflect_UInt16.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_UInt16.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=18 alignment=2 stride=18 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=18 alignment=2 stride=18 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_UInt16.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=10 alignment=2 stride=10 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=10 alignment=2 stride=10 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_UInt32.swift b/validation-test/Reflection/reflect_UInt32.swift
index ec17b4a..2742138 100644
--- a/validation-test/Reflection/reflect_UInt32.swift
+++ b/validation-test/Reflection/reflect_UInt32.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_UInt32.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=20 alignment=4 stride=20 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_UInt32.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=12 alignment=4 stride=12 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_UInt64.swift b/validation-test/Reflection/reflect_UInt64.swift
index c98d071..2e8e0d1 100644
--- a/validation-test/Reflection/reflect_UInt64.swift
+++ b/validation-test/Reflection/reflect_UInt64.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_UInt64.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_UInt64.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=16 alignment=8 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-32:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_UInt8.swift b/validation-test/Reflection/reflect_UInt8.swift
index 11afc7b..224b078 100644
--- a/validation-test/Reflection/reflect_UInt8.swift
+++ b/validation-test/Reflection/reflect_UInt8.swift
@@ -26,11 +26,11 @@
 // CHECK-64: (class reflect_UInt8.TestClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=17 alignment=1 stride=17 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=17 alignment=1 stride=17 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:       (field name=_value offset=0
-// CHECK-64:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
+// CHECK-64:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -38,11 +38,11 @@
 // CHECK-32: (class reflect_UInt8.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=9 alignment=1 stride=9 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=9 alignment=1 stride=9 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:       (field name=_value offset=0
-// CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
+// CHECK-32:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_empty_class.swift b/validation-test/Reflection/reflect_empty_class.swift
index 0a2c1ef..1bbafbc 100644
--- a/validation-test/Reflection/reflect_empty_class.swift
+++ b/validation-test/Reflection/reflect_empty_class.swift
@@ -21,7 +21,7 @@
 // CHECK-64: (class reflect_empty_class.EmptyClass)
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=16 alignment=1 stride=16 num_extra_inhabitants=0)
+// CHECK-64: (class_instance size=16 alignment=1 stride=16 num_extra_inhabitants=0 bitwise_takable=1)
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -29,7 +29,7 @@
 // CHECK-32: (class reflect_empty_class.EmptyClass)
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=8 alignment=1 stride=8 num_extra_inhabitants=0)
+// CHECK-32: (class_instance size=8 alignment=1 stride=8 num_extra_inhabitants=0 bitwise_takable=1)
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_existential.swift b/validation-test/Reflection/reflect_existential.swift
index d1ba446..ff8489d 100644
--- a/validation-test/Reflection/reflect_existential.swift
+++ b/validation-test/Reflection/reflect_existential.swift
@@ -29,22 +29,22 @@
 // CHECK-64:   (protocol_composition))
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=48 alignment=8 stride=48 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=48 alignment=8 stride=48 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (opaque_existential size=32 alignment=8 stride=32 num_extra_inhabitants=2147483647
+// CHECK-64:     (opaque_existential size=32 alignment=8 stride=32 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64:       (field name=metadata offset=24
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1)))))
 
 // CHECK-32: Type reference:
 // CHECK-32: (bound_generic_class reflect_existential.TestGeneric
 // CHECK-32:   (protocol_composition))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=24 alignment=4 stride=24 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=24 alignment=4 stride=24 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=4096
+// CHECK-32:     (opaque_existential size=16 alignment=4 stride=16 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32:       (field name=metadata offset=12
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1)))))
 
 reflect(object: TestGeneric(D() as P))
 
@@ -54,13 +54,13 @@
 // CHECK-64:     (protocol reflect_existential.P)))
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=56 alignment=8 stride=56 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=56 alignment=8 stride=56 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (opaque_existential size=40 alignment=8 stride=40 num_extra_inhabitants=2147483647
+// CHECK-64:     (opaque_existential size=40 alignment=8 stride=40 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64:       (field name=metadata offset=24
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1))
 // CHECK-64:       (field name=wtable offset=32
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 // CHECK-32: Type reference:
 // CHECK-32: (bound_generic_class reflect_existential.TestGeneric
@@ -68,13 +68,13 @@
 // CHECK-32:     (protocol reflect_existential.P)))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=28 alignment=4 stride=28 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=28 alignment=4 stride=28 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (opaque_existential size=20 alignment=4 stride=20 num_extra_inhabitants=4096
+// CHECK-32:     (opaque_existential size=20 alignment=4 stride=20 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32:       (field name=metadata offset=12
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1))
 // CHECK-32:       (field name=wtable offset=16
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 reflect(object: TestGeneric(D() as (P & AnyObject)))
 
@@ -84,13 +84,13 @@
 // CHECK-64:     (protocol reflect_existential.P)))
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647
+// CHECK-64:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64:       (field name=object offset=0
 // CHECK-64:         (reference kind=strong refcounting=unknown))
 // CHECK-64:       (field name=wtable offset=8
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 // CHECK-32: Type reference:
 // CHECK-32: (bound_generic_class reflect_existential.TestGeneric
@@ -98,13 +98,13 @@
 // CHECK-32:     (protocol reflect_existential.P)))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32:       (field name=object offset=0
 // CHECK-32:         (reference kind=strong refcounting=unknown))
 // CHECK-32:       (field name=wtable offset=4
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 reflect(object: TestGeneric(D() as CP))
 
@@ -114,13 +114,13 @@
 // CHECK-64:     (protocol reflect_existential.CP)))
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647
+// CHECK-64:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64:       (field name=object offset=0
 // CHECK-64:         (reference kind=strong refcounting=unknown))
 // CHECK-64:       (field name=wtable offset=8
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 // CHECK-32: Type reference:
 // CHECK-32: (bound_generic_class reflect_existential.TestGeneric
@@ -128,13 +128,13 @@
 // CHECK-32:     (protocol reflect_existential.CP)))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32:       (field name=object offset=0
 // CHECK-32:         (reference kind=strong refcounting=unknown))
 // CHECK-32:       (field name=wtable offset=4
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 reflect(object: TestGeneric(D() as (C & P)))
 
@@ -145,13 +145,13 @@
 // CHECK-64:     (protocol reflect_existential.P)))
 
 // CHECK-64: Type info:
-// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0
+// CHECK-64: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64:   (field name=t offset=16
-// CHECK-64:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647
+// CHECK-64:     (class_existential size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64:       (field name=object offset=0
 // CHECK-64:         (reference kind=strong refcounting=native))
 // CHECK-64:       (field name=wtable offset=8
-// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1)))))
+// CHECK-64:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 // CHECK-32: Type reference:
 // CHECK-32: (bound_generic_class reflect_existential.TestGeneric
@@ -160,13 +160,13 @@
 // CHECK-32:     (protocol reflect_existential.P)))
 
 // CHECK-32: Type info:
-// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0
+// CHECK-32: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32:   (field name=t offset=8
-// CHECK-32:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096
+// CHECK-32:     (class_existential size=8 alignment=4 stride=8 num_extra_inhabitants=4096 bitwise_takable=1
 // CHECK-32:       (field name=object offset=0
 // CHECK-32:         (reference kind=strong refcounting=native))
 // CHECK-32:       (field name=wtable offset=4
-// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1)))))
+// CHECK-32:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=1 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/Reflection/reflect_multiple_types.swift b/validation-test/Reflection/reflect_multiple_types.swift
index 3ffc002..bf4619a 100644
--- a/validation-test/Reflection/reflect_multiple_types.swift
+++ b/validation-test/Reflection/reflect_multiple_types.swift
@@ -115,63 +115,63 @@
 // CHECK-64: (class reflect_multiple_types.TestClass)
 
 // CHECK-64-LABEL: Type info:
-// CHECK-64-NEXT: (class_instance size=185 alignment=8 stride=192 num_extra_inhabitants=0
+// CHECK-64-NEXT: (class_instance size=185 alignment=8 stride=192 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:   (field name=t00 offset=16
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=1
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
 // (unstable implementation details omitted)
 // CHECK-64:   (field name=t01 offset=24
-// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254))))
+// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1))))
 
 // CHECK-64-NEXT:   (field name=t02 offset=32
-// CHECK-64-NEXT:     (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
+// CHECK-64-NEXT:     (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_str offset=0
-// CHECK-64-NEXT:         (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
+// CHECK-64-NEXT:         (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:           (field name=_guts offset=0
-// CHECK-64-NEXT:             (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
+// CHECK-64-NEXT:             (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:               (field name=_object offset=0
-// CHECK-64-NEXT:                 (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
+// CHECK-64-NEXT:                 (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // CHECK-64-NEXT:                   (field name=_countAndFlags offset=0
-// CHECK-64-NEXT:                     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:                     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                       (field name=_storage offset=0
-// CHECK-64-NEXT:                         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:                         (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:                           (field name=_value offset=0
-// CHECK-64-NEXT:                             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))))
+// CHECK-64-NEXT:                             (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))))
 // CHECK-64-NEXT:                   (field name=_object offset=8
-// CHECK-64-NEXT:                     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=1))))))))))
+// CHECK-64-NEXT:                     (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1))))))))))
 
 // CHECK-64-NEXT:   (field name=t03 offset=48
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=1
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
 // (unstable implementation details omitted)
 // CHECK-64:   (field name=t04 offset=56
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t05 offset=64
-// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t06 offset=72
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t07 offset=80
-// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t08 offset=84
-// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t09 offset=88
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t10 offset=96
-// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t11 offset=104
 // CHECK-64-NEXT:     (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:   (field name=t12 offset=112
@@ -181,34 +181,34 @@
 // CHECK-64-NEXT:   (field name=t14 offset=128
 // CHECK-64-NEXT:     (reference kind=strong refcounting=unknown))
 // CHECK-64-NEXT:   (field name=t15 offset=136
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=1
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1
 
 // (unstable implementation details omitted)
 
 // CHECK-64:   (field name=t16 offset=144
-// CHECK-64-NEXT:     (struct size=16 alignment=8 stride=16 num_extra_inhabitants=1
+// CHECK-64-NEXT:     (struct size=16 alignment=8 stride=16 num_extra_inhabitants=2147483647 bitwise_takable=1
 // (unstable implementation details omitted)
 
 // CHECK-64:   (field name=t17 offset=160
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t18 offset=168
-// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t19 offset=172
-// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t20 offset=176
-// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-64-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-64-NEXT:   (field name=t21 offset=184
-// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-64-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-64-NEXT:       (field name=_value offset=0
-// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
+// CHECK-64-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 // CHECK-32: Reflecting an object.
 // CHECK-32: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
@@ -216,49 +216,49 @@
 // CHECK-32: (class reflect_multiple_types.TestClass)
 
 // CHECK-32: Type info:
-// CHECK-32-NEXT: (class_instance size=121 alignment=8 stride=128 num_extra_inhabitants=0
+// CHECK-32-NEXT: (class_instance size=121 alignment=8 stride=128 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:   (field name=t00 offset=8
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=1
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // (unstable implementation details omitted)
 // CHECK-32:   (field name=t01 offset=12
-// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254
+// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254))))
+// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=254 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t02 offset=16
-// CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=128
+// CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=253 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_str offset=0
 // (unstable implementation details omitted)
 // CHECK-32:   (field name=t03 offset=28
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=1
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // (unstable implementation details omitted)
 // CHECK-32:   (field name=t04 offset=32
-// CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t05 offset=40
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t06 offset=44
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t07 offset=48
-// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t08 offset=52
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t09 offset=56
-// CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t10 offset=64
-// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t11 offset=68
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:   (field name=t12 offset=72
@@ -268,31 +268,31 @@
 // CHECK-32-NEXT:   (field name=t14 offset=80
 // CHECK-32-NEXT:     (reference kind=strong refcounting=unknown))
 // CHECK-32-NEXT:   (field name=t15 offset=84
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=1
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=4096 bitwise_takable=1
 // (unstable implementation details omitted)
 // CHECK-32:   (field name=t16 offset=88
-// CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=128
+// CHECK-32-NEXT:     (struct size=12 alignment=4 stride=12 num_extra_inhabitants=253 bitwise_takable=1
 // (unstable implementation details omitted)
 // CHECK-32:   (field name=t17 offset=100
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t18 offset=104
-// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=2 alignment=2 stride=2 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t19 offset=108
-// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t20 offset=112
-// CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0))))
+// CHECK-32-NEXT:         (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1))))
 // CHECK-32-NEXT:   (field name=t21 offset=120
-// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0
+// CHECK-32-NEXT:     (struct size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
 // CHECK-32-NEXT:       (field name=_value offset=0
-// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0)))))
+// CHECK-32-NEXT:         (builtin size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1)))))
 
 doneReflecting()
 
diff --git a/validation-test/SIL/crashers_fixed/007-swift-abstractstoragedecl-makecomputed.sil b/validation-test/SIL/crashers_fixed/007-swift-abstractstoragedecl-makecomputed.sil
index 43c1f69..4bbe53a 100644
--- a/validation-test/SIL/crashers_fixed/007-swift-abstractstoragedecl-makecomputed.sil
+++ b/validation-test/SIL/crashers_fixed/007-swift-abstractstoragedecl-makecomputed.sil
@@ -1,2 +1,2 @@
 // RUN: not %target-sil-opt %s
-protocol a{@sil_stored var e:a{get
+protocol a{@_hasStorage var e:a{get
diff --git a/validation-test/SIL/parse_stdlib.sil b/validation-test/SIL/parse_stdlib.sil
index 9629e8c..ec9ad1d 100644
--- a/validation-test/SIL/parse_stdlib.sil
+++ b/validation-test/SIL/parse_stdlib.sil
@@ -3,6 +3,3 @@
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=true %t.sil > /dev/null
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
-
-// <rdar://problem/36754225> Swift CI: parse_stdlib.sil tests failing with vtable verification
-// XFAIL: (objc_interop && asserts)
diff --git a/validation-test/Sema/type_checker_perf/fast/rdar32221800.swift b/validation-test/Sema/type_checker_perf/fast/rdar32221800.swift
new file mode 100644
index 0000000..2bc3201
--- /dev/null
+++ b/validation-test/Sema/type_checker_perf/fast/rdar32221800.swift
@@ -0,0 +1,11 @@
+// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1 -swift-version 5 -solver-disable-shrink -disable-constraint-solver-performance-hacks -solver-enable-operator-designated-types
+// REQUIRES: tools-release,no_asserts
+
+func test(header_field_mark: Bool?, header_value_mark: Bool?,
+  url_mark: Bool?, body_mark: Bool?, status_mark: Bool?) {
+  assert(((header_field_mark != nil ? 1 : 0) +
+      (header_value_mark != nil ? 1 : 0) +
+      (url_mark != nil ? 1 : 0)  +
+      (body_mark != nil ? 1 : 0) +
+      (status_mark != nil ? 1 : 0)) <= 1)
+}
diff --git a/validation-test/stdlib/AtomicInt.swift b/validation-test/StdlibUnittest/AtomicInt.swift
similarity index 100%
rename from validation-test/stdlib/AtomicInt.swift
rename to validation-test/StdlibUnittest/AtomicInt.swift
diff --git a/validation-test/StdlibUnittest/RaceTest.swift b/validation-test/StdlibUnittest/RaceTest.swift
index 652a16d..f99fbfd 100644
--- a/validation-test/StdlibUnittest/RaceTest.swift
+++ b/validation-test/StdlibUnittest/RaceTest.swift
@@ -3,6 +3,7 @@
 // REQUIRES: stress_test
 // UNSUPPORTED: nonatomic_rc
 
+import SwiftPrivate
 import StdlibUnittest
 #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
 import Darwin
diff --git a/validation-test/compiler_crashers_2_fixed/0148-rdar35773761.swift b/validation-test/compiler_crashers_2_fixed/0148-rdar35773761.swift
index 55b3a8c..5844463 100644
--- a/validation-test/compiler_crashers_2_fixed/0148-rdar35773761.swift
+++ b/validation-test/compiler_crashers_2_fixed/0148-rdar35773761.swift
@@ -1,4 +1,4 @@
 // RUN: %target-typecheck-verify-swift
 
 let b: () -> Void = withoutActuallyEscaping({ print("hello crash") }, do: { $0() })
-// expected-error@-1 {{cannot convert value of type '()' to specified type '() -> Void'}}
+// expected-error@-1 {{cannot convert value of type '()' to closure result type '() -> Void'}}
diff --git a/validation-test/compiler_crashers_2_fixed/0181-sr8930.swift b/validation-test/compiler_crashers_2_fixed/0181-sr8930.swift
new file mode 100644
index 0000000..4698527
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0181-sr8930.swift
@@ -0,0 +1,46 @@
+// RUN: %target-swift-frontend -emit-ir -g -o - %s 
+
+// REQUIRES: objc_interop
+
+import Foundation
+public final class Foo: NSObject, Collection {
+  public var storage = [String: Any]()
+  
+  public typealias DictionaryType = [String: Any]
+  public typealias IndexDistance = Int
+  public typealias Indices = DictionaryType.Indices
+  public typealias Iterator = DictionaryType.Iterator
+  public typealias SubSequence = DictionaryType.SubSequence
+  public typealias Index = DictionaryType.Index
+  
+  public var startIndex: Index { return storage.startIndex }
+  public var endIndex: DictionaryType.Index { return storage.endIndex }
+  public subscript(position: Index) -> Iterator.Element {
+    return storage[position]
+  }
+  
+  public subscript(bounds: Range<Index>) -> SubSequence {
+    return storage[bounds]
+  }
+  
+  public var indices: Indices { return storage.indices }
+  
+  public subscript(key: String) -> Any? {
+    get { return storage[key] }
+    set { storage[key] = newValue }
+  }
+  
+  public func index(after i: Index) -> Index { return storage.index(after: i) }
+  
+  public func makeIterator() -> DictionaryIterator<String, Any> {
+    return storage.makeIterator()
+  }
+  
+  public override func value(forKey key: String) -> Any? {
+    return storage[key]
+  }
+
+  public override func value(forUndefinedKey key: String) -> Any? {
+    return storage[key]
+  }
+}
diff --git a/validation-test/compiler_crashers_2_fixed/sr9199.swift b/validation-test/compiler_crashers_2_fixed/sr9199.swift
new file mode 100644
index 0000000..422f46b
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/sr9199.swift
@@ -0,0 +1,57 @@
+// RUN: %target-swift-frontend -emit-ir -o %t.ll %s
+
+// Just make sure we don't crash.
+
+protocol Publicable {
+    associatedtype PublicModel
+
+    func publicized() -> PublicModel
+}
+
+
+protocol WithReturnType {
+    associatedtype MainType
+    associatedtype ReturnType
+
+    func returnTheThing()
+}
+
+extension WithReturnType where MainType: Publicable {
+    typealias ReturnType = MainType.PublicModel
+
+    func returnTheThing() {
+        print("publicable")
+    }
+}
+
+extension WithReturnType {
+    func returnTheThing() {
+        print("not publicable")
+    }
+}
+
+extension String: Publicable {
+    struct PublicString {
+        let inner: String
+
+        init(str: String) {
+            self.inner = "Public: \(str)"
+        }
+    }
+
+    func publicized() -> PublicString {
+        return PublicString(str: self)
+    }
+}
+
+struct Controller<T> {
+
+}
+
+extension Controller: WithReturnType {
+    typealias MainType = T
+}
+
+let controller = Controller<String>()
+
+controller.returnTheThing()
\ No newline at end of file
diff --git a/validation-test/stdlib/Algorithm.swift b/validation-test/stdlib/Algorithm.swift
index d784d39..26e933a 100644
--- a/validation-test/stdlib/Algorithm.swift
+++ b/validation-test/stdlib/Algorithm.swift
@@ -222,83 +222,5 @@
   let _: Array = ([5, 4, 3, 2, 1] as ArraySlice).sorted()
 }
 
-Algorithm.test("sort3/simple")
-  .forEach(in: [
-    [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]
-  ]) {
-    var input = $0
-    input._sort3(0, 1, 2, by: <)
-    expectEqual([1, 2, 3], input)
-}
-
-func isSorted<T>(_ a: [T], by areInIncreasingOrder: (T, T) -> Bool) -> Bool {
-  return !a.dropFirst().enumerated().contains(where: { (offset, element) in
-    areInIncreasingOrder(element, a[offset])
-  })
-}
-
-Algorithm.test("sort3/stable")
-  .forEach(in: [
-    [1, 1, 2], [1, 2, 1], [2, 1, 1], [1, 2, 2], [2, 1, 2], [2, 2, 1], [1, 1, 1]
-  ]) {
-    // decorate with offset, but sort by value
-    var input = Array($0.enumerated())
-    input._sort3(0, 1, 2) { $0.element < $1.element }
-    // offsets should still be ordered for equal values
-    expectTrue(isSorted(input) {
-      if $0.element == $1.element {
-        return $0.offset < $1.offset
-      }
-      return $0.element < $1.element
-    })
-}
-
-Algorithm.test("heapSort") {
-  // This function generate next permutation of 0-1 using long arithmetics 
-  // approach.
-  func addOne(to num: inout [Int]) {
-
-    if num.isEmpty {
-      return
-    }
-    // Consider our num array reflects a binary integer.
-    // Here we are trying to add one to it.
-    var i = num.index(before: num.endIndex)
-    var carrier = 1
-
-    while carrier != 0 {
-      let b = num[i] + carrier
-      // Updating i's bit.
-      num[i] = b % 2
-      // Recalculate new carrier.
-      carrier = b / 2
-
-      // If the length of number was n, we don't want to create new number with
-      // length n + 1 in this test.
-      if i == num.startIndex {
-        break
-      } else {
-        num.formIndex(before: &i)
-      }
-    }
-  } // addOne end.
-
-  // Test binary number size.
-  let numberLength = 11
-  var binaryNumber = [Int](repeating: 0, count: numberLength)
-
-  // We are testing sort on all permutations off 0-1s of size `numberLength`
-  // except the all 1's case (Its equals to all 0's case).
-  while !binaryNumber.allSatisfy({ $0 == 1 }) {
-    var buffer = binaryNumber
-
-    buffer._heapSort(within: buffer.startIndex..<buffer.endIndex, by: <)
-
-    expectTrue(isSorted(buffer, by: <))
-
-    addOne(to: &binaryNumber)
-  }
-}
-
 runAllTests()
 
diff --git a/validation-test/stdlib/AtomicsDiagnostics.swift b/validation-test/stdlib/AtomicsDiagnostics.swift
index 6a30ae3..b327c05 100644
--- a/validation-test/stdlib/AtomicsDiagnostics.swift
+++ b/validation-test/stdlib/AtomicsDiagnostics.swift
@@ -1,4 +1,6 @@
 // RUN: %target-typecheck-verify-swift
 
+import SwiftPrivate
+
 class AtomicIntSubclass : _stdlib_AtomicInt {} // expected-error {{inheritance from a final class '_stdlib_AtomicInt'}}
 
diff --git a/validation-test/stdlib/CollectionOld.swift b/validation-test/stdlib/CollectionOld.swift
index dd9c7a4..64defcb 100644
--- a/validation-test/stdlib/CollectionOld.swift
+++ b/validation-test/stdlib/CollectionOld.swift
@@ -1,4 +1,4 @@
-// RUN: %target-run-simple-swift-swift3 --stdlib-unittest-in-process | tee %t.txt
+// RUN: %target-run-simple-swift --stdlib-unittest-in-process | tee %t.txt
 // RUN: %FileCheck %s < %t.txt
 // note: remove the --stdlib-unittest-in-process once all the FileCheck tests
 // have been converted to StdlibUnittest
diff --git a/validation-test/stdlib/FixedPoint.swift.gyb b/validation-test/stdlib/FixedPoint.swift.gyb
index f83f762..f096046 100644
--- a/validation-test/stdlib/FixedPoint.swift.gyb
+++ b/validation-test/stdlib/FixedPoint.swift.gyb
@@ -1,4 +1,4 @@
-// RUN: %target-run-stdlib-swiftgyb-swift3
+// RUN: %target-run-stdlib-swiftgyb
 // REQUIRES: executable_test
 
 import StdlibUnittest
@@ -80,7 +80,7 @@
 }
 
 //===----------------------------------------------------------------------===//
-// 'Int(truncatingBitPattern:)' initializer
+// 'Int(truncatingIfNeeded:)' initializer
 //===----------------------------------------------------------------------===//
 
 %{
@@ -97,11 +97,11 @@
 %
 %       for bit_pattern in test_bit_patterns:
 
-FixedPoint.test("${Dst}(truncatingBitPattern:) from ${Src}(${bit_pattern})") {
+FixedPoint.test("${Dst}(truncatingIfNeeded:) from ${Src}(${bit_pattern})") {
 %       input = prepare_bit_pattern(bit_pattern, src_ty.bits, src_ty.is_signed)
   let input = get${Src}(${input})
 %       input = prepare_bit_pattern(input, src_ty.bits, False)
-  let output = get${Dst}(${Dst}(truncatingBitPattern: input))
+  let output = get${Dst}(${Dst}(truncatingIfNeeded: input))
   let expected = get${Dst}(${prepare_bit_pattern(input, dst_ty.bits, dst_ty.is_signed)})
   expectEqual(expected, output)
 }
diff --git a/validation-test/stdlib/HashedCollectionFilter4.swift b/validation-test/stdlib/HashedCollectionFilter.swift
similarity index 72%
rename from validation-test/stdlib/HashedCollectionFilter4.swift
rename to validation-test/stdlib/HashedCollectionFilter.swift
index 9c4c9e0..ef73438 100644
--- a/validation-test/stdlib/HashedCollectionFilter4.swift
+++ b/validation-test/stdlib/HashedCollectionFilter.swift
@@ -1,13 +1,11 @@
-// RUN: %target-run-stdlib-swift-swift3
+// RUN: %target-run-stdlib-swift
 // REQUIRES: executable_test
 
 import StdlibUnittest
 
 var FilterTestSuite = TestSuite("HashedCollectionFilter")
 
-FilterTestSuite.test("Dictionary.filter(_:) -> [Key: Value]")
-  .xfail(.always("Not actually running under Swift 4")).code
-{
+FilterTestSuite.test("Dictionary.filter(_:) -> [Key: Value]") {
   let d = [10: 1010, 20: 1020, 30: 1030, 40: 1040]
   // filter(_:) should produce a dictionary in Swift 4
   let f: Any = d.filter { $0.key > 20 }
@@ -21,9 +19,7 @@
   expectEqual(2, f.count)
 }
 
-FilterTestSuite.test("Set.filter(_:) -> Set<Element>")
-  .xfail(.always("Not actually running under Swift 4")).code
-{
+FilterTestSuite.test("Set.filter(_:) -> Set<Element>") {
   let s: Set = [10, 20, 30, 40]
   // filter(_:) should produce a set in Swift 4
   let f: Any = s.filter { $0 > 20 }
@@ -37,18 +33,14 @@
   expectEqual(2, f.count)
 }
 
-FilterTestSuite.test("Dictionary.keys -> Keys")
-  .xfail(.always("Not actually running under Swift 4")).code
-{
+FilterTestSuite.test("Dictionary.keys -> Keys") {
   let d = [10: 1010, 20: 1020, 30: 1030, 40: 1040]
   // .keys should produce a Dictionary.Keys in Swift 4
   let f: Any = d.keys
   expectTrue(f is Dictionary<Int, Int>.Keys)
 }
 
-FilterTestSuite.test("Dictionary.values -> Values")
-  .xfail(.always("Not actually running under Swift 4")).code
-{
+FilterTestSuite.test("Dictionary.values -> Values") {
   let d = [10: 1010, 20: 1020, 30: 1030, 40: 1040]
   // .values should produce a Dictionary.Values in Swift 4
   let f: Any = d.values
diff --git a/validation-test/stdlib/HashedCollectionFilter3.swift b/validation-test/stdlib/HashedCollectionFilter3.swift
deleted file mode 100644
index ac1408e..0000000
--- a/validation-test/stdlib/HashedCollectionFilter3.swift
+++ /dev/null
@@ -1,37 +0,0 @@
-// RUN: %target-run-stdlib-swift-swift3
-// REQUIRES: executable_test
-
-import StdlibUnittest
-
-var FilterTestSuite = TestSuite("HashedCollectionFilter")
-
-FilterTestSuite.test("Dictionary.filter(_:) -> [(Key, Value)]") {
-  let d = [10: 1010, 20: 1020, 30: 1030, 40: 1040]
-  let f: Any = d.filter { (k, v) in k > 20 }
-  expectTrue(f is [(Int, Int)])
-}
-
-FilterTestSuite.test("Set.filter(_:) -> [Element]") {
-  let s: Set = [10, 20, 30, 40]
-  let f: Any = s.filter { $0 > 20 }
-  expectTrue(f is [Int])
-}
-
-FilterTestSuite.test("Dictionary.keys -> LazyMapCollection") {
-  let d = [10: 1010, 20: 1020, 30: 1030, 40: 1040]
-  // .keys should produce a LazyMapCollection in Swift 3
-  let f: Any = d.keys
-  let g = f as! LazyMapCollection<[Int: Int], Int>
-  expectEqual(4, g.count)
-}
-
-FilterTestSuite.test("Dictionary.values -> LazyMapCollection") {
-  let d = [10: 1010, 20: 1020, 30: 1030, 40: 1040]
-  // .values should produce a LazyMapCollection in Swift 3
-  let f: Any = d.values
-  let g = f as! LazyMapCollection<[Int: Int], Int>
-  expectEqual(4, g.count)
-}
-
-runAllTests()
-
diff --git a/validation-test/stdlib/HashingPrototype.swift b/validation-test/stdlib/HashingPrototype.swift
index ec3e2dc..182c8c9 100644
--- a/validation-test/stdlib/HashingPrototype.swift
+++ b/validation-test/stdlib/HashingPrototype.swift
@@ -1,4 +1,4 @@
-// RUN: %target-run-simple-swift-swift3
+// RUN: %target-run-simple-swift
 // REQUIRES: executable_test
 
 // REQUIRES: objc_interop
@@ -140,12 +140,12 @@
   mutating func squeezeHashValue<I : SignedInteger>(
     _ resultRange: Range<I>) -> I {
     // ... finalize hash value computation first...
-    return I(IntMax(_state)) // Should actually clamp the value
+    return I(Int64(_state)) // Should actually clamp the value
   }
   mutating func squeezeHashValue<I : UnsignedInteger>(
     _ resultRange: Range<I>) -> I {
     // ... finalize hash value computation first...
-    return I(UIntMax(_state)) // Should actually clamp the value
+    return I(UInt64(_state)) // Should actually clamp the value
   }
 }
 
diff --git a/validation-test/stdlib/ModelIO.swift b/validation-test/stdlib/ModelIO.swift
index 9ffeb4a..6272a35 100644
--- a/validation-test/stdlib/ModelIO.swift
+++ b/validation-test/stdlib/ModelIO.swift
@@ -3,11 +3,6 @@
 // UNSUPPORTED: OS=watchos
 // REQUIRES: objc_interop
 
-// Currently crashes on iphonesimulator.
-// rdar://35490456
-// UNSUPPORTED: OS=ios
-// UNSUPPORTED: OS=tvos
-
 import StdlibUnittest
 
 import Foundation
diff --git a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
index bcc26dd..d7cb1d1 100644
--- a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
+++ b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
@@ -99,6 +99,7 @@
 */
 
 import Swift
+import SwiftPrivate
 import SwiftShims
 
 // This prototype is only partially implemented, and it relies on specific hash
@@ -125,6 +126,15 @@
   pointer.deallocate()
 }
 
+@_transparent
+func _swift_stdlib_atomicStoreUInt64(
+  object target: UnsafeMutablePointer<UInt64>,
+  desired: UInt64
+) {
+  Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
+}
+
+
 func _swift_stdlib_atomicStoreInt(
   object target: UnsafeMutablePointer<Int>,
   desired: Int) {
diff --git a/validation-test/stdlib/Random.swift b/validation-test/stdlib/Random.swift
index 54119e3..6d50921 100644
--- a/validation-test/stdlib/Random.swift
+++ b/validation-test/stdlib/Random.swift
@@ -3,11 +3,19 @@
 
 import StdlibUnittest
 import StdlibCollectionUnittest
+import SwiftShims // for swift_stdlib_random
 
 let RandomTests = TestSuite("Random")
 
 // _fill(bytes:)
 
+extension RandomNumberGenerator {
+  func _fill(bytes buffer: UnsafeMutableRawBufferPointer) {
+    guard let start = buffer.baseAddress else { return }
+    swift_stdlib_random(start, buffer.count)
+  }
+}
+
 RandomTests.test("_fill(bytes:)") {
   for count in [100, 1000] {
     var bytes1 = [UInt8](repeating: 0, count: count)
diff --git a/validation-test/stdlib/Sort.swift.gyb b/validation-test/stdlib/Sort.swift.gyb
index 6cdd31c..acc8213 100644
--- a/validation-test/stdlib/Sort.swift.gyb
+++ b/validation-test/stdlib/Sort.swift.gyb
@@ -56,6 +56,12 @@
   expectSortedCollection([Int](sortedAry), [Int](originalAry))
 }
 
+func expectSortedCollection<C: Collection>(_ a: C,
+  by areInIncreasingOrder: (C.Element, C.Element) -> Bool
+) {
+  expectFalse(zip(a.dropFirst(), a).contains(where: areInIncreasingOrder))
+}
+
 class OffsetCollection : MutableCollection, RandomAccessCollection {
   typealias Indices = Range<Int>
 
@@ -104,28 +110,44 @@
 
 Algorithm.test("${t}/sorted/${name}") {
   let count = 1000
-  var ary = ${t}((0 ..< count).map { _ in Int.random(in: .min ... .max) })
-  var sortedAry1 = [Int]()
-  var sortedAry2 = ${t}<Int>()
+  let ary = ${t}((0 ..< count).map { _ in Int.random(in: .min ... .max) })
 
   // Similar test for sorting with predicate
 %       if comparePredicate:
-  sortedAry1 = ary.sorted(by: ${comparePredicate})
+  let sortedAry1 = ary.sorted(by: ${comparePredicate})
 %       else:
-  sortedAry1 = ary.sorted()
+  let sortedAry1 = ary.sorted()
 %       end
   expectSortedCollection(sortedAry1, ary)
 
   // Check that sorting works well on intervals
   let i1 = 400
   let i2 = 700
-  sortedAry2 = ary
-  sortedAry2._introSort(within: i1..<i2, by: <)
+  var sortedAry2 = ary
+  sortedAry2[i1..<i2].sort(by: <)
   expectEqual(ary[0..<i1], sortedAry2[0..<i1])
   expectSortedCollection(sortedAry2[i1..<i2], ary[i1..<i2])
   expectEqual(ary[i2..<count], sortedAry2[i2..<count])
 }
 %   end
+
+Algorithm.test("${t}/sorted/stable") {
+  let count = 1000
+  // Using a small range in the random array so that we have repeated elements
+  let ary = (0 ..< count).map { _ in Int.random(in: 1...20) }
+
+  // Decorate with offset, but sort by value
+  var input = ${t}(ary.enumerated())
+  input.sort(by: { $0.element < $1.element })
+
+  // Offsets should still be ordered for equal values
+  expectSortedCollection(input) {
+    if $0.element == $1.element {
+      return $0.offset < $1.offset
+    }
+    return $0.element < $1.element
+  }
+}
 % end
 
 Algorithm.test("sort/CollectionsWithUnusualIndices") {
@@ -134,19 +156,19 @@
 
   // Check if sorting routines work well on collections with startIndex != 0.
   var offsetAry = OffsetCollection(ary, offset: 500, forward: false)
-  offsetAry.sort(${comparePredicate})
+  offsetAry.sort()
   expectSortedCollection(offsetAry.toArray(), ary)
 
   // Check if sorting routines work well on collections with endIndex = Int.max.
   // That could expose overflow errors in index computations.
   offsetAry = OffsetCollection(ary, offset: Int.max, forward: false)
-  offsetAry.sort(${comparePredicate})
+  offsetAry.sort()
   expectSortedCollection(offsetAry.toArray(), ary)
 
   // Check if sorting routines work well on collections with
   // startIndex = Int.min.
   offsetAry = OffsetCollection(ary, offset: Int.min, forward: true)
-  offsetAry.sort(${comparePredicate})
+  offsetAry.sort()
   expectSortedCollection(offsetAry.toArray(), ary)
 }
 
diff --git a/validation-test/stdlib/String.swift b/validation-test/stdlib/String.swift
index fa7a537..a19b5c3 100644
--- a/validation-test/stdlib/String.swift
+++ b/validation-test/stdlib/String.swift
@@ -126,7 +126,7 @@
   typealias View = String.UTF16View
   expectCollectionAssociatedTypes(
     collectionType: View.self,
-    iteratorType: IndexingIterator<View>.self,
+    iteratorType: View.Iterator.self,
     subSequenceType: Substring.UTF16View.self,
     indexType: View.Index.self,
     indicesType: View.Indices.self)
@@ -145,7 +145,7 @@
 StringTests.test("AssociatedTypes-CharacterView") {
   expectCollectionAssociatedTypes(
     collectionType: String.self,
-    iteratorType: IndexingIterator<String>.self,
+    iteratorType: String.Iterator.self,
     subSequenceType: Substring.self,
     indexType: String.Index.self,
     indicesType: DefaultIndices<String>.self)
diff --git a/validation-test/stdlib/UnsafeBufferPointer.swift.gyb b/validation-test/stdlib/UnsafeBufferPointer.swift.gyb
index 45dd131..ddf8783 100644
--- a/validation-test/stdlib/UnsafeBufferPointer.swift.gyb
+++ b/validation-test/stdlib/UnsafeBufferPointer.swift.gyb
@@ -325,6 +325,37 @@
   expectEqual(-1.0, allocated[count-1])
 }
 
+UnsafeMutableBufferPointerTestSuite.test("_withUnsafeMutableBufferPointerIfSupported") {
+  let count = 4
+  let allocated = UnsafeMutablePointer<Int>.allocate(capacity: count)
+  defer { allocated.deallocate() }
+  allocated.initialize(repeating: 1, count: count)
+
+  var buffer = UnsafeMutableBufferPointer(start: allocated, count: count)
+  let result = buffer._withUnsafeMutableBufferPointerIfSupported { buffer in
+    return buffer.reduce(0, +)
+  }
+  expectEqual(count, result)
+}
+
+UnsafeMutableBufferPointerTestSuite.test("sort") {
+  var values = (0..<1000).map({ _ in Int.random(in: 0..<100) })
+  let sortedValues = values.sorted()
+  values.withUnsafeMutableBufferPointer { buffer in
+    buffer.sort()
+  }
+  expectEqual(values, sortedValues)
+}
+
+UnsafeMutableBufferPointerTestSuite.test("partition") {
+  var values = (0..<1000).map({ _ in Int.random(in: 0..<100) })
+  let partitionIndex = values.withUnsafeMutableBufferPointer { buffer in
+    return buffer.partition(by: { $0 % 2 == 0 })
+  }
+  expectTrue(values[..<partitionIndex].allSatisfy({ $0 % 2 != 0 }))
+  expectTrue(values[partitionIndex...].allSatisfy({ $0 % 2 == 0 }))
+}
+
 let bufCount = 4
 let sliceRange: Range = 1..<bufCount-1
 % for mutable in [True, False]:
diff --git a/validation-test/stdlib/XCTest.swift b/validation-test/stdlib/XCTest.swift
index f409a9e..62c4912 100644
--- a/validation-test/stdlib/XCTest.swift
+++ b/validation-test/stdlib/XCTest.swift
@@ -113,7 +113,7 @@
   let failingTestRun = failingTestCase.testRun!
   expectEqual(1, failingTestRun.failureCount)
   expectEqual(0, failingTestRun.unexpectedExceptionCount)
-  expectEqual(observer.failureDescription, "XCTAssertEqual failed: (\"1\") is not equal to (\"2\") - ")
+  expectTrue(observer.failureDescription!.starts(with:  "XCTAssertEqual failed: (\"1\") is not equal to (\"2\")"))
 }
 
 XCTestTestSuite.test("XCTAssertEqual/Optional<T>") {
@@ -147,7 +147,7 @@
   expectEqual(0, failingTestRun.unexpectedExceptionCount)
   expectEqual(1, failingTestRun.totalFailureCount)
   expectFalse(failingTestRun.hasSucceeded)
-  expectEqual(observer.failureDescription, "XCTAssertEqual failed: (\"Optional(1)\") is not equal to (\"Optional(2)\") - ")
+  expectTrue(observer.failureDescription!.starts(with:  "XCTAssertEqual failed: (\"Optional(1)\") is not equal to (\"Optional(2)\")"))
 }
 
 XCTestTestSuite.test("XCTAssertEqual/Array<T>") {